Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief contains a functional that calculates the energy and its derivatives
10 : !> for the geometry optimizer
11 : !> \par History
12 : !> none
13 : ! **************************************************************************************************
14 : MODULE gopt_f_methods
15 :
16 : USE atomic_kind_list_types, ONLY: atomic_kind_list_type
17 : USE atomic_kind_types, ONLY: atomic_kind_type, &
18 : get_atomic_kind_set
19 : USE cell_methods, ONLY: cell_create, &
20 : init_cell
21 : USE cell_types, ONLY: cell_copy, &
22 : cell_release, &
23 : cell_type, &
24 : real_to_scaled, &
25 : scaled_to_real
26 : USE cp_log_handling, ONLY: cp_to_string
27 : USE cp_subsys_types, ONLY: cp_subsys_get, &
28 : cp_subsys_set, &
29 : cp_subsys_type, &
30 : pack_subsys_particles
31 : USE cp_units, ONLY: cp_unit_from_cp2k
32 : USE dimer_types, ONLY: dimer_env_type
33 : USE dimer_utils, ONLY: update_dimer_vec
34 : USE distribution_1d_types, ONLY: distribution_1d_type
35 : USE force_env_types, ONLY: force_env_get, &
36 : force_env_get_natom, &
37 : force_env_get_nparticle, &
38 : force_env_type, &
39 : use_qmmm, &
40 : use_qmmmx
41 : USE gopt_f_types, ONLY: gopt_f_type
42 : USE gopt_param_types, ONLY: gopt_param_type
43 : USE input_constants, ONLY: default_cell_direct_id, &
44 : default_cell_geo_opt_id, &
45 : default_cell_md_id, &
46 : default_cell_method_id, &
47 : default_minimization_method_id, &
48 : default_shellcore_method_id, &
49 : default_ts_method_id, &
50 : fix_none
51 : USE input_cp2k_restarts, ONLY: write_restart
52 : USE input_section_types, ONLY: section_vals_type, &
53 : section_vals_val_get
54 : USE kinds, ONLY: default_string_length, &
55 : dp, &
56 : int_8
57 : USE machine, ONLY: m_flush
58 : USE md_energies, ONLY: sample_memory
59 : USE message_passing, ONLY: mp_para_env_type
60 : USE motion_utils, ONLY: write_simulation_cell, &
61 : write_stress_tensor_to_file, &
62 : write_trajectory
63 : USE particle_list_types, ONLY: particle_list_type
64 : USE particle_methods, ONLY: write_structure_data
65 : USE particle_types, ONLY: particle_type
66 : USE qmmm_util, ONLY: apply_qmmm_translate
67 : USE qmmmx_util, ONLY: apply_qmmmx_translate
68 : USE virial_methods, ONLY: virial_evaluate
69 : USE virial_types, ONLY: virial_type
70 : #include "../base/base_uses.f90"
71 :
72 : IMPLICIT NONE
73 : PRIVATE
74 :
75 : #:include "gopt_f77_methods.fypp"
76 :
77 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
78 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = "gopt_f_methods"
79 :
80 : PUBLIC :: gopt_f_create_x0, &
81 : print_geo_opt_header, print_geo_opt_nc, &
82 : gopt_f_io_init, gopt_f_io, gopt_f_io_finalize, gopt_f_ii, &
83 : apply_cell_change
84 :
85 : CONTAINS
86 :
87 : ! **************************************************************************************************
88 : !> \brief returns the value of the parameters for the actual configuration
89 : !> \param gopt_env the geometry optimization environment you want the info about
90 : !> x0: the parameter vector (is allocated by this routine)
91 : !> \param x0 ...
92 : !> \par History
93 : !> - Cell optimization revised (06.11.2012,MK)
94 : ! **************************************************************************************************
95 1964 : SUBROUTINE gopt_f_create_x0(gopt_env, x0)
96 :
97 : TYPE(gopt_f_type), POINTER :: gopt_env
98 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
99 :
100 : INTEGER :: i, idg, j, nparticle
101 : TYPE(cell_type), POINTER :: cell
102 : TYPE(cp_subsys_type), POINTER :: subsys
103 :
104 1964 : NULLIFY (cell)
105 1964 : NULLIFY (subsys)
106 :
107 3718 : SELECT CASE (gopt_env%type_id)
108 : CASE (default_minimization_method_id, default_ts_method_id)
109 1754 : CALL force_env_get(gopt_env%force_env, subsys=subsys)
110 : ! before starting we handle the case of translating coordinates (QM/MM)
111 1754 : IF (gopt_env%force_env%in_use == use_qmmm) &
112 36 : CALL apply_qmmm_translate(gopt_env%force_env%qmmm_env)
113 1754 : IF (gopt_env%force_env%in_use == use_qmmmx) &
114 0 : CALL apply_qmmmx_translate(gopt_env%force_env%qmmmx_env)
115 1754 : nparticle = force_env_get_nparticle(gopt_env%force_env)
116 5262 : ALLOCATE (x0(3*nparticle))
117 1754 : CALL pack_subsys_particles(subsys=subsys, r=x0)
118 : CASE (default_cell_method_id)
119 378 : SELECT CASE (gopt_env%cell_method_id)
120 : CASE (default_cell_direct_id)
121 168 : CALL force_env_get(gopt_env%force_env, subsys=subsys, cell=cell)
122 : ! Store reference cell
123 4368 : gopt_env%h_ref = cell%hmat
124 : ! before starting we handle the case of translating coordinates (QM/MM)
125 168 : IF (gopt_env%force_env%in_use == use_qmmm) &
126 0 : CALL apply_qmmm_translate(gopt_env%force_env%qmmm_env)
127 168 : IF (gopt_env%force_env%in_use == use_qmmmx) &
128 0 : CALL apply_qmmmx_translate(gopt_env%force_env%qmmmx_env)
129 168 : nparticle = force_env_get_nparticle(gopt_env%force_env)
130 504 : ALLOCATE (x0(3*nparticle + 6))
131 168 : CALL pack_subsys_particles(subsys=subsys, r=x0)
132 168 : idg = 3*nparticle
133 672 : DO i = 1, 3
134 1680 : DO j = 1, i
135 1008 : idg = idg + 1
136 1512 : x0(idg) = cell%hmat(j, i)
137 : END DO
138 : END DO
139 : CASE (default_cell_geo_opt_id, default_cell_md_id)
140 42 : CALL force_env_get(gopt_env%force_env, cell=cell)
141 42 : ALLOCATE (x0(6))
142 42 : idg = 0
143 168 : DO i = 1, 3
144 420 : DO j = 1, i
145 252 : idg = idg + 1
146 378 : x0(idg) = cell%hmat(j, i)
147 : END DO
148 : END DO
149 : CASE DEFAULT
150 210 : CPABORT("")
151 : END SELECT
152 : CASE DEFAULT
153 1964 : CPABORT("")
154 : END SELECT
155 :
156 1964 : END SUBROUTINE gopt_f_create_x0
157 :
158 : ! **************************************************************************************************
159 : !> \brief Prints iteration step of the optimization procedure on screen
160 : !> \param its ...
161 : !> \param output_unit ...
162 : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
163 : ! **************************************************************************************************
164 13631 : SUBROUTINE gopt_f_ii(its, output_unit)
165 :
166 : INTEGER, INTENT(IN) :: its, output_unit
167 :
168 13631 : IF (output_unit > 0) THEN
169 6613 : WRITE (UNIT=output_unit, FMT="(/,T2,26('-'))")
170 6613 : WRITE (UNIT=output_unit, FMT="(T2,A,I6)") "OPTIMIZATION STEP: ", its
171 6613 : WRITE (UNIT=output_unit, FMT="(T2,26('-'))")
172 6613 : CALL m_flush(output_unit)
173 : END IF
174 :
175 13631 : END SUBROUTINE gopt_f_ii
176 :
177 : ! **************************************************************************************************
178 : !> \brief Handles the Output during an optimization run
179 : !> \param gopt_env ...
180 : !> \param output_unit ...
181 : !> \param opt_energy ...
182 : !> \param wildcard ...
183 : !> \param its ...
184 : !> \param used_time ...
185 : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
186 : ! **************************************************************************************************
187 1724 : SUBROUTINE gopt_f_io_init(gopt_env, output_unit, opt_energy, wildcard, its, used_time)
188 :
189 : TYPE(gopt_f_type), POINTER :: gopt_env
190 : INTEGER, INTENT(IN) :: output_unit
191 : REAL(KIND=dp) :: opt_energy
192 : CHARACTER(LEN=5) :: wildcard
193 : INTEGER, INTENT(IN) :: its
194 : REAL(KIND=dp) :: used_time
195 :
196 : TYPE(mp_para_env_type), POINTER :: para_env
197 : CHARACTER(LEN=default_string_length) :: energy_unit, stress_unit
198 : REAL(KIND=dp) :: pres_int
199 : INTEGER(KIND=int_8) :: max_memory
200 : LOGICAL :: print_memory
201 :
202 1724 : NULLIFY (para_env)
203 1724 : CALL section_vals_val_get(gopt_env%motion_section, "PRINT%MEMORY_INFO", l_val=print_memory)
204 1724 : max_memory = 0
205 1724 : IF (print_memory) THEN
206 1724 : CALL force_env_get(gopt_env%force_env, para_env=para_env)
207 1724 : max_memory = sample_memory(para_env)
208 : END IF
209 :
210 : CALL section_vals_val_get(gopt_env%force_env%force_env_section, &
211 : "PRINT%PROGRAM_RUN_INFO%ENERGY_UNIT", &
212 1724 : c_val=energy_unit)
213 : CALL section_vals_val_get(gopt_env%force_env%force_env_section, &
214 : "PRINT%STRESS_TENSOR%STRESS_UNIT", &
215 1724 : c_val=stress_unit)
216 :
217 3264 : SELECT CASE (gopt_env%type_id)
218 : CASE (default_ts_method_id, default_minimization_method_id)
219 : ! Geometry Optimization (Minimization and Transition State Search)
220 1540 : IF (.NOT. gopt_env%dimer_rotation) THEN
221 : CALL write_cycle_infos(output_unit, &
222 : it=its, &
223 : etot=opt_energy, &
224 : wildcard=wildcard, &
225 : used_time=used_time, &
226 : max_memory=max_memory, &
227 : energy_unit=energy_unit, &
228 1408 : stress_unit=stress_unit)
229 : ELSE
230 : CALL write_rot_cycle_infos(output_unit, &
231 : it=its, &
232 : etot=opt_energy, &
233 : dimer_env=gopt_env%dimer_env, &
234 : wildcard=wildcard, &
235 : used_time=used_time, &
236 132 : max_memory=max_memory)
237 : END IF
238 : CASE (default_cell_method_id)
239 : ! Cell Optimization
240 164 : pres_int = gopt_env%cell_env%pres_int
241 : CALL write_cycle_infos(output_unit, &
242 : it=its, &
243 : etot=opt_energy, &
244 : pres_int=pres_int, &
245 : wildcard=wildcard, &
246 : used_time=used_time, &
247 : max_memory=max_memory, &
248 : energy_unit=energy_unit, &
249 164 : stress_unit=stress_unit)
250 : CASE (default_shellcore_method_id)
251 : CALL write_cycle_infos(output_unit, &
252 : it=its, &
253 : etot=opt_energy, &
254 : wildcard=wildcard, &
255 : used_time=used_time, &
256 : max_memory=max_memory, &
257 : energy_unit=energy_unit, &
258 1724 : stress_unit=stress_unit)
259 : END SELECT
260 :
261 1724 : END SUBROUTINE gopt_f_io_init
262 :
263 : ! **************************************************************************************************
264 : !> \brief Handles the Output during an optimization run
265 : !> \param gopt_env ...
266 : !> \param force_env ...
267 : !> \param root_section ...
268 : !> \param its ...
269 : !> \param opt_energy ...
270 : !> \param output_unit ...
271 : !> \param eold ...
272 : !> \param emin ...
273 : !> \param wildcard ...
274 : !> \param gopt_param ...
275 : !> \param ndf ...
276 : !> \param dx ...
277 : !> \param xi ...
278 : !> \param conv ...
279 : !> \param pred ...
280 : !> \param rat ...
281 : !> \param step ...
282 : !> \param rad ...
283 : !> \param used_time ...
284 : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
285 : ! **************************************************************************************************
286 27262 : SUBROUTINE gopt_f_io(gopt_env, force_env, root_section, its, opt_energy, &
287 13631 : output_unit, eold, emin, wildcard, gopt_param, ndf, dx, xi, conv, pred, rat, &
288 : step, rad, used_time)
289 :
290 : TYPE(gopt_f_type), POINTER :: gopt_env
291 : TYPE(force_env_type), POINTER :: force_env
292 : TYPE(section_vals_type), POINTER :: root_section
293 : INTEGER, INTENT(IN) :: its
294 : REAL(KIND=dp), INTENT(IN) :: opt_energy
295 : INTEGER, INTENT(IN) :: output_unit
296 : REAL(KIND=dp) :: eold, emin
297 : CHARACTER(LEN=5) :: wildcard
298 : TYPE(gopt_param_type), POINTER :: gopt_param
299 : INTEGER, INTENT(IN), OPTIONAL :: ndf
300 : REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL :: dx
301 : REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER :: xi
302 : LOGICAL, OPTIONAL :: conv
303 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: pred, rat, step, rad
304 : REAL(KIND=dp) :: used_time
305 :
306 : CHARACTER(LEN=default_string_length) :: energy_unit, stress_unit
307 : INTEGER(KIND=int_8) :: max_memory
308 : LOGICAL :: print_memory
309 : REAL(KIND=dp) :: pres_diff, pres_diff_constr, pres_int, &
310 : pres_tol
311 : TYPE(mp_para_env_type), POINTER :: para_env
312 :
313 13631 : NULLIFY (para_env)
314 13631 : CALL section_vals_val_get(gopt_env%motion_section, "PRINT%MEMORY_INFO", l_val=print_memory)
315 13631 : max_memory = 0
316 13631 : IF (print_memory) THEN
317 13631 : CALL force_env_get(force_env, para_env=para_env)
318 13631 : max_memory = sample_memory(para_env)
319 : END IF
320 :
321 : CALL section_vals_val_get(gopt_env%force_env%force_env_section, &
322 : "PRINT%PROGRAM_RUN_INFO%ENERGY_UNIT", &
323 13631 : c_val=energy_unit)
324 : CALL section_vals_val_get(gopt_env%force_env%force_env_section, &
325 : "PRINT%STRESS_TENSOR%STRESS_UNIT", &
326 13631 : c_val=stress_unit)
327 :
328 22994 : SELECT CASE (gopt_env%type_id)
329 : CASE (default_ts_method_id, default_minimization_method_id)
330 : ! Geometry Optimization (Minimization and Transition State Search)
331 9363 : IF (.NOT. gopt_env%dimer_rotation) THEN
332 : CALL geo_opt_io(force_env=force_env, root_section=root_section, &
333 8637 : motion_section=gopt_env%motion_section, its=its, opt_energy=opt_energy)
334 : CALL write_cycle_infos(output_unit, &
335 : it=its, &
336 : etot=opt_energy, &
337 : ediff=(opt_energy - eold), &
338 : pred=pred, &
339 : rat=rat, &
340 : step=step, &
341 : rad=rad, &
342 : emin=emin, &
343 : wildcard=wildcard, &
344 : used_time=used_time, &
345 : max_memory=max_memory, &
346 : energy_unit=energy_unit, &
347 8637 : stress_unit=stress_unit)
348 : ! Possibly check convergence
349 8637 : IF (PRESENT(conv)) THEN
350 8637 : CPASSERT(PRESENT(ndf))
351 8637 : CPASSERT(PRESENT(dx))
352 8637 : CPASSERT(PRESENT(xi))
353 8637 : CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory, stress_unit)
354 : END IF
355 : ELSE
356 726 : CALL update_dimer_vec(gopt_env%dimer_env, gopt_env%motion_section)
357 726 : CALL write_restart(force_env=force_env, root_section=root_section)
358 : CALL write_rot_cycle_infos(output_unit, its, opt_energy, opt_energy - eold, emin, gopt_env%dimer_env, &
359 726 : wildcard=wildcard, used_time=used_time, max_memory=max_memory)
360 : ! Possibly check convergence
361 726 : IF (PRESENT(conv)) THEN
362 726 : CPASSERT(ASSOCIATED(gopt_env%dimer_env))
363 726 : CALL check_rot_conv(gopt_env%dimer_env, output_unit, conv)
364 : END IF
365 : END IF
366 : CASE (default_cell_method_id)
367 : ! Cell Optimization
368 4098 : pres_diff = gopt_env%cell_env%pres_int - gopt_env%cell_env%pres_ext
369 4098 : pres_int = gopt_env%cell_env%pres_int
370 4098 : pres_tol = gopt_env%cell_env%pres_tol
371 : CALL geo_opt_io(force_env=force_env, root_section=root_section, &
372 4098 : motion_section=gopt_env%motion_section, its=its, opt_energy=opt_energy)
373 : CALL write_cycle_infos(output_unit, &
374 : it=its, &
375 : etot=opt_energy, &
376 : ediff=(opt_energy - eold), &
377 : pred=pred, &
378 : rat=rat, &
379 : step=step, &
380 : rad=rad, &
381 : emin=emin, &
382 : pres_int=pres_int, &
383 : wildcard=wildcard, &
384 : used_time=used_time, &
385 : max_memory=max_memory, &
386 : energy_unit=energy_unit, &
387 4098 : stress_unit=stress_unit)
388 : ! Possibly check convergence
389 4098 : IF (PRESENT(conv)) THEN
390 4098 : CPASSERT(PRESENT(ndf))
391 4098 : CPASSERT(PRESENT(dx))
392 4098 : CPASSERT(PRESENT(xi))
393 4098 : IF (gopt_env%cell_env%constraint_id == fix_none) THEN
394 : CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory, stress_unit, &
395 4082 : pres_diff, pres_tol)
396 : ELSE
397 16 : pres_diff_constr = gopt_env%cell_env%pres_constr - gopt_env%cell_env%pres_ext
398 : CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory, stress_unit, &
399 16 : pres_diff, pres_tol, pres_diff_constr)
400 : END IF
401 : END IF
402 : CASE (default_shellcore_method_id)
403 : CALL write_cycle_infos(output_unit, &
404 : it=its, &
405 : etot=opt_energy, &
406 : ediff=(opt_energy - eold), &
407 : pred=pred, &
408 : rat=rat, &
409 : step=step, &
410 : rad=rad, &
411 : emin=emin, &
412 : wildcard=wildcard, &
413 : used_time=used_time, &
414 : max_memory=max_memory, &
415 : energy_unit=energy_unit, &
416 170 : stress_unit=stress_unit)
417 : ! Possibly check convergence
418 13801 : IF (PRESENT(conv)) THEN
419 170 : CPASSERT(PRESENT(ndf))
420 170 : CPASSERT(PRESENT(dx))
421 170 : CPASSERT(PRESENT(xi))
422 170 : CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory, stress_unit)
423 : END IF
424 : END SELECT
425 :
426 13631 : END SUBROUTINE gopt_f_io
427 :
428 : ! **************************************************************************************************
429 : !> \brief Handles the Output at the end of an optimization run
430 : !> \param gopt_env ...
431 : !> \param force_env ...
432 : !> \param x0 ...
433 : !> \param conv ...
434 : !> \param its ...
435 : !> \param root_section ...
436 : !> \param para_env ...
437 : !> \param master ...
438 : !> \param output_unit ...
439 : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
440 : ! **************************************************************************************************
441 2116 : RECURSIVE SUBROUTINE gopt_f_io_finalize(gopt_env, force_env, x0, conv, its, root_section, &
442 : para_env, master, output_unit)
443 : TYPE(gopt_f_type), POINTER :: gopt_env
444 : TYPE(force_env_type), POINTER :: force_env
445 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
446 : LOGICAL :: conv
447 : INTEGER :: its
448 : TYPE(section_vals_type), POINTER :: root_section
449 : TYPE(mp_para_env_type), POINTER :: para_env
450 : INTEGER, INTENT(IN) :: master, output_unit
451 :
452 2116 : IF (gopt_env%eval_opt_geo) THEN
453 1200 : IF (.NOT. gopt_env%dimer_rotation) THEN
454 : CALL write_final_info(output_unit, conv, its, gopt_env, x0, master, &
455 1068 : para_env, force_env, gopt_env%motion_section, root_section)
456 : ELSE
457 132 : CALL update_dimer_vec(gopt_env%dimer_env, gopt_env%motion_section)
458 132 : CALL write_restart(force_env=force_env, root_section=root_section)
459 : END IF
460 : END IF
461 :
462 2116 : END SUBROUTINE gopt_f_io_finalize
463 :
464 : ! **************************************************************************************************
465 : !> \brief ...
466 : !> \param output_unit ...
467 : !> \param it ...
468 : !> \param etot ...
469 : !> \param ediff ...
470 : !> \param pred ...
471 : !> \param rat ...
472 : !> \param step ...
473 : !> \param rad ...
474 : !> \param emin ...
475 : !> \param pres_int ...
476 : !> \param wildcard ...
477 : !> \param used_time ...
478 : ! **************************************************************************************************
479 14497 : SUBROUTINE write_cycle_infos(output_unit, it, etot, ediff, pred, rat, step, rad, emin, &
480 : pres_int, wildcard, used_time, max_memory, energy_unit, stress_unit)
481 :
482 : INTEGER, INTENT(IN) :: output_unit, it
483 : REAL(KIND=dp), INTENT(IN) :: etot
484 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: ediff, pred, rat, step, rad, emin, &
485 : pres_int
486 : CHARACTER(LEN=5), INTENT(IN) :: wildcard
487 : REAL(KIND=dp), INTENT(IN) :: used_time
488 : INTEGER(KIND=int_8), INTENT(IN) :: max_memory
489 : CHARACTER(LEN=default_string_length), INTENT(IN) :: energy_unit, stress_unit
490 :
491 : CHARACTER(LEN=5) :: tag
492 :
493 14497 : IF (output_unit > 0) THEN
494 7052 : tag = "OPT| "
495 7052 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") tag//REPEAT("*", 74)
496 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,I25)") &
497 7052 : tag//"Step number", it
498 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,A25)") &
499 7052 : tag//"Optimization method", wildcard
500 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
501 7052 : tag//"Total energy ["//TRIM(ADJUSTL(energy_unit))//"]", &
502 14104 : cp_unit_from_cp2k(etot, TRIM(energy_unit))
503 7052 : IF (PRESENT(pres_int)) THEN
504 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
505 2131 : tag//"Internal pressure ["//TRIM(ADJUSTL(stress_unit))//"]", &
506 4262 : cp_unit_from_cp2k(pres_int, TRIM(stress_unit))
507 : END IF
508 7052 : IF (PRESENT(ediff)) THEN
509 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
510 6250 : tag//"Effective energy change ["//TRIM(ADJUSTL(energy_unit))//"]", &
511 12500 : cp_unit_from_cp2k(ediff, TRIM(energy_unit))
512 : END IF
513 7052 : IF (PRESENT(pred)) THEN
514 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
515 3296 : tag//"Predicted energy change ["//TRIM(ADJUSTL(energy_unit))//"]", &
516 6592 : cp_unit_from_cp2k(pred, TRIM(energy_unit))
517 : END IF
518 7052 : IF (PRESENT(rat)) THEN
519 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
520 3296 : tag//"Scaling factor", rat
521 : END IF
522 7052 : IF (PRESENT(step)) THEN
523 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
524 3296 : tag//"Step size", step
525 : END IF
526 7052 : IF (PRESENT(rad)) THEN
527 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
528 3296 : tag//"Trust radius", rad
529 : END IF
530 7052 : IF (PRESENT(emin)) THEN
531 6250 : IF (etot < emin) THEN
532 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
533 5690 : tag//"Decrease in energy", " YES"
534 : ELSE
535 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
536 560 : tag//"Decrease in energy", " NO"
537 : END IF
538 : END IF
539 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.3)") &
540 7052 : tag//"Used time [s]", used_time
541 7052 : IF (it == 0) THEN
542 796 : WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
543 796 : IF (max_memory /= 0) THEN
544 : WRITE (UNIT=output_unit, FMT="(T2,A,T60,1X,I20)") &
545 796 : tag//"Estimated peak process memory [MiB]", &
546 1592 : (max_memory + (1024*1024) - 1)/(1024*1024)
547 : END IF
548 : END IF
549 : END IF
550 :
551 14497 : END SUBROUTINE write_cycle_infos
552 :
553 : ! **************************************************************************************************
554 : !> \brief ...
555 : !> \param output_unit ...
556 : !> \param it ...
557 : !> \param etot ...
558 : !> \param ediff ...
559 : !> \param emin ...
560 : !> \param dimer_env ...
561 : !> \param used_time ...
562 : !> \param wildcard ...
563 : !> \date 01.2008
564 : !> \author Luca Bellucci and Teodoro Laino - created [tlaino]
565 : ! **************************************************************************************************
566 858 : SUBROUTINE write_rot_cycle_infos(output_unit, it, etot, ediff, emin, dimer_env, used_time, &
567 : wildcard, max_memory)
568 :
569 : INTEGER, INTENT(IN) :: output_unit, it
570 : REAL(KIND=dp), INTENT(IN) :: etot
571 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: ediff, emin
572 : TYPE(dimer_env_type), POINTER :: dimer_env
573 : REAL(KIND=dp), INTENT(IN) :: used_time
574 : CHARACTER(LEN=5), INTENT(IN) :: wildcard
575 : INTEGER(KIND=int_8), INTENT(IN) :: max_memory
576 :
577 : CHARACTER(LEN=5) :: tag
578 :
579 858 : IF (output_unit > 0) THEN
580 429 : tag = "OPT| "
581 429 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") tag//REPEAT("*", 74)
582 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,I25)") &
583 429 : tag//"Rotational step number", it
584 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,A25)") &
585 429 : tag//"Optimization method", wildcard
586 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
587 429 : tag//"Local curvature", dimer_env%rot%curvature, &
588 858 : tag//"Total rotational force", etot
589 429 : IF (PRESENT(ediff)) THEN
590 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
591 363 : tag//"Rotational force change", ediff
592 : END IF
593 429 : IF (PRESENT(emin)) THEN
594 363 : IF (etot < emin) THEN
595 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
596 157 : tag//"Decrease in rotational force", " YES"
597 : ELSE
598 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
599 206 : tag//"Decrease in rotational force", " NO"
600 : END IF
601 : END IF
602 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.3)") &
603 429 : tag//"Used time [s]", used_time
604 429 : IF (it == 0) THEN
605 66 : WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
606 66 : IF (max_memory /= 0) THEN
607 : WRITE (UNIT=output_unit, FMT="(T2,A,T60,1X,I20)") &
608 66 : tag//"Estimated peak process memory [MiB]", &
609 132 : (max_memory + (1024*1024) - 1)/(1024*1024)
610 : END IF
611 : END IF
612 : END IF
613 :
614 858 : END SUBROUTINE write_rot_cycle_infos
615 :
616 : ! **************************************************************************************************
617 : !> \brief ...
618 : !> \param ndf ...
619 : !> \param dr ...
620 : !> \param g ...
621 : !> \param output_unit ...
622 : !> \param conv ...
623 : !> \param gopt_param ...
624 : !> \param max_memory ...
625 : !> \param pres_diff ...
626 : !> \param pres_tol ...
627 : !> \param pres_diff_constr ...
628 : ! **************************************************************************************************
629 12905 : SUBROUTINE check_converg(ndf, dr, g, output_unit, conv, gopt_param, max_memory, stress_unit, &
630 : pres_diff, pres_tol, pres_diff_constr)
631 :
632 : INTEGER, INTENT(IN) :: ndf
633 : REAL(KIND=dp), INTENT(IN) :: dr(ndf), g(ndf)
634 : INTEGER, INTENT(IN) :: output_unit
635 : LOGICAL, INTENT(OUT) :: conv
636 : TYPE(gopt_param_type), POINTER :: gopt_param
637 : INTEGER(KIND=int_8), INTENT(IN) :: max_memory
638 : CHARACTER(LEN=default_string_length), INTENT(IN) :: stress_unit
639 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: pres_diff, pres_tol, pres_diff_constr
640 :
641 : CHARACTER(LEN=5) :: tag
642 : INTEGER :: indf
643 : LOGICAL :: conv_dx, conv_g, conv_p, conv_rdx, &
644 : conv_rg
645 : REAL(KIND=dp) :: dumm, dxcon, gcon, maxdum(4), rmsgcon, &
646 : rmsxcon
647 :
648 12905 : dxcon = gopt_param%max_dr
649 12905 : gcon = gopt_param%max_force
650 12905 : rmsgcon = gopt_param%rms_force
651 12905 : rmsxcon = gopt_param%rms_dr
652 :
653 12905 : conv = .FALSE.
654 12905 : conv_dx = .TRUE.
655 12905 : conv_rdx = .TRUE.
656 12905 : conv_g = .TRUE.
657 12905 : conv_rg = .TRUE.
658 12905 : conv_p = .TRUE.
659 :
660 12905 : dumm = 0.0_dp
661 2936534 : DO indf = 1, ndf
662 2923629 : IF (indf == 1) maxdum(1) = ABS(dr(indf))
663 2923629 : dumm = dumm + dr(indf)**2
664 2923629 : IF (ABS(dr(indf)) > dxcon) conv_dx = .FALSE.
665 2936534 : IF (ABS(dr(indf)) > maxdum(1)) maxdum(1) = ABS(dr(indf))
666 : END DO
667 : ! SQRT(dumm/ndf) > rmsxcon
668 12905 : IF (dumm > (rmsxcon*rmsxcon*ndf)) conv_rdx = .FALSE.
669 12905 : maxdum(2) = SQRT(dumm/ndf)
670 :
671 12905 : dumm = 0.0_dp
672 2936534 : DO indf = 1, ndf
673 2923629 : IF (indf == 1) maxdum(3) = ABS(g(indf))
674 2923629 : dumm = dumm + g(indf)**2
675 2923629 : IF (ABS(g(indf)) > gcon) conv_g = .FALSE.
676 2936534 : IF (ABS(g(indf)) > maxdum(3)) maxdum(3) = ABS(g(indf))
677 : END DO
678 : ! SQRT(dumm/ndf) > rmsgcon
679 12905 : IF (dumm > (rmsgcon*rmsgcon*ndf)) conv_rg = .FALSE.
680 12905 : maxdum(4) = SQRT(dumm/ndf)
681 :
682 12905 : IF (PRESENT(pres_diff_constr) .AND. PRESENT(pres_tol)) THEN
683 16 : conv_p = ABS(pres_diff_constr) < ABS(pres_tol)
684 12889 : ELSEIF (PRESENT(pres_diff) .AND. PRESENT(pres_tol)) THEN
685 4082 : conv_p = ABS(pres_diff) < ABS(pres_tol)
686 : END IF
687 :
688 12905 : IF (output_unit > 0) THEN
689 :
690 6250 : tag = "OPT| "
691 :
692 6250 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
693 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
694 6250 : tag//"Maximum step size", maxdum(1), &
695 12500 : tag//"Convergence limit for maximum step size", dxcon
696 6250 : IF (conv_dx) THEN
697 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
698 1442 : tag//"Maximum step size is converged", " YES"
699 : ELSE
700 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
701 4808 : tag//"Maximum step size is converged", " NO"
702 : END IF
703 :
704 6250 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
705 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
706 6250 : tag//"RMS step size", maxdum(2), &
707 12500 : tag//"Convergence limit for RMS step size", rmsxcon
708 6250 : IF (conv_rdx) THEN
709 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
710 1575 : tag//"RMS step size is converged", " YES"
711 : ELSE
712 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
713 4675 : tag//"RMS step size is converged", " NO"
714 : END IF
715 :
716 6250 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
717 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
718 6250 : tag//"Maximum gradient", maxdum(3), &
719 12500 : tag//"Convergence limit for maximum gradient", gcon
720 6250 : IF (conv_g) THEN
721 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
722 1491 : tag//"Maximum gradient is converged", " YES"
723 : ELSE
724 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
725 4759 : tag//"Maximum gradient is converged", " NO"
726 : END IF
727 :
728 6250 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
729 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
730 6250 : tag//"RMS gradient", maxdum(4), &
731 12500 : tag//"Convergence limit for RMS gradient", rmsgcon
732 6250 : IF (conv_rg) THEN
733 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
734 1778 : tag//"RMS gradient is converged", " YES"
735 : ELSE
736 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
737 4472 : tag//"RMS gradient is converged", " NO"
738 : END IF
739 :
740 6250 : IF (PRESENT(pres_diff) .AND. PRESENT(pres_tol)) THEN
741 2049 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
742 2049 : IF (PRESENT(pres_diff_constr)) THEN
743 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
744 : tag//"Pressure deviation without constraint ["// &
745 8 : TRIM(ADJUSTL(stress_unit))//"]", &
746 16 : cp_unit_from_cp2k(pres_diff, TRIM(stress_unit))
747 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
748 : tag//"Pressure deviation with constraint ["// &
749 8 : TRIM(ADJUSTL(stress_unit))//"]", &
750 16 : cp_unit_from_cp2k(pres_diff_constr, TRIM(stress_unit))
751 : ELSE
752 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
753 2041 : tag//"Pressure deviation ["//TRIM(ADJUSTL(stress_unit))//"]", &
754 4082 : cp_unit_from_cp2k(pres_diff, TRIM(stress_unit))
755 : END IF
756 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
757 2049 : tag//"Pressure tolerance ["//TRIM(ADJUSTL(stress_unit))//"]", &
758 4098 : cp_unit_from_cp2k(pres_tol, TRIM(stress_unit))
759 2049 : IF (conv_p) THEN
760 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
761 307 : tag//"Pressure is converged", " YES"
762 : ELSE
763 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
764 1742 : tag//"Pressure is converged", " NO"
765 : END IF
766 : END IF
767 :
768 6250 : WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
769 :
770 6250 : IF (max_memory /= 0) THEN
771 : WRITE (UNIT=output_unit, FMT="(T2,A,T60,1X,I20)") &
772 6250 : tag//"Estimated peak process memory after this step [MiB]", &
773 12500 : (max_memory + (1024*1024) - 1)/(1024*1024)
774 : END IF
775 :
776 : END IF
777 :
778 12905 : IF (conv_dx .AND. conv_rdx .AND. conv_g .AND. conv_rg .AND. conv_p) conv = .TRUE.
779 :
780 12905 : IF ((conv) .AND. (output_unit > 0)) THEN
781 653 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("*", 79)
782 : WRITE (UNIT=output_unit, FMT="(T2,A,T25,A,T78,A)") &
783 653 : "***", "GEOMETRY OPTIMIZATION COMPLETED", "***"
784 653 : WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("*", 79)
785 : END IF
786 :
787 12905 : END SUBROUTINE check_converg
788 :
789 : ! **************************************************************************************************
790 : !> \brief ...
791 : !> \param dimer_env ...
792 : !> \param output_unit ...
793 : !> \param conv ...
794 : !> \date 01.2008
795 : !> \author Luca Bellucci and Teodoro Laino - created [tlaino]
796 : ! **************************************************************************************************
797 726 : SUBROUTINE check_rot_conv(dimer_env, output_unit, conv)
798 :
799 : TYPE(dimer_env_type), POINTER :: dimer_env
800 : INTEGER, INTENT(IN) :: output_unit
801 : LOGICAL, INTENT(OUT) :: conv
802 :
803 : CHARACTER(LEN=5) :: tag
804 :
805 726 : conv = (ABS(dimer_env%rot%angle2) < dimer_env%rot%angle_tol)
806 :
807 726 : IF (output_unit > 0) THEN
808 363 : tag = "OPT| "
809 363 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
810 : WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
811 363 : tag//"Predicted angle step size", dimer_env%rot%angle1, &
812 363 : tag//"Effective angle step size", dimer_env%rot%angle2, &
813 726 : tag//"Convergence limit for angle step size", dimer_env%rot%angle_tol
814 363 : IF (conv) THEN
815 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
816 55 : tag//"Angle step size is converged", " YES"
817 : ELSE
818 : WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
819 308 : tag//"Angle step size is converged", " NO"
820 : END IF
821 363 : WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
822 : END IF
823 :
824 726 : IF ((conv) .AND. (output_unit > 0)) THEN
825 55 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("*", 79)
826 : WRITE (UNIT=output_unit, FMT="(T2,A,T25,A,T78,A)") &
827 55 : "***", "ROTATION OPTIMIZATION COMPLETED", "***"
828 55 : WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("*", 79)
829 : END IF
830 :
831 726 : END SUBROUTINE check_rot_conv
832 :
833 : ! **************************************************************************************************
834 : !> \brief ...
835 : !> \param output_unit ...
836 : !> \param conv ...
837 : !> \param it ...
838 : !> \param gopt_env ...
839 : !> \param x0 ...
840 : !> \param master ...
841 : !> \param para_env ...
842 : !> \param force_env ...
843 : !> \param motion_section ...
844 : !> \param root_section ...
845 : !> \date 11.2007
846 : !> \author Teodoro Laino [tlaino] - University of Zurich
847 : ! **************************************************************************************************
848 1068 : RECURSIVE SUBROUTINE write_final_info(output_unit, conv, it, gopt_env, x0, master, para_env, force_env, &
849 : motion_section, root_section)
850 : INTEGER, INTENT(IN) :: output_unit
851 : LOGICAL, INTENT(IN) :: conv
852 : INTEGER, INTENT(INOUT) :: it
853 : TYPE(gopt_f_type), POINTER :: gopt_env
854 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
855 : INTEGER, INTENT(IN) :: master
856 : TYPE(mp_para_env_type), POINTER :: para_env
857 : TYPE(force_env_type), POINTER :: force_env
858 : TYPE(section_vals_type), POINTER :: motion_section, root_section
859 :
860 : REAL(KIND=dp) :: etot
861 : TYPE(cell_type), POINTER :: cell
862 : TYPE(cp_subsys_type), POINTER :: subsys
863 : TYPE(particle_list_type), POINTER :: particles
864 1068 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
865 :
866 1068 : CALL force_env_get(force_env, cell=cell, subsys=subsys)
867 1068 : CALL cp_subsys_get(subsys=subsys, particles=particles)
868 1068 : particle_set => particles%els
869 1068 : IF (conv) THEN
870 391 : it = it + 1
871 391 : CALL write_structure_data(particle_set, cell, motion_section)
872 391 : CALL write_restart(force_env=force_env, root_section=root_section)
873 :
874 391 : IF (output_unit > 0) &
875 201 : WRITE (UNIT=output_unit, FMT="(/,T20,' Reevaluating energy at the minimum')")
876 :
877 : CALL cp_eval_at(gopt_env, x0, f=etot, master=master, final_evaluation=.TRUE., &
878 391 : para_env=para_env)
879 391 : CALL write_geo_traj(force_env, root_section, it, etot)
880 : END IF
881 :
882 1068 : END SUBROUTINE write_final_info
883 :
884 : ! **************************************************************************************************
885 : !> \brief Specific driver for dumping trajectory during a GEO_OPT
886 : !> \param force_env ...
887 : !> \param root_section ...
888 : !> \param it ...
889 : !> \param etot ...
890 : !> \date 11.2007
891 : !> \par History
892 : !> 09.2010: Output of core and shell positions and forces (MK)
893 : !> \author Teodoro Laino [tlaino] - University of Zurich
894 : ! **************************************************************************************************
895 26252 : SUBROUTINE write_geo_traj(force_env, root_section, it, etot)
896 :
897 : TYPE(force_env_type), POINTER :: force_env
898 : TYPE(section_vals_type), POINTER :: root_section
899 : INTEGER, INTENT(IN) :: it
900 : REAL(KIND=dp), INTENT(IN) :: etot
901 :
902 : LOGICAL :: shell_adiabatic, shell_present
903 : TYPE(atomic_kind_list_type), POINTER :: atomic_kinds
904 13126 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
905 : TYPE(cp_subsys_type), POINTER :: subsys
906 : TYPE(particle_list_type), POINTER :: core_particles, shell_particles
907 :
908 13126 : NULLIFY (atomic_kinds)
909 13126 : NULLIFY (atomic_kind_set)
910 13126 : NULLIFY (core_particles)
911 13126 : NULLIFY (shell_particles)
912 13126 : NULLIFY (subsys)
913 :
914 13126 : CALL write_trajectory(force_env, root_section, it, 0.0_dp, 0.0_dp, etot)
915 : ! Print Force
916 13126 : CALL write_trajectory(force_env, root_section, it, 0.0_dp, 0.0_dp, etot, "FORCES", middle_name="frc")
917 13126 : CALL force_env_get(force_env, subsys=subsys)
918 13126 : CALL cp_subsys_get(subsys, atomic_kinds=atomic_kinds)
919 13126 : atomic_kind_set => atomic_kinds%els
920 : CALL get_atomic_kind_set(atomic_kind_set, &
921 : shell_present=shell_present, &
922 13126 : shell_adiabatic=shell_adiabatic)
923 13126 : IF (shell_present) THEN
924 : CALL cp_subsys_get(subsys, &
925 : core_particles=core_particles, &
926 4106 : shell_particles=shell_particles)
927 : CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
928 : etot=etot, pk_name="SHELL_TRAJECTORY", middle_name="shpos", &
929 4106 : particles=shell_particles)
930 4106 : IF (shell_adiabatic) THEN
931 : CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
932 : etot=etot, pk_name="SHELL_FORCES", middle_name="shfrc", &
933 4106 : particles=shell_particles)
934 : CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
935 : etot=etot, pk_name="CORE_TRAJECTORY", middle_name="copos", &
936 4106 : particles=core_particles)
937 : CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
938 : etot=etot, pk_name="CORE_FORCES", middle_name="cofrc", &
939 4106 : particles=core_particles)
940 : END IF
941 : END IF
942 :
943 13126 : END SUBROUTINE write_geo_traj
944 :
945 : ! **************************************************************************************************
946 : !> \brief ...
947 : !> \param gopt_env ...
948 : !> \param output_unit ...
949 : !> \param label ...
950 : !> \date 01.2008
951 : !> \author Teodoro Laino [tlaino] - University of Zurich
952 : ! **************************************************************************************************
953 2116 : SUBROUTINE print_geo_opt_header(gopt_env, output_unit, label)
954 :
955 : TYPE(gopt_f_type), POINTER :: gopt_env
956 : INTEGER, INTENT(IN) :: output_unit
957 : CHARACTER(LEN=*), INTENT(IN) :: label
958 :
959 : CHARACTER(LEN=default_string_length) :: my_format, my_label
960 : INTEGER :: ix
961 :
962 2116 : IF (output_unit > 0) THEN
963 1064 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("*", 79)
964 1064 : IF (gopt_env%dimer_rotation) THEN
965 66 : my_label = "OPTIMIZING DIMER ROTATION"
966 : ELSE
967 998 : my_label = "STARTING "//gopt_env%tag(1:8)//" OPTIMIZATION"
968 : END IF
969 :
970 1064 : ix = (80 - 7 - LEN_TRIM(my_label))/2
971 1064 : ix = ix + 5
972 1064 : my_format = "(T2,A,T"//cp_to_string(ix)//",A,T78,A)"
973 1064 : WRITE (UNIT=output_unit, FMT=TRIM(my_format)) "***", TRIM(my_label), "***"
974 :
975 1064 : ix = (80 - 7 - LEN_TRIM(label))/2
976 1064 : ix = ix + 5
977 1064 : my_format = "(T2,A,T"//cp_to_string(ix)//",A,T78,A)"
978 1064 : WRITE (UNIT=output_unit, FMT=TRIM(my_format)) "***", TRIM(label), "***"
979 :
980 1064 : WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("*", 79)
981 1064 : CALL m_flush(output_unit)
982 : END IF
983 2116 : END SUBROUTINE print_geo_opt_header
984 :
985 : ! **************************************************************************************************
986 : !> \brief ...
987 : !> \param gopt_env ...
988 : !> \param output_unit ...
989 : !> \date 01.2008
990 : !> \author Teodoro Laino [tlaino] - University of Zurich
991 : ! **************************************************************************************************
992 699 : SUBROUTINE print_geo_opt_nc(gopt_env, output_unit)
993 :
994 : TYPE(gopt_f_type), POINTER :: gopt_env
995 : INTEGER, INTENT(IN) :: output_unit
996 :
997 699 : IF (output_unit > 0) THEN
998 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") &
999 350 : "*** MAXIMUM NUMBER OF OPTIMIZATION STEPS REACHED ***"
1000 350 : IF (.NOT. gopt_env%dimer_rotation) THEN
1001 : WRITE (UNIT=output_unit, FMT="(T2,A)") &
1002 339 : "*** EXITING GEOMETRY OPTIMIZATION ***"
1003 : ELSE
1004 : WRITE (UNIT=output_unit, FMT="(T2,A)") &
1005 11 : "*** EXITING ROTATION OPTIMIZATION ***"
1006 : END IF
1007 350 : CALL m_flush(output_unit)
1008 : END IF
1009 :
1010 699 : END SUBROUTINE print_geo_opt_nc
1011 :
1012 : ! **************************************************************************************************
1013 : !> \brief Prints information during GEO_OPT common to all optimizers
1014 : !> \param force_env ...
1015 : !> \param root_section ...
1016 : !> \param motion_section ...
1017 : !> \param its ...
1018 : !> \param opt_energy ...
1019 : !> \date 02.2008
1020 : !> \author Teodoro Laino [tlaino] - University of Zurich
1021 : !> \version 1.0
1022 : ! **************************************************************************************************
1023 12735 : SUBROUTINE geo_opt_io(force_env, root_section, motion_section, its, opt_energy)
1024 :
1025 : TYPE(force_env_type), POINTER :: force_env
1026 : TYPE(section_vals_type), POINTER :: root_section, motion_section
1027 : INTEGER, INTENT(IN) :: its
1028 : REAL(KIND=dp), INTENT(IN) :: opt_energy
1029 :
1030 : TYPE(atomic_kind_list_type), POINTER :: atomic_kinds
1031 12735 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1032 : TYPE(cell_type), POINTER :: cell
1033 : TYPE(cp_subsys_type), POINTER :: subsys
1034 : TYPE(distribution_1d_type), POINTER :: local_particles
1035 : TYPE(mp_para_env_type), POINTER :: para_env
1036 : TYPE(particle_list_type), POINTER :: particles
1037 12735 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1038 : TYPE(virial_type), POINTER :: virial
1039 :
1040 12735 : NULLIFY (para_env, atomic_kind_set, subsys, particle_set, &
1041 12735 : local_particles, atomic_kinds, particles)
1042 :
1043 : ! Write Restart File
1044 12735 : CALL write_restart(force_env=force_env, root_section=root_section)
1045 :
1046 : ! Write Trajectory
1047 12735 : CALL write_geo_traj(force_env, root_section, its, opt_energy)
1048 :
1049 : ! Write the stress Tensor
1050 : CALL force_env_get(force_env, cell=cell, para_env=para_env, &
1051 12735 : subsys=subsys)
1052 : CALL cp_subsys_get(subsys=subsys, atomic_kinds=atomic_kinds, local_particles=local_particles, &
1053 12735 : particles=particles, virial=virial)
1054 12735 : atomic_kind_set => atomic_kinds%els
1055 12735 : particle_set => particles%els
1056 : CALL virial_evaluate(atomic_kind_set, particle_set, local_particles, &
1057 12735 : virial, para_env)
1058 12735 : CALL write_stress_tensor_to_file(virial, cell, motion_section, its, 0.0_dp)
1059 :
1060 : ! Write the cell
1061 12735 : CALL write_simulation_cell(cell, motion_section, its, 0.0_dp)
1062 :
1063 12735 : END SUBROUTINE geo_opt_io
1064 :
1065 : ! **************************************************************************************************
1066 : !> \brief Apply coordinate transformations after cell (shape) change
1067 : !> \param gopt_env ...
1068 : !> \param cell ...
1069 : !> \param x ...
1070 : !> \param update_forces ...
1071 : !> \date 05.11.2012 (revised version of unbiase_coordinates moved here, MK)
1072 : !> \author Matthias Krack
1073 : !> \version 1.0
1074 : ! **************************************************************************************************
1075 8894 : SUBROUTINE apply_cell_change(gopt_env, cell, x, update_forces)
1076 :
1077 : TYPE(gopt_f_type), POINTER :: gopt_env
1078 : TYPE(cell_type), POINTER :: cell
1079 : REAL(KIND=dp), DIMENSION(:), POINTER :: x
1080 : LOGICAL, INTENT(IN) :: update_forces
1081 :
1082 : INTEGER :: i, iatom, idg, j, natom, nparticle, &
1083 : shell_index
1084 : REAL(KIND=dp) :: fc, fs, mass
1085 : REAL(KIND=dp), DIMENSION(3) :: s
1086 : TYPE(cell_type), POINTER :: cell_ref
1087 : TYPE(cp_subsys_type), POINTER :: subsys
1088 : TYPE(particle_list_type), POINTER :: core_particles, particles, &
1089 : shell_particles
1090 :
1091 8894 : NULLIFY (cell_ref)
1092 8894 : NULLIFY (core_particles)
1093 8894 : NULLIFY (particles)
1094 8894 : NULLIFY (shell_particles)
1095 8894 : NULLIFY (subsys)
1096 :
1097 8894 : natom = force_env_get_natom(gopt_env%force_env)
1098 8894 : nparticle = force_env_get_nparticle(gopt_env%force_env)
1099 : CALL force_env_get(gopt_env%force_env, &
1100 8894 : subsys=subsys)
1101 : CALL cp_subsys_get(subsys=subsys, &
1102 : core_particles=core_particles, &
1103 : particles=particles, &
1104 8894 : shell_particles=shell_particles)
1105 :
1106 : ! Retrieve the reference cell
1107 8894 : CALL cell_create(cell_ref)
1108 8894 : CALL cell_copy(cell, cell_ref, tag="CELL_OPT_REF")
1109 :
1110 : ! Load the updated cell information
1111 16848 : SELECT CASE (gopt_env%cell_method_id)
1112 : CASE (default_cell_direct_id)
1113 7954 : idg = 3*nparticle
1114 7954 : CALL init_cell(cell_ref, hmat=gopt_env%h_ref)
1115 : CASE (default_cell_geo_opt_id, default_cell_md_id)
1116 8894 : idg = 0
1117 : END SELECT
1118 8894 : CPASSERT((SIZE(x) == idg + 6))
1119 :
1120 8894 : IF (update_forces) THEN
1121 :
1122 : ! Transform particle forces back to reference cell
1123 : idg = 1
1124 231854 : DO iatom = 1, natom
1125 228840 : CALL real_to_scaled(s, x(idg:idg + 2), cell)
1126 228840 : CALL scaled_to_real(x(idg:idg + 2), s, cell_ref)
1127 231854 : idg = idg + 3
1128 : END DO
1129 :
1130 : ELSE
1131 :
1132 : ! Update cell
1133 23520 : DO i = 1, 3
1134 58800 : DO j = 1, i
1135 35280 : idg = idg + 1
1136 52920 : cell%hmat(j, i) = x(idg)
1137 : END DO
1138 : END DO
1139 5880 : CALL init_cell(cell)
1140 5880 : CALL cp_subsys_set(subsys, cell=cell)
1141 :
1142 : ! Retrieve particle coordinates for the current cell
1143 5880 : SELECT CASE (gopt_env%cell_method_id)
1144 : CASE (default_cell_direct_id)
1145 : idg = 1
1146 434492 : DO iatom = 1, natom
1147 429552 : CALL real_to_scaled(s, x(idg:idg + 2), cell_ref)
1148 429552 : shell_index = particles%els(iatom)%shell_index
1149 429552 : IF (shell_index == 0) THEN
1150 138588 : CALL scaled_to_real(particles%els(iatom)%r, s, cell)
1151 : ELSE
1152 290964 : CALL scaled_to_real(core_particles%els(shell_index)%r, s, cell)
1153 290964 : i = 3*(natom + shell_index - 1) + 1
1154 290964 : CALL real_to_scaled(s, x(i:i + 2), cell_ref)
1155 290964 : CALL scaled_to_real(shell_particles%els(shell_index)%r, s, cell)
1156 : ! Update atomic position due to core and shell motion
1157 290964 : mass = particles%els(iatom)%atomic_kind%mass
1158 290964 : fc = core_particles%els(shell_index)%atomic_kind%shell%mass_core/mass
1159 290964 : fs = shell_particles%els(shell_index)%atomic_kind%shell%mass_shell/mass
1160 : particles%els(iatom)%r(1:3) = fc*core_particles%els(shell_index)%r(1:3) + &
1161 2327712 : fs*shell_particles%els(shell_index)%r(1:3)
1162 : END IF
1163 434492 : idg = idg + 3
1164 : END DO
1165 : CASE (default_cell_geo_opt_id, default_cell_md_id)
1166 46096 : DO iatom = 1, natom
1167 39276 : shell_index = particles%els(iatom)%shell_index
1168 40216 : IF (shell_index == 0) THEN
1169 35244 : CALL real_to_scaled(s, particles%els(iatom)%r, cell_ref)
1170 35244 : CALL scaled_to_real(particles%els(iatom)%r, s, cell)
1171 : ELSE
1172 4032 : CALL real_to_scaled(s, core_particles%els(shell_index)%r, cell_ref)
1173 4032 : CALL scaled_to_real(core_particles%els(shell_index)%r, s, cell)
1174 4032 : i = 3*(natom + shell_index - 1) + 1
1175 4032 : CALL real_to_scaled(s, shell_particles%els(shell_index)%r, cell_ref)
1176 4032 : CALL scaled_to_real(shell_particles%els(shell_index)%r, s, cell)
1177 : ! Update atomic position due to core and shell motion
1178 4032 : mass = particles%els(iatom)%atomic_kind%mass
1179 4032 : fc = core_particles%els(shell_index)%atomic_kind%shell%mass_core/mass
1180 4032 : fs = shell_particles%els(shell_index)%atomic_kind%shell%mass_shell/mass
1181 : particles%els(iatom)%r(1:3) = fc*core_particles%els(shell_index)%r(1:3) + &
1182 32256 : fs*shell_particles%els(shell_index)%r(1:3)
1183 : END IF
1184 : END DO
1185 : END SELECT
1186 :
1187 : END IF
1188 :
1189 8894 : CALL cell_release(cell_ref)
1190 :
1191 8894 : END SUBROUTINE apply_cell_change
1192 :
1193 : END MODULE gopt_f_methods
|