80 #include "../base/base_uses.f90"
99 SUBROUTINE cp_eval_at(gopt_env, x, f, gradient, master, &
100 final_evaluation, para_env)
106 TYPE(gopt_f_type),
POINTER :: gopt_env
107 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: x
108 REAL(KIND=
dp),
INTENT(out),
OPTIONAL :: f
109 REAL(KIND=
dp),
DIMENSION(:),
OPTIONAL, &
111 INTEGER,
INTENT(IN) :: master
112 LOGICAL,
INTENT(IN),
OPTIONAL :: final_evaluation
113 TYPE(mp_para_env_type),
POINTER :: para_env
119 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'bfgs_optimizer'
120 LOGICAL,
PARAMETER :: debug_this_module = .true.
137 RECURSIVE SUBROUTINE geoopt_bfgs(force_env, gopt_param, globenv, geo_section, gopt_env, x0)
139 TYPE(force_env_type),
POINTER :: force_env
140 TYPE(gopt_param_type),
POINTER :: gopt_param
141 TYPE(global_environment_type),
POINTER :: globenv
142 TYPE(section_vals_type),
POINTER :: geo_section
143 TYPE(gopt_f_type),
POINTER :: gopt_env
144 REAL(kind=
dp),
DIMENSION(:),
POINTER :: x0
146 CHARACTER(len=*),
PARAMETER :: routinen =
'geoopt_bfgs'
147 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
149 CHARACTER(LEN=5) :: wildcard
150 CHARACTER(LEN=default_path_length) :: hes_filename
151 INTEGER :: handle, hesunit_read, indf, info, &
152 iter_nr, its, maxiter, ndf, nfree, &
154 LOGICAL :: conv, hesrest, ionode, shell_present, &
155 should_stop, use_mod_hes, use_rfo
156 REAL(kind=
dp) :: ediff, emin, eold, etot, pred, rad, rat, &
157 step, t_diff, t_now, t_old
158 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dg, dr, dx, eigval, gold, work, xold
159 REAL(kind=
dp),
DIMENSION(:),
POINTER :: g
160 TYPE(atomic_kind_list_type),
POINTER :: atomic_kinds
161 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
162 TYPE(cp_fm_struct_type),
POINTER :: fm_struct_hes
163 TYPE(cp_fm_type) :: eigvec_mat, hess_mat, hess_tmp
164 TYPE(cp_logger_type),
POINTER :: logger
165 TYPE(mp_para_env_type),
POINTER :: para_env
166 TYPE(cp_subsys_type),
POINTER :: subsys
167 TYPE(section_vals_type),
POINTER :: print_key, root_section
168 TYPE(spgr_type),
POINTER :: spgr
170 NULLIFY (logger, g, blacs_env, spgr)
172 para_env => force_env%para_env
173 root_section => force_env%root_section
174 spgr => gopt_env%spgr
177 CALL timeset(routinen, handle)
180 ionode = para_env%is_source()
181 maxiter = gopt_param%max_iter
187 SELECT CASE (gopt_env%type_id)
189 cpabort(
"BFGS method not yet working with DIMER")
197 IF (output_unit > 0)
THEN
199 WRITE (unit=output_unit, fmt=
"(/,T2,A,T78,A3)") &
200 "BFGS| Use rational function optimization for step estimation: ",
"YES"
202 WRITE (unit=output_unit, fmt=
"(/,T2,A,T78,A3)") &
203 "BFGS| Use rational function optimization for step estimation: ",
" NO"
205 IF (use_mod_hes)
THEN
206 WRITE (unit=output_unit, fmt=
"(T2,A,T78,A3)") &
207 "BFGS| Use model Hessian for initial guess: ",
"YES"
209 WRITE (unit=output_unit, fmt=
"(T2,A,T78,A3)") &
210 "BFGS| Use model Hessian for initial guess: ",
" NO"
213 WRITE (unit=output_unit, fmt=
"(T2,A,T78,A3)") &
214 "BFGS| Restart Hessian: ",
"YES"
216 WRITE (unit=output_unit, fmt=
"(T2,A,T78,A3)") &
217 "BFGS| Restart Hessian: ",
" NO"
219 WRITE (unit=output_unit, fmt=
"(T2,A,T61,F20.3)") &
220 "BFGS| Trust radius: ", rad
224 nfree = gopt_env%nfree
226 CALL cp_warn(__location__, &
227 "The dimension of the Hessian matrix ("// &
228 trim(adjustl(cp_to_string(ndf)))//
") is greater than 3000. "// &
229 "The diagonalisation of the full Hessian matrix needed for BFGS "// &
230 "is computationally expensive. You should consider to use the linear "// &
231 "scaling variant L-BFGS instead.")
235 globenv%blacs_repeatable)
237 nrow_global=ndf, ncol_global=ndf)
238 CALL cp_fm_create(hess_mat, fm_struct_hes, name=
"hess_mat")
239 CALL cp_fm_create(hess_tmp, fm_struct_hes, name=
"hess_tmp")
240 CALL cp_fm_create(eigvec_mat, fm_struct_hes, name=
"eigvec_mat")
241 ALLOCATE (eigval(ndf))
247 IF (use_mod_hes)
THEN
248 IF (shell_present)
THEN
249 CALL cp_warn(__location__, &
250 "No model Hessian is available for core-shell models. "// &
251 "A unit matrix is used as the initial Hessian.")
252 use_mod_hes = .false.
255 CALL cp_warn(__location__, &
256 "No model Hessian is available for cell optimizations. "// &
257 "A unit matrix is used as the initial Hessian.")
258 use_mod_hes = .false.
262 IF (use_mod_hes)
THEN
264 CALL construct_initial_hess(gopt_env%force_env, hess_mat)
265 CALL cp_fm_to_fm(hess_mat, hess_tmp)
270 IF (output_unit > 0)
WRITE (output_unit, *) &
271 "BFGS: Matrix diagonalization failed, using unity as model Hessian."
273 DO its = 1,
SIZE(eigval)
274 IF (eigval(its) .LT. 0.1_dp) eigval(its) = 0.1_dp
276 CALL cp_fm_to_fm(eigvec_mat, hess_tmp)
278 CALL parallel_gemm(
"N",
"T", ndf, ndf, ndf, one, hess_tmp, eigvec_mat, zero, hess_mat)
307 IF (spgr%keep_space_group)
THEN
314 CALL cp_iterate(logger%iter_info, increment=0, iter_nr_out=iter_nr)
318 CALL cp_eval_at(gopt_env, x0, etot, g, gopt_env%force_env%para_env%mepos, &
319 .false., gopt_env%force_env%para_env)
322 IF (spgr%keep_space_group)
THEN
330 t_diff = t_now - t_old
332 CALL gopt_f_io_init(gopt_env, output_unit, etot, wildcard=wildcard, its=iter_nr, used_time=t_diff)
333 DO its = iter_nr + 1, maxiter
334 CALL cp_iterate(logger%iter_info, last=(its == maxiter))
339 IF (((its - iter_nr) == 1) .AND. hesrest)
THEN
342 CALL open_file(file_name=hes_filename, file_status=
"OLD", &
343 file_form=
"UNFORMATTED", file_action=
"READ", unit_number=hesunit_read)
346 IF (ionode)
CALL close_file(unit_number=hesunit_read)
348 IF ((its - iter_nr) > 1)
THEN
350 IF (spgr%keep_space_group)
THEN
356 dx(indf) = x0(indf) - xold(indf)
357 dg(indf) = g(indf) - gold(indf)
360 CALL bfgs(ndf, dx, dg, hess_mat, work, para_env)
363 IF (spgr%keep_space_group)
THEN
370 CALL write_bfgs_hessian(geo_section, hess_mat, logger)
376 IF (spgr%keep_space_group)
THEN
386 CALL cp_fm_to_fm(hess_mat, hess_tmp)
392 IF (output_unit > 0)
WRITE (output_unit, *) &
393 "BFGS: Matrix diagonalization failed, resetting Hessian to unity."
395 CALL cp_fm_to_fm(hess_mat, hess_tmp)
400 CALL set_hes_eig(ndf, eigval, work)
402 CALL rat_fun_opt(ndf, dg, eigval, work, eigvec_mat, g, para_env)
404 CALL geoopt_get_step(ndf, eigval, eigvec_mat, hess_tmp, dr, g, para_env, use_rfo)
407 IF (spgr%keep_space_group)
THEN
411 CALL trust_radius(ndf, step, rad, rat, dr, output_unit)
417 IF (spgr%keep_space_group)
THEN
421 CALL energy_predict(ndf, work, hess_mat, dr, g, conv, pred, para_env)
425 CALL cp_eval_at(gopt_env, x0, etot, g, gopt_env%force_env%para_env%mepos, &
426 .false., gopt_env%force_env%para_env)
431 IF (spgr%keep_space_group)
THEN
437 IF (should_stop)
EXIT
441 t_diff = t_now - t_old
443 CALL gopt_f_io(gopt_env, force_env, root_section, its, etot, output_unit, &
444 eold, emin, wildcard, gopt_param, ndf, dr, g, conv, pred, rat, &
445 step, rad, used_time=t_diff)
447 IF (conv .OR. (its == maxiter))
EXIT
448 IF (etot < emin) emin = etot
449 IF (use_rfo)
CALL update_trust_rad(rat, rad, step, ediff)
452 IF (its == maxiter .AND. (.NOT. conv))
THEN
457 CALL cp_iterate(logger%iter_info, last=.true., increment=0)
458 CALL write_bfgs_hessian(geo_section, hess_mat, logger)
460 gopt_env%force_env%para_env, gopt_env%force_env%para_env%mepos, output_unit)
463 CALL cp_fm_release(hess_mat)
464 CALL cp_fm_release(eigvec_mat)
465 CALL cp_fm_release(hess_tmp)
478 "PRINT%PROGRAM_RUN_INFO")
479 CALL timestop(handle)
493 SUBROUTINE rat_fun_opt(ndf, dg, eigval, work, eigvec_mat, g, para_env)
495 INTEGER,
INTENT(IN) :: ndf
496 REAL(kind=
dp),
INTENT(INOUT) :: dg(ndf), eigval(ndf), work(ndf)
497 TYPE(cp_fm_type),
INTENT(IN) :: eigvec_mat
498 REAL(kind=
dp),
INTENT(INOUT) :: g(ndf)
499 TYPE(mp_para_env_type),
OPTIONAL,
POINTER :: para_env
501 CHARACTER(LEN=*),
PARAMETER :: routinen =
'rat_fun_opt'
502 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp
504 INTEGER :: handle, i, indf, iref, iter, j, k, l, &
505 maxit, ncol_local, nrow_local
506 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
507 LOGICAL :: bisec, fail, set
508 REAL(kind=
dp) :: fun, fun1, fun2, fun3, fung, lam1, lam2, &
509 ln, lp, ssize, step, stol
510 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :),
POINTER :: local_data
512 CALL timeset(routinen, handle)
522 CALL cp_fm_get_info(eigvec_mat, row_indices=row_indices, col_indices=col_indices, &
523 local_data=local_data, nrow_local=nrow_local, ncol_local=ncol_local)
529 dg(l) = dg(l) + local_data(i, k)*g(j)
532 CALL para_env%sum(dg)
543 IF (eigval(iref) < 0.0_dp) ln = eigval(iref) - 0.01_dp
551 fun = fun + dg(indf)**2/(ln - eigval(indf))
552 fung = fung - dg(indf)**2/(ln - eigval(indf)**2)
558 IF (abs(step) < stol)
GOTO 200
559 IF (iter >= maxit)
EXIT
566 IF (eigval(iref) < 0.0_dp) lam1 = eigval(iref) - 0.01_dp
569 fun1 = fun1 + dg(indf)**2/(lam1 - eigval(indf))
572 step = abs(lam1)/1000.0_dp
573 IF (step < ssize) step = ssize
576 IF (iter > maxit)
THEN
583 lam2 = lam1 - iter*step
585 fun2 = fun2 + eigval(indf)**2/(lam2 - eigval(indf))
588 IF (fun2*fun1 < 0.0_dp)
THEN
592 IF (iter > maxit)
THEN
598 step = (lam1 + lam2)/2
601 fun3 = fun3 + dg(indf)**2/(step - eigval(indf))
605 IF (abs(step - lam2) < stol)
THEN
610 IF (fun3*fun1 < stol)
THEN
620 IF ((ln > eigval(iref)) .OR. ((ln > 0.0_dp) .AND. &
621 (eigval(iref) > 0.0_dp)))
THEN
623 IF (.NOT. bisec)
GOTO 100
631 IF (fail .AND. .NOT. set)
THEN
634 eigval(indf) = eigval(indf)*work(indf)
644 eigval(indf) = eigval(indf) - ln
649 CALL timestop(handle)
651 END SUBROUTINE rat_fun_opt
662 SUBROUTINE bfgs(ndf, dx, dg, hess_mat, work, para_env)
663 INTEGER,
INTENT(IN) :: ndf
664 REAL(kind=
dp),
INTENT(INOUT) :: dx(ndf), dg(ndf)
665 TYPE(cp_fm_type),
INTENT(IN) :: hess_mat
666 REAL(kind=
dp),
INTENT(INOUT) :: work(ndf)
667 TYPE(mp_para_env_type),
OPTIONAL,
POINTER :: para_env
669 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bfgs'
670 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
672 INTEGER :: handle, i, j, k, l, ncol_local, &
674 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
675 REAL(kind=
dp) :: ddot, dxw, gdx
676 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :),
POINTER :: local_hes
678 CALL timeset(routinen, handle)
680 CALL cp_fm_get_info(hess_mat, row_indices=row_indices, col_indices=col_indices, &
681 local_data=local_hes, nrow_local=nrow_local, ncol_local=ncol_local)
688 work(j) = work(j) + local_hes(i, k)*dx(l)
692 CALL para_env%sum(work)
694 gdx = ddot(ndf, dg, 1, dx, 1)
696 dxw = ddot(ndf, dx, 1, work, 1)
703 local_hes(i, k) = local_hes(i, k) + gdx*dg(j)*dg(l) - &
708 CALL timestop(handle)
718 SUBROUTINE set_hes_eig(ndf, eigval, work)
719 INTEGER,
INTENT(IN) :: ndf
720 REAL(kind=
dp),
INTENT(INOUT) :: eigval(ndf), work(ndf)
722 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_hes_eig'
723 REAL(kind=
dp),
PARAMETER :: max_neg = -0.5_dp, max_pos = 5.0_dp, &
724 min_eig = 0.005_dp, one = 1.0_dp
726 INTEGER :: handle, indf
729 CALL timeset(routinen, handle)
732 IF (eigval(indf) < 0.0_dp) neg = .true.
733 IF (eigval(indf) > 1000.0_dp) eigval(indf) = 1000.0_dp
736 IF (eigval(indf) < 0.0_dp)
THEN
737 IF (eigval(indf) < max_neg)
THEN
738 eigval(indf) = max_neg
739 ELSE IF (eigval(indf) > -min_eig)
THEN
740 eigval(indf) = -min_eig
742 ELSE IF (eigval(indf) < 1000.0_dp)
THEN
743 IF (eigval(indf) < min_eig)
THEN
744 eigval(indf) = min_eig
745 ELSE IF (eigval(indf) > max_pos)
THEN
746 eigval(indf) = max_pos
752 IF (eigval(indf) < 0.0_dp)
THEN
759 CALL timestop(handle)
761 END SUBROUTINE set_hes_eig
774 SUBROUTINE geoopt_get_step(ndf, eigval, eigvec_mat, hess_tmp, dr, g, para_env, use_rfo)
776 INTEGER,
INTENT(IN) :: ndf
777 REAL(kind=
dp),
INTENT(INOUT) :: eigval(ndf)
778 TYPE(cp_fm_type),
INTENT(IN) :: eigvec_mat, hess_tmp
779 REAL(kind=
dp),
INTENT(INOUT) :: dr(ndf), g(ndf)
780 TYPE(mp_para_env_type),
OPTIONAL,
POINTER :: para_env
783 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
785 INTEGER :: i, indf, j, k, l, ncol_local, nrow_local
786 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
787 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :),
POINTER :: local_data
788 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct
789 TYPE(cp_fm_type) :: tmp
791 CALL cp_fm_to_fm(eigvec_mat, hess_tmp)
794 eigval(indf) = one/eigval(indf)
798 eigval(indf) = one/max(0.0001_dp, eigval(indf))
806 CALL parallel_gemm(
"N",
"T", ndf, ndf, ndf, one, hess_tmp, eigvec_mat, zero, tmp)
809 CALL cp_fm_release(tmp)
813 CALL cp_fm_get_info(hess_tmp, row_indices=row_indices, col_indices=col_indices, &
814 local_data=local_data, nrow_local=nrow_local, ncol_local=ncol_local)
821 dr(j) = dr(j) - local_data(i, k)*g(l)
825 CALL para_env%sum(dr)
827 END SUBROUTINE geoopt_get_step
838 SUBROUTINE trust_radius(ndf, step, rad, rat, dr, output_unit)
839 INTEGER,
INTENT(IN) :: ndf
840 REAL(kind=
dp),
INTENT(INOUT) :: step, rad, rat, dr(ndf)
841 INTEGER,
INTENT(IN) :: output_unit
843 CHARACTER(LEN=*),
PARAMETER :: routinen =
'trust_radius'
844 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp
847 REAL(kind=
dp) :: scal
849 CALL timeset(routinen, handle)
851 step = maxval(abs(dr))
852 scal = max(one, rad/step)
856 CALL dscal(ndf, rat, dr, 1)
858 IF (output_unit > 0)
THEN
859 WRITE (unit=output_unit, fmt=
"(/,T2,A,F8.5)") &
860 " Step is scaled; Scaling factor = ", rat
864 CALL timestop(handle)
866 END SUBROUTINE trust_radius
879 SUBROUTINE energy_predict(ndf, work, hess_mat, dr, g, conv, pred, para_env)
881 INTEGER,
INTENT(IN) :: ndf
882 REAL(kind=
dp),
INTENT(INOUT) :: work(ndf)
883 TYPE(cp_fm_type),
INTENT(IN) :: hess_mat
884 REAL(kind=
dp),
INTENT(INOUT) :: dr(ndf), g(ndf)
885 LOGICAL,
INTENT(INOUT) :: conv
886 REAL(kind=
dp),
INTENT(INOUT) :: pred
887 TYPE(mp_para_env_type),
POINTER :: para_env
889 CHARACTER(LEN=*),
PARAMETER :: routinen =
'energy_predict'
890 REAL(kind=
dp),
PARAMETER :: zero = 0.0_dp
892 INTEGER :: handle, i, j, k, l, ncol_local, &
894 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
895 REAL(kind=
dp) :: ddot, ener1, ener2
896 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :),
POINTER :: local_data
898 CALL timeset(routinen, handle)
900 ener1 = ddot(ndf, g, 1, dr, 1)
902 CALL cp_fm_get_info(hess_mat, row_indices=row_indices, col_indices=col_indices, &
903 local_data=local_data, nrow_local=nrow_local, ncol_local=ncol_local)
910 work(j) = work(j) + local_data(i, k)*dr(l)
914 CALL para_env%sum(work)
915 ener2 = ddot(ndf, dr, 1, work, 1)
916 pred = ener1 + 0.5_dp*ener2
918 CALL timestop(handle)
920 END SUBROUTINE energy_predict
929 SUBROUTINE update_trust_rad(rat, rad, step, ediff)
931 REAL(kind=
dp),
INTENT(INOUT) :: rat, rad, step, ediff
933 CHARACTER(LEN=*),
PARAMETER :: routinen =
'update_trust_rad'
934 REAL(kind=
dp),
PARAMETER :: max_trust = 1.0_dp, min_trust = 0.1_dp
938 CALL timeset(routinen, handle)
940 IF (rat > 4.0_dp)
THEN
941 IF (ediff < 0.0_dp)
THEN
946 ELSE IF (rat > 2.0_dp)
THEN
947 IF (ediff < 0.0_dp)
THEN
952 ELSE IF (rat > 4.0_dp/3.0_dp)
THEN
953 IF (ediff < 0.0_dp)
THEN
958 ELSE IF (rat > 10.0_dp/9.0_dp)
THEN
959 IF (ediff < 0.0_dp)
THEN
964 ELSE IF (rat > 0.9_dp)
THEN
965 IF (ediff < 0.0_dp)
THEN
970 ELSE IF (rat > 0.75_dp)
THEN
971 IF (ediff < 0.0_dp)
THEN
976 ELSE IF (rat > 0.5_dp)
THEN
977 IF (ediff < 0.0_dp)
THEN
982 ELSE IF (rat > 0.25_dp)
THEN
983 IF (ediff < 0.0_dp)
THEN
988 ELSE IF (ediff < 0.0_dp)
THEN
994 rad = max(rad, min_trust)
995 rad = min(rad, max_trust)
996 CALL timestop(handle)
998 END SUBROUTINE update_trust_rad
1008 SUBROUTINE write_bfgs_hessian(geo_section, hess_mat, logger)
1010 TYPE(section_vals_type),
POINTER :: geo_section
1011 TYPE(cp_fm_type),
INTENT(IN) :: hess_mat
1012 TYPE(cp_logger_type),
POINTER :: logger
1014 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_bfgs_hessian'
1016 INTEGER :: handle, hesunit
1018 CALL timeset(routinen, handle)
1021 extension=
".Hessian", file_form=
"UNFORMATTED", file_action=
"WRITE", &
1022 file_position=
"REWIND")
1028 CALL timestop(handle)
1030 END SUBROUTINE write_bfgs_hessian
1038 SUBROUTINE construct_initial_hess(force_env, hess_mat)
1040 TYPE(force_env_type),
POINTER :: force_env
1041 TYPE(cp_fm_type),
INTENT(IN) :: hess_mat
1043 INTEGER :: i, iat_col, iat_row, iglobal, iind, j, &
1044 jat_row, jglobal, jind, k, natom, &
1045 ncol_local, nrow_local, z
1046 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: at_row
1047 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1048 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: d_ij, rho_ij
1049 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: r_ij
1050 REAL(kind=
dp),
DIMENSION(3, 3) :: alpha, r0
1051 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :),
POINTER :: fixed, local_data
1052 TYPE(cell_type),
POINTER :: cell
1053 TYPE(cp_subsys_type),
POINTER :: subsys
1054 TYPE(particle_list_type),
POINTER :: particles
1056 CALL force_env_get(force_env=force_env, subsys=subsys, cell=cell)
1058 particles=particles)
1060 alpha(1, :) = (/1._dp, 0.3949_dp, 0.3949_dp/)
1061 alpha(2, :) = (/0.3494_dp, 0.2800_dp, 0.2800_dp/)
1062 alpha(3, :) = (/0.3494_dp, 0.2800_dp, 0.1800_dp/)
1064 r0(1, :) = (/1.35_dp, 2.10_dp, 2.53_dp/)
1065 r0(2, :) = (/2.10_dp, 2.87_dp, 3.40_dp/)
1066 r0(3, :) = (/2.53_dp, 3.40_dp, 3.40_dp/)
1068 CALL cp_fm_get_info(hess_mat, row_indices=row_indices, col_indices=col_indices, &
1069 local_data=local_data, nrow_local=nrow_local, ncol_local=ncol_local)
1070 natom = particles%n_els
1071 ALLOCATE (at_row(natom))
1072 ALLOCATE (rho_ij(natom, natom))
1073 ALLOCATE (d_ij(natom, natom))
1074 ALLOCATE (r_ij(natom, natom, 3))
1075 ALLOCATE (fixed(3, natom))
1079 CALL hess_mat%matrix_struct%para_env%min(fixed(i, :))
1086 IF (z .LE. 10) at_row(i) = 2
1087 IF (z .LE. 2) at_row(i) = 1
1094 r_ij(j, i, :) =
pbc(particles%els(i)%r, particles%els(j)%r, cell)
1095 r_ij(i, j, :) = -r_ij(j, i, :)
1096 d_ij(j, i) = sqrt(dot_product(r_ij(j, i, :), r_ij(j, i, :)))
1097 d_ij(i, j) = d_ij(j, i)
1098 rho_ij(j, i) = exp(alpha(jat_row, iat_row)*(r0(jat_row, iat_row)**2 - d_ij(j, i)**2))
1099 rho_ij(i, j) = rho_ij(j, i)
1102 DO i = 1, ncol_local
1103 iglobal = col_indices(i)
1104 iind = mod(iglobal - 1, 3) + 1
1105 iat_col = (iglobal + 2)/3
1106 IF (iat_col .GT. natom) cycle
1107 DO j = 1, nrow_local
1108 jglobal = row_indices(j)
1109 jind = mod(jglobal - 1, 3) + 1
1110 iat_row = (jglobal + 2)/3
1111 IF (iat_row .GT. natom) cycle
1112 IF (iat_row .NE. iat_col)
THEN
1113 IF (d_ij(iat_row, iat_col) .LT. 6.0_dp) &
1114 local_data(j, i) = local_data(j, i) + &
1115 angle_second_deriv(r_ij, d_ij, rho_ij, iind, jind, iat_col, iat_row, natom)
1117 local_data(j, i) = local_data(j, i) + &
1118 angle_second_deriv(r_ij, d_ij, rho_ij, iind, jind, iat_col, iat_row, natom)
1120 IF (iat_col .NE. iat_row)
THEN
1121 IF (d_ij(iat_row, iat_col) .LT. 6.0_dp) &
1122 local_data(j, i) = local_data(j, i) - &
1123 dist_second_deriv(r_ij(iat_col, iat_row, :), &
1124 iind, jind, d_ij(iat_row, iat_col), rho_ij(iat_row, iat_col))
1127 IF (k == iat_col) cycle
1128 IF (d_ij(iat_row, k) .LT. 6.0_dp) &
1129 local_data(j, i) = local_data(j, i) + &
1130 dist_second_deriv(r_ij(iat_col, k, :), &
1131 iind, jind, d_ij(iat_row, k), rho_ij(iat_row, k))
1134 IF (fixed(jind, iat_row) .LT. 0.5_dp .OR. fixed(iind, iat_col) .LT. 0.5_dp)
THEN
1135 local_data(j, i) = 0.0_dp
1136 IF (jind == iind .AND. iat_row == iat_col) local_data(j, i) = 1.0_dp
1146 END SUBROUTINE construct_initial_hess
1157 FUNCTION dist_second_deriv(r1, i, j, d, rho)
RESULT(deriv)
1158 REAL(kind=
dp),
DIMENSION(3) :: r1
1160 REAL(kind=
dp) :: d, rho, deriv
1162 deriv = 0.45_dp*rho*(r1(i)*r1(j))/d**2
1177 FUNCTION angle_second_deriv(r_ij, d_ij, rho_ij, idir, jdir, iat_der, jat_der, natom)
RESULT(deriv)
1178 REAL(kind=
dp),
DIMENSION(:, :, :) :: r_ij
1179 REAL(kind=
dp),
DIMENSION(:, :) :: d_ij, rho_ij
1180 INTEGER :: idir, jdir, iat_der, jat_der, natom
1181 REAL(kind=
dp) :: deriv
1183 INTEGER :: i, iat, idr, j, jat, jdr
1184 REAL(kind=
dp) :: d12, d23, d31, d_mat(3, 2), denom1, &
1185 denom2, denom3, ka1, ka2, ka3, rho12, &
1186 rho23, rho31, rsst1, rsst2, rsst3
1187 REAL(kind=
dp),
DIMENSION(3) :: r12, r23, r31
1190 IF (iat_der == jat_der)
THEN
1192 IF (rho_ij(iat_der, i) .LT. 0.00001) cycle
1194 IF (rho_ij(iat_der, j) .LT. 0.00001) cycle
1195 IF (i == iat_der .OR. j == iat_der) cycle
1196 IF (iat_der .LT. i .OR. iat_der .GT. j)
THEN
1197 r12 = r_ij(iat_der, i, :); r23 = r_ij(i, j, :); r31 = r_ij(j, iat_der, :)
1198 d12 = d_ij(iat_der, i); d23 = d_ij(i, j); d31 = d_ij(j, iat_der)
1199 rho12 = rho_ij(iat_der, i); rho23 = rho_ij(i, j); rho31 = rho_ij(j, iat_der)
1201 r12 = r_ij(iat_der, j, :); r23 = r_ij(j, i, :); r31 = r_ij(i, iat_der, :)
1202 d12 = d_ij(iat_der, j); d23 = d_ij(j, i); d31 = d_ij(i, iat_der)
1203 rho12 = rho_ij(iat_der, j); rho23 = rho_ij(j, i); rho31 = rho_ij(i, iat_der)
1205 ka1 = 0.15_dp*rho12*rho23; ka2 = 0.15_dp*rho23*rho31; ka3 = 0.15_dp*rho31*rho12
1206 rsst1 = dot_product(r12, r23); rsst2 = dot_product(r23, r31); rsst3 = dot_product(r31, r12)
1207 denom1 = 1.0_dp - rsst1**2/(d12**2*d23**2); denom2 = 1.0_dp - rsst2**2/(d23**2*d31**2)
1208 denom3 = 1.0_dp - rsst3**2/(d31**2*d12**2)
1209 denom1 = sign(1.0_dp, denom1)*max(abs(denom1), 0.01_dp)
1210 denom2 = sign(1.0_dp, denom2)*max(abs(denom2), 0.01_dp)
1211 denom3 = sign(1.0_dp, denom3)*max(abs(denom3), 0.01_dp)
1212 d_mat(1, 1) = r23(idir)/(d12*d23) - rsst1*r12(idir)/(d12**3*d23)
1213 d_mat(1, 2) = r23(jdir)/(d12*d23) - rsst1*r12(jdir)/(d12**3*d23)
1214 d_mat(2, 1) = -r23(idir)/(d23*d31) + rsst2*r31(idir)/(d23*d31**3)
1215 d_mat(2, 2) = -r23(jdir)/(d23*d31) + rsst2*r31(jdir)/(d23*d31**3)
1216 d_mat(3, 1) = (r31(idir) - r12(idir))/(d31*d12) + rsst3*r31(idir)/(d31**3*d12) - &
1217 rsst3*r12(idir)/(d31*d12**3)
1218 d_mat(3, 2) = (r31(jdir) - r12(jdir))/(d31*d12) + rsst3*r31(jdir)/(d31**3*d12) - &
1219 rsst3*r12(jdir)/(d31*d12**3)
1220 IF (abs(denom1) .LE. 0.011_dp) d_mat(1, 1) = 0.0_dp
1221 IF (abs(denom2) .LE. 0.011_dp) d_mat(2, 1) = 0.0_dp
1222 IF (abs(denom3) .LE. 0.011_dp) d_mat(3, 1) = 0.0_dp
1223 deriv = deriv + ka1*d_mat(1, 1)*d_mat(1, 2)/denom1 + &
1224 ka2*d_mat(2, 1)*d_mat(2, 2)/denom2 + &
1225 ka3*d_mat(3, 1)*d_mat(3, 2)/denom3
1231 IF (i == iat_der .OR. i == jat_der) cycle
1232 IF (jat_der .LT. iat_der)
THEN
1233 iat = jat_der; jat = iat_der; idr = jdir; jdr = idir
1235 iat = iat_der; jat = jat_der; idr = idir; jdr = jdir
1237 IF (jat .LT. i .OR. iat .GT. i)
THEN
1238 r12 = r_ij(iat, jat, :); r23 = r_ij(jat, i, :); r31 = r_ij(i, iat, :)
1239 d12 = d_ij(iat, jat); d23 = d_ij(jat, i); d31 = d_ij(i, iat)
1240 rho12 = rho_ij(iat, jat); rho23 = rho_ij(jat, i); rho31 = rho_ij(i, iat)
1242 r12 = r_ij(iat, i, :); r23 = r_ij(i, jat, :); r31 = r_ij(jat, iat, :)
1243 d12 = d_ij(iat, i); d23 = d_ij(i, jat); d31 = d_ij(jat, iat)
1244 rho12 = rho_ij(iat, i); rho23 = rho_ij(i, jat); rho31 = rho_ij(jat, iat)
1246 ka1 = 0.15_dp*rho12*rho23; ka2 = 0.15_dp*rho23*rho31; ka3 = 0.15_dp*rho31*rho12
1247 rsst1 = dot_product(r12, r23); rsst2 = dot_product(r23, r31); rsst3 = dot_product(r31, r12)
1248 denom1 = 1.0_dp - rsst1**2/(d12**2*d23**2); denom2 = 1.0_dp - rsst2**2/(d23**2*d31**2)
1249 denom3 = 1.0_dp - rsst3**2/(d31**2*d12**2)
1250 denom1 = sign(1.0_dp, denom1)*max(abs(denom1), 0.01_dp)
1251 denom2 = sign(1.0_dp, denom2)*max(abs(denom2), 0.01_dp)
1252 denom3 = sign(1.0_dp, denom3)*max(abs(denom3), 0.01_dp)
1253 d_mat(1, 1) = r23(idr)/(d12*d23) - rsst1*r12(idr)/(d12**3*d23)
1254 d_mat(2, 1) = -r23(idr)/(d23*d31) + rsst2*r31(idr)/(d23*d31**3)
1255 d_mat(3, 1) = (r31(idr) - r12(idr))/(d31*d12) + rsst3*r31(idr)/(d31**3*d12) - &
1256 rsst3*r12(idr)/(d31*d12**3)
1257 IF (jat .LT. i .OR. iat .GT. i)
THEN
1258 d_mat(1, 2) = (r12(jdr) - r23(jdr))/(d12*d23) + rsst1*r12(jdr)/(d12**3*d23) - &
1259 rsst1*r23(jdr)/(d12*d23**3)
1260 d_mat(2, 2) = r31(jdr)/(d23*d31) - rsst2*r23(jdr)/(d23**3*d31)
1261 d_mat(3, 2) = -r31(jdr)/(d31*d12) + rsst3*r12(jdr)/(d31*d12**3)
1263 d_mat(1, 2) = -r12(jdr)/(d12*d23) + rsst1*r23(jdr)/(d12*d23**3)
1264 d_mat(2, 2) = (r23(jdr) - r31(jdr))/(d23*d31) + rsst2*r23(jdr)/(d23**3*d31) - &
1265 rsst2*r31(jdr)/(d23*d31**3)
1266 d_mat(3, 2) = r12(jdr)/(d31*d12) - rsst3*r31(jdr)/(d31**3*d12)
1268 IF (abs(denom1) .LE. 0.011_dp) d_mat(1, 1) = 0.0_dp
1269 IF (abs(denom2) .LE. 0.011_dp) d_mat(2, 1) = 0.0_dp
1270 IF (abs(denom3) .LE. 0.011_dp) d_mat(3, 1) = 0.0_dp
1272 deriv = deriv + ka1*d_mat(1, 1)*d_mat(1, 2)/denom1 + &
1273 ka2*d_mat(2, 1)*d_mat(2, 2)/denom2 + &
1274 ka3*d_mat(3, 1)*d_mat(3, 2)/denom3
1277 deriv = 0.25_dp*deriv
1279 END FUNCTION angle_second_deriv
subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
subroutine cp_eval_at(gopt_env, x, f, gradient, master, final_evaluation, para_env)
evaluete the potential energy and its gradients using an array with same dimension as the particle_se...
represent a simple array based list of the given type
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Routines for Geometry optimization using BFGS algorithm.
recursive subroutine, public geoopt_bfgs(force_env, gopt_param, globenv, geo_section, gopt_env, x0)
Main driver for BFGS geometry optimizations.
Handles all functions related to the CELL.
subroutine, public fix_atom_control(force_env, w)
allows for fix atom constraints
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
basic linear algebra operations for full matrices
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
subroutine, public cp_fm_transpose(matrix, matrixt)
transposes a matrix matrixt = matrix ^ T
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_write_unformatted(fm, unit)
...
subroutine, public cp_fm_read_unformatted(fm, unit)
...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
subroutine, public cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
adds one to the actual iteration
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env)
returns various attributes about the force environment
Define type storing the global information of a run. Keep the amount of stored data small....
contains a functional that calculates the energy and its derivatives for the geometry optimizer
subroutine, public print_geo_opt_header(gopt_env, output_unit, label)
...
subroutine, public gopt_f_io_init(gopt_env, output_unit, opt_energy, wildcard, its, used_time)
Handles the Output during an optimization run.
recursive subroutine, public gopt_f_io_finalize(gopt_env, force_env, x0, conv, its, root_section, para_env, master, output_unit)
Handles the Output at the end of an optimization run.
subroutine, public gopt_f_io(gopt_env, force_env, root_section, its, opt_energy, output_unit, eold, emin, wildcard, gopt_param, ndf, dx, xi, conv, pred, rat, step, rad, used_time)
Handles the Output during an optimization run.
subroutine, public print_geo_opt_nc(gopt_env, output_unit)
...
subroutine, public gopt_f_ii(its, output_unit)
Prints iteration step of the optimization procedure on screen.
contains a functional that calculates the energy and its derivatives for the geometry optimizer
contains typo and related routines to handle parameters controlling the GEO_OPT module
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_path_length
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
represent a simple array based list of the given type
Space Group Symmetry Type Module (version 1.0, Ferbruary 12, 2021)
Space Group Symmetry Module (version 1.0, January 16, 2020)
subroutine, public print_spgr(spgr)
routine prints Space Group Information.
subroutine, public spgr_apply_rotations_coord(spgr, coord)
routine applies the rotation matrices to the coordinates.
subroutine, public identify_space_group(subsys, geo_section, gopt_env, iunit)
routine indentifies the space group and finds rotation matrices.
subroutine, public spgr_apply_rotations_force(spgr, force)
routine applies the rotation matrices to the forces.