(git:ed6f26b)
Loading...
Searching...
No Matches
force_env_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Interface for the force calculations
10!> \par History
11!> cjm, FEB-20-2001: pass variable box_ref
12!> cjm, SEPT-12-2002: major reorganization
13!> fawzi, APR-12-2003: introduced force_env (based on the work by CJM&JGH)
14!> fawzi, NOV-3-2004: reorganized interface for f77 interface
15!> \author fawzi
16! **************************************************************************************************
18 USE atprop_types, ONLY: atprop_init,&
21 huang2011,&
22 cite_reference
23 USE cell_methods, ONLY: cell_create,&
25 USE cell_types, ONLY: cell_clone,&
28 cell_type,&
60 USE eip_silicon, ONLY: eip_bazant,&
62 USE embed_types, ONLY: embed_env_type,&
68 USE force_env_types, ONLY: &
76 USE fp_methods, ONLY: fp_eval
77 USE fparser, ONLY: evalerrtype,&
78 evalf,&
79 evalfd,&
80 finalizef,&
81 initf,&
82 parsef
85 USE grrm_utils, ONLY: write_grrm
86 USE input_constants, ONLY: &
94 USE ipi_server, ONLY: request_forces
95 USE kahan_sum, ONLY: accurate_sum
96 USE kinds, ONLY: default_path_length,&
98 dp
99 USE machine, ONLY: m_memory
100 USE mathlib, ONLY: abnormal_value
130 USE physcon, ONLY: debye
131 USE pw_env_types, ONLY: pw_env_get,&
133 USE pw_methods, ONLY: pw_axpy,&
134 pw_copy,&
136 pw_zero
137 USE pw_pool_types, ONLY: pw_pool_type
138 USE pw_types, ONLY: pw_r3d_rs_type
142 USE qmmm_types, ONLY: qmmm_env_type
145 USE qmmmx_types, ONLY: qmmmx_env_type
151 USE qs_rho_types, ONLY: qs_rho_get,&
154 USE scine_utils, ONLY: write_scine
155 USE string_utilities, ONLY: compress
162#include "./base/base_uses.f90"
163
164 IMPLICIT NONE
165
166 PRIVATE
167
168 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'force_env_methods'
169
170 PUBLIC :: force_env_create, &
173
174 INTEGER, SAVE, PRIVATE :: last_force_env_id = 0
175
176CONTAINS
177
178! **************************************************************************************************
179!> \brief Interface routine for force and energy calculations
180!> \param force_env the force_env of which you want the energy and forces
181!> \param calc_force if false the forces *might* be left unchanged
182!> or be invalid, no guarantees can be given. Defaults to true
183!> \param consistent_energies Performs an additional qs_ks_update_qs_env, so
184!> that the energies are appropriate to the forces, they are in the
185!> non-selfconsistent case not consistent to each other! [08.2005, TdK]
186!> \param skip_external_control ...
187!> \param eval_energy_forces ...
188!> \param require_consistent_energy_force ...
189!> \param linres ...
190!> \param calc_stress_tensor ...
191!> \author CJM & fawzi
192! **************************************************************************************************
193 RECURSIVE SUBROUTINE force_env_calc_energy_force(force_env, calc_force, &
194 consistent_energies, skip_external_control, eval_energy_forces, &
195 require_consistent_energy_force, linres, calc_stress_tensor)
196
197 TYPE(force_env_type), POINTER :: force_env
198 LOGICAL, INTENT(IN), OPTIONAL :: calc_force, consistent_energies, skip_external_control, &
199 eval_energy_forces, require_consistent_energy_force, linres, calc_stress_tensor
200
201 REAL(kind=dp), PARAMETER :: ateps = 1.0e-6_dp
202
203 CHARACTER(LEN=default_string_length) :: unit_string
204 INTEGER :: ikind, nat, ndigits, nfixed_atoms, &
205 nfixed_atoms_total, nkind, &
206 output_unit, print_forces, print_grrm, &
207 print_scine
208 LOGICAL :: calculate_forces, calculate_stress_tensor, energy_consistency, eval_ef, &
209 linres_run, my_skip, print_components
210 REAL(kind=dp) :: checksum, e_entropy, e_gap, e_pot, &
211 fconv, sum_energy
212 REAL(kind=dp), DIMENSION(3) :: grand_total_force, total_force
213 TYPE(atprop_type), POINTER :: atprop_env
214 TYPE(cell_type), POINTER :: cell
215 TYPE(cp_logger_type), POINTER :: logger
216 TYPE(cp_subsys_type), POINTER :: subsys
217 TYPE(molecule_kind_list_type), POINTER :: molecule_kinds
218 TYPE(molecule_kind_type), DIMENSION(:), POINTER :: molecule_kind_set
219 TYPE(molecule_kind_type), POINTER :: molecule_kind
220 TYPE(particle_list_type), POINTER :: core_particles, particles, &
221 shell_particles
222 TYPE(virial_type), POINTER :: virial
223
224 NULLIFY (logger, virial, subsys, atprop_env, cell)
225 logger => cp_get_default_logger()
226 eval_ef = .true.
227 my_skip = .false.
228 calculate_forces = .true.
229 energy_consistency = .false.
230 linres_run = .false.
231 e_gap = -1.0_dp
232 e_entropy = -1.0_dp
233 unit_string = ""
234
235 IF (PRESENT(eval_energy_forces)) eval_ef = eval_energy_forces
236 IF (PRESENT(skip_external_control)) my_skip = skip_external_control
237 IF (PRESENT(calc_force)) calculate_forces = calc_force
238 IF (PRESENT(calc_stress_tensor)) THEN
239 calculate_stress_tensor = calc_stress_tensor
240 ELSE
241 calculate_stress_tensor = calculate_forces
242 END IF
243 IF (PRESENT(consistent_energies)) energy_consistency = consistent_energies
244 IF (PRESENT(linres)) linres_run = linres
245
246 cpassert(ASSOCIATED(force_env))
247 cpassert(force_env%ref_count > 0)
248 CALL force_env_get(force_env, subsys=subsys)
249 CALL force_env_set(force_env, additional_potential=0.0_dp)
250 CALL cp_subsys_get(subsys, virial=virial, atprop=atprop_env, cell=cell)
251 IF (virial%pv_availability) CALL zero_virial(virial, reset=.false.)
252
253 nat = force_env_get_natom(force_env)
254 CALL atprop_init(atprop_env, nat)
255 IF (eval_ef) THEN
256 SELECT CASE (force_env%in_use)
257 CASE (use_fist_force)
258 CALL fist_calc_energy_force(force_env%fist_env)
259 CASE (use_qs_force)
260 CALL qs_calc_energy_force(force_env%qs_env, calculate_forces, energy_consistency, linres_run)
261 CASE (use_pwdft_force)
262 IF (virial%pv_availability .AND. calculate_stress_tensor) THEN
263 CALL pwdft_calc_energy_force(force_env%pwdft_env, calculate_forces,.NOT. virial%pv_numer)
264 ELSE
265 CALL pwdft_calc_energy_force(force_env%pwdft_env, calculate_forces, .false.)
266 END IF
267 e_gap = force_env%pwdft_env%energy%band_gap
268 e_entropy = force_env%pwdft_env%energy%entropy
269 CASE (use_eip_force)
270 IF (force_env%eip_env%eip_model == use_lenosky_eip) THEN
271 CALL eip_lenosky(force_env%eip_env)
272 ELSE IF (force_env%eip_env%eip_model == use_bazant_eip) THEN
273 CALL eip_bazant(force_env%eip_env)
274 END IF
275 CASE (use_qmmm)
276 CALL qmmm_calc_energy_force(force_env%qmmm_env, &
277 calculate_forces, energy_consistency, linres=linres_run)
278 CASE (use_qmmmx)
279 CALL qmmmx_calc_energy_force(force_env%qmmmx_env, &
280 calculate_forces, energy_consistency, linres=linres_run, &
281 require_consistent_energy_force=require_consistent_energy_force)
282 CASE (use_mixed_force)
283 CALL mixed_energy_forces(force_env, calculate_forces)
284 CASE (use_nnp_force)
285 CALL nnp_calc_energy_force(force_env%nnp_env, &
286 calculate_forces)
287 CASE (use_embed)
288 CALL embed_energy(force_env)
289 CASE (use_ipi)
290 CALL request_forces(force_env%ipi_env)
291 CASE default
292 cpabort("")
293 END SELECT
294 END IF
295 ! In case it is requested, we evaluate the stress tensor numerically
296 IF (virial%pv_availability) THEN
297 IF (virial%pv_numer .AND. calculate_stress_tensor) THEN
298 ! Compute the numerical stress tensor
299 CALL force_env_calc_num_pressure(force_env)
300 ELSE
301 IF (calculate_forces) THEN
302 ! Symmetrize analytical stress tensor
303 CALL symmetrize_virial(virial)
304 ELSE
305 IF (calculate_stress_tensor) THEN
306 CALL cp_warn(__location__, "The calculation of the stress tensor "// &
307 "requires the calculation of the forces")
308 END IF
309 END IF
310 END IF
311 END IF
312
313 !sample peak memory
314 CALL m_memory()
315
316 ! Some additional tasks..
317 IF (.NOT. my_skip) THEN
318 ! Flexible Partitioning
319 IF (ASSOCIATED(force_env%fp_env)) THEN
320 IF (force_env%fp_env%use_fp) THEN
321 CALL fp_eval(force_env%fp_env, subsys, cell)
322 END IF
323 END IF
324 ! Constraints ONLY of Fixed Atom type
325 CALL fix_atom_control(force_env)
326 ! All Restraints
327 CALL restraint_control(force_env)
328 ! Virtual Sites
329 CALL vsite_force_control(force_env)
330 ! External Potential
331 CALL add_external_potential(force_env)
332 ! Rescale forces if requested
333 CALL rescale_forces(force_env)
334 END IF
335
336 CALL force_env_get(force_env, potential_energy=e_pot)
337
338 ! Print energy always in the same format for all methods
339 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
340 extension=".Log")
341 IF (output_unit > 0) THEN
342 CALL section_vals_val_get(force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO%ENERGY_UNIT", &
343 c_val=unit_string)
344 fconv = cp_unit_from_cp2k(1.0_dp, trim(adjustl(unit_string)))
345 WRITE (unit=output_unit, fmt="(/,T2,A,T55,F26.15)") &
346 "ENERGY| Total FORCE_EVAL ( "//trim(adjustl(use_prog_name(force_env%in_use)))// &
347 " ) energy ["//trim(adjustl(unit_string))//"]", e_pot*fconv
348 IF (e_gap > -0.1_dp) THEN
349 WRITE (unit=output_unit, fmt="(/,T2,A,T55,F26.15)") &
350 "ENERGY| Total FORCE_EVAL ( "//trim(adjustl(use_prog_name(force_env%in_use)))// &
351 " ) gap ["//trim(adjustl(unit_string))//"]", e_gap*fconv
352 END IF
353 IF (e_entropy > -0.1_dp) THEN
354 WRITE (unit=output_unit, fmt="(/,T2,A,T55,F26.15)") &
355 "ENERGY| Total FORCE_EVAL ( "//trim(adjustl(use_prog_name(force_env%in_use)))// &
356 " ) free energy ["//trim(adjustl(unit_string))//"]", (e_pot - e_entropy)*fconv
357 END IF
358 END IF
359 CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
360 "PRINT%PROGRAM_RUN_INFO")
361
362 ! terminate the run if the value of the potential is abnormal
363 IF (abnormal_value(e_pot)) &
364 cpabort("Potential energy is an abnormal value (NaN/Inf).")
365
366 ! Print forces, if requested
367 print_forces = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%FORCES", &
368 extension=".xyz")
369 IF ((print_forces > 0) .AND. calculate_forces) THEN
370 CALL force_env_get(force_env, subsys=subsys)
371 CALL cp_subsys_get(subsys, &
372 core_particles=core_particles, &
373 particles=particles, &
374 shell_particles=shell_particles)
375 ! Variable precision output of the forces
376 CALL section_vals_val_get(force_env%force_env_section, "PRINT%FORCES%NDIGITS", &
377 i_val=ndigits)
378 CALL section_vals_val_get(force_env%force_env_section, "PRINT%FORCES%FORCE_UNIT", &
379 c_val=unit_string)
380 IF (ASSOCIATED(core_particles) .OR. ASSOCIATED(shell_particles)) THEN
381 CALL write_forces(particles, print_forces, "Atomic", ndigits, unit_string, &
382 total_force, zero_force_core_shell_atom=.true.)
383 grand_total_force(1:3) = total_force(1:3)
384 IF (ASSOCIATED(core_particles)) THEN
385 CALL write_forces(core_particles, print_forces, "Core particle", ndigits, &
386 unit_string, total_force, zero_force_core_shell_atom=.false.)
387 grand_total_force(:) = grand_total_force(:) + total_force(:)
388 END IF
389 IF (ASSOCIATED(shell_particles)) THEN
390 CALL write_forces(shell_particles, print_forces, "Shell particle", ndigits, &
391 unit_string, total_force, zero_force_core_shell_atom=.false., &
392 grand_total_force=grand_total_force)
393 END IF
394 ELSE
395 CALL write_forces(particles, print_forces, "Atomic", ndigits, unit_string, total_force)
396 END IF
397 END IF
398 CALL cp_print_key_finished_output(print_forces, logger, force_env%force_env_section, "PRINT%FORCES")
399
400 ! Write stress tensor
401 IF (virial%pv_availability) THEN
402 ! If the virial is defined but we are not computing forces let's zero the
403 ! virial for consistency
404 IF (calculate_forces .AND. calculate_stress_tensor) THEN
405 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%STRESS_TENSOR", &
406 extension=".stress_tensor")
407 IF (output_unit > 0) THEN
408 CALL section_vals_val_get(force_env%force_env_section, "PRINT%STRESS_TENSOR%COMPONENTS", &
409 l_val=print_components)
410 CALL section_vals_val_get(force_env%force_env_section, "PRINT%STRESS_TENSOR%STRESS_UNIT", &
411 c_val=unit_string)
412 IF (print_components) THEN
413 IF ((.NOT. virial%pv_numer) .AND. (force_env%in_use == use_qs_force)) THEN
414 CALL write_stress_tensor_components(virial, output_unit, cell, unit_string)
415 END IF
416 END IF
417 CALL write_stress_tensor(virial%pv_virial, output_unit, cell, unit_string, virial%pv_numer)
418 END IF
419 CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
420 "PRINT%STRESS_TENSOR")
421 ELSE
422 CALL zero_virial(virial, reset=.false.)
423 END IF
424 ELSE
425 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%STRESS_TENSOR", &
426 extension=".stress_tensor")
427 IF (output_unit > 0) THEN
428 CALL cp_warn(__location__, "To print the stress tensor switch on the "// &
429 "virial evaluation with the keyword: STRESS_TENSOR")
430 END IF
431 CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
432 "PRINT%STRESS_TENSOR")
433 END IF
434
435 ! Atomic energy
436 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
437 extension=".Log")
438 IF (atprop_env%energy) THEN
439 CALL force_env%para_env%sum(atprop_env%atener)
440 CALL force_env_get(force_env, potential_energy=e_pot)
441 IF (output_unit > 0) THEN
442 IF (logger%iter_info%print_level >= low_print_level) THEN
443 CALL cp_subsys_get(subsys=subsys, particles=particles)
444 CALL write_atener(output_unit, particles, atprop_env%atener, "Mulliken Atomic Energies")
445 END IF
446 sum_energy = accurate_sum(atprop_env%atener(:))
447 checksum = abs(e_pot - sum_energy)
448 WRITE (unit=output_unit, fmt="(/,(T2,A,T56,F25.13))") &
449 "Potential energy (Atomic):", sum_energy, &
450 "Potential energy (Total) :", e_pot, &
451 "Difference :", checksum
452 cpassert((checksum < ateps*abs(e_pot)))
453 END IF
454 CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
455 "PRINT%PROGRAM_RUN_INFO")
456 END IF
457
458 ! Print GRMM interface file
459 print_grrm = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%GRRM", &
460 file_position="REWIND", extension=".rrm")
461 IF (print_grrm > 0) THEN
462 CALL force_env_get(force_env, subsys=subsys)
463 CALL cp_subsys_get(subsys=subsys, particles=particles, &
464 molecule_kinds=molecule_kinds)
465 ! Count the number of fixed atoms
466 nfixed_atoms_total = 0
467 nkind = molecule_kinds%n_els
468 molecule_kind_set => molecule_kinds%els
469 DO ikind = 1, nkind
470 molecule_kind => molecule_kind_set(ikind)
471 CALL get_molecule_kind(molecule_kind, nfixd=nfixed_atoms)
472 nfixed_atoms_total = nfixed_atoms_total + nfixed_atoms
473 END DO
474 !
475 CALL write_grrm(print_grrm, force_env, particles%els, e_pot, fixed_atoms=nfixed_atoms_total)
476 END IF
477 CALL cp_print_key_finished_output(print_grrm, logger, force_env%force_env_section, "PRINT%GRRM")
478
479 print_scine = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%SCINE", &
480 file_position="REWIND", extension=".scine")
481 IF (print_scine > 0) THEN
482 CALL force_env_get(force_env, subsys=subsys)
483 CALL cp_subsys_get(subsys=subsys, particles=particles)
484 !
485 CALL write_scine(print_scine, force_env, particles%els, e_pot)
486 END IF
487 CALL cp_print_key_finished_output(print_scine, logger, force_env%force_env_section, "PRINT%SCINE")
488
489 END SUBROUTINE force_env_calc_energy_force
490
491! **************************************************************************************************
492!> \brief Evaluates the stress tensor and pressure numerically
493!> \param force_env ...
494!> \param dx ...
495!> \par History
496!> 10.2005 created [JCS]
497!> 05.2009 Teodoro Laino [tlaino] - rewriting for general force_env
498!>
499!> \author JCS
500! **************************************************************************************************
501 SUBROUTINE force_env_calc_num_pressure(force_env, dx)
502
503 TYPE(force_env_type), POINTER :: force_env
504 REAL(kind=dp), INTENT(IN), OPTIONAL :: dx
505
506 REAL(kind=dp), PARAMETER :: default_dx = 0.001_dp
507
508 CHARACTER(LEN=default_string_length) :: unit_string
509 INTEGER :: i, ip, iq, j, k, natom, ncore, nshell, &
510 output_unit, symmetry_id
511 REAL(kind=dp) :: dx_w
512 REAL(kind=dp), DIMENSION(2) :: numer_energy
513 REAL(kind=dp), DIMENSION(3) :: s
514 REAL(kind=dp), DIMENSION(3, 3) :: numer_stress
515 REAL(kind=dp), DIMENSION(:, :), POINTER :: ref_pos_atom, ref_pos_core, ref_pos_shell
516 TYPE(cell_type), POINTER :: cell, cell_local
517 TYPE(cp_logger_type), POINTER :: logger
518 TYPE(cp_subsys_type), POINTER :: subsys
519 TYPE(global_environment_type), POINTER :: globenv
520 TYPE(particle_list_type), POINTER :: core_particles, particles, &
521 shell_particles
522 TYPE(virial_type), POINTER :: virial
523
524 NULLIFY (cell_local)
525 NULLIFY (core_particles)
526 NULLIFY (particles)
527 NULLIFY (shell_particles)
528 NULLIFY (ref_pos_atom)
529 NULLIFY (ref_pos_core)
530 NULLIFY (ref_pos_shell)
531 natom = 0
532 ncore = 0
533 nshell = 0
534 numer_stress = 0.0_dp
535
536 logger => cp_get_default_logger()
537
538 dx_w = default_dx
539 IF (PRESENT(dx)) dx_w = dx
540 CALL force_env_get(force_env, subsys=subsys, globenv=globenv)
541 CALL cp_subsys_get(subsys, &
542 core_particles=core_particles, &
543 particles=particles, &
544 shell_particles=shell_particles, &
545 virial=virial)
546 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%STRESS_TENSOR", &
547 extension=".stress_tensor")
548 IF (output_unit > 0) THEN
549 WRITE (output_unit, "(/A,A/)") " **************************** ", &
550 "NUMERICAL STRESS ********************************"
551 END IF
552
553 ! Save all original particle positions
554 natom = particles%n_els
555 ALLOCATE (ref_pos_atom(natom, 3))
556 DO i = 1, natom
557 ref_pos_atom(i, :) = particles%els(i)%r
558 END DO
559 IF (ASSOCIATED(core_particles)) THEN
560 ncore = core_particles%n_els
561 ALLOCATE (ref_pos_core(ncore, 3))
562 DO i = 1, ncore
563 ref_pos_core(i, :) = core_particles%els(i)%r
564 END DO
565 END IF
566 IF (ASSOCIATED(shell_particles)) THEN
567 nshell = shell_particles%n_els
568 ALLOCATE (ref_pos_shell(nshell, 3))
569 DO i = 1, nshell
570 ref_pos_shell(i, :) = shell_particles%els(i)%r
571 END DO
572 END IF
573 CALL force_env_get(force_env, cell=cell)
574 ! Save cell symmetry (distorted cell has no symmetry)
575 symmetry_id = cell%symmetry_id
576 cell%symmetry_id = cell_sym_triclinic
577 !
578 CALL cell_create(cell_local)
579 CALL cell_clone(cell, cell_local)
580 ! First change box
581 DO ip = 1, 3
582 DO iq = 1, 3
583 IF (virial%pv_diagonal .AND. (ip /= iq)) cycle
584 DO k = 1, 2
585 cell%hmat(ip, iq) = cell_local%hmat(ip, iq) - (-1.0_dp)**k*dx_w
586 CALL init_cell(cell)
587 ! Scale positions
588 DO i = 1, natom
589 CALL real_to_scaled(s, ref_pos_atom(i, 1:3), cell_local)
590 CALL scaled_to_real(particles%els(i)%r, s, cell)
591 END DO
592 DO i = 1, ncore
593 CALL real_to_scaled(s, ref_pos_core(i, 1:3), cell_local)
594 CALL scaled_to_real(core_particles%els(i)%r, s, cell)
595 END DO
596 DO i = 1, nshell
597 CALL real_to_scaled(s, ref_pos_shell(i, 1:3), cell_local)
598 CALL scaled_to_real(shell_particles%els(i)%r, s, cell)
599 END DO
600 ! Compute energies
601 CALL force_env_calc_energy_force(force_env, &
602 calc_force=.false., &
603 consistent_energies=.true., &
604 calc_stress_tensor=.false.)
605 CALL force_env_get(force_env, potential_energy=numer_energy(k))
606 ! Reset cell
607 cell%hmat(ip, iq) = cell_local%hmat(ip, iq)
608 END DO
609 CALL init_cell(cell)
610 numer_stress(ip, iq) = 0.5_dp*(numer_energy(1) - numer_energy(2))/dx_w
611 IF (output_unit > 0) THEN
612 IF (globenv%run_type_id == debug_run) THEN
613 WRITE (unit=output_unit, fmt="(/,T2,A,T19,A,F7.4,A,T44,A,F7.4,A,T69,A)") &
614 "DEBUG|", "E("//achar(119 + ip)//achar(119 + iq)//" +", dx_w, ")", &
615 "E("//achar(119 + ip)//achar(119 + iq)//" -", dx_w, ")", &
616 "f(numerical)"
617 WRITE (unit=output_unit, fmt="(T2,A,2(1X,F24.8),1X,F22.8)") &
618 "DEBUG|", numer_energy(1:2), numer_stress(ip, iq)
619 ELSE
620 WRITE (unit=output_unit, fmt="(/,T7,A,F7.4,A,T27,A,F7.4,A,T49,A)") &
621 "E("//achar(119 + ip)//achar(119 + iq)//" +", dx_w, ")", &
622 "E("//achar(119 + ip)//achar(119 + iq)//" -", dx_w, ")", &
623 "f(numerical)"
624 WRITE (unit=output_unit, fmt="(3(1X,F19.8))") &
625 numer_energy(1:2), numer_stress(ip, iq)
626 END IF
627 END IF
628 END DO
629 END DO
630
631 ! Reset positions and rebuild original environment
632 cell%symmetry_id = symmetry_id
633 CALL init_cell(cell)
634 DO i = 1, natom
635 particles%els(i)%r = ref_pos_atom(i, :)
636 END DO
637 DO i = 1, ncore
638 core_particles%els(i)%r = ref_pos_core(i, :)
639 END DO
640 DO i = 1, nshell
641 shell_particles%els(i)%r = ref_pos_shell(i, :)
642 END DO
643 CALL force_env_calc_energy_force(force_env, &
644 calc_force=.false., &
645 consistent_energies=.true., &
646 calc_stress_tensor=.false.)
647
648 ! Computing pv_test
649 virial%pv_virial = 0.0_dp
650 DO i = 1, 3
651 DO j = 1, 3
652 DO k = 1, 3
653 virial%pv_virial(i, j) = virial%pv_virial(i, j) - &
654 0.5_dp*(numer_stress(i, k)*cell_local%hmat(j, k) + &
655 numer_stress(j, k)*cell_local%hmat(i, k))
656 END DO
657 END DO
658 END DO
659
660 IF (output_unit > 0) THEN
661 IF (globenv%run_type_id == debug_run) THEN
662 CALL section_vals_val_get(force_env%force_env_section, "PRINT%FORCES%FORCE_UNIT", &
663 c_val=unit_string)
664 CALL write_stress_tensor(virial%pv_virial, output_unit, cell, unit_string, virial%pv_numer)
665 END IF
666 WRITE (output_unit, "(/,A,/)") " **************************** "// &
667 "NUMERICAL STRESS END *****************************"
668 END IF
669
670 CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
671 "PRINT%STRESS_TENSOR")
672
673 ! Release storage
674 IF (ASSOCIATED(ref_pos_atom)) THEN
675 DEALLOCATE (ref_pos_atom)
676 END IF
677 IF (ASSOCIATED(ref_pos_core)) THEN
678 DEALLOCATE (ref_pos_core)
679 END IF
680 IF (ASSOCIATED(ref_pos_shell)) THEN
681 DEALLOCATE (ref_pos_shell)
682 END IF
683 IF (ASSOCIATED(cell_local)) CALL cell_release(cell_local)
684
685 END SUBROUTINE force_env_calc_num_pressure
686
687! **************************************************************************************************
688!> \brief creates and initializes a force environment
689!> \param force_env the force env to create
690!> \param root_section ...
691!> \param para_env ...
692!> \param globenv ...
693!> \param fist_env , qs_env: exactly one of these should be
694!> associated, the one that is active
695!> \param qs_env ...
696!> \param meta_env ...
697!> \param sub_force_env ...
698!> \param qmmm_env ...
699!> \param qmmmx_env ...
700!> \param eip_env ...
701!> \param pwdft_env ...
702!> \param force_env_section ...
703!> \param mixed_env ...
704!> \param embed_env ...
705!> \param nnp_env ...
706!> \param ipi_env ...
707!> \par History
708!> 04.2003 created [fawzi]
709!> \author fawzi
710! **************************************************************************************************
711 SUBROUTINE force_env_create(force_env, root_section, para_env, globenv, fist_env, &
712 qs_env, meta_env, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, force_env_section, &
713 mixed_env, embed_env, nnp_env, ipi_env)
714
715 TYPE(force_env_type), POINTER :: force_env
716 TYPE(section_vals_type), POINTER :: root_section
717 TYPE(mp_para_env_type), POINTER :: para_env
718 TYPE(global_environment_type), POINTER :: globenv
719 TYPE(fist_environment_type), OPTIONAL, POINTER :: fist_env
720 TYPE(qs_environment_type), OPTIONAL, POINTER :: qs_env
721 TYPE(meta_env_type), OPTIONAL, POINTER :: meta_env
722 TYPE(force_env_p_type), DIMENSION(:), OPTIONAL, &
723 POINTER :: sub_force_env
724 TYPE(qmmm_env_type), OPTIONAL, POINTER :: qmmm_env
725 TYPE(qmmmx_env_type), OPTIONAL, POINTER :: qmmmx_env
726 TYPE(eip_environment_type), OPTIONAL, POINTER :: eip_env
727 TYPE(pwdft_environment_type), OPTIONAL, POINTER :: pwdft_env
728 TYPE(section_vals_type), POINTER :: force_env_section
729 TYPE(mixed_environment_type), OPTIONAL, POINTER :: mixed_env
730 TYPE(embed_env_type), OPTIONAL, POINTER :: embed_env
731 TYPE(nnp_type), OPTIONAL, POINTER :: nnp_env
732 TYPE(ipi_environment_type), OPTIONAL, POINTER :: ipi_env
733
734 ALLOCATE (force_env)
735 NULLIFY (force_env%fist_env, force_env%qs_env, &
736 force_env%para_env, force_env%globenv, &
737 force_env%meta_env, force_env%sub_force_env, &
738 force_env%qmmm_env, force_env%qmmmx_env, force_env%fp_env, &
739 force_env%force_env_section, force_env%eip_env, force_env%mixed_env, &
740 force_env%embed_env, force_env%pwdft_env, force_env%nnp_env, &
741 force_env%root_section)
742 last_force_env_id = last_force_env_id + 1
743 force_env%ref_count = 1
744 force_env%in_use = 0
745 force_env%additional_potential = 0.0_dp
746
747 force_env%globenv => globenv
748 CALL globenv_retain(force_env%globenv)
749
750 force_env%root_section => root_section
751 CALL section_vals_retain(root_section)
752
753 force_env%para_env => para_env
754 CALL force_env%para_env%retain()
755
756 CALL section_vals_retain(force_env_section)
757 force_env%force_env_section => force_env_section
758
759 IF (PRESENT(fist_env)) THEN
760 cpassert(ASSOCIATED(fist_env))
761 cpassert(force_env%in_use == 0)
762 force_env%in_use = use_fist_force
763 force_env%fist_env => fist_env
764 END IF
765 IF (PRESENT(eip_env)) THEN
766 cpassert(ASSOCIATED(eip_env))
767 cpassert(force_env%in_use == 0)
768 force_env%in_use = use_eip_force
769 force_env%eip_env => eip_env
770 END IF
771 IF (PRESENT(pwdft_env)) THEN
772 cpassert(ASSOCIATED(pwdft_env))
773 cpassert(force_env%in_use == 0)
774 force_env%in_use = use_pwdft_force
775 force_env%pwdft_env => pwdft_env
776 END IF
777 IF (PRESENT(qs_env)) THEN
778 cpassert(ASSOCIATED(qs_env))
779 cpassert(force_env%in_use == 0)
780 force_env%in_use = use_qs_force
781 force_env%qs_env => qs_env
782 END IF
783 IF (PRESENT(qmmm_env)) THEN
784 cpassert(ASSOCIATED(qmmm_env))
785 cpassert(force_env%in_use == 0)
786 force_env%in_use = use_qmmm
787 force_env%qmmm_env => qmmm_env
788 END IF
789 IF (PRESENT(qmmmx_env)) THEN
790 cpassert(ASSOCIATED(qmmmx_env))
791 cpassert(force_env%in_use == 0)
792 force_env%in_use = use_qmmmx
793 force_env%qmmmx_env => qmmmx_env
794 END IF
795 IF (PRESENT(mixed_env)) THEN
796 cpassert(ASSOCIATED(mixed_env))
797 cpassert(force_env%in_use == 0)
798 force_env%in_use = use_mixed_force
799 force_env%mixed_env => mixed_env
800 END IF
801 IF (PRESENT(embed_env)) THEN
802 cpassert(ASSOCIATED(embed_env))
803 cpassert(force_env%in_use == 0)
804 force_env%in_use = use_embed
805 force_env%embed_env => embed_env
806 END IF
807 IF (PRESENT(nnp_env)) THEN
808 cpassert(ASSOCIATED(nnp_env))
809 cpassert(force_env%in_use == 0)
810 force_env%in_use = use_nnp_force
811 force_env%nnp_env => nnp_env
812 END IF
813 IF (PRESENT(ipi_env)) THEN
814 cpassert(ASSOCIATED(ipi_env))
815 cpassert(force_env%in_use == 0)
816 force_env%in_use = use_ipi
817 force_env%ipi_env => ipi_env
818 END IF
819 cpassert(force_env%in_use /= 0)
820
821 IF (PRESENT(sub_force_env)) THEN
822 force_env%sub_force_env => sub_force_env
823 END IF
824
825 IF (PRESENT(meta_env)) THEN
826 force_env%meta_env => meta_env
827 ELSE
828 NULLIFY (force_env%meta_env)
829 END IF
830
831 END SUBROUTINE force_env_create
832
833! **************************************************************************************************
834!> \brief ****f* force_env_methods/mixed_energy_forces [1.0]
835!>
836!> Computes energy and forces for a mixed force_env type
837!> \param force_env the force_env that holds the mixed_env type
838!> \param calculate_forces decides if forces should be calculated
839!> \par History
840!> 11.06 created [fschiff]
841!> 04.07 generalization to an illimited number of force_eval [tlaino]
842!> 04.07 further generalization to force_eval with different geometrical
843!> structures [tlaino]
844!> 04.08 reorganizing the genmix structure (collecting common code)
845!> 01.16 added CDFT [Nico Holmberg]
846!> 08.17 added DFT embedding [Vladimir Rybkin]
847!> \author Florian Schiffmann
848! **************************************************************************************************
849 SUBROUTINE mixed_energy_forces(force_env, calculate_forces)
850
851 TYPE(force_env_type), POINTER :: force_env
852 LOGICAL, INTENT(IN) :: calculate_forces
853
854 CHARACTER(LEN=default_path_length) :: coupling_function
855 CHARACTER(LEN=default_string_length) :: def_error, description, this_error
856 INTEGER :: iforce_eval, iparticle, istate(2), &
857 jparticle, mixing_type, my_group, &
858 natom, nforce_eval, source, unit_nr
859 INTEGER, DIMENSION(:), POINTER :: glob_natoms, itmplist, map_index
860 LOGICAL :: dip_exists
861 REAL(kind=dp) :: coupling_parameter, dedf, der_1, der_2, &
862 dx, energy, err, lambda, lerr, &
863 restraint_strength, restraint_target, &
864 sd
865 REAL(kind=dp), DIMENSION(3) :: dip_mix
866 REAL(kind=dp), DIMENSION(:), POINTER :: energies
867 TYPE(cell_type), POINTER :: cell_mix
868 TYPE(cp_logger_type), POINTER :: logger, my_logger
869 TYPE(cp_result_p_type), DIMENSION(:), POINTER :: results
870 TYPE(cp_result_type), POINTER :: loc_results, results_mix
871 TYPE(cp_subsys_p_type), DIMENSION(:), POINTER :: subsystems
872 TYPE(cp_subsys_type), POINTER :: subsys_mix
873 TYPE(mixed_energy_type), POINTER :: mixed_energy
874 TYPE(mixed_force_type), DIMENSION(:), POINTER :: global_forces
875 TYPE(particle_list_p_type), DIMENSION(:), POINTER :: particles
876 TYPE(particle_list_type), POINTER :: particles_mix
877 TYPE(section_vals_type), POINTER :: force_env_section, gen_section, &
878 mapping_section, mixed_section, &
879 root_section
880 TYPE(virial_p_type), DIMENSION(:), POINTER :: virials
881 TYPE(virial_type), POINTER :: loc_virial, virial_mix
882
883 logger => cp_get_default_logger()
884 cpassert(ASSOCIATED(force_env))
885 ! Get infos about the mixed subsys
886 CALL force_env_get(force_env=force_env, &
887 subsys=subsys_mix, &
888 force_env_section=force_env_section, &
889 root_section=root_section, &
890 cell=cell_mix)
891 CALL cp_subsys_get(subsys=subsys_mix, &
892 particles=particles_mix, &
893 virial=virial_mix, &
894 results=results_mix)
895 NULLIFY (map_index, glob_natoms, global_forces, itmplist)
896
897 nforce_eval = SIZE(force_env%sub_force_env)
898 mixed_section => section_vals_get_subs_vals(force_env_section, "MIXED")
899 mapping_section => section_vals_get_subs_vals(mixed_section, "MAPPING")
900 ! Global Info
901 ALLOCATE (subsystems(nforce_eval))
902 ALLOCATE (particles(nforce_eval))
903 ! Local Info to sync
904 ALLOCATE (global_forces(nforce_eval))
905 ALLOCATE (energies(nforce_eval))
906 ALLOCATE (glob_natoms(nforce_eval))
907 ALLOCATE (virials(nforce_eval))
908 ALLOCATE (results(nforce_eval))
909 energies = 0.0_dp
910 glob_natoms = 0
911 ! Check if mixed CDFT calculation is requested and initialize
912 CALL mixed_cdft_init(force_env, calculate_forces)
913
914 !
915 IF (.NOT. force_env%mixed_env%do_mixed_cdft) THEN
916 DO iforce_eval = 1, nforce_eval
917 NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
918 NULLIFY (results(iforce_eval)%results, virials(iforce_eval)%virial)
919 ALLOCATE (virials(iforce_eval)%virial)
920 CALL cp_result_create(results(iforce_eval)%results)
921 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
922 ! From this point on the error is the sub_error
923 my_group = force_env%mixed_env%group_distribution(force_env%para_env%mepos)
924 my_logger => force_env%mixed_env%sub_logger(my_group + 1)%p
925 ! Copy iterations info (they are updated only in the main mixed_env)
926 CALL cp_iteration_info_copy_iter(logger%iter_info, my_logger%iter_info)
927 CALL cp_add_default_logger(my_logger)
928
929 ! Get all available subsys
930 CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
931 subsys=subsystems(iforce_eval)%subsys)
932
933 ! all force_env share the same cell
934 CALL cp_subsys_set(subsystems(iforce_eval)%subsys, cell=cell_mix)
935
936 ! Get available particles
937 CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
938 particles=particles(iforce_eval)%list)
939
940 ! Get Mapping index array
941 natom = SIZE(particles(iforce_eval)%list%els)
942
943 CALL get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, &
944 map_index)
945
946 ! Mapping particles from iforce_eval environment to the mixed env
947 DO iparticle = 1, natom
948 jparticle = map_index(iparticle)
949 particles(iforce_eval)%list%els(iparticle)%r = particles_mix%els(jparticle)%r
950 END DO
951
952 ! Calculate energy and forces for each sub_force_env
953 CALL force_env_calc_energy_force(force_env%sub_force_env(iforce_eval)%force_env, &
954 calc_force=calculate_forces, &
955 skip_external_control=.true.)
956
957 ! Only the rank 0 process collect info for each computation
958 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
959 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, &
960 potential_energy=energy)
961 CALL cp_subsys_get(subsystems(iforce_eval)%subsys, &
962 virial=loc_virial, results=loc_results)
963 energies(iforce_eval) = energy
964 glob_natoms(iforce_eval) = natom
965 virials(iforce_eval)%virial = loc_virial
966 CALL cp_result_copy(loc_results, results(iforce_eval)%results)
967 END IF
968 ! Deallocate map_index array
969 IF (ASSOCIATED(map_index)) THEN
970 DEALLOCATE (map_index)
971 END IF
973 END DO
974 ELSE
975 CALL mixed_cdft_energy_forces(force_env, calculate_forces, particles, energies, &
976 glob_natoms, virials, results)
977 END IF
978 ! Handling Parallel execution
979 CALL force_env%para_env%sync()
980 ! Post CDFT operations
981 CALL mixed_cdft_post_energy_forces(force_env)
982 ! Let's transfer energy, natom, forces, virials
983 CALL force_env%para_env%sum(energies)
984 CALL force_env%para_env%sum(glob_natoms)
985 ! Transfer forces
986 DO iforce_eval = 1, nforce_eval
987 ALLOCATE (global_forces(iforce_eval)%forces(3, glob_natoms(iforce_eval)))
988 global_forces(iforce_eval)%forces = 0.0_dp
989 IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) THEN
990 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
991 ! Forces
992 DO iparticle = 1, glob_natoms(iforce_eval)
993 global_forces(iforce_eval)%forces(:, iparticle) = &
994 particles(iforce_eval)%list%els(iparticle)%f
995 END DO
996 END IF
997 END IF
998 CALL force_env%para_env%sum(global_forces(iforce_eval)%forces)
999 !Transfer only the relevant part of the virial..
1000 CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_total)
1001 CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_kinetic)
1002 CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_virial)
1003 CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_xc)
1004 CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_fock_4c)
1005 CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_constraint)
1006 !Transfer results
1007 source = 0
1008 IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) THEN
1009 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) &
1010 source = force_env%para_env%mepos
1011 END IF
1012 CALL force_env%para_env%sum(source)
1013 CALL cp_results_mp_bcast(results(iforce_eval)%results, source, force_env%para_env)
1014 END DO
1015
1016 force_env%mixed_env%energies = energies
1017 ! Start combining the different sub_force_env
1018 CALL get_mixed_env(mixed_env=force_env%mixed_env, &
1019 mixed_energy=mixed_energy)
1020
1021 !NB: do this for all MIXING_TYPE values, since some need it (e.g. linear mixing
1022 !NB if the first system has fewer atoms than the second)
1023 DO iparticle = 1, SIZE(particles_mix%els)
1024 particles_mix%els(iparticle)%f(:) = 0.0_dp
1025 END DO
1026
1027 CALL section_vals_val_get(mixed_section, "MIXING_TYPE", i_val=mixing_type)
1028 SELECT CASE (mixing_type)
1030 ! Support offered only 2 force_eval
1031 cpassert(nforce_eval == 2)
1032 CALL section_vals_val_get(mixed_section, "LINEAR%LAMBDA", r_val=lambda)
1033 mixed_energy%pot = lambda*energies(1) + (1.0_dp - lambda)*energies(2)
1034 ! General Mapping of forces...
1035 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1036 lambda, 1, nforce_eval, map_index, mapping_section, .true.)
1037 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1038 (1.0_dp - lambda), 2, nforce_eval, map_index, mapping_section, .false.)
1039 CASE (mix_minimum)
1040 ! Support offered only 2 force_eval
1041 cpassert(nforce_eval == 2)
1042 IF (energies(1) < energies(2)) THEN
1043 mixed_energy%pot = energies(1)
1044 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1045 1.0_dp, 1, nforce_eval, map_index, mapping_section, .true.)
1046 ELSE
1047 mixed_energy%pot = energies(2)
1048 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1049 1.0_dp, 2, nforce_eval, map_index, mapping_section, .true.)
1050 END IF
1051 CASE (mix_coupled)
1052 ! Support offered only 2 force_eval
1053 cpassert(nforce_eval == 2)
1054 CALL section_vals_val_get(mixed_section, "COUPLING%COUPLING_PARAMETER", &
1055 r_val=coupling_parameter)
1056 sd = sqrt((energies(1) - energies(2))**2 + 4.0_dp*coupling_parameter**2)
1057 der_1 = (1.0_dp - (1.0_dp/(2.0_dp*sd))*2.0_dp*(energies(1) - energies(2)))/2.0_dp
1058 der_2 = (1.0_dp + (1.0_dp/(2.0_dp*sd))*2.0_dp*(energies(1) - energies(2)))/2.0_dp
1059 mixed_energy%pot = (energies(1) + energies(2) - sd)/2.0_dp
1060 ! General Mapping of forces...
1061 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1062 der_1, 1, nforce_eval, map_index, mapping_section, .true.)
1063 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1064 der_2, 2, nforce_eval, map_index, mapping_section, .false.)
1065 CASE (mix_restrained)
1066 ! Support offered only 2 force_eval
1067 cpassert(nforce_eval == 2)
1068 CALL section_vals_val_get(mixed_section, "RESTRAINT%RESTRAINT_TARGET", &
1069 r_val=restraint_target)
1070 CALL section_vals_val_get(mixed_section, "RESTRAINT%RESTRAINT_STRENGTH", &
1071 r_val=restraint_strength)
1072 mixed_energy%pot = energies(1) + restraint_strength*(energies(1) - energies(2) - restraint_target)**2
1073 der_2 = -2.0_dp*restraint_strength*(energies(1) - energies(2) - restraint_target)
1074 der_1 = 1.0_dp - der_2
1075 ! General Mapping of forces...
1076 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1077 der_1, 1, nforce_eval, map_index, mapping_section, .true.)
1078 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1079 der_2, 2, nforce_eval, map_index, mapping_section, .false.)
1080 CASE (mix_generic)
1081 ! Support any number of force_eval sections
1082 gen_section => section_vals_get_subs_vals(mixed_section, "GENERIC")
1083 CALL get_generic_info(gen_section, "MIXING_FUNCTION", coupling_function, force_env%mixed_env%par, &
1084 force_env%mixed_env%val, energies)
1085 CALL initf(1)
1086 CALL parsef(1, trim(coupling_function), force_env%mixed_env%par)
1087 ! Now the hardest part.. map energy with corresponding force_eval
1088 mixed_energy%pot = evalf(1, force_env%mixed_env%val)
1089 cpassert(evalerrtype <= 0)
1090 CALL zero_virial(virial_mix, reset=.false.)
1091 CALL cp_results_erase(results_mix)
1092 DO iforce_eval = 1, nforce_eval
1093 CALL section_vals_val_get(gen_section, "DX", r_val=dx)
1094 CALL section_vals_val_get(gen_section, "ERROR_LIMIT", r_val=lerr)
1095 dedf = evalfd(1, iforce_eval, force_env%mixed_env%val, dx, err)
1096 IF (abs(err) > lerr) THEN
1097 WRITE (this_error, "(A,G12.6,A)") "(", err, ")"
1098 WRITE (def_error, "(A,G12.6,A)") "(", lerr, ")"
1099 CALL compress(this_error, .true.)
1100 CALL compress(def_error, .true.)
1101 CALL cp_warn(__location__, &
1102 'ASSERTION (cond) failed at line '//cp_to_string(__line__)// &
1103 ' Error '//trim(this_error)//' in computing numerical derivatives larger then'// &
1104 trim(def_error)//' .')
1105 END IF
1106 ! General Mapping of forces...
1107 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1108 dedf, iforce_eval, nforce_eval, map_index, mapping_section, .false.)
1109 force_env%mixed_env%val(iforce_eval) = energies(iforce_eval)
1110 END DO
1111 ! Let's store the needed information..
1112 force_env%mixed_env%dx = dx
1113 force_env%mixed_env%lerr = lerr
1114 force_env%mixed_env%coupling_function = trim(coupling_function)
1115 CALL finalizef()
1116 CASE (mix_cdft)
1117 ! Supports any number of force_evals for calculation of CDFT properties, but forces only from two
1118 CALL section_vals_val_get(mixed_section, "MIXED_CDFT%LAMBDA", r_val=lambda)
1119 ! Get the states which determine the forces
1120 CALL section_vals_val_get(mixed_section, "MIXED_CDFT%FORCE_STATES", i_vals=itmplist)
1121 IF (SIZE(itmplist) /= 2) &
1122 CALL cp_abort(__location__, &
1123 "Keyword FORCE_STATES takes exactly two input values.")
1124 IF (any(itmplist .LT. 0)) &
1125 cpabort("Invalid force_eval index.")
1126 istate = itmplist
1127 IF (istate(1) > nforce_eval .OR. istate(2) > nforce_eval) &
1128 cpabort("Invalid force_eval index.")
1129 mixed_energy%pot = lambda*energies(istate(1)) + (1.0_dp - lambda)*energies(istate(2))
1130 ! General Mapping of forces...
1131 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1132 lambda, istate(1), nforce_eval, map_index, mapping_section, .true.)
1133 CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
1134 (1.0_dp - lambda), istate(2), nforce_eval, map_index, mapping_section, .false.)
1135 CASE DEFAULT
1136 cpabort("")
1137 END SELECT
1138 !Simply deallocate and loose the pointer references..
1139 DO iforce_eval = 1, nforce_eval
1140 DEALLOCATE (global_forces(iforce_eval)%forces)
1141 IF (ASSOCIATED(virials(iforce_eval)%virial)) DEALLOCATE (virials(iforce_eval)%virial)
1142 CALL cp_result_release(results(iforce_eval)%results)
1143 END DO
1144 DEALLOCATE (global_forces)
1145 DEALLOCATE (subsystems)
1146 DEALLOCATE (particles)
1147 DEALLOCATE (energies)
1148 DEALLOCATE (glob_natoms)
1149 DEALLOCATE (virials)
1150 DEALLOCATE (results)
1151 ! Print Section
1152 unit_nr = cp_print_key_unit_nr(logger, mixed_section, "PRINT%DIPOLE", &
1153 extension=".data", middle_name="MIXED_DIPOLE", log_filename=.false.)
1154 IF (unit_nr > 0) THEN
1155 description = '[DIPOLE]'
1156 dip_exists = test_for_result(results=results_mix, description=description)
1157 IF (dip_exists) THEN
1158 CALL get_results(results=results_mix, description=description, values=dip_mix)
1159 WRITE (unit_nr, '(/,1X,A,T48,3F21.16)') "MIXED ENV| DIPOLE ( A.U.)|", dip_mix
1160 WRITE (unit_nr, '( 1X,A,T48,3F21.16)') "MIXED ENV| DIPOLE (Debye)|", dip_mix*debye
1161 ELSE
1162 WRITE (unit_nr, *) "NO FORCE_EVAL section calculated the dipole"
1163 END IF
1164 END IF
1165 CALL cp_print_key_finished_output(unit_nr, logger, mixed_section, "PRINT%DIPOLE")
1166 END SUBROUTINE mixed_energy_forces
1167
1168! **************************************************************************************************
1169!> \brief Driver routine for mixed CDFT energy and force calculations
1170!> \param force_env the force_env that holds the mixed_env
1171!> \param calculate_forces if forces should be calculated
1172!> \param particles system particles
1173!> \param energies the energies of the CDFT states
1174!> \param glob_natoms the total number of particles
1175!> \param virials the virials stored in subsys
1176!> \param results results stored in subsys
1177!> \par History
1178!> 01.17 created [Nico Holmberg]
1179!> \author Nico Holmberg
1180! **************************************************************************************************
1181 SUBROUTINE mixed_cdft_energy_forces(force_env, calculate_forces, particles, energies, &
1182 glob_natoms, virials, results)
1183 TYPE(force_env_type), POINTER :: force_env
1184 LOGICAL, INTENT(IN) :: calculate_forces
1185 TYPE(particle_list_p_type), DIMENSION(:), POINTER :: particles
1186 REAL(kind=dp), DIMENSION(:), POINTER :: energies
1187 INTEGER, DIMENSION(:), POINTER :: glob_natoms
1188 TYPE(virial_p_type), DIMENSION(:), POINTER :: virials
1189 TYPE(cp_result_p_type), DIMENSION(:), POINTER :: results
1190
1191 INTEGER :: iforce_eval, iparticle, jparticle, &
1192 my_group, natom, nforce_eval
1193 INTEGER, DIMENSION(:), POINTER :: map_index
1194 REAL(kind=dp) :: energy
1195 TYPE(cell_type), POINTER :: cell_mix
1196 TYPE(cp_logger_type), POINTER :: logger, my_logger
1197 TYPE(cp_result_type), POINTER :: loc_results, results_mix
1198 TYPE(cp_subsys_p_type), DIMENSION(:), POINTER :: subsystems
1199 TYPE(cp_subsys_type), POINTER :: subsys_mix
1200 TYPE(particle_list_type), POINTER :: particles_mix
1201 TYPE(section_vals_type), POINTER :: force_env_section, mapping_section, &
1202 mixed_section, root_section
1203 TYPE(virial_type), POINTER :: loc_virial, virial_mix
1204
1205 logger => cp_get_default_logger()
1206 cpassert(ASSOCIATED(force_env))
1207 ! Get infos about the mixed subsys
1208 CALL force_env_get(force_env=force_env, &
1209 subsys=subsys_mix, &
1210 force_env_section=force_env_section, &
1211 root_section=root_section, &
1212 cell=cell_mix)
1213 CALL cp_subsys_get(subsys=subsys_mix, &
1214 particles=particles_mix, &
1215 virial=virial_mix, &
1216 results=results_mix)
1217 NULLIFY (map_index)
1218 nforce_eval = SIZE(force_env%sub_force_env)
1219 mixed_section => section_vals_get_subs_vals(force_env_section, "MIXED")
1220 mapping_section => section_vals_get_subs_vals(mixed_section, "MAPPING")
1221 ALLOCATE (subsystems(nforce_eval))
1222 DO iforce_eval = 1, nforce_eval
1223 NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
1224 NULLIFY (results(iforce_eval)%results, virials(iforce_eval)%virial)
1225 ALLOCATE (virials(iforce_eval)%virial)
1226 CALL cp_result_create(results(iforce_eval)%results)
1227 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1228 ! Get all available subsys
1229 CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
1230 subsys=subsystems(iforce_eval)%subsys)
1231
1232 ! all force_env share the same cell
1233 CALL cp_subsys_set(subsystems(iforce_eval)%subsys, cell=cell_mix)
1234
1235 ! Get available particles
1236 CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
1237 particles=particles(iforce_eval)%list)
1238
1239 ! Get Mapping index array
1240 natom = SIZE(particles(iforce_eval)%list%els)
1241 ! Serial mode need to deallocate first
1242 IF (ASSOCIATED(map_index)) &
1243 DEALLOCATE (map_index)
1244 CALL get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, &
1245 map_index)
1246
1247 ! Mapping particles from iforce_eval environment to the mixed env
1248 DO iparticle = 1, natom
1249 jparticle = map_index(iparticle)
1250 particles(iforce_eval)%list%els(iparticle)%r = particles_mix%els(jparticle)%r
1251 END DO
1252 ! Mixed CDFT + QMMM: Need to translate now
1253 IF (force_env%mixed_env%do_mixed_qmmm_cdft) &
1254 CALL apply_qmmm_translate(force_env%sub_force_env(iforce_eval)%force_env%qmmm_env)
1255 END DO
1256 ! For mixed CDFT calculations parallelized over CDFT states
1257 ! build weight and gradient on all processors before splitting into groups and
1258 ! starting energy calculation
1259 CALL mixed_cdft_build_weight(force_env, calculate_forces)
1260 DO iforce_eval = 1, nforce_eval
1261 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1262 ! From this point on the error is the sub_error
1263 IF (force_env%mixed_env%cdft_control%run_type == mixed_cdft_serial .AND. iforce_eval .GE. 2) THEN
1264 my_logger => force_env%mixed_env%cdft_control%sub_logger(iforce_eval - 1)%p
1265 ELSE
1266 my_group = force_env%mixed_env%group_distribution(force_env%para_env%mepos)
1267 my_logger => force_env%mixed_env%sub_logger(my_group + 1)%p
1268 END IF
1269 ! Copy iterations info (they are updated only in the main mixed_env)
1270 CALL cp_iteration_info_copy_iter(logger%iter_info, my_logger%iter_info)
1271 CALL cp_add_default_logger(my_logger)
1272 ! Serial CDFT calculation: transfer weight/gradient
1273 CALL mixed_cdft_build_weight(force_env, calculate_forces, iforce_eval)
1274 ! Calculate energy and forces for each sub_force_env
1275 CALL force_env_calc_energy_force(force_env%sub_force_env(iforce_eval)%force_env, &
1276 calc_force=calculate_forces, &
1277 skip_external_control=.true.)
1278 ! Only the rank 0 process collect info for each computation
1279 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
1280 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, &
1281 potential_energy=energy)
1282 CALL cp_subsys_get(subsystems(iforce_eval)%subsys, &
1283 virial=loc_virial, results=loc_results)
1284 energies(iforce_eval) = energy
1285 glob_natoms(iforce_eval) = natom
1286 virials(iforce_eval)%virial = loc_virial
1287 CALL cp_result_copy(loc_results, results(iforce_eval)%results)
1288 END IF
1289 ! Deallocate map_index array
1290 IF (ASSOCIATED(map_index)) THEN
1291 DEALLOCATE (map_index)
1292 END IF
1294 END DO
1295 DEALLOCATE (subsystems)
1296
1297 END SUBROUTINE mixed_cdft_energy_forces
1298
1299! **************************************************************************************************
1300!> \brief Perform additional tasks for mixed CDFT calculations after solving the electronic structure
1301!> of both CDFT states
1302!> \param force_env the force_env that holds the CDFT states
1303!> \par History
1304!> 01.17 created [Nico Holmberg]
1305!> \author Nico Holmberg
1306! **************************************************************************************************
1307 SUBROUTINE mixed_cdft_post_energy_forces(force_env)
1308 TYPE(force_env_type), POINTER :: force_env
1309
1310 INTEGER :: iforce_eval, nforce_eval, nvar
1311 TYPE(dft_control_type), POINTER :: dft_control
1312 TYPE(qs_environment_type), POINTER :: qs_env
1313
1314 cpassert(ASSOCIATED(force_env))
1315 NULLIFY (qs_env, dft_control)
1316 IF (force_env%mixed_env%do_mixed_cdft) THEN
1317 nforce_eval = SIZE(force_env%sub_force_env)
1318 nvar = force_env%mixed_env%cdft_control%nconstraint
1319 ! Transfer cdft strengths for writing restart
1320 IF (.NOT. ASSOCIATED(force_env%mixed_env%strength)) &
1321 ALLOCATE (force_env%mixed_env%strength(nforce_eval, nvar))
1322 force_env%mixed_env%strength = 0.0_dp
1323 DO iforce_eval = 1, nforce_eval
1324 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1325 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1326 qs_env => force_env%sub_force_env(iforce_eval)%force_env%qmmm_env%qs_env
1327 ELSE
1328 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, qs_env=qs_env)
1329 END IF
1330 CALL get_qs_env(qs_env, dft_control=dft_control)
1331 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) &
1332 force_env%mixed_env%strength(iforce_eval, :) = dft_control%qs_control%cdft_control%strength(:)
1333 END DO
1334 CALL force_env%para_env%sum(force_env%mixed_env%strength)
1335 ! Mixed CDFT: calculate ET coupling
1336 IF (force_env%mixed_env%do_mixed_et) THEN
1337 IF (modulo(force_env%mixed_env%cdft_control%sim_step, force_env%mixed_env%et_freq) == 0) &
1338 CALL mixed_cdft_calculate_coupling(force_env)
1339 END IF
1340 END IF
1341
1342 END SUBROUTINE mixed_cdft_post_energy_forces
1343
1344! **************************************************************************************************
1345!> \brief Computes the total energy for an embedded calculation
1346!> \param force_env ...
1347!> \author Vladimir Rybkin
1348! **************************************************************************************************
1349 SUBROUTINE embed_energy(force_env)
1350
1351 TYPE(force_env_type), POINTER :: force_env
1352
1353 INTEGER :: iforce_eval, iparticle, jparticle, &
1354 my_group, natom, nforce_eval
1355 INTEGER, DIMENSION(:), POINTER :: glob_natoms, map_index
1356 LOGICAL :: converged_embed
1357 REAL(kind=dp) :: energy
1358 REAL(kind=dp), DIMENSION(:), POINTER :: energies
1359 TYPE(cell_type), POINTER :: cell_embed
1360 TYPE(cp_logger_type), POINTER :: logger, my_logger
1361 TYPE(cp_result_p_type), DIMENSION(:), POINTER :: results
1362 TYPE(cp_result_type), POINTER :: loc_results, results_embed
1363 TYPE(cp_subsys_p_type), DIMENSION(:), POINTER :: subsystems
1364 TYPE(cp_subsys_type), POINTER :: subsys_embed
1365 TYPE(dft_control_type), POINTER :: dft_control
1366 TYPE(particle_list_p_type), DIMENSION(:), POINTER :: particles
1367 TYPE(particle_list_type), POINTER :: particles_embed
1368 TYPE(pw_env_type), POINTER :: pw_env
1369 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1370 TYPE(pw_r3d_rs_type), POINTER :: embed_pot, spin_embed_pot
1371 TYPE(section_vals_type), POINTER :: embed_section, force_env_section, &
1372 mapping_section, root_section
1373
1374 logger => cp_get_default_logger()
1375 cpassert(ASSOCIATED(force_env))
1376 ! Get infos about the embedding subsys
1377 CALL force_env_get(force_env=force_env, &
1378 subsys=subsys_embed, &
1379 force_env_section=force_env_section, &
1380 root_section=root_section, &
1381 cell=cell_embed)
1382 CALL cp_subsys_get(subsys=subsys_embed, &
1383 particles=particles_embed, &
1384 results=results_embed)
1385 NULLIFY (map_index, glob_natoms)
1386
1387 nforce_eval = SIZE(force_env%sub_force_env)
1388 embed_section => section_vals_get_subs_vals(force_env_section, "EMBED")
1389 mapping_section => section_vals_get_subs_vals(embed_section, "MAPPING")
1390 ! Global Info
1391 ALLOCATE (subsystems(nforce_eval))
1392 ALLOCATE (particles(nforce_eval))
1393 ! Local Info to sync
1394 ALLOCATE (energies(nforce_eval))
1395 ALLOCATE (glob_natoms(nforce_eval))
1396 ALLOCATE (results(nforce_eval))
1397 energies = 0.0_dp
1398 glob_natoms = 0
1399
1400 DO iforce_eval = 1, nforce_eval
1401 NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
1402 NULLIFY (results(iforce_eval)%results)
1403 CALL cp_result_create(results(iforce_eval)%results)
1404 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1405 ! From this point on the error is the sub_error
1406 my_group = force_env%embed_env%group_distribution(force_env%para_env%mepos)
1407 my_logger => force_env%embed_env%sub_logger(my_group + 1)%p
1408 ! Copy iterations info (they are updated only in the main embed_env)
1409 CALL cp_iteration_info_copy_iter(logger%iter_info, my_logger%iter_info)
1410 CALL cp_add_default_logger(my_logger)
1411
1412 ! Get all available subsys
1413 CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
1414 subsys=subsystems(iforce_eval)%subsys)
1415
1416 ! Check if we import density from previous force calculations
1417 ! Only for QUICKSTEP
1418 IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env%qs_env)) THEN
1419 NULLIFY (dft_control)
1420 CALL get_qs_env(force_env%sub_force_env(iforce_eval)%force_env%qs_env, dft_control=dft_control)
1421 IF (dft_control%qs_control%ref_embed_subsys) THEN
1422 IF (iforce_eval .EQ. 2) cpabort("Density importing force_eval can't be the first.")
1423 END IF
1424 END IF
1425
1426 ! all force_env share the same cell
1427 CALL cp_subsys_set(subsystems(iforce_eval)%subsys, cell=cell_embed)
1428
1429 ! Get available particles
1430 CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
1431 particles=particles(iforce_eval)%list)
1432
1433 ! Get Mapping index array
1434 natom = SIZE(particles(iforce_eval)%list%els)
1435
1436 CALL get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, &
1437 map_index, .true.)
1438
1439 ! Mapping particles from iforce_eval environment to the embed env
1440 DO iparticle = 1, natom
1441 jparticle = map_index(iparticle)
1442 particles(iforce_eval)%list%els(iparticle)%r = particles_embed%els(jparticle)%r
1443 END DO
1444
1445 ! Calculate energy and forces for each sub_force_env
1446 CALL force_env_calc_energy_force(force_env%sub_force_env(iforce_eval)%force_env, &
1447 calc_force=.false., &
1448 skip_external_control=.true.)
1449
1450 ! Call DFT embedding
1451 IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env%qs_env)) THEN
1452 NULLIFY (dft_control)
1453 CALL get_qs_env(force_env%sub_force_env(iforce_eval)%force_env%qs_env, dft_control=dft_control)
1454 IF (dft_control%qs_control%ref_embed_subsys) THEN
1455 ! Now we can optimize the embedding potential
1456 CALL dft_embedding(force_env, iforce_eval, energies, converged_embed)
1457 IF (.NOT. converged_embed) cpabort("Embedding potential optimization not converged.")
1458 END IF
1459 ! Deallocate embedding potential on the high-level subsystem
1460 IF (dft_control%qs_control%high_level_embed_subsys) THEN
1461 CALL get_qs_env(qs_env=force_env%sub_force_env(iforce_eval)%force_env%qs_env, &
1462 embed_pot=embed_pot, spin_embed_pot=spin_embed_pot, pw_env=pw_env)
1463 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1464 CALL auxbas_pw_pool%give_back_pw(embed_pot)
1465 IF (ASSOCIATED(embed_pot)) THEN
1466 CALL embed_pot%release()
1467 DEALLOCATE (embed_pot)
1468 END IF
1469 IF (ASSOCIATED(spin_embed_pot)) THEN
1470 CALL auxbas_pw_pool%give_back_pw(spin_embed_pot)
1471 CALL spin_embed_pot%release()
1472 DEALLOCATE (spin_embed_pot)
1473 END IF
1474 END IF
1475 END IF
1476
1477 ! Only the rank 0 process collect info for each computation
1478 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
1479 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, &
1480 potential_energy=energy)
1481 CALL cp_subsys_get(subsystems(iforce_eval)%subsys, &
1482 results=loc_results)
1483 energies(iforce_eval) = energy
1484 glob_natoms(iforce_eval) = natom
1485 CALL cp_result_copy(loc_results, results(iforce_eval)%results)
1486 END IF
1487 ! Deallocate map_index array
1488 IF (ASSOCIATED(map_index)) THEN
1489 DEALLOCATE (map_index)
1490 END IF
1492 END DO
1493
1494 ! Handling Parallel execution
1495 CALL force_env%para_env%sync()
1496 ! Let's transfer energy, natom
1497 CALL force_env%para_env%sum(energies)
1498 CALL force_env%para_env%sum(glob_natoms)
1499
1500 force_env%embed_env%energies = energies
1501
1502 !NB if the first system has fewer atoms than the second)
1503 DO iparticle = 1, SIZE(particles_embed%els)
1504 particles_embed%els(iparticle)%f(:) = 0.0_dp
1505 END DO
1506
1507 ! ONIOM type of mixing in embedding: E = E_total + E_cluster_high - E_cluster
1508 force_env%embed_env%pot_energy = energies(3) + energies(4) - energies(2)
1509
1510 !Simply deallocate and loose the pointer references..
1511 DO iforce_eval = 1, nforce_eval
1512 CALL cp_result_release(results(iforce_eval)%results)
1513 END DO
1514 DEALLOCATE (subsystems)
1515 DEALLOCATE (particles)
1516 DEALLOCATE (energies)
1517 DEALLOCATE (glob_natoms)
1518 DEALLOCATE (results)
1519
1520 END SUBROUTINE embed_energy
1521
1522! **************************************************************************************************
1523!> \brief ...
1524!> \param force_env ...
1525!> \param ref_subsys_number ...
1526!> \param energies ...
1527!> \param converged_embed ...
1528! **************************************************************************************************
1529 SUBROUTINE dft_embedding(force_env, ref_subsys_number, energies, converged_embed)
1530 TYPE(force_env_type), POINTER :: force_env
1531 INTEGER :: ref_subsys_number
1532 REAL(kind=dp), DIMENSION(:), POINTER :: energies
1533 LOGICAL :: converged_embed
1534
1535 INTEGER :: embed_method
1536 TYPE(section_vals_type), POINTER :: embed_section, force_env_section
1537
1538 ! Find out which embedding scheme is used
1539 CALL force_env_get(force_env=force_env, &
1540 force_env_section=force_env_section)
1541 embed_section => section_vals_get_subs_vals(force_env_section, "EMBED")
1542
1543 CALL section_vals_val_get(embed_section, "EMBED_METHOD", i_val=embed_method)
1544 SELECT CASE (embed_method)
1545 CASE (dfet)
1546 ! Density functional embedding
1547 CALL dfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
1548 CASE (dmfet)
1549 ! Density matrix embedding theory
1550 CALL dmfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
1551 END SELECT
1552
1553 END SUBROUTINE dft_embedding
1554! **************************************************************************************************
1555!> \brief ... Main driver for DFT embedding
1556!> \param force_env ...
1557!> \param ref_subsys_number ...
1558!> \param energies ...
1559!> \param converged_embed ...
1560!> \author Vladimir Rybkin
1561! **************************************************************************************************
1562 SUBROUTINE dfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
1563 TYPE(force_env_type), POINTER :: force_env
1564 INTEGER :: ref_subsys_number
1565 REAL(kind=dp), DIMENSION(:), POINTER :: energies
1566 LOGICAL :: converged_embed
1567
1568 CHARACTER(LEN=*), PARAMETER :: routinen = 'dfet_embedding'
1569
1570 INTEGER :: cluster_subsys_num, handle, &
1571 i_force_eval, i_iter, i_spin, &
1572 nforce_eval, nspins, nspins_subsys, &
1573 output_unit
1574 REAL(kind=dp) :: cluster_energy
1575 REAL(kind=dp), DIMENSION(:), POINTER :: rhs
1576 TYPE(cp_logger_type), POINTER :: logger
1577 TYPE(dft_control_type), POINTER :: dft_control
1578 TYPE(opt_embed_pot_type) :: opt_embed
1579 TYPE(pw_env_type), POINTER :: pw_env
1580 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1581 TYPE(pw_r3d_rs_type) :: diff_rho_r, diff_rho_spin
1582 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r_ref, rho_r_subsys
1583 TYPE(pw_r3d_rs_type), POINTER :: embed_pot, embed_pot_subsys, &
1584 spin_embed_pot, spin_embed_pot_subsys
1585 TYPE(qs_energy_type), POINTER :: energy
1586 TYPE(qs_rho_type), POINTER :: rho, subsys_rho
1587 TYPE(section_vals_type), POINTER :: dft_section, embed_section, &
1588 force_env_section, input, &
1589 mapping_section, opt_embed_section
1590
1591 CALL timeset(routinen, handle)
1592
1593 CALL cite_reference(huang2011)
1594 CALL cite_reference(heaton_burgess2007)
1595
1596 CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
1597
1598 ! Reveal input file
1599 NULLIFY (logger)
1600 logger => cp_get_default_logger()
1601 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
1602 extension=".Log")
1603
1604 NULLIFY (dft_section, input, opt_embed_section)
1605 NULLIFY (energy, dft_control)
1606
1607 CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1608 pw_env=pw_env, dft_control=dft_control, rho=rho, energy=energy, &
1609 input=input)
1610 nspins = dft_control%nspins
1611
1612 dft_section => section_vals_get_subs_vals(input, "DFT")
1613 opt_embed_section => section_vals_get_subs_vals(input, &
1614 "DFT%QS%OPT_EMBED")
1615 ! Rho_r is the reference
1616 CALL qs_rho_get(rho_struct=rho, rho_r=rho_r_ref)
1617
1618 ! We need to understand how to treat spins states
1619 CALL understand_spin_states(force_env, ref_subsys_number, opt_embed%change_spin, opt_embed%open_shell_embed, &
1620 opt_embed%all_nspins)
1621
1622 ! Prepare everything for the potential maximization
1623 CALL prepare_embed_opt(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, opt_embed, &
1624 opt_embed_section)
1625
1626 ! Initialize embedding potential
1627 CALL init_embed_pot(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, embed_pot, &
1628 opt_embed%add_const_pot, opt_embed%Fermi_Amaldi, opt_embed%const_pot, &
1629 opt_embed%open_shell_embed, spin_embed_pot, &
1630 opt_embed%pot_diff, opt_embed%Coulomb_guess, opt_embed%grid_opt)
1631
1632 ! Read embedding potential vector from the file
1633 IF (opt_embed%read_embed_pot .OR. opt_embed%read_embed_pot_cube) CALL read_embed_pot( &
1634 force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, embed_pot, spin_embed_pot, &
1635 opt_embed_section, opt_embed)
1636
1637 ! Prepare the pw object to store density differences
1638 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1639 CALL auxbas_pw_pool%create_pw(diff_rho_r)
1640 CALL pw_zero(diff_rho_r)
1641 IF (opt_embed%open_shell_embed) THEN
1642 CALL auxbas_pw_pool%create_pw(diff_rho_spin)
1643 CALL pw_zero(diff_rho_spin)
1644 END IF
1645
1646 ! Check the preliminary density differences
1647 DO i_spin = 1, nspins
1648 CALL pw_axpy(rho_r_ref(i_spin), diff_rho_r, -1.0_dp)
1649 END DO
1650 IF (opt_embed%open_shell_embed) THEN ! Spin part
1651 IF (nspins .EQ. 2) THEN ! Reference systems has an open shell, else the reference diff_rho_spin is zero
1652 CALL pw_axpy(rho_r_ref(1), diff_rho_spin, -1.0_dp)
1653 CALL pw_axpy(rho_r_ref(2), diff_rho_spin, 1.0_dp)
1654 END IF
1655 END IF
1656
1657 DO i_force_eval = 1, ref_subsys_number - 1
1658 NULLIFY (subsys_rho, rho_r_subsys, dft_control)
1659 CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, rho=subsys_rho, energy=energy, &
1660 dft_control=dft_control)
1661 nspins_subsys = dft_control%nspins
1662 ! Add subsystem densities
1663 CALL qs_rho_get(rho_struct=subsys_rho, rho_r=rho_r_subsys)
1664 DO i_spin = 1, nspins_subsys
1665 CALL pw_axpy(rho_r_subsys(i_spin), diff_rho_r, allow_noncompatible_grids=.true.)
1666 END DO
1667 IF (opt_embed%open_shell_embed) THEN ! Spin part
1668 IF (nspins_subsys .EQ. 2) THEN ! The subsystem makes contribution if it is spin-polarized
1669 ! We may need to change spin ONLY FOR THE SECOND SUBSYSTEM: that's the internal convention
1670 IF ((i_force_eval .EQ. 2) .AND. (opt_embed%change_spin)) THEN
1671 CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.true.)
1672 CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.true.)
1673 ELSE
1674 ! First subsystem (always) and second subsystem (without spin change)
1675 CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.true.)
1676 CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.true.)
1677 END IF
1678 END IF
1679 END IF
1680 END DO
1681
1682 ! Print density difference
1683 CALL print_rho_diff(diff_rho_r, 0, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .false.)
1684 IF (opt_embed%open_shell_embed) THEN ! Spin part
1685 CALL print_rho_spin_diff(diff_rho_spin, 0, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .false.)
1686 END IF
1687
1688 ! Construct electrostatic guess if needed
1689 IF (opt_embed%Coulomb_guess) THEN
1690 ! Reveal resp charges for total system
1691 nforce_eval = SIZE(force_env%sub_force_env)
1692 NULLIFY (rhs)
1693 CALL get_qs_env(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, rhs=rhs)
1694 ! Get the mapping
1695 CALL force_env_get(force_env=force_env, &
1696 force_env_section=force_env_section)
1697 embed_section => section_vals_get_subs_vals(force_env_section, "EMBED")
1698 mapping_section => section_vals_get_subs_vals(embed_section, "MAPPING")
1699
1700 DO i_force_eval = 1, ref_subsys_number - 1
1701 IF (i_force_eval .EQ. 1) THEN
1702 CALL coulomb_guess(embed_pot, rhs, mapping_section, &
1703 force_env%sub_force_env(i_force_eval)%force_env%qs_env, nforce_eval, i_force_eval, opt_embed%eta)
1704 ELSE
1705 CALL coulomb_guess(opt_embed%pot_diff, rhs, mapping_section, &
1706 force_env%sub_force_env(i_force_eval)%force_env%qs_env, nforce_eval, i_force_eval, opt_embed%eta)
1707 END IF
1708 END DO
1709 CALL pw_axpy(opt_embed%pot_diff, embed_pot)
1710 IF (.NOT. opt_embed%grid_opt) CALL pw_copy(embed_pot, opt_embed%const_pot)
1711
1712 END IF
1713
1714 ! Difference guess
1715 IF (opt_embed%diff_guess) THEN
1716 CALL pw_copy(diff_rho_r, embed_pot)
1717 IF (.NOT. opt_embed%grid_opt) CALL pw_copy(embed_pot, opt_embed%const_pot)
1718 ! Open shell
1719 IF (opt_embed%open_shell_embed) CALL pw_copy(diff_rho_spin, spin_embed_pot)
1720 END IF
1721
1722 ! Calculate subsystems with trial embedding potential
1723 DO i_iter = 1, opt_embed%n_iter
1724 opt_embed%i_iter = i_iter
1725
1726 ! Set the density difference as the negative reference one
1727 CALL pw_zero(diff_rho_r)
1728 CALL get_qs_env(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, dft_control=dft_control)
1729 nspins = dft_control%nspins
1730 DO i_spin = 1, nspins
1731 CALL pw_axpy(rho_r_ref(i_spin), diff_rho_r, -1.0_dp)
1732 END DO
1733 IF (opt_embed%open_shell_embed) THEN ! Spin part
1734 CALL pw_zero(diff_rho_spin)
1735 IF (nspins .EQ. 2) THEN ! Reference systems has an open shell, else the reference diff_rho_spin is zero
1736 CALL pw_axpy(rho_r_ref(1), diff_rho_spin, -1.0_dp)
1737 CALL pw_axpy(rho_r_ref(2), diff_rho_spin, 1.0_dp)
1738 END IF
1739 END IF
1740
1741 DO i_force_eval = 1, ref_subsys_number - 1
1742 NULLIFY (dft_control)
1743 CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, dft_control=dft_control)
1744 nspins_subsys = dft_control%nspins
1745
1746 IF ((i_force_eval .EQ. 2) .AND. (opt_embed%change_spin)) THEN
1747 ! Here we change the sign of the spin embedding potential due to spin change:
1748 ! only in spin_embed_subsys
1749 CALL make_subsys_embed_pot(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
1750 embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, &
1751 opt_embed%open_shell_embed, .true.)
1752 ELSE ! Regular case
1753 CALL make_subsys_embed_pot(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
1754 embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, &
1755 opt_embed%open_shell_embed, .false.)
1756 END IF
1757
1758 ! Switch on external potential in the subsystems
1759 dft_control%apply_embed_pot = .true.
1760
1761 ! Add the embedding potential
1762 CALL set_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, embed_pot=embed_pot_subsys)
1763 IF ((opt_embed%open_shell_embed) .AND. (nspins_subsys .EQ. 2)) THEN ! Spin part
1764 CALL set_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
1765 spin_embed_pot=spin_embed_pot_subsys)
1766 END IF
1767
1768 ! Get the previous subsystem densities
1769 CALL get_prev_density(opt_embed, force_env%sub_force_env(i_force_eval)%force_env, i_force_eval)
1770
1771 ! Calculate the new density
1772 CALL force_env_calc_energy_force(force_env=force_env%sub_force_env(i_force_eval)%force_env, &
1773 calc_force=.false., &
1774 skip_external_control=.true.)
1775
1776 CALL get_max_subsys_diff(opt_embed, force_env%sub_force_env(i_force_eval)%force_env, i_force_eval)
1777
1778 ! Extract subsystem density and energy
1779 NULLIFY (rho_r_subsys, energy)
1780
1781 CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, rho=subsys_rho, &
1782 energy=energy)
1783 opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) + energy%total
1784
1785 ! Find out which subsystem is the cluster
1786 IF (dft_control%qs_control%cluster_embed_subsys) THEN
1787 cluster_subsys_num = i_force_eval
1788 cluster_energy = energy%total
1789 END IF
1790
1791 ! Add subsystem densities
1792 CALL qs_rho_get(rho_struct=subsys_rho, rho_r=rho_r_subsys)
1793 DO i_spin = 1, nspins_subsys
1794 CALL pw_axpy(rho_r_subsys(i_spin), diff_rho_r, allow_noncompatible_grids=.true.)
1795 END DO
1796 IF (opt_embed%open_shell_embed) THEN ! Spin part
1797 IF (nspins_subsys .EQ. 2) THEN ! The subsystem makes contribution if it is spin-polarized
1798 ! We may need to change spin ONLY FOR THE SECOND SUBSYSTEM: that's the internal convention
1799 IF ((i_force_eval .EQ. 2) .AND. (opt_embed%change_spin)) THEN
1800 CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.true.)
1801 CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.true.)
1802 ELSE
1803 ! First subsystem (always) and second subsystem (without spin change)
1804 CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.true.)
1805 CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.true.)
1806 END IF
1807 END IF
1808 END IF
1809
1810 ! Release embedding potential for subsystem
1811 CALL embed_pot_subsys%release()
1812 DEALLOCATE (embed_pot_subsys)
1813 IF (opt_embed%open_shell_embed) THEN
1814 CALL spin_embed_pot_subsys%release()
1815 DEALLOCATE (spin_embed_pot_subsys)
1816 END IF
1817
1818 END DO ! i_force_eval
1819
1820 ! Print embedding potential for restart
1821 CALL print_embed_restart(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1822 opt_embed%dimen_aux, opt_embed%embed_pot_coef, embed_pot, i_iter, &
1823 spin_embed_pot, opt_embed%open_shell_embed, opt_embed%grid_opt, .false.)
1824 CALL print_pot_simple_grid(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1825 embed_pot, spin_embed_pot, i_iter, opt_embed%open_shell_embed, .false., &
1826 force_env%sub_force_env(cluster_subsys_num)%force_env%qs_env)
1827
1828 ! Integrate the potential over density differences and add to w functional; also add regularization contribution
1829 DO i_spin = 1, nspins ! Sum over nspins for the reference system, not subsystem!
1830 opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) - pw_integral_ab(embed_pot, rho_r_ref(i_spin))
1831 END DO
1832 ! Spin part
1833 IF (opt_embed%open_shell_embed) THEN
1834 ! If reference system is not spin-polarized then it does not make a contribution to W functional
1835 IF (nspins .EQ. 2) THEN
1836 opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) &
1837 - pw_integral_ab(spin_embed_pot, rho_r_ref(1)) &
1838 + pw_integral_ab(spin_embed_pot, rho_r_ref(2))
1839 END IF
1840 END IF
1841 ! Finally, add the regularization term
1842 opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) + opt_embed%reg_term
1843
1844 ! Print information and check convergence
1845 CALL print_emb_opt_info(output_unit, i_iter, opt_embed)
1846 CALL conv_check_embed(opt_embed, diff_rho_r, diff_rho_spin, output_unit)
1847 IF (opt_embed%converged) EXIT
1848
1849 ! Update the trust radius and control the step
1850 IF ((i_iter .GT. 1) .AND. (.NOT. opt_embed%steep_desc)) CALL step_control(opt_embed)
1851
1852 ! Print density difference
1853 CALL print_rho_diff(diff_rho_r, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .false.)
1854 IF (opt_embed%open_shell_embed) THEN ! Spin part
1855 CALL print_rho_spin_diff(diff_rho_spin, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .false.)
1856 END IF
1857
1858 ! Calculate potential gradient if the step has been accepted. Otherwise, we reuse the previous one
1859
1860 IF (opt_embed%accept_step .AND. (.NOT. opt_embed%grid_opt)) &
1861 CALL calculate_embed_pot_grad(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1862 diff_rho_r, diff_rho_spin, opt_embed)
1863 ! Take the embedding step
1864 CALL opt_embed_step(diff_rho_r, diff_rho_spin, opt_embed, embed_pot, spin_embed_pot, rho_r_ref, &
1865 force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
1866
1867 END DO ! i_iter
1868
1869 ! Print final embedding potential for restart
1870 CALL print_embed_restart(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1871 opt_embed%dimen_aux, opt_embed%embed_pot_coef, embed_pot, i_iter, &
1872 spin_embed_pot, opt_embed%open_shell_embed, opt_embed%grid_opt, .true.)
1873 CALL print_pot_simple_grid(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1874 embed_pot, spin_embed_pot, i_iter, opt_embed%open_shell_embed, .true., &
1875 force_env%sub_force_env(cluster_subsys_num)%force_env%qs_env)
1876
1877 ! Print final density difference
1878 !CALL print_rho_diff(diff_rho_r, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .TRUE.)
1879 IF (opt_embed%open_shell_embed) THEN ! Spin part
1880 CALL print_rho_spin_diff(diff_rho_spin, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .true.)
1881 END IF
1882
1883 ! Give away plane waves pools
1884 CALL diff_rho_r%release()
1885 IF (opt_embed%open_shell_embed) THEN
1886 CALL diff_rho_spin%release()
1887 END IF
1888
1889 CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
1890 "PRINT%PROGRAM_RUN_INFO")
1891
1892 ! If converged send the embedding potential to the higher-level calculation.
1893 IF (opt_embed%converged) THEN
1894 CALL get_qs_env(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, dft_control=dft_control, &
1895 pw_env=pw_env)
1896 nspins_subsys = dft_control%nspins
1897 dft_control%apply_embed_pot = .true.
1898 ! The embedded subsystem corresponds to subsystem #2, where spin change is possible
1899 CALL make_subsys_embed_pot(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, &
1900 embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, &
1901 opt_embed%open_shell_embed, opt_embed%change_spin)
1902
1903 IF (opt_embed%Coulomb_guess) THEN
1904 CALL pw_axpy(opt_embed%pot_diff, embed_pot_subsys, -1.0_dp, allow_noncompatible_grids=.true.)
1905 END IF
1906
1907 CALL set_qs_env(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, embed_pot=embed_pot_subsys)
1908
1909 IF ((opt_embed%open_shell_embed) .AND. (nspins_subsys .EQ. 2)) THEN
1910 CALL set_qs_env(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, &
1911 spin_embed_pot=spin_embed_pot_subsys)
1912 END IF
1913
1914 ! Substitute the correct energy in energies: only on rank 0
1915 IF (force_env%sub_force_env(cluster_subsys_num)%force_env%para_env%is_source()) THEN
1916 energies(cluster_subsys_num) = cluster_energy
1917 END IF
1918 END IF
1919
1920 ! Deallocate and release opt_embed content
1921 CALL release_opt_embed(opt_embed)
1922
1923 ! Deallocate embedding potential
1924 CALL embed_pot%release()
1925 DEALLOCATE (embed_pot)
1926 IF (opt_embed%open_shell_embed) THEN
1927 CALL spin_embed_pot%release()
1928 DEALLOCATE (spin_embed_pot)
1929 END IF
1930
1931 converged_embed = opt_embed%converged
1932
1933 CALL timestop(handle)
1934
1935 END SUBROUTINE dfet_embedding
1936
1937! **************************************************************************************************
1938!> \brief Main driver for the DMFET embedding
1939!> \param force_env ...
1940!> \param ref_subsys_number ...
1941!> \param energies ...
1942!> \param converged_embed ...
1943!> \author Vladimir Rybkin
1944! **************************************************************************************************
1945 SUBROUTINE dmfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
1946 TYPE(force_env_type), POINTER :: force_env
1947 INTEGER :: ref_subsys_number
1948 REAL(kind=dp), DIMENSION(:), POINTER :: energies
1949 LOGICAL :: converged_embed
1950
1951 CHARACTER(LEN=*), PARAMETER :: routinen = 'dmfet_embedding'
1952
1953 INTEGER :: cluster_subsys_num, handle, &
1954 i_force_eval, i_iter, output_unit
1955 LOGICAL :: subsys_open_shell
1956 REAL(kind=dp) :: cluster_energy
1957 TYPE(cp_logger_type), POINTER :: logger
1958 TYPE(dft_control_type), POINTER :: dft_control
1959 TYPE(mp_para_env_type), POINTER :: para_env
1960 TYPE(opt_dmfet_pot_type) :: opt_dmfet
1961 TYPE(qs_energy_type), POINTER :: energy
1962 TYPE(section_vals_type), POINTER :: dft_section, input, opt_dmfet_section
1963
1964 CALL timeset(routinen, handle)
1965
1966 CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1967 para_env=para_env)
1968
1969 ! Reveal input file
1970 NULLIFY (logger)
1971 logger => cp_get_default_logger()
1972 output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
1973 extension=".Log")
1974
1975 NULLIFY (dft_section, input, opt_dmfet_section)
1976 NULLIFY (energy)
1977
1978 CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1979 energy=energy, input=input)
1980
1981 dft_section => section_vals_get_subs_vals(input, "DFT")
1982 opt_dmfet_section => section_vals_get_subs_vals(input, &
1983 "DFT%QS%OPT_DMFET")
1984
1985 ! We need to understand how to treat spins states
1986 CALL understand_spin_states(force_env, ref_subsys_number, opt_dmfet%change_spin, opt_dmfet%open_shell_embed, &
1987 opt_dmfet%all_nspins)
1988
1989 ! Prepare for the potential optimization
1990 CALL prepare_dmfet_opt(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1991 opt_dmfet, opt_dmfet_section)
1992
1993 ! Get the reference density matrix/matrices
1994 subsys_open_shell = subsys_spin(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
1995 CALL build_full_dm(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
1996 opt_dmfet%dm_total, subsys_open_shell, opt_dmfet%open_shell_embed, opt_dmfet%dm_total_beta)
1997
1998 ! Check the preliminary DM difference
1999 CALL cp_fm_copy_general(opt_dmfet%dm_total, opt_dmfet%dm_diff, para_env)
2000 IF (opt_dmfet%open_shell_embed) CALL cp_fm_copy_general(opt_dmfet%dm_total_beta, &
2001 opt_dmfet%dm_diff_beta, para_env)
2002
2003 DO i_force_eval = 1, ref_subsys_number - 1
2004
2005 ! Get the subsystem density matrix/matrices
2006 subsys_open_shell = subsys_spin(force_env%sub_force_env(i_force_eval)%force_env%qs_env)
2007
2008 CALL build_full_dm(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
2009 opt_dmfet%dm_subsys, subsys_open_shell, opt_dmfet%open_shell_embed, &
2010 opt_dmfet%dm_subsys_beta)
2011
2012 CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys)
2013
2014 IF (opt_dmfet%open_shell_embed) CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff_beta, &
2015 1.0_dp, opt_dmfet%dm_subsys_beta)
2016
2017 END DO
2018
2019 ! Main loop of iterative matrix potential optimization
2020 DO i_iter = 1, opt_dmfet%n_iter
2021
2022 opt_dmfet%i_iter = i_iter
2023
2024 ! Set the dm difference as the reference one
2025 CALL cp_fm_copy_general(opt_dmfet%dm_total, opt_dmfet%dm_diff, para_env)
2026
2027 IF (opt_dmfet%open_shell_embed) CALL cp_fm_copy_general(opt_dmfet%dm_total_beta, &
2028 opt_dmfet%dm_diff_beta, para_env)
2029
2030 ! Loop over force evaluations
2031 DO i_force_eval = 1, ref_subsys_number - 1
2032
2033 ! Switch on external potential in the subsystems
2034 NULLIFY (dft_control)
2035 CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, dft_control=dft_control)
2036 dft_control%apply_dmfet_pot = .true.
2037
2038 ! Calculate the new density
2039 CALL force_env_calc_energy_force(force_env=force_env%sub_force_env(i_force_eval)%force_env, &
2040 calc_force=.false., &
2041 skip_external_control=.true.)
2042
2043 ! Extract subsystem density matrix and energy
2044 NULLIFY (energy)
2045
2046 CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, energy=energy)
2047 opt_dmfet%w_func(i_iter) = opt_dmfet%w_func(i_iter) + energy%total
2048
2049 ! Find out which subsystem is the cluster
2050 IF (dft_control%qs_control%cluster_embed_subsys) THEN
2051 cluster_subsys_num = i_force_eval
2052 cluster_energy = energy%total
2053 END IF
2054
2055 ! Add subsystem density matrices
2056 subsys_open_shell = subsys_spin(force_env%sub_force_env(i_force_eval)%force_env%qs_env)
2057
2058 CALL build_full_dm(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
2059 opt_dmfet%dm_subsys, subsys_open_shell, opt_dmfet%open_shell_embed, &
2060 opt_dmfet%dm_subsys_beta)
2061
2062 IF (opt_dmfet%open_shell_embed) THEN ! Open-shell embedding
2063 ! We may need to change spin ONLY FOR THE SECOND SUBSYSTEM: that's the internal convention
2064 IF ((i_force_eval .EQ. 2) .AND. (opt_dmfet%change_spin)) THEN
2065 CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff_beta, 1.0_dp, opt_dmfet%dm_subsys)
2066 CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys_beta)
2067 ELSE
2068 CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys)
2069 CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff_beta, 1.0_dp, opt_dmfet%dm_subsys_beta)
2070 END IF
2071 ELSE ! Closed-shell embedding
2072 CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys)
2073 END IF
2074
2075 END DO ! i_force_eval
2076
2077 CALL check_dmfet(opt_dmfet, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
2078
2079 END DO ! i_iter
2080
2081 ! Substitute the correct energy in energies: only on rank 0
2082 IF (force_env%sub_force_env(cluster_subsys_num)%force_env%para_env%is_source()) THEN
2083 energies(cluster_subsys_num) = cluster_energy
2084 END IF
2085
2086 CALL release_dmfet_opt(opt_dmfet)
2087
2088 converged_embed = .false.
2089
2090 END SUBROUTINE dmfet_embedding
2091
2092END MODULE force_env_methods
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Holds information on atomic properties.
subroutine, public atprop_init(atprop_env, natom)
...
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public huang2011
integer, save, public heaton_burgess2007
Handles all functions related to the CELL.
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public scaled_to_real(r, s, cell)
Transform scaled cell coordinates real coordinates. r=h*s.
Definition cell_types.F:516
integer, parameter, public cell_sym_triclinic
Definition cell_types.F:29
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
Definition cell_types.F:486
subroutine, public cell_release(cell)
releases the given cell (see doc/ReferenceCounting.html)
Definition cell_types.F:559
subroutine, public cell_clone(cell_in, cell_out, tag)
Clone cell variable.
Definition cell_types.F:107
subroutine, public fix_atom_control(force_env, w)
allows for fix atom constraints
Routines to handle the virtual site constraint/restraint.
subroutine, public vsite_force_control(force_env)
control force distribution for virtual sites
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
basic linear algebra operations for full matrices
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
Collection of routines to handle the iteration info.
subroutine, public cp_iteration_info_copy_iter(iteration_info_in, iteration_info_out)
Copies iterations info of an iteration info into another iteration info.
various routines to log and control the output. The idea is that decisions about where to log should ...
subroutine, public cp_rm_default_logger()
the cousin of cp_add_default_logger, decrements the stack, so that the default logger is what it has ...
subroutine, public cp_add_default_logger(logger)
adds a default logger. MUST be called before logging occours
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)
...
integer, parameter, public low_print_level
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,...
set of type/routines to handle the storage of results in force_envs
subroutine, public cp_results_mp_bcast(results, source, para_env)
broadcast results type
subroutine, public cp_results_erase(results, description, nval)
erase a part of result_list
logical function, public test_for_result(results, description)
test for a certain result in the result_list
set of type/routines to handle the storage of results in force_envs
subroutine, public cp_result_copy(results_in, results_out)
Copies the cp_result type.
subroutine, public cp_result_release(results)
Releases cp_result type.
subroutine, public cp_result_create(results)
Allocates and intitializes the cp_result.
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_set(subsys, atomic_kinds, particles, local_particles, molecules, molecule_kinds, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, results, cell)
sets various propreties of the subsys
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
unit conversion facility
Definition cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1179
The environment for the empirical interatomic potential methods.
Empirical interatomic potentials for Silicon.
Definition eip_silicon.F:17
subroutine, public eip_lenosky(eip_env)
Interface routine of Goedecker's Lenosky force field to CP2K.
subroutine, public eip_bazant(eip_env)
Interface routine of Goedecker's Bazant EDIP to CP2K.
Definition eip_silicon.F:75
Methods to include the effect of an external potential during an MD or energy calculation.
subroutine, public add_external_potential(force_env)
...
subroutine, public fist_calc_energy_force(fist_env, debug)
Calculates the total potential energy, total force, and the total pressure tensor from the potentials...
Definition fist_force.F:112
Interface for the force calculations.
recursive subroutine, public force_env_calc_energy_force(force_env, calc_force, consistent_energies, skip_external_control, eval_energy_forces, require_consistent_energy_force, linres, calc_stress_tensor)
Interface routine for force and energy calculations.
subroutine, public force_env_calc_num_pressure(force_env, dx)
Evaluates the stress tensor and pressure numerically.
subroutine, public force_env_create(force_env, root_section, para_env, globenv, fist_env, qs_env, meta_env, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, force_env_section, mixed_env, embed_env, nnp_env, ipi_env)
creates and initializes a force environment
Interface for the force calculations.
integer function, public force_env_get_natom(force_env)
returns the number of atoms
integer, parameter, public use_qmmm
integer, parameter, public use_mixed_force
character(len=10), dimension(501:510), parameter, public use_prog_name
integer, parameter, public use_eip_force
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, ipi_env)
returns various attributes about the force environment
integer, parameter, public use_embed
integer, parameter, public use_qmmmx
subroutine, public force_env_set(force_env, meta_env, fp_env, force_env_section, method_name_id, additional_potential)
changes some attributes of the force_env
integer, parameter, public use_qs_force
integer, parameter, public use_pwdft_force
integer, parameter, public use_nnp_force
integer, parameter, public use_ipi
integer, parameter, public use_fist_force
Util force_env module.
subroutine, public write_forces(particles, iw, label, ndigits, unit_string, total_force, grand_total_force, zero_force_core_shell_atom)
Write forces.
subroutine, public write_atener(iounit, particles, atener, label)
Write the atomic coordinates, types, and energies.
subroutine, public rescale_forces(force_env)
Rescale forces if requested.
subroutine, public get_generic_info(gen_section, func_name, xfunction, parameters, values, var_values, size_variables, i_rep_sec, input_variables)
Reads from the input structure all information for generic functions.
methods used in the flexible partitioning scheme
Definition fp_methods.F:14
subroutine, public fp_eval(fp_env, subsys, cell)
computest the forces and the energy due to the flexible potential & bias, and writes the weights file
Definition fp_methods.F:54
This public domain function parser module is intended for applications where a set of mathematical ex...
Definition fparser.F:17
subroutine, public parsef(i, funcstr, var)
Parse ith function string FuncStr and compile it into bytecode.
Definition fparser.F:148
real(rn) function, public evalf(i, val)
...
Definition fparser.F:180
integer, public evalerrtype
Definition fparser.F:32
real(kind=rn) function, public evalfd(id_fun, ipar, vals, h, err)
Evaluates derivatives.
Definition fparser.F:976
subroutine, public finalizef()
...
Definition fparser.F:101
subroutine, public initf(n)
...
Definition fparser.F:130
Define type storing the global information of a run. Keep the amount of stored data small....
subroutine, public globenv_retain(globenv)
Retains the global environment globenv.
GRRM interface.
Definition grrm_utils.F:12
subroutine, public write_grrm(iounit, force_env, particles, energy, dipole, hessian, dipder, polar, fixed_atoms)
Write GRRM interface file.
Definition grrm_utils.F:50
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public use_bazant_eip
integer, parameter, public mixed_cdft_serial
integer, parameter, public mix_cdft
integer, parameter, public mix_linear_combination
integer, parameter, public dmfet
integer, parameter, public use_lenosky_eip
integer, parameter, public mix_coupled
integer, parameter, public debug_run
integer, parameter, public mix_restrained
integer, parameter, public mix_generic
integer, parameter, public dfet
integer, parameter, public mix_minimum
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_retain(section_vals)
retains the given section values (see doc/ReferenceCounting.html)
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
The environment for the empirical interatomic potential methods.
i–PI server mode: Communication with i–PI clients
Definition ipi_server.F:14
subroutine, public request_forces(ipi_env)
Send atomic positions to a client and retrieve forces.
Definition ipi_server.F:169
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Definition kahan_sum.F:29
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
Definition machine.F:440
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
logical function, public abnormal_value(a)
determines if a value is not normal (e.g. for Inf and Nan) based on IO to work also under optimizatio...
Definition mathlib.F:151
Interface to the message passing library MPI.
defines types for metadynamics calculation
Methods for mixed CDFT calculations.
subroutine, public mixed_cdft_calculate_coupling(force_env)
Driver routine to calculate the electronic coupling(s) between CDFT states.
subroutine, public mixed_cdft_build_weight(force_env, calculate_forces, iforce_eval)
Driver routine to handle the build of CDFT weight/gradient in parallel and serial modes.
subroutine, public mixed_cdft_init(force_env, calculate_forces)
Initialize a mixed CDFT calculation.
subroutine, public get_mixed_env(mixed_env, atomic_kind_set, particle_set, local_particles, local_molecules, molecule_kind_set, molecule_set, cell, cell_ref, mixed_energy, para_env, sub_para_env, subsys, input, results, cdft_control)
Get the MIXED environment.
Util mixed_environment.
subroutine, public get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, map_index, force_eval_embed)
performs mapping of the subsystems of different force_eval
subroutine, public mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, factor, iforce_eval, nforce_eval, map_index, mapping_section, overwrite)
Maps forces between the different force_eval sections/environments.
represent a simple array based list of the given type
Define the molecule kind structure types and the corresponding functionality.
subroutine, public get_molecule_kind(molecule_kind, atom_list, bond_list, bend_list, ub_list, impr_list, opbend_list, colv_list, fixd_list, g3x3_list, g4x6_list, vsite_list, torsion_list, shell_list, name, mass, charge, kind_number, natom, nbend, nbond, nub, nimpr, nopbend, nconstraint, nconstraint_fixd, nfixd, ncolv, ng3x3, ng4x6, nvsite, nfixd_restraint, ng3x3_restraint, ng4x6_restraint, nvsite_restraint, nrestraints, nmolecule, nsgf, nshell, ntorsion, molecule_list, nelectron, nelectron_alpha, nelectron_beta, bond_kind_set, bend_kind_set, ub_kind_set, impr_kind_set, opbend_kind_set, torsion_kind_set, molname_generated)
Get informations about a molecule kind.
Data types for neural network potentials.
Methods dealing with Neural Network potentials.
Definition nnp_force.F:13
subroutine, public nnp_calc_energy_force(nnp, calc_forces)
Calculate the energy and force for a given configuration with the NNP.
Definition nnp_force.F:62
subroutine, public check_dmfet(opt_dmfet, qs_env)
...
subroutine, public release_dmfet_opt(opt_dmfet)
...
subroutine, public build_full_dm(qs_env, dm, open_shell, open_shell_embed, dm_beta)
Builds density matrices from MO coefficients in full matrix format.
subroutine, public prepare_dmfet_opt(qs_env, opt_dmfet, opt_dmfet_section)
...
logical function, public subsys_spin(qs_env)
...
subroutine, public print_embed_restart(qs_env, dimen_aux, embed_pot_coef, embed_pot, i_iter, embed_pot_spin, open_shell_embed, grid_opt, final_one)
Print embedding potential as a cube and as a binary (for restarting)
subroutine, public make_subsys_embed_pot(qs_env, embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, open_shell_embed, change_spin_sign)
Creates a subsystem embedding potential.
subroutine, public print_rho_spin_diff(spin_diff_rho_r, i_iter, qs_env, final_one)
Prints a cube for the (spin_rho_A + spin_rho_B - spin_rho_ref) to be minimized in embedding.
subroutine, public get_max_subsys_diff(opt_embed, force_env, subsys_num)
...
subroutine, public print_emb_opt_info(output_unit, step_num, opt_embed)
...
subroutine, public init_embed_pot(qs_env, embed_pot, add_const_pot, fermi_amaldi, const_pot, open_shell_embed, spin_embed_pot, pot_diff, coulomb_guess, grid_opt)
...
subroutine, public understand_spin_states(force_env, ref_subsys_number, change_spin, open_shell_embed, all_nspins)
Find out whether we need to swap alpha- and beta- spind densities in the second subsystem.
subroutine, public read_embed_pot(qs_env, embed_pot, spin_embed_pot, section, opt_embed)
...
subroutine, public get_prev_density(opt_embed, force_env, subsys_num)
...
subroutine, public coulomb_guess(v_rspace, rhs, mapping_section, qs_env, nforce_eval, iforce_eval, eta)
Calculates subsystem Coulomb potential from the RESP charges of the total system.
subroutine, public print_rho_diff(diff_rho_r, i_iter, qs_env, final_one)
Prints a cube for the (rho_A + rho_B - rho_ref) to be minimized in embedding.
subroutine, public conv_check_embed(opt_embed, diff_rho_r, diff_rho_spin, output_unit)
...
subroutine, public step_control(opt_embed)
Controls the step, changes the trust radius if needed in maximization of the V_emb.
subroutine, public opt_embed_step(diff_rho_r, diff_rho_spin, opt_embed, embed_pot, spin_embed_pot, rho_r_ref, qs_env)
Takes maximization step in embedding potential optimization.
subroutine, public calculate_embed_pot_grad(qs_env, diff_rho_r, diff_rho_spin, opt_embed)
Calculates the derivative of the embedding potential wrt to the expansion coefficients.
subroutine, public print_pot_simple_grid(qs_env, embed_pot, embed_pot_spin, i_iter, open_shell_embed, final_one, qs_env_cluster)
Prints a volumetric file: X Y Z value for interfacing with external programs.
subroutine, public prepare_embed_opt(qs_env, opt_embed, opt_embed_section)
Creates and allocates objects for optimization of embedding potential.
subroutine, public release_opt_embed(opt_embed)
Deallocate stuff for optimizing embedding potential.
represent a simple array based list of the given type
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public debye
Definition physcon.F:201
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
The type definitions for the PWDFT environment.
Methods and functions on the PWDFT environment.
subroutine, public pwdft_calc_energy_force(pwdft_env, calculate_forces, calculate_stress)
Calculate energy and forces within the PWDFT/SIRIUS code.
Calculates QM/MM energy and forces.
Definition qmmm_force.F:14
subroutine, public qmmm_calc_energy_force(qmmm_env, calc_force, consistent_energies, linres)
calculates the qm/mm energy and forces
Definition qmmm_force.F:76
Basic container type for QM/MM.
Definition qmmm_types.F:12
subroutine, public apply_qmmm_translate(qmmm_env)
Apply translation to the full system in order to center the QM system into the QM box.
Definition qmmm_util.F:373
Calculates QM/MM energy and forces with Force-Mixing.
Definition qmmmx_force.F:14
subroutine, public qmmmx_calc_energy_force(qmmmx_env, calc_force, consistent_energies, linres, require_consistent_energy_force)
calculates the qm/mm energy and forces
Definition qmmmx_force.F:66
Basic container type for QM/MM with force mixing.
Definition qmmmx_types.F:12
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Set the QUICKSTEP environment.
Quickstep force driver routine.
Definition qs_force.F:12
subroutine, public qs_calc_energy_force(qs_env, calc_force, consistent_energies, linres)
...
Definition qs_force.F:107
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Handles all possible kinds of restraints in CP2K.
Definition restraint.F:14
subroutine, public restraint_control(force_env)
Computes restraints.
Definition restraint.F:67
SCINE interface.
Definition scine_utils.F:12
subroutine, public write_scine(iounit, force_env, particles, energy, hessian)
Write SCINE interface file.
Definition scine_utils.F:46
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
subroutine, public write_stress_tensor(pv_virial, iw, cell, unit_string, numerical)
Print stress tensor to output file.
subroutine, public write_stress_tensor_components(virial, iw, cell, unit_string)
...
subroutine, public zero_virial(virial, reset)
...
subroutine, public symmetrize_virial(virial)
Symmetrize the virial components.
type for the atomic properties
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
type of a logger, at the moment it contains just a print level starting at which level it should be l...
contains arbitrary information which need to be stored
represent a pointer to a subsys, to be able to create arrays of pointers
represents a system: atoms, molecules, their pos,vel,...
The empirical interatomic potential environment.
Embedding environment type.
Type containing main data for matrix embedding potential optimization.
Type containing main data for embedding potential optimization.
Definition embed_types.F:67
allows for the creation of an array of force_env
wrapper to abstract the force evaluation of the various methods
contains the initially parsed file and the initial parallel environment
stores all the informations relevant to an mpi environment
Main data type collecting all relevant data for neural network potentials.
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
keeps the density in various representations, keeping track of which ones are valid.