32 USE ieee_arithmetic,
ONLY: ieee_is_finite
44 USE iso_fortran_env,
ONLY: iostat_end
60#include "./base/base_uses.f90"
65 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'mode_selective'
66 LOGICAL,
PARAMETER :: debug_this_module = .false.
67 REAL(KIND=
dp),
PARAMETER :: bfgs_guess_degeneracy_tol = 1.0e-8_dp
70 INTEGER :: mat_size = -1
71 INTEGER :: select_id = -1
72 INTEGER,
DIMENSION(:),
POINTER :: inv_atoms => null()
73 REAL(KIND=
dp) :: eps(2) = 0.0_dp
74 REAL(KIND=
dp) :: sel_freq = 0.0_dp
75 REAL(KIND=
dp) :: low_freq = 0.0_dp
76 REAL(KIND=
dp),
POINTER,
DIMENSION(:, :) :: b_vec => null()
77 REAL(KIND=
dp),
POINTER,
DIMENSION(:, :) :: delta_vec => null()
78 REAL(KIND=
dp),
POINTER,
DIMENSION(:, :) :: ms_force => null()
79 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: eig_bfgs => null()
80 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: f_range => null()
81 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: inv_range => null()
82 REAL(KIND=
dp),
POINTER,
DIMENSION(:) :: step_b => null()
83 REAL(KIND=
dp),
POINTER,
DIMENSION(:) :: step_r => null()
84 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: b_mat => null()
85 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: dip_deriv => null()
86 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: hes_bfgs => null()
87 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: s_mat => null()
88 INTEGER :: initial_guess = -1
109 SUBROUTINE ms_vb_anal(input, rep_env, para_env, globenv, particles, &
110 nrep, calc_intens, dx, output_unit, logger, cell)
117 LOGICAL :: calc_intens
119 INTEGER :: output_unit
123 CHARACTER(len=*),
PARAMETER :: routinen =
'ms_vb_anal'
125 CHARACTER(LEN=default_string_length) :: description
126 INTEGER :: handle, i, ip1, j, natoms, ncoord
128 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: mass, pos0
129 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: tmp_deriv
130 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: tmp_dip
131 TYPE(ms_vib_type) :: ms_vib
133 CALL timeset(routinen, handle)
135 natoms =
SIZE(particles)
137 ALLOCATE (mass(3*natoms))
140 mass((i - 1)*3 + j) = particles(i)%atomic_kind%mass
141 mass((i - 1)*3 + j) = sqrt(mass((i - 1)*3 + j))
145 ALLOCATE (ms_vib%delta_vec(ncoord, nrep))
146 ALLOCATE (ms_vib%b_vec(ncoord, nrep))
147 ALLOCATE (ms_vib%step_r(nrep))
148 ALLOCATE (ms_vib%step_b(nrep))
149 IF (calc_intens)
THEN
150 description =
'[DIPOLE]'
151 ALLOCATE (tmp_dip(nrep, 3, 2))
152 ALLOCATE (ms_vib%dip_deriv(3, nrep))
154 CALL ms_initial_moves(para_env, nrep, input, globenv, ms_vib, &
160 ALLOCATE (pos0(ncoord))
161 ALLOCATE (ms_vib%ms_force(ncoord, nrep))
164 pos0((i - 1)*3 + j) = particles((i))%r(j)
169 ms_vib%ms_force = huge(0.0_dp)
172 rep_env%r(j, i) = pos0(j) + ms_vib%step_r(i)*ms_vib%delta_vec(j, i)
178 IF (calc_intens)
THEN
179 CALL get_results(results=rep_env%results(i)%results, &
180 description=description, &
182 CALL get_results(results=rep_env%results(i)%results, &
183 description=description, &
184 values=tmp_dip(i, :, 1), &
188 ms_vib%ms_force(j, i) = rep_env%f(j, i)
193 rep_env%r(j, i) = pos0(j) - ms_vib%step_r(i)*ms_vib%delta_vec(j, i)
197 IF (calc_intens)
THEN
199 CALL get_results(results=rep_env%results(i)%results, &
200 description=description, &
202 CALL get_results(results=rep_env%results(i)%results, &
203 description=description, &
204 values=tmp_dip(i, :, 2), &
206 ms_vib%dip_deriv(:, ms_vib%mat_size + i) = (tmp_dip(i, :, 1) - tmp_dip(i, :, 2))/(2*ms_vib%step_b(i))
210 CALL evaluate_h_update_b(rep_env, ms_vib, input, nrep, &
215 output_unit, logger, cell)
217 IF (calc_intens)
THEN
218 ALLOCATE (tmp_deriv(3, ms_vib%mat_size))
219 tmp_deriv = ms_vib%dip_deriv
220 DEALLOCATE (ms_vib%dip_deriv)
221 ALLOCATE (ms_vib%dip_deriv(3, ms_vib%mat_size + nrep))
222 ms_vib%dip_deriv(:, 1:ms_vib%mat_size) = tmp_deriv(:, 1:ms_vib%mat_size)
223 DEALLOCATE (tmp_deriv)
226 DEALLOCATE (ms_vib%ms_force)
228 DEALLOCATE (ms_vib%step_r)
229 DEALLOCATE (ms_vib%step_b)
230 DEALLOCATE (ms_vib%b_vec)
231 DEALLOCATE (ms_vib%delta_vec)
233 DEALLOCATE (ms_vib%b_mat)
234 DEALLOCATE (ms_vib%s_mat)
235 IF (ms_vib%select_id == 3)
THEN
236 DEALLOCATE (ms_vib%inv_atoms)
238 IF (
ASSOCIATED(ms_vib%eig_bfgs))
THEN
239 DEALLOCATE (ms_vib%eig_bfgs)
241 IF (
ASSOCIATED(ms_vib%hes_bfgs))
THEN
242 DEALLOCATE (ms_vib%hes_bfgs)
244 IF (calc_intens)
THEN
245 DEALLOCATE (ms_vib%dip_deriv)
248 CALL timestop(handle)
265 SUBROUTINE ms_initial_moves(para_env, nrep, input, globenv, ms_vib, particles, &
272 TYPE(ms_vib_type) :: ms_vib
274 REAL(kind=
dp),
DIMENSION(:) :: mass
276 LOGICAL :: calc_intens
279 CHARACTER(len=*),
PARAMETER :: routinen =
'MS_initial_moves'
281 INTEGER :: guess, handle, i, j, jj, k, m, &
282 n_rep_val, natoms, ncoord
283 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: map_atoms
284 INTEGER,
DIMENSION(:),
POINTER :: tmplist
285 LOGICAL :: do_involved_atoms, ionode
286 REAL(kind=
dp) :: my_val, norm
289 CALL timeset(routinen, handle)
290 NULLIFY (ms_vib%eig_bfgs, ms_vib%f_range, ms_vib%hes_bfgs, ms_vib%inv_range)
297 IF (n_rep_val /= 0)
THEN
299 IF (ms_vib%f_range(1) > ms_vib%f_range(2))
THEN
300 my_val = ms_vib%f_range(2)
301 ms_vib%f_range(2) = ms_vib%f_range(1)
302 ms_vib%f_range(1) = my_val
308 IF (ms_vib%sel_freq > 0._dp) ms_vib%select_id = 1
311 IF (do_involved_atoms)
THEN
316 DO j = 1,
SIZE(tmplist)
322 ALLOCATE (ms_vib%inv_atoms(natoms))
326 DO j = 1,
SIZE(tmplist)
327 ms_vib%inv_atoms(j) = tmplist(j)
333 IF (n_rep_val /= 0)
THEN
335 IF (ms_vib%inv_range(1) > ms_vib%inv_range(2))
THEN
336 ms_vib%inv_range(2) = my_val
337 ms_vib%inv_range(2) = ms_vib%inv_range(1)
338 ms_vib%inv_range(1) = my_val
342 IF (ms_vib%select_id == 0)
THEN
343 cpabort(
"no frequency, range or involved atoms specified ")
345 ionode = para_env%is_source()
348 ms_vib%initial_guess = 1
353 DO j = 1,
SIZE(tmplist)
358 natoms =
SIZE(particles)
359 ALLOCATE (map_atoms(natoms))
365 ALLOCATE (map_atoms(natoms))
369 DO j = 1,
SIZE(tmplist)
370 map_atoms(j) = tmplist(j)
377 ms_vib%delta_vec = 0._dp
383 jj = (map_atoms(j) - 1)*3 + k
384 ms_vib%b_vec(jj, i) = abs(globenv%gaussian_rng_stream%next())
387 norm = norm2(ms_vib%b_vec(:, i))
388 ms_vib%b_vec(:, i) = ms_vib%b_vec(:, i)/norm
396 ms_vib%b_vec(:, j) = &
397 ms_vib%b_vec(:, j) - dot_product(ms_vib%b_vec(:, j), ms_vib%b_vec(:, i))*ms_vib%b_vec(:, i)
398 ms_vib%b_vec(:, j) = &
399 ms_vib%b_vec(:, j)/norm2(ms_vib%b_vec(:, j))
407 DO i = 1,
SIZE(ms_vib%b_vec, 1)
408 ms_vib%delta_vec(i, :) = ms_vib%b_vec(i, :)/mass(i)
412 ms_vib%initial_guess = 2
413 CALL bfgs_guess(ms_vib_section, ms_vib, particles, mass, para_env, nrep)
418 ms_vib%initial_guess = 3
419 ncoord = 3*
SIZE(particles)
420 CALL rest_guess(ms_vib_section, para_env, ms_vib, mass, ionode, particles, nrep, calc_intens)
424 ms_vib%initial_guess = 4
425 ncoord = 3*
SIZE(particles)
426 CALL rest_guess(ms_vib_section, para_env, ms_vib, mass, ionode, particles, nrep, calc_intens)
429 ms_vib%initial_guess = 5
430 ncoord = 3*
SIZE(particles)
431 CALL molden_guess(ms_vib_section, input, para_env, ms_vib, mass, ncoord, nrep, logger)
434 CALL para_env%bcast(ms_vib%b_vec)
435 CALL para_env%bcast(ms_vib%delta_vec)
437 ms_vib%step_r(i) = dx/norm2(ms_vib%delta_vec(:, i))
438 ms_vib%step_b(i) = norm2(ms_vib%step_r(i)*ms_vib%b_vec(:, i))
440 CALL timestop(handle)
442 END SUBROUTINE ms_initial_moves
450 SUBROUTINE read_bfgs_guess_hessian(unit, ncoord, hessian)
451 INTEGER,
INTENT(IN) :: unit, ncoord
452 REAL(kind=
dp),
DIMENSION(ncoord, ncoord), &
453 INTENT(OUT) :: hessian
455 INTEGER :: i, ios, stored_method, stored_ndf, &
458 REAL(kind=
dp) :: extra
459 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: column, eigenvalues
460 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: stored_matrix
461 REAL(kind=
dp),
DIMENSION(3, 3) :: cell_frame, reference_cell
464 reference_cell, cell_frame)
466 IF (.NOT. tagged)
THEN
470 READ (unit, iostat=ios) hessian(:, i)
471 IF (ios /= 0) cpabort(
"Error while reading legacy BFGS Hessian")
476 IF (stored_ndf < ncoord)
THEN
477 cpabort(
"BFGS restart matrix is smaller than the mode-selective ionic Hessian")
480 SELECT CASE (stored_method)
482 ALLOCATE (column(stored_ndf))
484 READ (unit, iostat=ios) column(:)
485 IF (ios /= 0) cpabort(
"Truncated BFGS restart matrix")
486 IF (.NOT. all(ieee_is_finite(column(:)))) cpabort(
"Non-finite BFGS restart matrix")
487 IF (i <= ncoord) hessian(:, i) = column(1:ncoord)
492 ALLOCATE (stored_matrix(stored_ndf, stored_ndf), eigenvalues(stored_ndf))
494 READ (unit, iostat=ios) stored_matrix(:, i)
495 IF (ios /= 0) cpabort(
"Truncated inverse BFGS restart matrix")
497 IF (.NOT. all(ieee_is_finite(stored_matrix(:, :))))
THEN
498 cpabort(
"Non-finite inverse BFGS restart matrix")
504 IF (.NOT. all(ieee_is_finite(eigenvalues(:))))
THEN
505 cpabort(
"Non-finite inverse BFGS restart spectrum")
507 IF (minval(eigenvalues(:)) <= 0.0_dp)
THEN
508 cpabort(
"Inverse BFGS restart matrix is not positive definite")
510 eigenvalues(:) = 1.0_dp/eigenvalues(:)
511 IF (.NOT. all(ieee_is_finite(eigenvalues(:))))
THEN
512 cpabort(
"Unrepresentable inverse BFGS restart matrix")
515 stored_matrix(1:ncoord, i) = &
516 sqrt(eigenvalues(i))*stored_matrix(1:ncoord, i)
518 hessian(:, :) = matmul(stored_matrix(1:ncoord, :), &
519 transpose(stored_matrix(1:ncoord, :)))
520 DEALLOCATE (stored_matrix, eigenvalues)
523 cpabort(
"Unknown matrix representation in BFGS restart")
527 READ (unit, iostat=ios) extra
528 IF (ios /= iostat_end) cpabort(
"Extra data in BFGS restart matrix")
529 mark_used(stored_type)
530 mark_used(reference_cell)
531 mark_used(cell_frame)
532 END SUBROUTINE read_bfgs_guess_hessian
544 SUBROUTINE bfgs_guess(ms_vib_section, ms_vib, particles, mass, para_env, nrep)
547 TYPE(ms_vib_type) :: ms_vib
549 REAL(kind=
dp),
DIMENSION(:) :: mass
553 CHARACTER(LEN=default_path_length) :: hes_filename
554 INTEGER :: hesunit, i, j, jj, k, natoms, ncoord, &
556 INTEGER,
DIMENSION(:),
POINTER :: tmplist
557 REAL(kind=
dp) :: my_val, norm
558 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: tmp
564 natoms =
SIZE(particles)
567 ALLOCATE (ms_vib%hes_bfgs(ncoord, ncoord))
568 ALLOCATE (ms_vib%eig_bfgs(ncoord))
570 IF (para_env%is_source())
THEN
572 IF (hes_filename ==
"") hes_filename =
"HESSIAN"
573 CALL open_file(file_name=hes_filename, file_status=
"OLD", &
574 file_form=
"UNFORMATTED", file_action=
"READ", unit_number=hesunit)
575 ALLOCATE (tmp(ncoord))
576 ALLOCATE (tmplist(ncoord))
578 CALL read_bfgs_guess_hessian(hesunit, ncoord, ms_vib%hes_bfgs)
580 IF (output_unit > 0)
THEN
581 WRITE (output_unit, fmt=
"(/,T2,A)") &
582 "*** Initial Hessian has been read successfully ***"
586 ms_vib%hes_bfgs(i, j) = ms_vib%hes_bfgs(i, j)/(mass(i)*mass(j))
590 CALL diamat_all(ms_vib%hes_bfgs, ms_vib%eig_bfgs)
592 IF (ms_vib%select_id == 1) my_val = (ms_vib%sel_freq/
vibfac)**2/
massunit
593 IF (ms_vib%select_id == 2) my_val = (((ms_vib%f_range(2) + ms_vib%f_range(1))*0.5_dp)/
vibfac)**2/
massunit
594 IF (ms_vib%select_id == 1 .OR. ms_vib%select_id == 2)
THEN
596 tmp(i) = abs(my_val - ms_vib%eig_bfgs(i))
598 ELSE IF (ms_vib%select_id == 3)
THEN
599 CALL bfgs_canonicalize_degenerate_modes(ms_vib%hes_bfgs, ms_vib%eig_bfgs)
601 DO j = 1,
SIZE(ms_vib%inv_atoms)
603 jj = (ms_vib%inv_atoms(j) - 1)*3 + k
604 tmp(i) = tmp(i) + sqrt(ms_vib%hes_bfgs(jj, i)**2)
607 IF ((sign(1._dp, ms_vib%eig_bfgs(i))*sqrt(abs(ms_vib%eig_bfgs(i))*
massunit)*
vibfac) <= 400._dp) tmp(i) = 0._dp
611 CALL sort(tmp, ncoord, tmplist)
613 ms_vib%b_vec(:, i) = ms_vib%hes_bfgs(:, tmplist(i))
614 norm = norm2(ms_vib%b_vec(:, i))
615 ms_vib%b_vec(:, i) = ms_vib%b_vec(:, i)/norm
617 DO i = 1,
SIZE(ms_vib%b_vec, 1)
618 ms_vib%delta_vec(i, :) = ms_vib%b_vec(i, :)/mass(i)
624 CALL para_env%bcast(ms_vib%b_vec)
625 CALL para_env%bcast(ms_vib%delta_vec)
627 DEALLOCATE (ms_vib%hes_bfgs)
628 DEALLOCATE (ms_vib%eig_bfgs)
631 END SUBROUTINE bfgs_guess
639 SUBROUTINE bfgs_canonicalize_degenerate_modes(modes, eigenvalues)
640 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: modes
641 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: eigenvalues
643 INTEGER :: first, last, n
644 REAL(kind=
dp) :: cutoff, scale
646 n =
SIZE(eigenvalues)
647 cpassert(
SIZE(modes, 1) == n .AND.
SIZE(modes, 2) == n)
651 DO WHILE (first <= n)
652 IF (eigenvalues(first) <= cutoff)
THEN
658 scale = max(abs(eigenvalues(first)), abs(eigenvalues(last + 1)))
659 IF (eigenvalues(last + 1) - eigenvalues(first) > bfgs_guess_degeneracy_tol*scale)
EXIT
662 IF (last > first)
CALL bfgs_canonical_modes(modes(:, first:last))
665 END SUBROUTINE bfgs_canonicalize_degenerate_modes
671 SUBROUTINE bfgs_canonical_modes(modes)
672 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: modes
674 INTEGER :: i, j, k, m, n, pass, pivot
675 REAL(kind=
dp) :: maximum, norm
676 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: norms, projection, vector
677 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: residual, rotation
681 ALLOCATE (residual(n, m), rotation(m, m), norms(n), projection(n), vector(m))
682 residual(:, :) = modes(:, :)
683 rotation(:, :) = 0.0_dp
685 norms(:) = sum(residual(:, :)**2, dim=2)
686 maximum = maxval(norms)
689 IF (norms(i) >= maximum*(1.0_dp - bfgs_guess_degeneracy_tol))
THEN
694 vector(:) = residual(pivot, :)
697 vector(:) = vector(:) - dot_product(rotation(:, k), vector)*rotation(:, k)
701 cpassert(norm > sqrt(epsilon(1.0_dp)))
702 rotation(:, j) = vector(:)/norm
703 projection(:) = matmul(residual, rotation(:, j))
705 residual(:, k) = residual(:, k) - projection(:)*rotation(k, j)
708 residual(:, :) = matmul(modes, rotation)
709 modes(:, :) = residual(:, :)
710 DEALLOCATE (residual, rotation, norms, projection, vector)
711 END SUBROUTINE bfgs_canonical_modes
725 SUBROUTINE rest_guess(ms_vib_section, para_env, ms_vib, mass, ionode, particles, nrep, calc_intens)
729 TYPE(ms_vib_type) :: ms_vib
730 REAL(kind=
dp),
DIMENSION(:) :: mass
734 LOGICAL :: calc_intens
736 CHARACTER(LEN=default_path_length) :: ms_filename
737 INTEGER :: hesunit, i, j, mat, natoms, ncoord, &
738 output_unit, stat, statint
739 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ind
740 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval
741 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: approx_h
747 natoms =
SIZE(particles)
749 IF (calc_intens)
THEN
750 DEALLOCATE (ms_vib%dip_deriv)
756 IF (ms_filename ==
"") ms_filename =
"MS_RESTART"
758 file_status=
"UNKNOWN", &
759 file_form=
"UNFORMATTED", &
760 file_action=
"READ", &
762 READ (unit=hesunit, iostat=stat) mat
764 ms_vib%mat_size = mat
766 CALL para_env%bcast(ms_vib%mat_size)
767 ALLOCATE (ms_vib%b_mat(ncoord, ms_vib%mat_size))
768 ALLOCATE (ms_vib%s_mat(ncoord, ms_vib%mat_size))
769 IF (calc_intens)
THEN
770 ALLOCATE (ms_vib%dip_deriv(3, ms_vib%mat_size + nrep))
774 READ (unit=hesunit) ms_vib%b_mat
775 READ (unit=hesunit, iostat=stat) ms_vib%s_mat
776 IF (stat /= 0 .AND. output_unit > 0)
THEN
777 WRITE (output_unit, fmt=
"(/,T2,A)")
"** Error while reading MS_RESTART **"
779 IF (calc_intens)
THEN
780 READ (unit=hesunit, iostat=statint) ms_vib%dip_deriv(:, 1:ms_vib%mat_size)
781 IF (statint /= 0 .AND. output_unit > 0)
WRITE (output_unit, fmt=
"(/,T2,A)")
"** Error while reading MS_RESTART,", &
782 "intensities are requested but not present in restart file **"
785 IF (stat == 0 .AND. statint == 0 .AND. output_unit > 0)
THEN
786 WRITE (output_unit, fmt=
"(/,T2,A)")
"*** MS_RESTART has been read successfully ***"
789 CALL para_env%bcast(ms_vib%b_mat)
790 CALL para_env%bcast(ms_vib%s_mat)
791 IF (calc_intens)
CALL para_env%bcast(ms_vib%dip_deriv)
792 ALLOCATE (approx_h(ms_vib%mat_size, ms_vib%mat_size))
793 ALLOCATE (eigenval(ms_vib%mat_size))
794 ALLOCATE (ind(ms_vib%mat_size))
796 CALL dgemm(
'T',
'N', ms_vib%mat_size, ms_vib%mat_size,
SIZE(ms_vib%s_mat, 1), 1._dp, ms_vib%b_mat,
SIZE(ms_vib%b_mat, 1), &
797 ms_vib%s_mat,
SIZE(ms_vib%s_mat, 1), 0._dp, approx_h, ms_vib%mat_size)
800 CALL select_vector(ms_vib, nrep, mass, ncoord, approx_h, eigenval, ind, ms_vib%b_vec)
801 IF (ms_vib%initial_guess /= 4)
THEN
805 DO j = 1, ms_vib%mat_size
806 ms_vib%b_vec(:, i) = ms_vib%b_vec(:, i) + approx_h(j, ind(i))*ms_vib%b_mat(:, j)
808 ms_vib%b_vec(:, i) = ms_vib%b_vec(:, i)/norm2(ms_vib%b_vec(:, i))
811 DEALLOCATE (ms_vib%s_mat)
812 DEALLOCATE (ms_vib%b_mat)
813 IF (calc_intens)
THEN
814 DEALLOCATE (ms_vib%dip_deriv)
815 ALLOCATE (ms_vib%dip_deriv(3, nrep))
818 DEALLOCATE (approx_h)
819 DEALLOCATE (eigenval)
822 ms_vib%delta_vec(:, i) = ms_vib%b_vec(:, i)/mass(:)
825 END SUBROUTINE rest_guess
839 SUBROUTINE molden_guess(ms_vib_section, input, para_env, ms_vib, mass, ncoord, nrep, logger)
842 TYPE(ms_vib_type) :: ms_vib
843 REAL(kind=
dp),
DIMENSION(:) :: mass
844 INTEGER :: ncoord, nrep
847 CHARACTER(LEN=2) :: at_name
848 CHARACTER(LEN=default_path_length) :: ms_filename
849 CHARACTER(LEN=max_line_length) :: info
850 INTEGER :: i, istat, iw, j, jj, k, nvibs, &
851 output_molden, output_unit, stat
852 INTEGER,
DIMENSION(:),
POINTER :: tmplist
853 LOGICAL :: reading_vib
854 REAL(kind=
dp) :: my_val, norm
855 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: freq, tmp
856 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: modes
857 REAL(kind=
dp),
DIMENSION(3, ncoord/3) :: pos
862 IF (ms_filename ==
"") output_molden = &
864 extension=
".mol", file_status=
'UNKNOWN', &
866 IF (para_env%is_source())
THEN
868 IF (ms_filename ==
"")
THEN
871 CALL open_file(file_name=trim(ms_filename), &
872 file_status=
"UNKNOWN", &
873 file_form=
"FORMATTED", &
874 file_action=
"READ", &
882 reading_vib = .false.
884 READ (iw, *, iostat=stat) info
886 IF (trim(adjustl(info)) ==
"[FR-COORD]")
EXIT
890 IF (reading_vib) nvibs = nvibs + 1
891 IF (trim(adjustl(info)) ==
"[FREQ]") reading_vib = .true.
895 READ (iw, *, iostat=stat) info
897 READ (iw, *, iostat=stat) info
901 READ (iw, *, iostat=stat) info
904 IF (trim(adjustl(info)) ==
"[FREQ]")
EXIT
907 ALLOCATE (freq(nvibs))
908 ALLOCATE (modes(ncoord, nvibs))
911 READ (iw, *, iostat=stat) freq(i)
916 READ (iw, *, iostat=stat) at_name, pos(:, i)
925 READ (iw, *, iostat=stat) modes(k:k + 2, i)
930 IF (output_unit > 0)
THEN
932 WRITE (output_unit, fmt=
"(/,T2,A)")
"** Error while reading MOLDEN file **"
934 WRITE (output_unit, fmt=
"(/,T2,A)")
"*** MOLDEN file has been read successfully ***"
938 ALLOCATE (tmp(nvibs))
940 ALLOCATE (tmplist(nvibs))
941 IF (ms_vib%select_id == 1) my_val = ms_vib%sel_freq
942 IF (ms_vib%select_id == 2) my_val = (ms_vib%f_range(2) + ms_vib%f_range(1))*0.5_dp
943 IF (ms_vib%select_id == 1 .OR. ms_vib%select_id == 2)
THEN
945 tmp(i) = abs(my_val - freq(i))
947 ELSE IF (ms_vib%select_id == 3)
THEN
949 DO j = 1,
SIZE(ms_vib%inv_atoms)
951 jj = (ms_vib%inv_atoms(j) - 1)*3 + k
952 tmp(i) = tmp(i) + sqrt(modes(jj, i)**2)
955 IF (freq(i) <= 400._dp) tmp(i) = 0._dp
959 CALL sort(tmp, nvibs, tmplist)
961 ms_vib%b_vec(:, i) = modes(:, tmplist(i))*mass(:)
962 norm = norm2(ms_vib%b_vec(:, i))
963 ms_vib%b_vec(:, i) = ms_vib%b_vec(:, i)/norm
966 ms_vib%delta_vec(:, i) = ms_vib%b_vec(:, i)/mass(:)
975 CALL para_env%bcast(ms_vib%b_vec)
976 CALL para_env%bcast(ms_vib%delta_vec)
979 "VIBRATIONAL_ANALYSIS%PRINT%MOLDEN_VIB")
980 END SUBROUTINE molden_guess
999 SUBROUTINE evaluate_h_update_b(rep_env, ms_vib, input, nrep, &
1003 calc_intens, output_unit_ms, logger, cell)
1005 TYPE(ms_vib_type) :: ms_vib
1009 REAL(kind=
dp),
DIMENSION(:) :: mass
1010 LOGICAL :: converged
1012 LOGICAL :: calc_intens
1013 INTEGER :: output_unit_ms
1017 INTEGER :: i, j, jj, k, natoms, ncoord
1018 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ind
1019 LOGICAL :: dump_only_positive
1020 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval, freq
1021 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: approx_h, h_save, residuum, tmp_b, tmp_s
1022 REAL(kind=
dp),
DIMENSION(2, nrep) :: criteria
1023 REAL(kind=
dp),
DIMENSION(:),
POINTER :: intensities
1025 natoms =
SIZE(particles)
1027 nrep =
SIZE(rep_env%f, 2)
1030 IF (ms_vib%mat_size /= 0)
THEN
1032 ALLOCATE (tmp_b(3*natoms, ms_vib%mat_size))
1033 ALLOCATE (tmp_s(3*natoms, ms_vib%mat_size))
1035 tmp_b(:, :) = ms_vib%b_mat
1036 tmp_s(:, :) = ms_vib%s_mat
1038 DEALLOCATE (ms_vib%b_mat)
1039 DEALLOCATE (ms_vib%s_mat)
1042 ALLOCATE (ms_vib%b_mat(3*natoms, ms_vib%mat_size + nrep))
1043 ALLOCATE (ms_vib%s_mat(3*natoms, ms_vib%mat_size + nrep))
1045 ms_vib%s_mat = 0.0_dp
1048 IF (ms_vib%mat_size /= 0)
THEN
1049 DO j = 1, ms_vib%mat_size
1050 ms_vib%b_mat(i, j) = tmp_b(i, j)
1051 ms_vib%s_mat(i, j) = tmp_s(i, j)
1055 ms_vib%b_mat(i, ms_vib%mat_size + j) = ms_vib%b_vec(i, j)
1059 IF (ms_vib%mat_size /= 0)
THEN
1064 ms_vib%mat_size = ms_vib%mat_size + nrep
1066 ALLOCATE (approx_h(ms_vib%mat_size, ms_vib%mat_size))
1067 ALLOCATE (h_save(ms_vib%mat_size, ms_vib%mat_size))
1068 ALLOCATE (eigenval(ms_vib%mat_size))
1074 ms_vib%s_mat(j, ms_vib%mat_size - nrep + i) = -(ms_vib%ms_force(j, i) - rep_env%f(j, i))/(2*ms_vib%step_b(i)*mass(j))
1078 CALL dgemm(
'T',
'N', ms_vib%mat_size, ms_vib%mat_size,
SIZE(ms_vib%s_mat, 1), 1._dp, ms_vib%b_mat,
SIZE(ms_vib%b_mat, 1), &
1079 ms_vib%s_mat,
SIZE(ms_vib%s_mat, 1), 0._dp, approx_h, ms_vib%mat_size)
1080 h_save(:, :) = approx_h
1085 ALLOCATE (ind(ms_vib%mat_size))
1086 ALLOCATE (residuum(
SIZE(ms_vib%s_mat, 1), nrep))
1088 CALL select_vector(ms_vib, nrep, mass, ncoord, approx_h, eigenval, ind, residuum, criteria)
1094 ms_vib%delta_vec(jj, i) = ms_vib%b_vec(jj, i)/mass(jj)
1100 ms_vib%step_r(i) = dx/norm2(ms_vib%delta_vec(:, i))
1101 ms_vib%step_b(i) = norm2(ms_vib%step_r(i)*ms_vib%b_vec(:, i))
1104 IF (maxval(criteria(1, :)) <= ms_vib%eps(1) .AND. maxval(criteria(2, :)) &
1105 <= ms_vib%eps(2) .OR. ms_vib%mat_size >= ncoord) converged = .true.
1106 ALLOCATE (freq(nrep))
1113 eigenval(:) = sign(1._dp, eigenval(:))*sqrt(abs(eigenval(:))*
massunit)*
vibfac
1114 ALLOCATE (tmp_b(ncoord, ms_vib%mat_size))
1116 ALLOCATE (tmp_s(3, ms_vib%mat_size))
1118 IF (calc_intens)
THEN
1119 ALLOCATE (intensities(ms_vib%mat_size))
1122 DO i = 1, ms_vib%mat_size
1123 DO j = 1, ms_vib%mat_size
1124 tmp_b(:, i) = tmp_b(:, i) + approx_h(j, i)*ms_vib%b_mat(:, j)/mass(:)
1126 tmp_b(:, i) = tmp_b(:, i)/norm2(tmp_b(:, i))
1128 IF (calc_intens)
THEN
1129 DO i = 1, ms_vib%mat_size
1130 DO j = 1, ms_vib%mat_size
1131 tmp_s(:, i) = tmp_s(:, i) + ms_vib%dip_deriv(:, j)*approx_h(j, i)
1133 IF (calc_intens) intensities(i) = norm2(tmp_s(:, i))
1136 IF (calc_intens)
THEN
1137 CALL ms_out(output_unit_ms, converged, freq, criteria, ms_vib, &
1138 input, nrep, approx_h, eigenval, calc_intens, &
1139 intensities=intensities, logger=logger)
1141 CALL ms_out(output_unit_ms, converged, freq, criteria, ms_vib, &
1142 input, nrep, approx_h, eigenval, calc_intens, logger=logger)
1144 dump_only_positive = ms_vib%low_freq > 0.0_dp
1146 dump_only_positive=dump_only_positive, logger=logger, cell=cell)
1147 IF (calc_intens)
THEN
1148 DEALLOCATE (intensities)
1154 IF (.NOT. converged)
CALL ms_out(output_unit_ms, converged, freq, criteria, &
1155 ms_vib, input, nrep, approx_h, eigenval, calc_intens, logger=logger)
1158 DEALLOCATE (approx_h)
1159 DEALLOCATE (eigenval)
1160 DEALLOCATE (residuum)
1163 END SUBROUTINE evaluate_h_update_b
1178 SUBROUTINE select_vector(ms_vib, nrep, mass, ncoord, approx_H, eigenval, ind, residuum, criteria)
1180 TYPE(ms_vib_type) :: ms_vib
1182 REAL(kind=
dp),
DIMENSION(:) :: mass
1184 REAL(kind=
dp),
DIMENSION(:, :) :: approx_h
1185 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1186 INTEGER,
DIMENSION(:) :: ind
1187 REAL(kind=
dp),
DIMENSION(:, :) :: residuum
1188 REAL(kind=
dp),
DIMENSION(2, nrep),
OPTIONAL :: criteria
1190 INTEGER :: i, j, jj, k
1191 REAL(kind=
dp) :: my_val, norm
1192 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: tmp
1193 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_b
1195 ALLOCATE (tmp(ms_vib%mat_size))
1197 SELECT CASE (ms_vib%select_id)
1200 DO i = 1, ms_vib%mat_size
1201 tmp(i) = abs(my_val - eigenval(i))
1203 CALL sort(tmp, (ms_vib%mat_size), ind)
1206 DO i = 1, ms_vib%mat_size
1207 residuum(:, j) = residuum(:, j) + approx_h(i, ind(j))*(ms_vib%s_mat(:, i) - eigenval(ind(j))*ms_vib%b_mat(:, i))
1211 CALL get_vibs_in_range(ms_vib, approx_h, eigenval, residuum, nrep, ind)
1214 ALLOCATE (tmp_b(ncoord, ms_vib%mat_size))
1217 DO i = 1, ms_vib%mat_size
1218 DO j = 1, ms_vib%mat_size
1219 tmp_b(:, i) = tmp_b(:, i) + approx_h(j, i)*ms_vib%b_mat(:, j)/mass(:)
1221 tmp_b(:, i) = tmp_b(:, i)/norm2(tmp_b(:, i))
1224 DO i = 1, ms_vib%mat_size
1225 DO j = 1,
SIZE(ms_vib%inv_atoms)
1227 jj = (ms_vib%inv_atoms(j) - 1)*3 + k
1228 tmp(i) = tmp(i) + sqrt(tmp_b(jj, i)**2)
1231 IF (.NOT.
ASSOCIATED(ms_vib%inv_range))
THEN
1232 IF ((sign(1._dp, eigenval(i))*sqrt(abs(eigenval(i))*
massunit)*
vibfac) <= 400._dp) tmp(i) = 0._dp
1234 IF ((sign(1._dp, eigenval(i))*sqrt(abs(eigenval(i))*
massunit)*
vibfac) <= ms_vib%inv_range(1)) tmp(i) = 0._dp
1235 IF ((sign(1._dp, eigenval(i))*sqrt(abs(eigenval(i))*
massunit)*
vibfac) >= ms_vib%inv_range(2)) tmp(i) = 0._dp
1239 CALL sort(tmp, (ms_vib%mat_size), ind)
1240 residuum(:, :) = 0._dp
1243 DO i = 1, ms_vib%mat_size
1244 residuum(:, j) = residuum(:, j) + approx_h(i, ind(j))*(ms_vib%s_mat(:, i) - eigenval(ind(j))*ms_vib%b_mat(:, i))
1251 DO i = 1, ms_vib%mat_size
1252 residuum(:, j) = residuum(:, j) - dot_product(residuum(:, j), ms_vib%b_mat(:, i))*ms_vib%b_mat(:, i)
1255 IF (
PRESENT(criteria))
THEN
1257 criteria(1, i) = maxval((residuum(:, i)))
1258 criteria(2, i) = norm2(residuum(:, i))
1263 norm = norm2(residuum(:, i))
1264 residuum(:, i) = residuum(:, i)/norm
1269 DO i = 1, ms_vib%mat_size
1270 residuum(:, j) = residuum(:, j) - dot_product(residuum(:, j), ms_vib%b_mat(:, i))*ms_vib%b_mat(:, i)
1271 residuum(:, j) = residuum(:, j)/norm2(residuum(:, j))
1276 residuum(:, j) = residuum(:, j) - dot_product(residuum(:, j), residuum(:, i))*residuum(:, i)
1277 residuum(:, j) = residuum(:, j)/norm2(residuum(:, j))
1283 ms_vib%b_vec = residuum
1285 END SUBROUTINE select_vector
1303 SUBROUTINE ms_out(iw, converged, freq, criter, ms_vib, input, nrep, &
1304 approx_H, eigenval, calc_intens, intensities, logger)
1307 LOGICAL :: converged
1308 REAL(kind=
dp),
DIMENSION(:) :: freq
1309 REAL(kind=
dp),
DIMENSION(:, :) :: criter
1310 TYPE(ms_vib_type) :: ms_vib
1313 REAL(kind=
dp),
DIMENSION(:, :) :: approx_h
1314 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1315 LOGICAL :: calc_intens
1316 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL :: intensities
1319 REAL(kind=
dp),
PARAMETER :: eps_criter1 = 1.0e-07_dp, &
1320 eps_criter2 = 1.0e-06_dp
1322 INTEGER :: i, j, msunit
1323 REAL(kind=
dp) :: crit_a, crit_b, fint, gintval
1324 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: residuum
1328 "VIBRATIONAL_ANALYSIS%MODE_SELECTIVE")
1334 WRITE (iw,
'(T2,A)')
"MS| DAVIDSON ALGORITHM CONVERGED"
1336 WRITE (iw,
'(T2,"MS| TRACKED FREQUENCY (",I0,") IS:",F12.6,3X,A)') i, freq(i),
'cm-1'
1338 ALLOCATE (residuum(
SIZE(ms_vib%b_mat, 1)))
1339 WRITE (iw,
'( /, 1X, 79("-") )')
1340 WRITE (iw,
'( 25X, A)')
'FREQUENCY AND CONVERGENCE LIST'
1341 IF (
PRESENT(intensities))
THEN
1342 WRITE (iw,
'(3X,5(4X, A))')
'FREQUENCY',
'INT[KM/Mole]',
'MAXVAL CRITERIA',
'NORM CRITERIA',
'CONVERGENCE'
1344 WRITE (iw,
'(3X,5(4X, A))')
'FREQUENCY',
'MAXVAL CRITERIA',
'NORM CRITERIA',
'CONVERGENCE'
1346 DO i = 1,
SIZE(ms_vib%b_mat, 2)
1348 DO j = 1,
SIZE(ms_vib%b_mat, 2)
1349 residuum(:) = residuum(:) + approx_h(j, i)*(ms_vib%s_mat(:, j) - eigenval(i)*ms_vib%b_mat(:, j))
1351 DO j = 1, ms_vib%mat_size
1352 residuum(:) = residuum(:) - dot_product(residuum(:), ms_vib%b_mat(:, j))*ms_vib%b_mat(:, j)
1354 crit_a = maxval(residuum(:))
1355 crit_b = norm2(residuum)
1356 IF (
PRESENT(intensities))
THEN
1357 gintval = fint*intensities(i)**2
1358 IF (crit_a <= ms_vib%eps(1) .AND. crit_b <= ms_vib%eps(2))
THEN
1359 IF (eigenval(i) > ms_vib%low_freq)
WRITE (iw,
'(2X,A,2X,F9.3,1X,F12.6,3X,E12.3,7X,E12.3,11X,A)') &
1360 'VIB|', eigenval(i), gintval, crit_a, crit_b,
'YES'
1362 IF (eigenval(i) > ms_vib%low_freq)
WRITE (iw,
'(2X,A,2X,F9.3,1X,F12.6,3X,E12.3,7X,E12.3,11X,A)') &
1363 'VIB|', eigenval(i), gintval, crit_a, crit_b,
'NO'
1366 IF (crit_a <= ms_vib%eps(1) .AND. crit_b <= ms_vib%eps(2))
THEN
1367 IF (eigenval(i) > ms_vib%low_freq)
WRITE (iw,
'(2X,A,2X,F9.3,5X,E12.6,5X,E12.3,11X,A)') &
1368 'VIB|', eigenval(i), crit_a, crit_b,
'YES'
1370 IF (eigenval(i) > ms_vib%low_freq)
WRITE (iw,
'(2X,A,2X,F9.3,5X,E12.6,5X,E12.3,11X,A)') &
1371 'VIB|', eigenval(i), crit_a, crit_b,
'NO'
1375 DEALLOCATE (residuum)
1378 "PRINT%MS_RESTART", extension=
".bin", middle_name=
"MS_RESTART", &
1379 file_status=
"REPLACE", file_form=
"UNFORMATTED", &
1380 file_action=
"WRITE")
1382 IF (msunit > 0)
THEN
1383 WRITE (unit=msunit) ms_vib%mat_size
1384 WRITE (unit=msunit) ms_vib%b_mat
1385 WRITE (unit=msunit) ms_vib%s_mat
1386 IF (calc_intens)
WRITE (unit=msunit) ms_vib%dip_deriv
1395 "PRINT%MS_RESTART", extension=
".bin", middle_name=
"MS_RESTART", &
1396 file_status=
"REPLACE", file_form=
"UNFORMATTED", &
1397 file_action=
"WRITE")
1399 IF (msunit > 0)
THEN
1400 WRITE (unit=msunit) ms_vib%mat_size
1401 WRITE (unit=msunit) ms_vib%b_mat
1402 WRITE (unit=msunit) ms_vib%s_mat
1403 IF (calc_intens)
WRITE (unit=msunit) ms_vib%dip_deriv
1409 WRITE (iw,
'(T2,A,3X,I6)')
"MS| ITERATION STEP", ms_vib%mat_size/nrep
1411 IF (criter(1, i) <= eps_criter1 .AND. (criter(2, i)) <= eps_criter2)
THEN
1412 WRITE (iw,
'(T2,A,3X,F12.6,A)')
"MS| TRACKED MODE ", freq(i),
"cm-1 IS CONVERGED"
1414 WRITE (iw,
'(T2,A,3X,F12.6,A)')
"MS| TRACKED MODE ", freq(i),
"cm-1 NOT CONVERGED"
1420 END SUBROUTINE ms_out
1432 SUBROUTINE get_vibs_in_range(ms_vib, approx_H, eigenval, residuum, nrep, ind)
1434 TYPE(ms_vib_type) :: ms_vib
1435 REAL(kind=
dp),
DIMENSION(:, :) :: approx_h
1436 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1437 REAL(kind=
dp),
DIMENSION(:, :) :: residuum
1439 INTEGER,
DIMENSION(:) :: ind
1441 INTEGER :: count1, count2, i, j
1442 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: map2
1443 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: map1
1444 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: tmp, tmp1
1445 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_resid
1446 REAL(kind=
dp),
DIMENSION(2) :: myrange
1452 ms_vib%mat_size =
SIZE(ms_vib%b_mat, 2)
1453 ALLOCATE (map1(
SIZE(eigenval), 2))
1454 ALLOCATE (tmp(
SIZE(eigenval)))
1455 DO i = 1,
SIZE(eigenval)
1456 IF (abs(eigenval(i) - myrange(1)) + abs(eigenval(i) - myrange(2)) <= &
1457 abs(myrange(1) - myrange(2)) + myrange(1)*0.001_dp)
THEN
1463 tmp(count2) = min(abs(eigenval(i) - myrange(1)), abs(eigenval(i) - myrange(2)))
1467 IF (count1 == nrep)
THEN
1469 DO i = 1, ms_vib%mat_size
1470 residuum(:, j) = residuum(:, j) + approx_h(i, map1(j, 1))*(ms_vib%s_mat(:, i) - eigenval(map1(j, 1))*ms_vib%b_mat(:, i))
1474 ELSE IF (count1 > nrep)
THEN
1475 ALLOCATE (tmp_resid(
SIZE(ms_vib%b_mat, 1), count1))
1476 ALLOCATE (tmp1(count1))
1477 ALLOCATE (map2(count1))
1480 DO i = 1, ms_vib%mat_size
1481 tmp_resid(:, j) = tmp_resid(:, j) + approx_h(i, map1(j, 1))* &
1482 (ms_vib%s_mat(:, i) - eigenval(map1(j, 1))*ms_vib%b_mat(:, i))
1487 DO i = 1, ms_vib%mat_size
1488 tmp_resid(:, j) = tmp_resid(:, j) - dot_product(tmp_resid(:, j), ms_vib%b_mat(:, i))*ms_vib%b_mat(:, i)
1490 tmp(j) = maxval(tmp_resid(:, j))
1492 CALL sort(tmp, count1, map2)
1494 residuum(:, j) = tmp_resid(:, map2(count1 + 1 - j))
1495 ind(j) = map1(map2(count1 + 1 - j), 1)
1497 DEALLOCATE (tmp_resid)
1500 ELSE IF (count1 < nrep)
THEN
1502 ALLOCATE (map2(count2))
1503 IF (count1 /= 0)
THEN
1505 DO i = 1, ms_vib%mat_size
1506 residuum(:, j) = residuum(:, j) + approx_h(i, map1(j, 1))* &
1507 (ms_vib%s_mat(:, i) - eigenval(map1(j, 1))*ms_vib%b_mat(:, i))
1512 CALL sort(tmp, count2, map2)
1513 DO j = 1, nrep - count1
1514 DO i = 1, ms_vib%mat_size
1515 residuum(:, count1 + j) = residuum(:, count1 + j) + approx_h(i, map1(map2(j), 2)) &
1516 *(ms_vib%s_mat(:, i) - eigenval(map1(map2(j), 2))*ms_vib%b_mat(:, i))
1518 ind(count1 + j) = map1(map2(j), 2)
1527 END SUBROUTINE get_vibs_in_range
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Routines for Geometry optimization using BFGS algorithm.
subroutine, public bfgs_read_restart_header(unit, stored_method, stored_ndf, stored_type, tagged, reference_cell, cell_frame)
Read the metadata of a tagged BFGS restart, or identify a legacy raw Hessian.
Handles all functions related to the CELL.
Utility routines to open and close files.
subroutine, public open_file(file_name, unit_number, file_status, file_form, file_action, file_position, file_pad, file_access, debug)
Opens a file and returns its logical unit number.
subroutine, public close_file(unit_number, file_status)
Closes an open file given by its logical unit number.
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
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...
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,...
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, file_access)
...
set of type/routines to handle the storage of results in force_envs
Define type storing the global information of a run. Keep the amount of stored data small....
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Interface to the message passing library MPI.
Module performing a mdoe selective vibrational analysis.
subroutine, public ms_vb_anal(input, rep_env, para_env, globenv, particles, nrep, calc_intens, dx, output_unit, logger, cell)
Module performing a vibrational analysis.
Functions handling the MOLDEN format. Split from mode_selective.
subroutine, public write_vibrations_molden(input, particles, freq, eigen_vec, intensities, calc_intens, dump_only_positive, logger, list, cell)
writes the output for vibrational analysis in MOLDEN format
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public vibfac
real(kind=dp), parameter, public massunit
real(kind=dp), parameter, public bohr
real(kind=dp), parameter, public debye
methods to setup replicas of the same system differing only by atom positions and velocities (as used...
subroutine, public rep_env_calc_e_f(rep_env, calc_f)
evaluates the forces
types used to handle many replica of the same system that differ only in atom positions,...
All kind of helpful little routines.
Type defining parameters related to the simulation cell.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
contains the initially parsed file and the initial parallel environment
stores all the informations relevant to an mpi environment
keeps replicated information about the replicas