LCOV - code coverage report
Current view: top level - src - force_env_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:c24029e) Lines: 91.5 % 985 901
Test Date: 2026-07-04 06:36:57 Functions: 91.7 % 12 11

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 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              : ! **************************************************************************************************
      17              : MODULE force_env_methods
      18              :    USE atprop_types,                    ONLY: atprop_init,&
      19              :                                               atprop_type
      20              :    USE bibliography,                    ONLY: Heaton_Burgess2007,&
      21              :                                               Huang2011,&
      22              :                                               cite_reference
      23              :    USE cell_methods,                    ONLY: cell_create,&
      24              :                                               init_cell
      25              :    USE cell_types,                      ONLY: cell_clone,&
      26              :                                               cell_release,&
      27              :                                               cell_sym_triclinic,&
      28              :                                               cell_type,&
      29              :                                               real_to_scaled,&
      30              :                                               scaled_to_real
      31              :    USE constraint_fxd,                  ONLY: fix_atom_control
      32              :    USE constraint_vsite,                ONLY: vsite_force_control
      33              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      34              :    USE cp_control_types,                ONLY: dft_control_type
      35              :    USE cp_fm_basic_linalg,              ONLY: cp_fm_scale_and_add
      36              :    USE cp_fm_types,                     ONLY: cp_fm_copy_general
      37              :    USE cp_iter_types,                   ONLY: cp_iteration_info_copy_iter
      38              :    USE cp_log_handling,                 ONLY: cp_add_default_logger,&
      39              :                                               cp_get_default_logger,&
      40              :                                               cp_logger_type,&
      41              :                                               cp_rm_default_logger,&
      42              :                                               cp_to_string
      43              :    USE cp_output_handling,              ONLY: cp_p_file,&
      44              :                                               cp_print_key_finished_output,&
      45              :                                               cp_print_key_should_output,&
      46              :                                               cp_print_key_unit_nr,&
      47              :                                               low_print_level
      48              :    USE cp_result_methods,               ONLY: cp_results_erase,&
      49              :                                               cp_results_mp_bcast,&
      50              :                                               get_results,&
      51              :                                               test_for_result
      52              :    USE cp_result_types,                 ONLY: cp_result_copy,&
      53              :                                               cp_result_create,&
      54              :                                               cp_result_p_type,&
      55              :                                               cp_result_release,&
      56              :                                               cp_result_type
      57              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      58              :                                               cp_subsys_p_type,&
      59              :                                               cp_subsys_set,&
      60              :                                               cp_subsys_type
      61              :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      62              :    USE eip_environment_types,           ONLY: eip_environment_type
      63              :    USE eip_silicon,                     ONLY: eip_bazant,&
      64              :                                               eip_lenosky,&
      65              :                                               eip_stillinger_weber,&
      66              :                                               eip_tersoff
      67              :    USE embed_types,                     ONLY: embed_env_type,&
      68              :                                               opt_dmfet_pot_type,&
      69              :                                               opt_embed_pot_type
      70              :    USE external_potential_methods,      ONLY: add_external_potential
      71              :    USE fist_environment_types,          ONLY: fist_environment_type
      72              :    USE fist_force,                      ONLY: fist_calc_energy_force
      73              :    USE force_env_types,                 ONLY: &
      74              :         force_env_get, force_env_get_natom, force_env_p_type, force_env_set, force_env_type, &
      75              :         use_eip_force, use_embed, use_fist_force, use_ipi, use_mixed_force, use_nnp_force, &
      76              :         use_prog_name, use_pwdft_force, use_qmmm, use_qmmmx, use_qs_force
      77              :    USE force_env_utils,                 ONLY: rescale_forces,&
      78              :                                               write_atener,&
      79              :                                               write_forces
      80              :    USE force_fields_util,               ONLY: get_generic_info
      81              :    USE fp_methods,                      ONLY: fp_eval
      82              :    USE fparser,                         ONLY: EvalErrType,&
      83              :                                               evalf,&
      84              :                                               evalfd,&
      85              :                                               finalizef,&
      86              :                                               initf,&
      87              :                                               parsef
      88              :    USE global_types,                    ONLY: global_environment_type,&
      89              :                                               globenv_retain
      90              :    USE grrm_utils,                      ONLY: write_grrm
      91              :    USE input_constants,                 ONLY: &
      92              :         cell_opt_run, debug_run, dfet, dmfet, do_method_gapw, do_method_gapw_xc, do_method_gpw, &
      93              :         do_method_lrigpw, do_method_ofgpw, do_method_rigpw, driver_run, ehrenfest, geo_opt_run, &
      94              :         mix_cdft, mix_coupled, mix_generic, mix_linear_combination, mix_minimum, mix_restrained, &
      95              :         mixed_cdft_serial, mol_dyn_run, use_bazant_eip, use_lenosky_eip, use_stillinger_weber_eip, &
      96              :         use_tersoff_eip
      97              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      98              :                                               section_vals_retain,&
      99              :                                               section_vals_type,&
     100              :                                               section_vals_val_get
     101              :    USE ipi_environment_types,           ONLY: ipi_environment_type
     102              :    USE ipi_server,                      ONLY: request_forces
     103              :    USE kahan_sum,                       ONLY: accurate_sum
     104              :    USE kinds,                           ONLY: default_path_length,&
     105              :                                               default_string_length,&
     106              :                                               dp
     107              :    USE kpoint_methods,                  ONLY: kpoint_env_initialize,&
     108              :                                               kpoint_initialize,&
     109              :                                               kpoint_initialize_mos
     110              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
     111              :                                               kpoint_reset_initialization,&
     112              :                                               kpoint_sym_type,&
     113              :                                               kpoint_type,&
     114              :                                               set_kpoint_info
     115              :    USE machine,                         ONLY: m_memory
     116              :    USE mathlib,                         ONLY: abnormal_value
     117              :    USE message_passing,                 ONLY: mp_para_env_type
     118              :    USE metadynamics_types,              ONLY: meta_env_type
     119              :    USE mixed_cdft_methods,              ONLY: mixed_cdft_build_weight,&
     120              :                                               mixed_cdft_calculate_coupling,&
     121              :                                               mixed_cdft_init
     122              :    USE mixed_energy_types,              ONLY: mixed_energy_type,&
     123              :                                               mixed_force_type
     124              :    USE mixed_environment_types,         ONLY: get_mixed_env,&
     125              :                                               mixed_environment_type
     126              :    USE mixed_environment_utils,         ONLY: get_subsys_map_index,&
     127              :                                               mixed_map_forces
     128              :    USE molecule_kind_list_types,        ONLY: molecule_kind_list_type
     129              :    USE molecule_kind_types,             ONLY: get_molecule_kind,&
     130              :                                               molecule_kind_type
     131              :    USE nnp_environment_types,           ONLY: nnp_type
     132              :    USE nnp_force,                       ONLY: nnp_calc_energy_force
     133              :    USE optimize_dmfet_potential,        ONLY: build_full_dm,&
     134              :                                               check_dmfet,&
     135              :                                               prepare_dmfet_opt,&
     136              :                                               release_dmfet_opt,&
     137              :                                               subsys_spin
     138              :    USE optimize_embedding_potential,    ONLY: &
     139              :         Coulomb_guess, calculate_embed_pot_grad, conv_check_embed, get_max_subsys_diff, &
     140              :         get_prev_density, init_embed_pot, make_subsys_embed_pot, opt_embed_step, &
     141              :         prepare_embed_opt, print_emb_opt_info, print_embed_restart, print_pot_simple_grid, &
     142              :         print_rho_diff, print_rho_spin_diff, read_embed_pot, release_opt_embed, step_control, &
     143              :         understand_spin_states
     144              :    USE particle_list_types,             ONLY: particle_list_p_type,&
     145              :                                               particle_list_type
     146              :    USE particle_types,                  ONLY: particle_type
     147              :    USE physcon,                         ONLY: debye
     148              :    USE pw_env_types,                    ONLY: pw_env_get,&
     149              :                                               pw_env_type
     150              :    USE pw_methods,                      ONLY: pw_axpy,&
     151              :                                               pw_copy,&
     152              :                                               pw_integral_ab,&
     153              :                                               pw_zero
     154              :    USE pw_pool_types,                   ONLY: pw_pool_type
     155              :    USE pw_types,                        ONLY: pw_r3d_rs_type
     156              :    USE pwdft_environment,               ONLY: pwdft_calc_energy_force
     157              :    USE pwdft_environment_types,         ONLY: pwdft_environment_type
     158              :    USE qmmm_force,                      ONLY: qmmm_calc_energy_force
     159              :    USE qmmm_types,                      ONLY: qmmm_env_type
     160              :    USE qmmm_util,                       ONLY: apply_qmmm_translate
     161              :    USE qmmmx_force,                     ONLY: qmmmx_calc_energy_force
     162              :    USE qmmmx_types,                     ONLY: qmmmx_env_type
     163              :    USE qs_apt_fdiff_methods,            ONLY: apt_fdiff
     164              :    USE qs_basis_rotation_methods,       ONLY: qs_basis_rotation
     165              :    USE qs_energy_types,                 ONLY: qs_energy_type
     166              :    USE qs_environment_types,            ONLY: get_qs_env,&
     167              :                                               qs_environment_type,&
     168              :                                               set_qs_env
     169              :    USE qs_force,                        ONLY: qs_calc_energy_force
     170              :    USE qs_mo_types,                     ONLY: mo_set_type
     171              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
     172              :                                               qs_rho_type
     173              :    USE qs_wf_history_types,             ONLY: qs_wf_history_type,&
     174              :                                               wfi_clear
     175              :    USE restraint,                       ONLY: restraint_control
     176              :    USE scine_utils,                     ONLY: write_scine
     177              :    USE string_utilities,                ONLY: compress
     178              :    USE virial_methods,                  ONLY: write_stress_tensor,&
     179              :                                               write_stress_tensor_components
     180              :    USE virial_types,                    ONLY: symmetrize_virial,&
     181              :                                               virial_p_type,&
     182              :                                               virial_type,&
     183              :                                               zero_virial
     184              : #include "./base/base_uses.f90"
     185              : 
     186              :    IMPLICIT NONE
     187              : 
     188              :    PRIVATE
     189              : 
     190              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'force_env_methods'
     191              : 
     192              :    PUBLIC :: force_env_create, &
     193              :              force_env_calc_energy_force, &
     194              :              force_env_calc_num_pressure
     195              : 
     196              :    INTEGER, SAVE, PRIVATE :: last_force_env_id = 0
     197              : 
     198              : CONTAINS
     199              : 
     200              : ! **************************************************************************************************
     201              : !> \brief Interface routine for force and energy calculations
     202              : !> \param force_env the force_env of which you want the energy and forces
     203              : !> \param calc_force if false the forces *might* be left unchanged
     204              : !>        or be invalid, no guarantees can be given. Defaults to true
     205              : !> \param consistent_energies Performs an additional qs_ks_update_qs_env, so
     206              : !>          that the energies are appropriate to the forces, they are in the
     207              : !>          non-selfconsistent case not consistent to each other! [08.2005, TdK]
     208              : !> \param skip_external_control ...
     209              : !> \param eval_energy_forces ...
     210              : !> \param require_consistent_energy_force ...
     211              : !> \param linres ...
     212              : !> \param calc_stress_tensor ...
     213              : !> \author CJM & fawzi
     214              : ! **************************************************************************************************
     215       203530 :    RECURSIVE SUBROUTINE force_env_calc_energy_force(force_env, calc_force, &
     216              :                                                     consistent_energies, skip_external_control, eval_energy_forces, &
     217              :                                                     require_consistent_energy_force, linres, calc_stress_tensor)
     218              : 
     219              :       TYPE(force_env_type), POINTER                      :: force_env
     220              :       LOGICAL, INTENT(IN), OPTIONAL :: calc_force, consistent_energies, skip_external_control, &
     221              :          eval_energy_forces, require_consistent_energy_force, linres, calc_stress_tensor
     222              : 
     223              :       REAL(kind=dp), PARAMETER                           :: ateps = 1.0E-6_dp
     224              : 
     225              :       CHARACTER(LEN=default_string_length)               :: unit_string
     226              :       INTEGER                                            :: ikind, nat, ndigits, nfixed_atoms, &
     227              :                                                             nfixed_atoms_total, nkind, &
     228              :                                                             output_unit, print_forces, print_grrm, &
     229              :                                                             print_scine
     230              :       LOGICAL :: calculate_forces, calculate_stress_tensor, do_apt_fd, energy_consistency, &
     231              :          eval_ef, linres_run, my_skip, print_components
     232              :       REAL(KIND=dp)                                      :: checksum, e_entropy, e_gap, e_pot, &
     233              :                                                             fconv, sum_energy
     234              :       REAL(KIND=dp), DIMENSION(3)                        :: grand_total_force, total_force
     235              :       TYPE(atprop_type), POINTER                         :: atprop_env
     236              :       TYPE(cell_type), POINTER                           :: cell
     237              :       TYPE(cp_logger_type), POINTER                      :: logger
     238              :       TYPE(cp_subsys_type), POINTER                      :: subsys
     239              :       TYPE(molecule_kind_list_type), POINTER             :: molecule_kinds
     240       101765 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     241              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     242              :       TYPE(particle_list_type), POINTER                  :: core_particles, particles, &
     243              :                                                             shell_particles
     244              :       TYPE(section_vals_type), POINTER                   :: print_key
     245              :       TYPE(virial_type), POINTER                         :: virial
     246              : 
     247       101765 :       NULLIFY (logger, virial, subsys, atprop_env, cell)
     248       203530 :       logger => cp_get_default_logger()
     249       101765 :       eval_ef = .TRUE.
     250       101765 :       my_skip = .FALSE.
     251       101765 :       calculate_forces = .TRUE.
     252       101765 :       energy_consistency = .FALSE.
     253       101765 :       linres_run = .FALSE.
     254       101765 :       e_gap = -1.0_dp
     255       101765 :       e_entropy = -1.0_dp
     256       101765 :       unit_string = ""
     257              : 
     258       101765 :       IF (PRESENT(eval_energy_forces)) eval_ef = eval_energy_forces
     259       101765 :       IF (PRESENT(skip_external_control)) my_skip = skip_external_control
     260       101765 :       IF (PRESENT(calc_force)) calculate_forces = calc_force
     261       101765 :       IF (PRESENT(calc_stress_tensor)) THEN
     262        13190 :          calculate_stress_tensor = calc_stress_tensor
     263              :       ELSE
     264        88575 :          calculate_stress_tensor = calculate_forces
     265              :       END IF
     266       101765 :       IF (PRESENT(consistent_energies)) energy_consistency = consistent_energies
     267       101765 :       IF (PRESENT(linres)) linres_run = linres
     268              : 
     269       101765 :       CPASSERT(ASSOCIATED(force_env))
     270       101765 :       CPASSERT(force_env%ref_count > 0)
     271       101765 :       CALL force_env_get(force_env, subsys=subsys)
     272       101765 :       CALL force_env_set(force_env, additional_potential=0.0_dp)
     273       101765 :       CALL cp_subsys_get(subsys, virial=virial, atprop=atprop_env, cell=cell)
     274       101765 :       IF (virial%pv_availability) CALL zero_virial(virial, reset=.FALSE.)
     275              : 
     276       101765 :       nat = force_env_get_natom(force_env)
     277       101765 :       CALL atprop_init(atprop_env, nat)
     278       101765 :       IF (eval_ef) THEN
     279       174321 :          SELECT CASE (force_env%in_use)
     280              :          CASE (use_fist_force)
     281        72696 :             CALL fist_calc_energy_force(force_env%fist_env)
     282              :          CASE (use_qs_force)
     283        24209 :             CALL force_env_refresh_kpoint_symmetry(force_env, fd_energy=.NOT. calculate_forces)
     284        24209 :             CALL qs_calc_energy_force(force_env%qs_env, calculate_forces, energy_consistency, linres_run)
     285              :          CASE (use_pwdft_force)
     286           20 :             IF (virial%pv_availability .AND. calculate_stress_tensor) THEN
     287            0 :                CALL pwdft_calc_energy_force(force_env%pwdft_env, calculate_forces,.NOT. virial%pv_numer)
     288              :             ELSE
     289           20 :                CALL pwdft_calc_energy_force(force_env%pwdft_env, calculate_forces, .FALSE.)
     290              :             END IF
     291           20 :             e_gap = force_env%pwdft_env%energy%band_gap
     292           20 :             e_entropy = force_env%pwdft_env%energy%entropy
     293              :          CASE (use_eip_force)
     294         3808 :             SELECT CASE (force_env%eip_env%eip_model)
     295              :             CASE (use_lenosky_eip)
     296           22 :                CALL eip_lenosky(force_env%eip_env)
     297              :             CASE (use_bazant_eip)
     298           22 :                CALL eip_bazant(force_env%eip_env)
     299              :             CASE (use_stillinger_weber_eip)
     300           22 :                CALL eip_stillinger_weber(force_env%eip_env)
     301              :             CASE (use_tersoff_eip)
     302           22 :                CALL eip_tersoff(force_env%eip_env)
     303              :             CASE DEFAULT
     304           88 :                CPABORT("Unknown EIP model.")
     305              :             END SELECT
     306              :          CASE (use_qmmm)
     307              :             CALL qmmm_calc_energy_force(force_env%qmmm_env, &
     308         3698 :                                         calculate_forces, energy_consistency, linres=linres_run)
     309              :          CASE (use_qmmmx)
     310              :             CALL qmmmx_calc_energy_force(force_env%qmmmx_env, &
     311              :                                          calculate_forces, energy_consistency, linres=linres_run, &
     312           52 :                                          require_consistent_energy_force=require_consistent_energy_force)
     313              :          CASE (use_mixed_force)
     314          530 :             CALL mixed_energy_forces(force_env, calculate_forces)
     315              :          CASE (use_nnp_force)
     316              :             CALL nnp_calc_energy_force(force_env%nnp_env, &
     317          308 :                                        calculate_forces)
     318              :          CASE (use_embed)
     319           24 :             CALL embed_energy(force_env)
     320              :          CASE (use_ipi)
     321            0 :             CALL request_forces(force_env%ipi_env)
     322              :          CASE default
     323       101625 :             CPABORT("Unknown force environment; cannot evaluate energy or force")
     324              :          END SELECT
     325              :       END IF
     326              :       ! In case it is requested, we evaluate the stress tensor numerically
     327       101765 :       IF (virial%pv_availability) THEN
     328        20840 :          IF (virial%pv_numer .AND. calculate_stress_tensor) THEN
     329              :             ! Compute the numerical stress tensor
     330           34 :             CALL force_env_calc_num_pressure(force_env)
     331              :          ELSE
     332        20806 :             IF (calculate_forces) THEN
     333              :                ! Symmetrize analytical stress tensor
     334        13812 :                CALL symmetrize_virial(virial)
     335              :             ELSE
     336         6994 :                IF (calculate_stress_tensor) THEN
     337              :                   CALL cp_warn(__LOCATION__, "The calculation of the stress tensor "// &
     338            0 :                                "requires the calculation of the forces")
     339              :                END IF
     340              :             END IF
     341              :          END IF
     342              :       END IF
     343              : 
     344              :       ! In case requested, compute the APT numerically
     345       101765 :       do_apt_FD = .FALSE.
     346       101765 :       IF (force_env%in_use == use_qs_force) THEN
     347        24209 :          CALL section_vals_val_get(force_env%qs_env%input, "PROPERTIES%LINRES%DCDR%APT_FD", l_val=do_apt_FD)
     348        24209 :          IF (do_apt_FD) THEN
     349              :             print_key => section_vals_get_subs_vals(force_env%qs_env%input, &
     350            2 :                                                     subsection_name="PROPERTIES%LINRES%DCDR%PRINT%APT")
     351            2 :             IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
     352            2 :                CALL apt_fdiff(force_env)
     353              :             END IF
     354              :          END IF
     355              :       END IF
     356              : 
     357              :       !sample peak memory
     358       101765 :       CALL m_memory()
     359              : 
     360              :       ! Some additional tasks..
     361       101765 :       IF (.NOT. my_skip) THEN
     362              :          ! Flexible Partitioning
     363       100861 :          IF (ASSOCIATED(force_env%fp_env)) THEN
     364       100785 :             IF (force_env%fp_env%use_fp) THEN
     365          122 :                CALL fp_eval(force_env%fp_env, subsys, cell)
     366              :             END IF
     367              :          END IF
     368              :          ! Constraints ONLY of Fixed Atom type
     369       100861 :          CALL fix_atom_control(force_env)
     370              :          ! All Restraints
     371       100861 :          CALL restraint_control(force_env)
     372              :          ! Virtual Sites
     373       100861 :          CALL vsite_force_control(force_env)
     374              :          ! External Potential
     375       100861 :          CALL add_external_potential(force_env)
     376              :          ! Rescale forces if requested
     377       100861 :          CALL rescale_forces(force_env)
     378              :       END IF
     379              : 
     380       101765 :       CALL force_env_get(force_env, potential_energy=e_pot)
     381              : 
     382              :       ! Print energy always in the same format for all methods
     383              :       output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
     384       101765 :                                          extension=".Log")
     385       101765 :       IF (output_unit > 0) THEN
     386              :          CALL section_vals_val_get(force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO%ENERGY_UNIT", &
     387        51652 :                                    c_val=unit_string)
     388        51652 :          fconv = cp_unit_from_cp2k(1.0_dp, TRIM(ADJUSTL(unit_string)))
     389              :          WRITE (UNIT=output_unit, FMT="(/,T2,A,T55,F26.15)") &
     390              :             "ENERGY| Total FORCE_EVAL ( "//TRIM(ADJUSTL(use_prog_name(force_env%in_use)))// &
     391        51652 :             " ) energy ["//TRIM(ADJUSTL(unit_string))//"]", e_pot*fconv
     392        51652 :          IF (e_gap > -0.1_dp) THEN
     393              :             WRITE (UNIT=output_unit, FMT="(/,T2,A,T55,F26.15)") &
     394              :                "ENERGY| Total FORCE_EVAL ( "//TRIM(ADJUSTL(use_prog_name(force_env%in_use)))// &
     395           10 :                " ) gap ["//TRIM(ADJUSTL(unit_string))//"]", e_gap*fconv
     396              :          END IF
     397        51652 :          IF (e_entropy > -0.1_dp) THEN
     398              :             WRITE (UNIT=output_unit, FMT="(/,T2,A,T55,F26.15)") &
     399              :                "ENERGY| Total FORCE_EVAL ( "//TRIM(ADJUSTL(use_prog_name(force_env%in_use)))// &
     400           10 :                " ) free energy ["//TRIM(ADJUSTL(unit_string))//"]", (e_pot - e_entropy)*fconv
     401              :          END IF
     402              :       END IF
     403              :       CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
     404       101765 :                                         "PRINT%PROGRAM_RUN_INFO")
     405              : 
     406              :       ! terminate the run if the value of the potential is abnormal
     407       101765 :       IF (abnormal_value(e_pot)) &
     408            0 :          CPABORT("Potential energy is an abnormal value (NaN/Inf).")
     409              : 
     410              :       ! Print forces, if requested
     411              :       print_forces = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%FORCES", &
     412       101765 :                                           extension=".xyz")
     413       101765 :       IF ((print_forces > 0) .AND. calculate_forces) THEN
     414         1566 :          CALL force_env_get(force_env, subsys=subsys)
     415              :          CALL cp_subsys_get(subsys, &
     416              :                             core_particles=core_particles, &
     417              :                             particles=particles, &
     418         1566 :                             shell_particles=shell_particles)
     419              :          ! Variable precision output of the forces
     420              :          CALL section_vals_val_get(force_env%force_env_section, "PRINT%FORCES%NDIGITS", &
     421         1566 :                                    i_val=ndigits)
     422              :          CALL section_vals_val_get(force_env%force_env_section, "PRINT%FORCES%FORCE_UNIT", &
     423         1566 :                                    c_val=unit_string)
     424         1566 :          IF (ASSOCIATED(core_particles) .OR. ASSOCIATED(shell_particles)) THEN
     425              :             CALL write_forces(particles, print_forces, "Atomic", ndigits, unit_string, &
     426          165 :                               total_force, zero_force_core_shell_atom=.TRUE.)
     427          165 :             grand_total_force(1:3) = total_force(1:3)
     428          165 :             IF (ASSOCIATED(core_particles)) THEN
     429              :                CALL write_forces(core_particles, print_forces, "Core particle", ndigits, &
     430          165 :                                  unit_string, total_force, zero_force_core_shell_atom=.FALSE.)
     431          660 :                grand_total_force(:) = grand_total_force(:) + total_force(:)
     432              :             END IF
     433          165 :             IF (ASSOCIATED(shell_particles)) THEN
     434              :                CALL write_forces(shell_particles, print_forces, "Shell particle", ndigits, &
     435              :                                  unit_string, total_force, zero_force_core_shell_atom=.FALSE., &
     436          165 :                                  grand_total_force=grand_total_force)
     437              :             END IF
     438              :          ELSE
     439         1401 :             CALL write_forces(particles, print_forces, "Atomic", ndigits, unit_string, total_force)
     440              :          END IF
     441              :       END IF
     442       101765 :       CALL cp_print_key_finished_output(print_forces, logger, force_env%force_env_section, "PRINT%FORCES")
     443              : 
     444              :       ! Write stress tensor
     445       101765 :       IF (virial%pv_availability) THEN
     446              :          ! If the virial is defined but we are not computing forces let's zero the
     447              :          ! virial for consistency
     448        20840 :          IF (calculate_forces .AND. calculate_stress_tensor) THEN
     449              :             output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%STRESS_TENSOR", &
     450        13750 :                                                extension=".stress_tensor")
     451        13750 :             IF (output_unit > 0) THEN
     452              :                CALL section_vals_val_get(force_env%force_env_section, "PRINT%STRESS_TENSOR%COMPONENTS", &
     453         5065 :                                          l_val=print_components)
     454              :                CALL section_vals_val_get(force_env%force_env_section, "PRINT%STRESS_TENSOR%STRESS_UNIT", &
     455         5065 :                                          c_val=unit_string)
     456         5065 :                IF (print_components) THEN
     457          147 :                   IF ((.NOT. virial%pv_numer) .AND. (force_env%in_use == use_qs_force)) THEN
     458          142 :                      CALL write_stress_tensor_components(virial, output_unit, cell, unit_string)
     459              :                   END IF
     460              :                END IF
     461         5065 :                CALL write_stress_tensor(virial%pv_virial, output_unit, cell, unit_string, virial%pv_numer)
     462              :             END IF
     463              :             CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
     464        13750 :                                               "PRINT%STRESS_TENSOR")
     465              :          ELSE
     466         7090 :             CALL zero_virial(virial, reset=.FALSE.)
     467              :          END IF
     468              :       ELSE
     469              :          output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%STRESS_TENSOR", &
     470        80925 :                                             extension=".stress_tensor")
     471        80925 :          IF (output_unit > 0) THEN
     472              :             CALL cp_warn(__LOCATION__, "To print the stress tensor switch on the "// &
     473          318 :                          "virial evaluation with the keyword: STRESS_TENSOR")
     474              :          END IF
     475              :          CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
     476        80925 :                                            "PRINT%STRESS_TENSOR")
     477              :       END IF
     478              : 
     479              :       ! Atomic energy
     480              :       output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
     481       101765 :                                          extension=".Log")
     482       101765 :       IF (atprop_env%energy) THEN
     483        70174 :          CALL force_env%para_env%sum(atprop_env%atener)
     484          978 :          CALL force_env_get(force_env, potential_energy=e_pot)
     485          978 :          IF (output_unit > 0) THEN
     486          489 :             IF (logger%iter_info%print_level >= low_print_level) THEN
     487          489 :                CALL cp_subsys_get(subsys=subsys, particles=particles)
     488          489 :                CALL write_atener(output_unit, particles, atprop_env%atener, "Mulliken Atomic Energies")
     489              :             END IF
     490          489 :             sum_energy = accurate_sum(atprop_env%atener(:))
     491          489 :             checksum = ABS(e_pot - sum_energy)
     492              :             WRITE (UNIT=output_unit, FMT="(/,(T2,A,T56,F25.13))") &
     493          489 :                "Potential energy (Atomic):", sum_energy, &
     494          489 :                "Potential energy (Total) :", e_pot, &
     495          978 :                "Difference               :", checksum
     496          489 :             CPASSERT((checksum < ateps*ABS(e_pot)))
     497              :          END IF
     498              :          CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
     499          978 :                                            "PRINT%PROGRAM_RUN_INFO")
     500              :       END IF
     501              : 
     502              :       ! Print GRMM interface file
     503              :       print_grrm = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%GRRM", &
     504       101765 :                                         file_position="REWIND", extension=".rrm")
     505       101765 :       IF (print_grrm > 0) THEN
     506           38 :          CALL force_env_get(force_env, subsys=subsys)
     507              :          CALL cp_subsys_get(subsys=subsys, particles=particles, &
     508           38 :                             molecule_kinds=molecule_kinds)
     509              :          ! Count the number of fixed atoms
     510           38 :          nfixed_atoms_total = 0
     511           38 :          nkind = molecule_kinds%n_els
     512           38 :          molecule_kind_set => molecule_kinds%els
     513          158 :          DO ikind = 1, nkind
     514          120 :             molecule_kind => molecule_kind_set(ikind)
     515          120 :             CALL get_molecule_kind(molecule_kind, nfixd=nfixed_atoms)
     516          158 :             nfixed_atoms_total = nfixed_atoms_total + nfixed_atoms
     517              :          END DO
     518              :          !
     519           38 :          CALL write_grrm(print_grrm, force_env, particles%els, e_pot, fixed_atoms=nfixed_atoms_total)
     520              :       END IF
     521       101765 :       CALL cp_print_key_finished_output(print_grrm, logger, force_env%force_env_section, "PRINT%GRRM")
     522              : 
     523              :       print_scine = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%SCINE", &
     524       101765 :                                          file_position="REWIND", extension=".scine")
     525       101765 :       IF (print_scine > 0) THEN
     526           23 :          CALL force_env_get(force_env, subsys=subsys)
     527           23 :          CALL cp_subsys_get(subsys=subsys, particles=particles)
     528              :          !
     529           23 :          CALL write_scine(print_scine, force_env, particles%els, e_pot)
     530              :       END IF
     531       101765 :       CALL cp_print_key_finished_output(print_scine, logger, force_env%force_env_section, "PRINT%SCINE")
     532              : 
     533       101765 :    END SUBROUTINE force_env_calc_energy_force
     534              : 
     535              : ! **************************************************************************************************
     536              : !> \brief Rebuild k-point data for geometries whose atomic symmetry can change.
     537              : !>        Atomic k-point symmetry may change when atoms or cell vectors move.
     538              : !> \param force_env ...
     539              : !> \param fd_energy ...
     540              : ! **************************************************************************************************
     541        24209 :    SUBROUTINE force_env_refresh_kpoint_symmetry(force_env, fd_energy)
     542              : 
     543              :       TYPE(force_env_type), POINTER                      :: force_env
     544              :       LOGICAL, INTENT(IN)                                :: fd_energy
     545              : 
     546              :       CHARACTER(LEN=default_string_length)               :: kp_scheme
     547              :       INTEGER                                            :: run_type_id
     548              :       LOGICAL :: debug_full_kpoint_symmetry, debug_inversion_only, do_kpoints, dynamic_symmetry, &
     549              :          full_grid, input_full_grid, input_inversion_symmetry_only, inversion_symmetry_only, &
     550              :          kpoint_symmetry, moving_geometry, use_full_grid, use_inversion_symmetry_only
     551              :       TYPE(cell_type), POINTER                           :: cell
     552              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     553              :       TYPE(dft_control_type), POINTER                    :: dft_control
     554              :       TYPE(global_environment_type), POINTER             :: globenv
     555              :       TYPE(kpoint_type), POINTER                         :: kpoints
     556        24209 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     557              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     558        24209 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     559              :       TYPE(qs_wf_history_type), POINTER                  :: wf_history
     560              :       TYPE(section_vals_type), POINTER                   :: input, kpoint_section
     561              : 
     562        22119 :       IF (.NOT. ASSOCIATED(force_env)) RETURN
     563        24209 :       IF (force_env%in_use /= use_qs_force) RETURN
     564              : 
     565        24209 :       NULLIFY (globenv)
     566        24209 :       CALL force_env_get(force_env, globenv=globenv)
     567        24209 :       IF (.NOT. ASSOCIATED(globenv)) RETURN
     568        24201 :       run_type_id = globenv%run_type_id
     569        24201 :       moving_geometry = .FALSE.
     570              :       SELECT CASE (run_type_id)
     571              :       CASE (cell_opt_run, driver_run, ehrenfest, geo_opt_run, mol_dyn_run)
     572        16591 :          moving_geometry = .TRUE.
     573              :       CASE DEFAULT
     574        24201 :          moving_geometry = .FALSE.
     575              :       END SELECT
     576        24201 :       IF (run_type_id /= debug_run .AND. .NOT. moving_geometry) RETURN
     577              : 
     578        17912 :       NULLIFY (blacs_env, cell, dft_control, input, kpoint_section, kpoints, mos, para_env, &
     579        17912 :                particle_set, wf_history)
     580              :       CALL get_qs_env(qs_env=force_env%qs_env, &
     581              :                       blacs_env=blacs_env, &
     582              :                       cell=cell, &
     583              :                       dft_control=dft_control, &
     584              :                       do_kpoints=do_kpoints, &
     585              :                       input=input, &
     586              :                       kpoints=kpoints, &
     587              :                       mos=mos, &
     588              :                       para_env=para_env, &
     589              :                       particle_set=particle_set, &
     590        17912 :                       wf_history=wf_history)
     591        17912 :       IF (.NOT. do_kpoints) RETURN
     592              : 
     593              :       CALL get_kpoint_info(kpoints, kp_scheme=kp_scheme, symmetry=kpoint_symmetry, full_grid=full_grid, &
     594         2846 :                            inversion_symmetry_only=inversion_symmetry_only)
     595         2846 :       IF (.NOT. kpoint_symmetry) RETURN
     596         2176 :       IF (TRIM(kp_scheme) /= "MONKHORST-PACK" .AND. TRIM(kp_scheme) /= "MACDONALD" .AND. &
     597              :           TRIM(kp_scheme) /= "GENERAL") RETURN
     598              : 
     599         2176 :       input_full_grid = full_grid
     600         2176 :       input_inversion_symmetry_only = inversion_symmetry_only
     601         2176 :       debug_full_kpoint_symmetry = .FALSE.
     602         2176 :       IF (ASSOCIATED(input)) THEN
     603         2176 :          kpoint_section => section_vals_get_subs_vals(input, "DFT%KPOINTS")
     604         2176 :          CALL section_vals_val_get(kpoint_section, "FULL_GRID", l_val=input_full_grid)
     605              :          CALL section_vals_val_get(kpoint_section, "INVERSION_SYMMETRY_ONLY", &
     606         2176 :                                    l_val=input_inversion_symmetry_only)
     607              :          CALL section_vals_val_get(kpoint_section, "DEBUG_FULL_KPOINT_SYMMETRY", &
     608         2176 :                                    l_val=debug_full_kpoint_symmetry)
     609              :       END IF
     610              :       ! Moving geometries and DEBUG finite differences must not reuse atomic symmetry from
     611              :       ! another geometry. Rebuild the k-point symmetry from the current cell and positions.
     612              :       ! Keep numerical finite-difference energies and DFTB DEBUG checks on the established
     613              :       ! inversion/time-reversal reduction.
     614              :       debug_inversion_only = run_type_id == debug_run .AND. .NOT. debug_full_kpoint_symmetry .AND. &
     615         2176 :                              (fd_energy .OR. dft_control%qs_control%dftb)
     616         2176 :       use_full_grid = input_full_grid
     617              :       use_inversion_symmetry_only = (input_inversion_symmetry_only .OR. debug_inversion_only) .AND. &
     618         2176 :                                     (.NOT. use_full_grid)
     619              :       dynamic_symmetry = kpoint_symmetry .AND. .NOT. use_full_grid .AND. &
     620         2176 :                          .NOT. use_inversion_symmetry_only
     621              :       IF (run_type_id == debug_run .AND. .NOT. fd_energy .AND. .NOT. dynamic_symmetry .AND. &
     622         2176 :           (full_grid .EQV. use_full_grid) .AND. &
     623              :           (inversion_symmetry_only .EQV. use_inversion_symmetry_only)) THEN
     624           22 :          CALL qs_basis_rotation(force_env%qs_env, kpoints)
     625           22 :          RETURN
     626              :       END IF
     627         2154 :       IF (moving_geometry .AND. .NOT. dynamic_symmetry) RETURN
     628         2094 :       IF (moving_geometry .AND. .NOT. kpoint_has_nontrivial_atomic_symmetry(kpoints)) RETURN
     629              :       CALL set_kpoint_info(kpoints, full_grid=use_full_grid, &
     630         2090 :                            inversion_symmetry_only=use_inversion_symmetry_only)
     631              : 
     632         2090 :       CALL kpoint_reset_initialization(kpoints)
     633         2090 :       CALL kpoint_initialize(kpoints, particle_set, cell)
     634         2090 :       CALL kpoint_env_initialize(kpoints, para_env, blacs_env, with_aux_fit=dft_control%do_admm)
     635         2090 :       CALL kpoint_initialize_mos(kpoints, mos)
     636         2090 :       CALL wfi_clear(wf_history)
     637         2090 :       CALL qs_basis_rotation(force_env%qs_env, kpoints)
     638              : 
     639        24209 :    END SUBROUTINE force_env_refresh_kpoint_symmetry
     640              : 
     641              : ! **************************************************************************************************
     642              : !> \brief Return whether the current reduced mesh uses nontrivial atomic symmetry operations.
     643              : !> \param kpoints ...
     644              : !> \return has_symmetry
     645              : ! **************************************************************************************************
     646           20 :    FUNCTION kpoint_has_nontrivial_atomic_symmetry(kpoints) RESULT(has_symmetry)
     647              : 
     648              :       TYPE(kpoint_type), POINTER                         :: kpoints
     649              :       LOGICAL                                            :: has_symmetry
     650              : 
     651              :       INTEGER                                            :: iatom, ik, isym, natom
     652              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: eye3
     653              :       TYPE(kpoint_sym_type), POINTER                     :: kpsym
     654              : 
     655           20 :       has_symmetry = .FALSE.
     656           20 :       IF (.NOT. ASSOCIATED(kpoints)) RETURN
     657           20 :       IF (.NOT. ASSOCIATED(kpoints%kp_sym)) RETURN
     658              : 
     659           20 :       eye3 = 0.0_dp
     660           20 :       eye3(1, 1) = 1.0_dp
     661           20 :       eye3(2, 2) = 1.0_dp
     662           20 :       eye3(3, 3) = 1.0_dp
     663              : 
     664           36 :       DO ik = 1, kpoints%nkp
     665           32 :          kpsym => kpoints%kp_sym(ik)%kpoint_sym
     666           32 :          IF (.NOT. ASSOCIATED(kpsym)) CYCLE
     667           32 :          IF (.NOT. kpsym%apply_symmetry) CYCLE
     668           16 :          IF (.NOT. ASSOCIATED(kpsym%rot)) CYCLE
     669           16 :          IF (.NOT. ASSOCIATED(kpsym%f0)) CYCLE
     670           16 :          IF (.NOT. ASSOCIATED(kpsym%fcell)) CYCLE
     671              : 
     672           16 :          natom = SIZE(kpsym%f0, 1)
     673           36 :          DO isym = 1, SIZE(kpsym%rot, 3)
     674          992 :             IF (MAXVAL(ABS(kpsym%rot(1:3, 1:3, isym) - eye3(1:3, 1:3))) > 1.e-12_dp .OR. &
     675              :                 ANY(kpsym%fcell(1:3, 1:natom, isym) /= 0)) THEN
     676           20 :                has_symmetry = .TRUE.
     677              :                RETURN
     678              :             END IF
     679          160 :             DO iatom = 1, natom
     680          144 :                IF (kpsym%f0(iatom, isym) /= iatom) THEN
     681           20 :                   has_symmetry = .TRUE.
     682              :                   RETURN
     683              :                END IF
     684              :             END DO
     685              :          END DO
     686              :       END DO
     687              : 
     688              :    END FUNCTION kpoint_has_nontrivial_atomic_symmetry
     689              : 
     690              : ! **************************************************************************************************
     691              : !> \brief Evaluates the stress tensor and pressure numerically
     692              : !> \param force_env ...
     693              : !> \param dx ...
     694              : !> \par History
     695              : !>      10.2005 created [JCS]
     696              : !>      05.2009 Teodoro Laino [tlaino] - rewriting for general force_env
     697              : !>
     698              : !> \author JCS
     699              : ! **************************************************************************************************
     700          220 :    SUBROUTINE force_env_calc_num_pressure(force_env, dx)
     701              : 
     702              :       TYPE(force_env_type), POINTER                      :: force_env
     703              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: dx
     704              : 
     705              :       REAL(kind=dp), PARAMETER                           :: default_dx = 0.001_dp
     706              : 
     707              :       CHARACTER(LEN=default_string_length)               :: unit_string
     708              :       INTEGER                                            :: i, ip, iq, j, k, method_id, natom, &
     709              :                                                             ncore, nshell, output_unit, symmetry_id
     710              :       LOGICAL                                            :: use_sym_strain_2d
     711              :       REAL(KIND=dp)                                      :: dx_w, eps_w
     712              :       REAL(KIND=dp), DIMENSION(2)                        :: numer_energy
     713              :       REAL(KIND=dp), DIMENSION(3)                        :: s
     714              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat_deformed, numer_pv_2d, &
     715              :                                                             numer_stress, strain
     716          220 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: ref_pos_atom, ref_pos_core, ref_pos_shell
     717              :       TYPE(cell_type), POINTER                           :: cell, cell_local
     718              :       TYPE(cp_logger_type), POINTER                      :: logger
     719              :       TYPE(cp_subsys_type), POINTER                      :: subsys
     720              :       TYPE(dft_control_type), POINTER                    :: dft_control
     721              :       TYPE(global_environment_type), POINTER             :: globenv
     722              :       TYPE(particle_list_type), POINTER                  :: core_particles, particles, &
     723              :                                                             shell_particles
     724              :       TYPE(virial_type), POINTER                         :: virial
     725              : 
     726          220 :       NULLIFY (cell_local)
     727          220 :       NULLIFY (dft_control)
     728          220 :       NULLIFY (core_particles)
     729          220 :       NULLIFY (particles)
     730          220 :       NULLIFY (shell_particles)
     731          220 :       NULLIFY (ref_pos_atom)
     732          220 :       NULLIFY (ref_pos_core)
     733          220 :       NULLIFY (ref_pos_shell)
     734          220 :       natom = 0
     735              :       method_id = 0
     736          220 :       ncore = 0
     737          220 :       nshell = 0
     738          220 :       numer_pv_2d = 0.0_dp
     739          220 :       numer_stress = 0.0_dp
     740          220 :       use_sym_strain_2d = .FALSE.
     741              : 
     742          440 :       logger => cp_get_default_logger()
     743              : 
     744          220 :       dx_w = default_dx
     745          220 :       IF (PRESENT(dx)) dx_w = dx
     746          220 :       CALL force_env_get(force_env, subsys=subsys, globenv=globenv, in_use=method_id)
     747              :       CALL cp_subsys_get(subsys, &
     748              :                          core_particles=core_particles, &
     749              :                          particles=particles, &
     750              :                          shell_particles=shell_particles, &
     751          220 :                          virial=virial)
     752              :       output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%STRESS_TENSOR", &
     753          220 :                                          extension=".stress_tensor")
     754          220 :       IF (output_unit > 0) THEN
     755           21 :          WRITE (output_unit, "(/A,A/)") " **************************** ", &
     756           42 :             "NUMERICAL STRESS ********************************"
     757              :       END IF
     758              : 
     759              :       ! Save all original particle positions
     760          220 :       natom = particles%n_els
     761          660 :       ALLOCATE (ref_pos_atom(natom, 3))
     762         7418 :       DO i = 1, natom
     763        29012 :          ref_pos_atom(i, :) = particles%els(i)%r
     764              :       END DO
     765          220 :       IF (ASSOCIATED(core_particles)) THEN
     766            4 :          ncore = core_particles%n_els
     767           12 :          ALLOCATE (ref_pos_core(ncore, 3))
     768         1544 :          DO i = 1, ncore
     769         6164 :             ref_pos_core(i, :) = core_particles%els(i)%r
     770              :          END DO
     771              :       END IF
     772          220 :       IF (ASSOCIATED(shell_particles)) THEN
     773            4 :          nshell = shell_particles%n_els
     774           12 :          ALLOCATE (ref_pos_shell(nshell, 3))
     775         1544 :          DO i = 1, nshell
     776         6164 :             ref_pos_shell(i, :) = shell_particles%els(i)%r
     777              :          END DO
     778              :       END IF
     779          220 :       CALL force_env_get(force_env, cell=cell)
     780              :       ! Save cell symmetry (distorted cell has no symmetry)
     781          220 :       symmetry_id = cell%symmetry_id
     782          220 :       cell%symmetry_id = cell_sym_triclinic
     783              :       !
     784          220 :       CALL cell_create(cell_local)
     785          220 :       CALL cell_clone(cell, cell_local)
     786          880 :       IF (COUNT(cell_local%perd /= 0) == 2 .AND. method_id == use_qs_force) THEN
     787           30 :          CALL get_qs_env(qs_env=force_env%qs_env, dft_control=dft_control)
     788           46 :          SELECT CASE (dft_control%qs_control%method_id)
     789              :          CASE (do_method_gapw, do_method_gapw_xc, do_method_gpw, &
     790              :                do_method_lrigpw, do_method_ofgpw, do_method_rigpw)
     791           30 :             use_sym_strain_2d = .TRUE.
     792              :          END SELECT
     793              :       END IF
     794              :       ! First change box
     795          880 :       DO ip = 1, 3
     796         2860 :          DO iq = 1, 3
     797         1980 :             IF (use_sym_strain_2d) THEN
     798          144 :                IF (cell_local%perd(ip) == 0 .OR. cell_local%perd(iq) == 0) CYCLE
     799           64 :                IF (iq < ip) CYCLE
     800              :             END IF
     801         1884 :             IF (virial%pv_diagonal .AND. (ip /= iq)) CYCLE
     802         4320 :             DO k = 1, 2
     803        37440 :                hmat_deformed = cell_local%hmat
     804         2880 :                IF (use_sym_strain_2d) THEN
     805           96 :                   eps_w = -(-1.0_dp)**k*dx_w
     806           96 :                   strain = 0.0_dp
     807          384 :                   DO i = 1, 3
     808          384 :                      strain(i, i) = 1.0_dp
     809              :                   END DO
     810           96 :                   IF (ip == iq) THEN
     811           64 :                      strain(ip, ip) = strain(ip, ip) + eps_w
     812              :                   ELSE
     813           32 :                      strain(ip, iq) = strain(ip, iq) + 0.5_dp*eps_w
     814           32 :                      strain(iq, ip) = strain(iq, ip) + 0.5_dp*eps_w
     815              :                   END IF
     816         3840 :                   hmat_deformed = MATMUL(strain, cell_local%hmat)
     817              :                ELSE
     818         2784 :                   hmat_deformed(ip, iq) = hmat_deformed(ip, iq) - (-1.0_dp)**k*dx_w
     819              :                END IF
     820        37440 :                cell%hmat = hmat_deformed
     821         2880 :                CALL init_cell(cell)
     822              :                ! Scale positions
     823        74340 :                DO i = 1, natom
     824        71460 :                   CALL real_to_scaled(s, ref_pos_atom(i, 1:3), cell_local)
     825        74340 :                   CALL scaled_to_real(particles%els(i)%r, s, cell)
     826              :                END DO
     827        30600 :                DO i = 1, ncore
     828        27720 :                   CALL real_to_scaled(s, ref_pos_core(i, 1:3), cell_local)
     829        30600 :                   CALL scaled_to_real(core_particles%els(i)%r, s, cell)
     830              :                END DO
     831        30600 :                DO i = 1, nshell
     832        27720 :                   CALL real_to_scaled(s, ref_pos_shell(i, 1:3), cell_local)
     833        30600 :                   CALL scaled_to_real(shell_particles%els(i)%r, s, cell)
     834              :                END DO
     835              :                ! Compute energies
     836              :                CALL force_env_calc_energy_force(force_env, &
     837              :                                                 calc_force=.FALSE., &
     838              :                                                 consistent_energies=.TRUE., &
     839         2880 :                                                 calc_stress_tensor=.FALSE.)
     840         2880 :                CALL force_env_get(force_env, potential_energy=numer_energy(k))
     841              :                ! Reset cell
     842        73440 :                cell%hmat = cell_local%hmat
     843              :             END DO
     844         1440 :             CALL init_cell(cell)
     845         2100 :             IF (use_sym_strain_2d) THEN
     846           48 :                numer_pv_2d(ip, iq) = -0.5_dp*(numer_energy(1) - numer_energy(2))/dx_w
     847           48 :                numer_pv_2d(iq, ip) = numer_pv_2d(ip, iq)
     848           48 :                IF (output_unit > 0) THEN
     849           24 :                   IF (globenv%run_type_id == debug_run) THEN
     850              :                      WRITE (UNIT=output_unit, FMT="(/,T2,A,T19,A,F7.4,A,T44,A,F7.4,A,T69,A)") &
     851           24 :                         "DEBUG|", "E(e"//ACHAR(119 + ip)//ACHAR(119 + iq)//" +", dx_w, ")", &
     852           24 :                         "E(e"//ACHAR(119 + ip)//ACHAR(119 + iq)//" -", dx_w, ")", &
     853           48 :                         "pv(numerical)"
     854              :                      WRITE (UNIT=output_unit, FMT="(T2,A,2(1X,F24.8),1X,F22.8)") &
     855           24 :                         "DEBUG|", numer_energy(1:2), numer_pv_2d(ip, iq)
     856              :                   ELSE
     857              :                      WRITE (UNIT=output_unit, FMT="(/,T7,A,F7.4,A,T27,A,F7.4,A,T49,A)") &
     858            0 :                         "E(e"//ACHAR(119 + ip)//ACHAR(119 + iq)//" +", dx_w, ")", &
     859            0 :                         "E(e"//ACHAR(119 + ip)//ACHAR(119 + iq)//" -", dx_w, ")", &
     860            0 :                         "pv(numerical)"
     861              :                      WRITE (UNIT=output_unit, FMT="(3(1X,F19.8))") &
     862            0 :                         numer_energy(1:2), numer_pv_2d(ip, iq)
     863              :                   END IF
     864              :                END IF
     865              :             ELSE
     866         1392 :                numer_stress(ip, iq) = 0.5_dp*(numer_energy(1) - numer_energy(2))/dx_w
     867         1392 :                IF (output_unit > 0) THEN
     868           99 :                   IF (globenv%run_type_id == debug_run) THEN
     869              :                      WRITE (UNIT=output_unit, FMT="(/,T2,A,T19,A,F7.4,A,T44,A,F7.4,A,T69,A)") &
     870           81 :                         "DEBUG|", "E("//ACHAR(119 + ip)//ACHAR(119 + iq)//" +", dx_w, ")", &
     871           81 :                         "E("//ACHAR(119 + ip)//ACHAR(119 + iq)//" -", dx_w, ")", &
     872          162 :                         "f(numerical)"
     873              :                      WRITE (UNIT=output_unit, FMT="(T2,A,2(1X,F24.8),1X,F22.8)") &
     874           81 :                         "DEBUG|", numer_energy(1:2), numer_stress(ip, iq)
     875              :                   ELSE
     876              :                      WRITE (UNIT=output_unit, FMT="(/,T7,A,F7.4,A,T27,A,F7.4,A,T49,A)") &
     877           18 :                         "E("//ACHAR(119 + ip)//ACHAR(119 + iq)//" +", dx_w, ")", &
     878           18 :                         "E("//ACHAR(119 + ip)//ACHAR(119 + iq)//" -", dx_w, ")", &
     879           36 :                         "f(numerical)"
     880              :                      WRITE (UNIT=output_unit, FMT="(3(1X,F19.8))") &
     881           18 :                         numer_energy(1:2), numer_stress(ip, iq)
     882              :                   END IF
     883              :                END IF
     884              :             END IF
     885              :          END DO
     886              :       END DO
     887              : 
     888              :       ! Reset positions and rebuild original environment
     889          220 :       cell%symmetry_id = symmetry_id
     890          220 :       CALL init_cell(cell)
     891         7418 :       DO i = 1, natom
     892        50606 :          particles%els(i)%r = ref_pos_atom(i, :)
     893              :       END DO
     894         1760 :       DO i = 1, ncore
     895        11000 :          core_particles%els(i)%r = ref_pos_core(i, :)
     896              :       END DO
     897         1760 :       DO i = 1, nshell
     898        11000 :          shell_particles%els(i)%r = ref_pos_shell(i, :)
     899              :       END DO
     900              :       CALL force_env_calc_energy_force(force_env, &
     901              :                                        calc_force=.FALSE., &
     902              :                                        consistent_energies=.TRUE., &
     903          220 :                                        calc_stress_tensor=.FALSE.)
     904              : 
     905              :       ! Computing pv_test
     906         2860 :       virial%pv_virial = 0.0_dp
     907          220 :       IF (use_sym_strain_2d) THEN
     908          208 :          virial%pv_virial = numer_pv_2d
     909              :       ELSE
     910          816 :          DO i = 1, 3
     911         2652 :             DO j = 1, 3
     912         7956 :                DO k = 1, 3
     913              :                   virial%pv_virial(i, j) = virial%pv_virial(i, j) - &
     914              :                                            0.5_dp*(numer_stress(i, k)*cell_local%hmat(j, k) + &
     915         7344 :                                                    numer_stress(j, k)*cell_local%hmat(i, k))
     916              :                END DO
     917              :             END DO
     918              :          END DO
     919              :       END IF
     920          220 :       IF (output_unit > 0) THEN
     921           21 :          IF (globenv%run_type_id == debug_run) THEN
     922              :             CALL section_vals_val_get(force_env%force_env_section, "PRINT%FORCES%FORCE_UNIT", &
     923           17 :                                       c_val=unit_string)
     924           17 :             CALL write_stress_tensor(virial%pv_virial, output_unit, cell, unit_string, virial%pv_numer)
     925              :          END IF
     926              :          WRITE (output_unit, "(/,A,/)") " **************************** "// &
     927           21 :             "NUMERICAL STRESS END *****************************"
     928              :       END IF
     929              : 
     930              :       CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
     931          220 :                                         "PRINT%STRESS_TENSOR")
     932              : 
     933              :       ! Release storage
     934          220 :       IF (ASSOCIATED(ref_pos_atom)) THEN
     935          220 :          DEALLOCATE (ref_pos_atom)
     936              :       END IF
     937          220 :       IF (ASSOCIATED(ref_pos_core)) THEN
     938            4 :          DEALLOCATE (ref_pos_core)
     939              :       END IF
     940          220 :       IF (ASSOCIATED(ref_pos_shell)) THEN
     941            4 :          DEALLOCATE (ref_pos_shell)
     942              :       END IF
     943          220 :       IF (ASSOCIATED(cell_local)) CALL cell_release(cell_local)
     944              : 
     945          440 :    END SUBROUTINE force_env_calc_num_pressure
     946              : 
     947              : ! **************************************************************************************************
     948              : !> \brief creates and initializes a force environment
     949              : !> \param force_env the force env to create
     950              : !> \param root_section ...
     951              : !> \param para_env ...
     952              : !> \param globenv ...
     953              : !> \param fist_env , qs_env: exactly one of these should be
     954              : !>        associated, the one that is active
     955              : !> \param qs_env ...
     956              : !> \param meta_env ...
     957              : !> \param sub_force_env ...
     958              : !> \param qmmm_env ...
     959              : !> \param qmmmx_env ...
     960              : !> \param eip_env ...
     961              : !> \param pwdft_env ...
     962              : !> \param force_env_section ...
     963              : !> \param mixed_env ...
     964              : !> \param embed_env ...
     965              : !> \param nnp_env ...
     966              : !> \param ipi_env ...
     967              : !> \par History
     968              : !>      04.2003 created [fawzi]
     969              : !> \author fawzi
     970              : ! **************************************************************************************************
     971        10791 :    SUBROUTINE force_env_create(force_env, root_section, para_env, globenv, fist_env, &
     972              :                                qs_env, meta_env, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, force_env_section, &
     973              :                                mixed_env, embed_env, nnp_env, ipi_env)
     974              : 
     975              :       TYPE(force_env_type), POINTER                      :: force_env
     976              :       TYPE(section_vals_type), POINTER                   :: root_section
     977              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     978              :       TYPE(global_environment_type), POINTER             :: globenv
     979              :       TYPE(fist_environment_type), OPTIONAL, POINTER     :: fist_env
     980              :       TYPE(qs_environment_type), OPTIONAL, POINTER       :: qs_env
     981              :       TYPE(meta_env_type), OPTIONAL, POINTER             :: meta_env
     982              :       TYPE(force_env_p_type), DIMENSION(:), OPTIONAL, &
     983              :          POINTER                                         :: sub_force_env
     984              :       TYPE(qmmm_env_type), OPTIONAL, POINTER             :: qmmm_env
     985              :       TYPE(qmmmx_env_type), OPTIONAL, POINTER            :: qmmmx_env
     986              :       TYPE(eip_environment_type), OPTIONAL, POINTER      :: eip_env
     987              :       TYPE(pwdft_environment_type), OPTIONAL, POINTER    :: pwdft_env
     988              :       TYPE(section_vals_type), POINTER                   :: force_env_section
     989              :       TYPE(mixed_environment_type), OPTIONAL, POINTER    :: mixed_env
     990              :       TYPE(embed_env_type), OPTIONAL, POINTER            :: embed_env
     991              :       TYPE(nnp_type), OPTIONAL, POINTER                  :: nnp_env
     992              :       TYPE(ipi_environment_type), OPTIONAL, POINTER      :: ipi_env
     993              : 
     994        10791 :       ALLOCATE (force_env)
     995              :       NULLIFY (force_env%fist_env, force_env%qs_env, &
     996              :                force_env%para_env, force_env%globenv, &
     997              :                force_env%meta_env, force_env%sub_force_env, &
     998              :                force_env%qmmm_env, force_env%qmmmx_env, force_env%fp_env, &
     999              :                force_env%force_env_section, force_env%eip_env, force_env%mixed_env, &
    1000              :                force_env%embed_env, force_env%pwdft_env, force_env%nnp_env, &
    1001              :                force_env%root_section)
    1002        10791 :       last_force_env_id = last_force_env_id + 1
    1003        10791 :       force_env%ref_count = 1
    1004              :       force_env%in_use = 0
    1005              :       force_env%additional_potential = 0.0_dp
    1006              : 
    1007        10791 :       force_env%globenv => globenv
    1008        10791 :       CALL globenv_retain(force_env%globenv)
    1009              : 
    1010        10791 :       force_env%root_section => root_section
    1011        10791 :       CALL section_vals_retain(root_section)
    1012              : 
    1013        10791 :       force_env%para_env => para_env
    1014        10791 :       CALL force_env%para_env%retain()
    1015              : 
    1016        10791 :       CALL section_vals_retain(force_env_section)
    1017        10791 :       force_env%force_env_section => force_env_section
    1018              : 
    1019        10791 :       IF (PRESENT(fist_env)) THEN
    1020         2241 :          CPASSERT(ASSOCIATED(fist_env))
    1021         2241 :          CPASSERT(force_env%in_use == 0)
    1022         2241 :          force_env%in_use = use_fist_force
    1023         2241 :          force_env%fist_env => fist_env
    1024              :       END IF
    1025        10791 :       IF (PRESENT(eip_env)) THEN
    1026            8 :          CPASSERT(ASSOCIATED(eip_env))
    1027            8 :          CPASSERT(force_env%in_use == 0)
    1028            8 :          force_env%in_use = use_eip_force
    1029            8 :          force_env%eip_env => eip_env
    1030              :       END IF
    1031        10791 :       IF (PRESENT(pwdft_env)) THEN
    1032           20 :          CPASSERT(ASSOCIATED(pwdft_env))
    1033           20 :          CPASSERT(force_env%in_use == 0)
    1034           20 :          force_env%in_use = use_pwdft_force
    1035           20 :          force_env%pwdft_env => pwdft_env
    1036              :       END IF
    1037        10791 :       IF (PRESENT(qs_env)) THEN
    1038         8014 :          CPASSERT(ASSOCIATED(qs_env))
    1039         8014 :          CPASSERT(force_env%in_use == 0)
    1040         8014 :          force_env%in_use = use_qs_force
    1041         8014 :          force_env%qs_env => qs_env
    1042              :       END IF
    1043        10791 :       IF (PRESENT(qmmm_env)) THEN
    1044          326 :          CPASSERT(ASSOCIATED(qmmm_env))
    1045          326 :          CPASSERT(force_env%in_use == 0)
    1046          326 :          force_env%in_use = use_qmmm
    1047          326 :          force_env%qmmm_env => qmmm_env
    1048              :       END IF
    1049        10791 :       IF (PRESENT(qmmmx_env)) THEN
    1050            8 :          CPASSERT(ASSOCIATED(qmmmx_env))
    1051            8 :          CPASSERT(force_env%in_use == 0)
    1052            8 :          force_env%in_use = use_qmmmx
    1053            8 :          force_env%qmmmx_env => qmmmx_env
    1054              :       END IF
    1055        10791 :       IF (PRESENT(mixed_env)) THEN
    1056          136 :          CPASSERT(ASSOCIATED(mixed_env))
    1057          136 :          CPASSERT(force_env%in_use == 0)
    1058          136 :          force_env%in_use = use_mixed_force
    1059          136 :          force_env%mixed_env => mixed_env
    1060              :       END IF
    1061        10791 :       IF (PRESENT(embed_env)) THEN
    1062           24 :          CPASSERT(ASSOCIATED(embed_env))
    1063           24 :          CPASSERT(force_env%in_use == 0)
    1064           24 :          force_env%in_use = use_embed
    1065           24 :          force_env%embed_env => embed_env
    1066              :       END IF
    1067        10791 :       IF (PRESENT(nnp_env)) THEN
    1068           14 :          CPASSERT(ASSOCIATED(nnp_env))
    1069           14 :          CPASSERT(force_env%in_use == 0)
    1070           14 :          force_env%in_use = use_nnp_force
    1071           14 :          force_env%nnp_env => nnp_env
    1072              :       END IF
    1073        10791 :       IF (PRESENT(ipi_env)) THEN
    1074            0 :          CPASSERT(ASSOCIATED(ipi_env))
    1075            0 :          CPASSERT(force_env%in_use == 0)
    1076            0 :          force_env%in_use = use_ipi
    1077            0 :          force_env%ipi_env => ipi_env
    1078              :       END IF
    1079        10791 :       CPASSERT(force_env%in_use /= 0)
    1080              : 
    1081        10791 :       IF (PRESENT(sub_force_env)) THEN
    1082            0 :          force_env%sub_force_env => sub_force_env
    1083              :       END IF
    1084              : 
    1085        10791 :       IF (PRESENT(meta_env)) THEN
    1086            0 :          force_env%meta_env => meta_env
    1087              :       ELSE
    1088        10791 :          NULLIFY (force_env%meta_env)
    1089              :       END IF
    1090              : 
    1091        10791 :    END SUBROUTINE force_env_create
    1092              : 
    1093              : ! **************************************************************************************************
    1094              : !> \brief ****f* force_env_methods/mixed_energy_forces  [1.0]
    1095              : !>
    1096              : !>     Computes energy and forces for a mixed force_env type
    1097              : !> \param force_env the force_env that holds the mixed_env type
    1098              : !> \param calculate_forces decides if forces should be calculated
    1099              : !> \par History
    1100              : !>       11.06  created [fschiff]
    1101              : !>       04.07  generalization to an illimited number of force_eval [tlaino]
    1102              : !>       04.07  further generalization to force_eval with different geometrical
    1103              : !>              structures [tlaino]
    1104              : !>       04.08  reorganizing the genmix structure (collecting common code)
    1105              : !>       01.16  added CDFT [Nico Holmberg]
    1106              : !>       08.17  added DFT embedding [Vladimir Rybkin]
    1107              : !> \author Florian Schiffmann
    1108              : ! **************************************************************************************************
    1109          530 :    SUBROUTINE mixed_energy_forces(force_env, calculate_forces)
    1110              : 
    1111              :       TYPE(force_env_type), POINTER                      :: force_env
    1112              :       LOGICAL, INTENT(IN)                                :: calculate_forces
    1113              : 
    1114              :       CHARACTER(LEN=default_path_length)                 :: coupling_function
    1115              :       CHARACTER(LEN=default_string_length)               :: def_error, description, this_error
    1116              :       INTEGER                                            :: iforce_eval, iparticle, istate(2), &
    1117              :                                                             jparticle, mixing_type, my_group, &
    1118              :                                                             natom, nforce_eval, source, unit_nr
    1119          530 :       INTEGER, DIMENSION(:), POINTER                     :: glob_natoms, itmplist, map_index
    1120              :       LOGICAL                                            :: dip_exists
    1121              :       REAL(KIND=dp)                                      :: coupling_parameter, dedf, der_1, der_2, &
    1122              :                                                             dx, energy, err, lambda, lerr, &
    1123              :                                                             restraint_strength, restraint_target, &
    1124              :                                                             sd
    1125              :       REAL(KIND=dp), DIMENSION(3)                        :: dip_mix
    1126          530 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energies
    1127              :       TYPE(cell_type), POINTER                           :: cell_mix
    1128              :       TYPE(cp_logger_type), POINTER                      :: logger, my_logger
    1129          530 :       TYPE(cp_result_p_type), DIMENSION(:), POINTER      :: results
    1130              :       TYPE(cp_result_type), POINTER                      :: loc_results, results_mix
    1131          530 :       TYPE(cp_subsys_p_type), DIMENSION(:), POINTER      :: subsystems
    1132              :       TYPE(cp_subsys_type), POINTER                      :: subsys_mix
    1133              :       TYPE(mixed_energy_type), POINTER                   :: mixed_energy
    1134          530 :       TYPE(mixed_force_type), DIMENSION(:), POINTER      :: global_forces
    1135              :       TYPE(particle_list_p_type), DIMENSION(:), POINTER  :: particles
    1136              :       TYPE(particle_list_type), POINTER                  :: particles_mix
    1137              :       TYPE(section_vals_type), POINTER                   :: force_env_section, gen_section, &
    1138              :                                                             mapping_section, mixed_section, &
    1139              :                                                             root_section
    1140          530 :       TYPE(virial_p_type), DIMENSION(:), POINTER         :: virials
    1141              :       TYPE(virial_type), POINTER                         :: loc_virial, virial_mix
    1142              : 
    1143         1060 :       logger => cp_get_default_logger()
    1144          530 :       CPASSERT(ASSOCIATED(force_env))
    1145              :       ! Get infos about the mixed subsys
    1146              :       CALL force_env_get(force_env=force_env, &
    1147              :                          subsys=subsys_mix, &
    1148              :                          force_env_section=force_env_section, &
    1149              :                          root_section=root_section, &
    1150          530 :                          cell=cell_mix)
    1151              :       CALL cp_subsys_get(subsys=subsys_mix, &
    1152              :                          particles=particles_mix, &
    1153              :                          virial=virial_mix, &
    1154          530 :                          results=results_mix)
    1155          530 :       NULLIFY (map_index, glob_natoms, global_forces, itmplist)
    1156              : 
    1157          530 :       nforce_eval = SIZE(force_env%sub_force_env)
    1158          530 :       mixed_section => section_vals_get_subs_vals(force_env_section, "MIXED")
    1159          530 :       mapping_section => section_vals_get_subs_vals(mixed_section, "MAPPING")
    1160              :       ! Global Info
    1161         2742 :       ALLOCATE (subsystems(nforce_eval))
    1162         2212 :       ALLOCATE (particles(nforce_eval))
    1163              :       ! Local Info to sync
    1164         2742 :       ALLOCATE (global_forces(nforce_eval))
    1165         1060 :       ALLOCATE (energies(nforce_eval))
    1166         1590 :       ALLOCATE (glob_natoms(nforce_eval))
    1167         2212 :       ALLOCATE (virials(nforce_eval))
    1168         2212 :       ALLOCATE (results(nforce_eval))
    1169         1682 :       energies = 0.0_dp
    1170         1682 :       glob_natoms = 0
    1171              :       ! Check if mixed CDFT calculation is requested and initialize
    1172          530 :       CALL mixed_cdft_init(force_env, calculate_forces)
    1173              : 
    1174              :       !
    1175          530 :       IF (.NOT. force_env%mixed_env%do_mixed_cdft) THEN
    1176         1358 :          DO iforce_eval = 1, nforce_eval
    1177          928 :             NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
    1178          928 :             NULLIFY (results(iforce_eval)%results, virials(iforce_eval)%virial)
    1179       212512 :             ALLOCATE (virials(iforce_eval)%virial)
    1180          928 :             CALL cp_result_create(results(iforce_eval)%results)
    1181          928 :             IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) CYCLE
    1182              :             ! From this point on the error is the sub_error
    1183          466 :             my_group = force_env%mixed_env%group_distribution(force_env%para_env%mepos)
    1184          466 :             my_logger => force_env%mixed_env%sub_logger(my_group + 1)%p
    1185              :             ! Copy iterations info (they are updated only in the main mixed_env)
    1186          466 :             CALL cp_iteration_info_copy_iter(logger%iter_info, my_logger%iter_info)
    1187          466 :             CALL cp_add_default_logger(my_logger)
    1188              : 
    1189              :             ! Get all available subsys
    1190              :             CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
    1191          466 :                                subsys=subsystems(iforce_eval)%subsys)
    1192              : 
    1193              :             ! all force_env share the same cell
    1194          466 :             CALL cp_subsys_set(subsystems(iforce_eval)%subsys, cell=cell_mix)
    1195              : 
    1196              :             ! Get available particles
    1197              :             CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
    1198          466 :                                particles=particles(iforce_eval)%list)
    1199              : 
    1200              :             ! Get Mapping index array
    1201          466 :             natom = SIZE(particles(iforce_eval)%list%els)
    1202              : 
    1203              :             CALL get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, &
    1204          466 :                                       map_index)
    1205              : 
    1206              :             ! Mapping particles from iforce_eval environment to the mixed env
    1207       439077 :             DO iparticle = 1, natom
    1208       438611 :                jparticle = map_index(iparticle)
    1209      3070743 :                particles(iforce_eval)%list%els(iparticle)%r = particles_mix%els(jparticle)%r
    1210              :             END DO
    1211              : 
    1212              :             ! Calculate energy and forces for each sub_force_env
    1213              :             CALL force_env_calc_energy_force(force_env%sub_force_env(iforce_eval)%force_env, &
    1214              :                                              calc_force=calculate_forces, &
    1215          466 :                                              skip_external_control=.TRUE.)
    1216              : 
    1217              :             ! Only the rank 0 process collect info for each computation
    1218          466 :             IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
    1219              :                CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, &
    1220          464 :                                   potential_energy=energy)
    1221              :                CALL cp_subsys_get(subsystems(iforce_eval)%subsys, &
    1222          464 :                                   virial=loc_virial, results=loc_results)
    1223          464 :                energies(iforce_eval) = energy
    1224          464 :                glob_natoms(iforce_eval) = natom
    1225          464 :                virials(iforce_eval)%virial = loc_virial
    1226          464 :                CALL cp_result_copy(loc_results, results(iforce_eval)%results)
    1227              :             END IF
    1228              :             ! Deallocate map_index array
    1229          466 :             IF (ASSOCIATED(map_index)) THEN
    1230          466 :                DEALLOCATE (map_index)
    1231              :             END IF
    1232         1358 :             CALL cp_rm_default_logger()
    1233              :          END DO
    1234              :       ELSE
    1235              :          CALL mixed_cdft_energy_forces(force_env, calculate_forces, particles, energies, &
    1236          100 :                                        glob_natoms, virials, results)
    1237              :       END IF
    1238              :       ! Handling Parallel execution
    1239          530 :       CALL force_env%para_env%sync()
    1240              :       ! Post CDFT operations
    1241          530 :       CALL mixed_cdft_post_energy_forces(force_env)
    1242              :       ! Let's transfer energy, natom, forces, virials
    1243         2834 :       CALL force_env%para_env%sum(energies)
    1244         2834 :       CALL force_env%para_env%sum(glob_natoms)
    1245              :       ! Transfer forces
    1246         1682 :       DO iforce_eval = 1, nforce_eval
    1247         3456 :          ALLOCATE (global_forces(iforce_eval)%forces(3, glob_natoms(iforce_eval)))
    1248      3512208 :          global_forces(iforce_eval)%forces = 0.0_dp
    1249         1152 :          IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) THEN
    1250          652 :             IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
    1251              :                ! Forces
    1252       439458 :                DO iparticle = 1, glob_natoms(iforce_eval)
    1253              :                   global_forces(iforce_eval)%forces(:, iparticle) = &
    1254      3072750 :                      particles(iforce_eval)%list%els(iparticle)%f
    1255              :                END DO
    1256              :             END IF
    1257              :          END IF
    1258      7023264 :          CALL force_env%para_env%sum(global_forces(iforce_eval)%forces)
    1259              :          !Transfer only the relevant part of the virial..
    1260         1152 :          CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_total)
    1261         1152 :          CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_kinetic)
    1262         1152 :          CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_virial)
    1263         1152 :          CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_xc)
    1264         1152 :          CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_fock_4c)
    1265         1152 :          CALL force_env%para_env%sum(virials(iforce_eval)%virial%pv_constraint)
    1266              :          !Transfer results
    1267         1152 :          source = 0
    1268         1152 :          IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) THEN
    1269          652 :             IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) &
    1270          576 :                source = force_env%para_env%mepos
    1271              :          END IF
    1272         1152 :          CALL force_env%para_env%sum(source)
    1273         1682 :          CALL cp_results_mp_bcast(results(iforce_eval)%results, source, force_env%para_env)
    1274              :       END DO
    1275              : 
    1276         2834 :       force_env%mixed_env%energies = energies
    1277              :       ! Start combining the different sub_force_env
    1278              :       CALL get_mixed_env(mixed_env=force_env%mixed_env, &
    1279          530 :                          mixed_energy=mixed_energy)
    1280              : 
    1281              :       !NB: do this for all MIXING_TYPE values, since some need it (e.g. linear mixing
    1282              :       !NB if the first system has fewer atoms than the second)
    1283       440700 :       DO iparticle = 1, SIZE(particles_mix%els)
    1284      1761210 :          particles_mix%els(iparticle)%f(:) = 0.0_dp
    1285              :       END DO
    1286              : 
    1287          530 :       CALL section_vals_val_get(mixed_section, "MIXING_TYPE", i_val=mixing_type)
    1288           42 :       SELECT CASE (mixing_type)
    1289              :       CASE (mix_linear_combination)
    1290              :          ! Support offered only 2 force_eval
    1291           42 :          CPASSERT(nforce_eval == 2)
    1292           42 :          CALL section_vals_val_get(mixed_section, "LINEAR%LAMBDA", r_val=lambda)
    1293           42 :          mixed_energy%pot = lambda*energies(1) + (1.0_dp - lambda)*energies(2)
    1294              :          ! General Mapping of forces...
    1295              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1296           42 :                                lambda, 1, nforce_eval, map_index, mapping_section, .TRUE.)
    1297              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1298           42 :                                (1.0_dp - lambda), 2, nforce_eval, map_index, mapping_section, .FALSE.)
    1299              :       CASE (mix_minimum)
    1300              :          ! Support offered only 2 force_eval
    1301            0 :          CPASSERT(nforce_eval == 2)
    1302            0 :          IF (energies(1) < energies(2)) THEN
    1303            0 :             mixed_energy%pot = energies(1)
    1304              :             CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1305            0 :                                   1.0_dp, 1, nforce_eval, map_index, mapping_section, .TRUE.)
    1306              :          ELSE
    1307            0 :             mixed_energy%pot = energies(2)
    1308              :             CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1309            0 :                                   1.0_dp, 2, nforce_eval, map_index, mapping_section, .TRUE.)
    1310              :          END IF
    1311              :       CASE (mix_coupled)
    1312              :          ! Support offered only 2 force_eval
    1313           12 :          CPASSERT(nforce_eval == 2)
    1314              :          CALL section_vals_val_get(mixed_section, "COUPLING%COUPLING_PARAMETER", &
    1315           12 :                                    r_val=coupling_parameter)
    1316           12 :          sd = SQRT((energies(1) - energies(2))**2 + 4.0_dp*coupling_parameter**2)
    1317           12 :          der_1 = (1.0_dp - (1.0_dp/(2.0_dp*sd))*2.0_dp*(energies(1) - energies(2)))/2.0_dp
    1318           12 :          der_2 = (1.0_dp + (1.0_dp/(2.0_dp*sd))*2.0_dp*(energies(1) - energies(2)))/2.0_dp
    1319           12 :          mixed_energy%pot = (energies(1) + energies(2) - sd)/2.0_dp
    1320              :          ! General Mapping of forces...
    1321              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1322           12 :                                der_1, 1, nforce_eval, map_index, mapping_section, .TRUE.)
    1323              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1324           12 :                                der_2, 2, nforce_eval, map_index, mapping_section, .FALSE.)
    1325              :       CASE (mix_restrained)
    1326              :          ! Support offered only 2 force_eval
    1327           12 :          CPASSERT(nforce_eval == 2)
    1328              :          CALL section_vals_val_get(mixed_section, "RESTRAINT%RESTRAINT_TARGET", &
    1329           12 :                                    r_val=restraint_target)
    1330              :          CALL section_vals_val_get(mixed_section, "RESTRAINT%RESTRAINT_STRENGTH", &
    1331           12 :                                    r_val=restraint_strength)
    1332           12 :          mixed_energy%pot = energies(1) + restraint_strength*(energies(1) - energies(2) - restraint_target)**2
    1333           12 :          der_2 = -2.0_dp*restraint_strength*(energies(1) - energies(2) - restraint_target)
    1334           12 :          der_1 = 1.0_dp - der_2
    1335              :          ! General Mapping of forces...
    1336              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1337           12 :                                der_1, 1, nforce_eval, map_index, mapping_section, .TRUE.)
    1338              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1339           12 :                                der_2, 2, nforce_eval, map_index, mapping_section, .FALSE.)
    1340              :       CASE (mix_generic)
    1341              :          ! Support any number of force_eval sections
    1342          364 :          gen_section => section_vals_get_subs_vals(mixed_section, "GENERIC")
    1343              :          CALL get_generic_info(gen_section, "MIXING_FUNCTION", coupling_function, force_env%mixed_env%par, &
    1344          364 :                                force_env%mixed_env%val, energies)
    1345          364 :          CALL initf(1)
    1346          364 :          CALL parsef(1, TRIM(coupling_function), force_env%mixed_env%par)
    1347              :          ! Now the hardest part.. map energy with corresponding force_eval
    1348          364 :          mixed_energy%pot = evalf(1, force_env%mixed_env%val)
    1349          364 :          CPASSERT(EvalErrType <= 0)
    1350          364 :          CALL zero_virial(virial_mix, reset=.FALSE.)
    1351          364 :          CALL cp_results_erase(results_mix)
    1352         1160 :          DO iforce_eval = 1, nforce_eval
    1353          796 :             CALL section_vals_val_get(gen_section, "DX", r_val=dx)
    1354          796 :             CALL section_vals_val_get(gen_section, "ERROR_LIMIT", r_val=lerr)
    1355          796 :             dedf = evalfd(1, iforce_eval, force_env%mixed_env%val, dx, err)
    1356          796 :             IF (ABS(err) > lerr) THEN
    1357            0 :                WRITE (this_error, "(A,G12.6,A)") "(", err, ")"
    1358            0 :                WRITE (def_error, "(A,G12.6,A)") "(", lerr, ")"
    1359            0 :                CALL compress(this_error, .TRUE.)
    1360            0 :                CALL compress(def_error, .TRUE.)
    1361              :                CALL cp_warn(__LOCATION__, &
    1362              :                             'ASSERTION (cond) failed at line '//cp_to_string(__LINE__)// &
    1363              :                             ' Error '//TRIM(this_error)//' in computing numerical derivatives larger then'// &
    1364            0 :                             TRIM(def_error)//' .')
    1365              :             END IF
    1366              :             ! General Mapping of forces...
    1367              :             CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1368          796 :                                   dedf, iforce_eval, nforce_eval, map_index, mapping_section, .FALSE.)
    1369         1956 :             force_env%mixed_env%val(iforce_eval) = energies(iforce_eval)
    1370              :          END DO
    1371              :          ! Let's store the needed information..
    1372          364 :          force_env%mixed_env%dx = dx
    1373          364 :          force_env%mixed_env%lerr = lerr
    1374          364 :          force_env%mixed_env%coupling_function = TRIM(coupling_function)
    1375          364 :          CALL finalizef()
    1376              :       CASE (mix_cdft)
    1377              :          ! Supports any number of force_evals for calculation of CDFT properties, but forces only from two
    1378          100 :          CALL section_vals_val_get(mixed_section, "MIXED_CDFT%LAMBDA", r_val=lambda)
    1379              :          ! Get the states which determine the forces
    1380          100 :          CALL section_vals_val_get(mixed_section, "MIXED_CDFT%FORCE_STATES", i_vals=itmplist)
    1381          100 :          IF (SIZE(itmplist) /= 2) &
    1382              :             CALL cp_abort(__LOCATION__, &
    1383            0 :                           "Keyword FORCE_STATES takes exactly two input values.")
    1384          300 :          IF (ANY(itmplist < 0)) &
    1385            0 :             CPABORT("Invalid force_eval index.")
    1386          300 :          istate = itmplist
    1387          100 :          IF (istate(1) > nforce_eval .OR. istate(2) > nforce_eval) &
    1388            0 :             CPABORT("Invalid force_eval index.")
    1389          100 :          mixed_energy%pot = lambda*energies(istate(1)) + (1.0_dp - lambda)*energies(istate(2))
    1390              :          ! General Mapping of forces...
    1391              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1392          100 :                                lambda, istate(1), nforce_eval, map_index, mapping_section, .TRUE.)
    1393              :          CALL mixed_map_forces(particles_mix, virial_mix, results_mix, global_forces, virials, results, &
    1394          100 :                                (1.0_dp - lambda), istate(2), nforce_eval, map_index, mapping_section, .FALSE.)
    1395              :       CASE DEFAULT
    1396          596 :          CPABORT("Unknown mixing type for mixed_energy_forces")
    1397              :       END SELECT
    1398              :       !Simply deallocate and loose the pointer references..
    1399         1682 :       DO iforce_eval = 1, nforce_eval
    1400         1152 :          DEALLOCATE (global_forces(iforce_eval)%forces)
    1401         1152 :          IF (ASSOCIATED(virials(iforce_eval)%virial)) DEALLOCATE (virials(iforce_eval)%virial)
    1402         1682 :          CALL cp_result_release(results(iforce_eval)%results)
    1403              :       END DO
    1404          530 :       DEALLOCATE (global_forces)
    1405          530 :       DEALLOCATE (subsystems)
    1406          530 :       DEALLOCATE (particles)
    1407          530 :       DEALLOCATE (energies)
    1408          530 :       DEALLOCATE (glob_natoms)
    1409          530 :       DEALLOCATE (virials)
    1410          530 :       DEALLOCATE (results)
    1411              :       ! Print Section
    1412              :       unit_nr = cp_print_key_unit_nr(logger, mixed_section, "PRINT%DIPOLE", &
    1413          530 :                                      extension=".data", middle_name="MIXED_DIPOLE", log_filename=.FALSE.)
    1414          530 :       IF (unit_nr > 0) THEN
    1415          108 :          description = '[DIPOLE]'
    1416          108 :          dip_exists = test_for_result(results=results_mix, description=description)
    1417          108 :          IF (dip_exists) THEN
    1418           66 :             CALL get_results(results=results_mix, description=description, values=dip_mix)
    1419           66 :             WRITE (unit_nr, '(/,1X,A,T48,3F21.16)') "MIXED ENV| DIPOLE  ( A.U.)|", dip_mix
    1420          264 :             WRITE (unit_nr, '(  1X,A,T48,3F21.16)') "MIXED ENV| DIPOLE  (Debye)|", dip_mix*debye
    1421              :          ELSE
    1422           42 :             WRITE (unit_nr, *) "NO FORCE_EVAL section calculated the dipole"
    1423              :          END IF
    1424              :       END IF
    1425          530 :       CALL cp_print_key_finished_output(unit_nr, logger, mixed_section, "PRINT%DIPOLE")
    1426         1060 :    END SUBROUTINE mixed_energy_forces
    1427              : 
    1428              : ! **************************************************************************************************
    1429              : !> \brief Driver routine for mixed CDFT energy and force calculations
    1430              : !> \param force_env the force_env that holds the mixed_env
    1431              : !> \param calculate_forces if forces should be calculated
    1432              : !> \param particles system particles
    1433              : !> \param energies the energies of the CDFT states
    1434              : !> \param glob_natoms the total number of particles
    1435              : !> \param virials the virials stored in subsys
    1436              : !> \param results results stored in subsys
    1437              : !> \par History
    1438              : !>       01.17  created [Nico Holmberg]
    1439              : !> \author Nico Holmberg
    1440              : ! **************************************************************************************************
    1441          100 :    SUBROUTINE mixed_cdft_energy_forces(force_env, calculate_forces, particles, energies, &
    1442              :                                        glob_natoms, virials, results)
    1443              :       TYPE(force_env_type), POINTER                      :: force_env
    1444              :       LOGICAL, INTENT(IN)                                :: calculate_forces
    1445              :       TYPE(particle_list_p_type), DIMENSION(:), POINTER  :: particles
    1446              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energies
    1447              :       INTEGER, DIMENSION(:), POINTER                     :: glob_natoms
    1448              :       TYPE(virial_p_type), DIMENSION(:), POINTER         :: virials
    1449              :       TYPE(cp_result_p_type), DIMENSION(:), POINTER      :: results
    1450              : 
    1451              :       INTEGER                                            :: iforce_eval, iparticle, jparticle, &
    1452              :                                                             my_group, natom, nforce_eval
    1453          100 :       INTEGER, DIMENSION(:), POINTER                     :: map_index
    1454              :       REAL(KIND=dp)                                      :: energy
    1455              :       TYPE(cell_type), POINTER                           :: cell_mix
    1456              :       TYPE(cp_logger_type), POINTER                      :: logger, my_logger
    1457              :       TYPE(cp_result_type), POINTER                      :: loc_results, results_mix
    1458          100 :       TYPE(cp_subsys_p_type), DIMENSION(:), POINTER      :: subsystems
    1459              :       TYPE(cp_subsys_type), POINTER                      :: subsys_mix
    1460              :       TYPE(particle_list_type), POINTER                  :: particles_mix
    1461              :       TYPE(section_vals_type), POINTER                   :: force_env_section, mapping_section, &
    1462              :                                                             mixed_section, root_section
    1463              :       TYPE(virial_type), POINTER                         :: loc_virial, virial_mix
    1464              : 
    1465          200 :       logger => cp_get_default_logger()
    1466          100 :       CPASSERT(ASSOCIATED(force_env))
    1467              :       ! Get infos about the mixed subsys
    1468              :       CALL force_env_get(force_env=force_env, &
    1469              :                          subsys=subsys_mix, &
    1470              :                          force_env_section=force_env_section, &
    1471              :                          root_section=root_section, &
    1472          100 :                          cell=cell_mix)
    1473              :       CALL cp_subsys_get(subsys=subsys_mix, &
    1474              :                          particles=particles_mix, &
    1475              :                          virial=virial_mix, &
    1476          100 :                          results=results_mix)
    1477          100 :       NULLIFY (map_index)
    1478          100 :       nforce_eval = SIZE(force_env%sub_force_env)
    1479          100 :       mixed_section => section_vals_get_subs_vals(force_env_section, "MIXED")
    1480          100 :       mapping_section => section_vals_get_subs_vals(mixed_section, "MAPPING")
    1481          524 :       ALLOCATE (subsystems(nforce_eval))
    1482          324 :       DO iforce_eval = 1, nforce_eval
    1483          224 :          NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
    1484          224 :          NULLIFY (results(iforce_eval)%results, virials(iforce_eval)%virial)
    1485        51296 :          ALLOCATE (virials(iforce_eval)%virial)
    1486          224 :          CALL cp_result_create(results(iforce_eval)%results)
    1487          224 :          IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) CYCLE
    1488              :          ! Get all available subsys
    1489              :          CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
    1490          186 :                             subsys=subsystems(iforce_eval)%subsys)
    1491              : 
    1492              :          ! all force_env share the same cell
    1493          186 :          CALL cp_subsys_set(subsystems(iforce_eval)%subsys, cell=cell_mix)
    1494              : 
    1495              :          ! Get available particles
    1496              :          CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
    1497          186 :                             particles=particles(iforce_eval)%list)
    1498              : 
    1499              :          ! Get Mapping index array
    1500          186 :          natom = SIZE(particles(iforce_eval)%list%els)
    1501              :          ! Serial mode need to deallocate first
    1502          186 :          IF (ASSOCIATED(map_index)) &
    1503           86 :             DEALLOCATE (map_index)
    1504              :          CALL get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, &
    1505          186 :                                    map_index)
    1506              : 
    1507              :          ! Mapping particles from iforce_eval environment to the mixed env
    1508          668 :          DO iparticle = 1, natom
    1509          482 :             jparticle = map_index(iparticle)
    1510         3560 :             particles(iforce_eval)%list%els(iparticle)%r = particles_mix%els(jparticle)%r
    1511              :          END DO
    1512              :          ! Mixed CDFT + QMMM: Need to translate now
    1513          186 :          IF (force_env%mixed_env%do_mixed_qmmm_cdft) &
    1514          124 :             CALL apply_qmmm_translate(force_env%sub_force_env(iforce_eval)%force_env%qmmm_env)
    1515              :       END DO
    1516              :       ! For mixed CDFT calculations parallelized over CDFT states
    1517              :       ! build weight and gradient on all processors before splitting into groups and
    1518              :       ! starting energy calculation
    1519          100 :       CALL mixed_cdft_build_weight(force_env, calculate_forces)
    1520          324 :       DO iforce_eval = 1, nforce_eval
    1521          224 :          IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) CYCLE
    1522              :          ! From this point on the error is the sub_error
    1523          186 :          IF (force_env%mixed_env%cdft_control%run_type == mixed_cdft_serial .AND. iforce_eval >= 2) THEN
    1524           86 :             my_logger => force_env%mixed_env%cdft_control%sub_logger(iforce_eval - 1)%p
    1525              :          ELSE
    1526          100 :             my_group = force_env%mixed_env%group_distribution(force_env%para_env%mepos)
    1527          100 :             my_logger => force_env%mixed_env%sub_logger(my_group + 1)%p
    1528              :          END IF
    1529              :          ! Copy iterations info (they are updated only in the main mixed_env)
    1530          186 :          CALL cp_iteration_info_copy_iter(logger%iter_info, my_logger%iter_info)
    1531          186 :          CALL cp_add_default_logger(my_logger)
    1532              :          ! Serial CDFT calculation: transfer weight/gradient
    1533          186 :          CALL mixed_cdft_build_weight(force_env, calculate_forces, iforce_eval)
    1534              :          ! Calculate energy and forces for each sub_force_env
    1535              :          CALL force_env_calc_energy_force(force_env%sub_force_env(iforce_eval)%force_env, &
    1536              :                                           calc_force=calculate_forces, &
    1537          186 :                                           skip_external_control=.TRUE.)
    1538              :          ! Only the rank 0 process collect info for each computation
    1539          186 :          IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
    1540              :             CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, &
    1541          112 :                                potential_energy=energy)
    1542              :             CALL cp_subsys_get(subsystems(iforce_eval)%subsys, &
    1543          112 :                                virial=loc_virial, results=loc_results)
    1544          112 :             energies(iforce_eval) = energy
    1545          112 :             glob_natoms(iforce_eval) = natom
    1546          112 :             virials(iforce_eval)%virial = loc_virial
    1547          112 :             CALL cp_result_copy(loc_results, results(iforce_eval)%results)
    1548              :          END IF
    1549              :          ! Deallocate map_index array
    1550          186 :          IF (ASSOCIATED(map_index)) THEN
    1551          100 :             DEALLOCATE (map_index)
    1552              :          END IF
    1553          324 :          CALL cp_rm_default_logger()
    1554              :       END DO
    1555          100 :       DEALLOCATE (subsystems)
    1556              : 
    1557          100 :    END SUBROUTINE mixed_cdft_energy_forces
    1558              : 
    1559              : ! **************************************************************************************************
    1560              : !> \brief Perform additional tasks for mixed CDFT calculations after solving the electronic structure
    1561              : !>        of both CDFT states
    1562              : !> \param force_env the force_env that holds the CDFT states
    1563              : !> \par History
    1564              : !>       01.17  created [Nico Holmberg]
    1565              : !> \author Nico Holmberg
    1566              : ! **************************************************************************************************
    1567          530 :    SUBROUTINE mixed_cdft_post_energy_forces(force_env)
    1568              :       TYPE(force_env_type), POINTER                      :: force_env
    1569              : 
    1570              :       INTEGER                                            :: iforce_eval, nforce_eval, nvar
    1571              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1572              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1573              : 
    1574          530 :       CPASSERT(ASSOCIATED(force_env))
    1575          530 :       NULLIFY (qs_env, dft_control)
    1576          530 :       IF (force_env%mixed_env%do_mixed_cdft) THEN
    1577          100 :          nforce_eval = SIZE(force_env%sub_force_env)
    1578          100 :          nvar = force_env%mixed_env%cdft_control%nconstraint
    1579              :          ! Transfer cdft strengths for writing restart
    1580          100 :          IF (.NOT. ASSOCIATED(force_env%mixed_env%strength)) &
    1581          312 :             ALLOCATE (force_env%mixed_env%strength(nforce_eval, nvar))
    1582          430 :          force_env%mixed_env%strength = 0.0_dp
    1583          324 :          DO iforce_eval = 1, nforce_eval
    1584          224 :             IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) CYCLE
    1585          186 :             IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
    1586           24 :                qs_env => force_env%sub_force_env(iforce_eval)%force_env%qmmm_env%qs_env
    1587              :             ELSE
    1588          162 :                CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, qs_env=qs_env)
    1589              :             END IF
    1590          186 :             CALL get_qs_env(qs_env, dft_control=dft_control)
    1591          186 :             IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) &
    1592          478 :                force_env%mixed_env%strength(iforce_eval, :) = dft_control%qs_control%cdft_control%strength(:)
    1593              :          END DO
    1594          760 :          CALL force_env%para_env%sum(force_env%mixed_env%strength)
    1595              :          ! Mixed CDFT: calculate ET coupling
    1596          100 :          IF (force_env%mixed_env%do_mixed_et) THEN
    1597          100 :             IF (MODULO(force_env%mixed_env%cdft_control%sim_step, force_env%mixed_env%et_freq) == 0) &
    1598          100 :                CALL mixed_cdft_calculate_coupling(force_env)
    1599              :          END IF
    1600              :       END IF
    1601              : 
    1602          530 :    END SUBROUTINE mixed_cdft_post_energy_forces
    1603              : 
    1604              : ! **************************************************************************************************
    1605              : !> \brief Computes the total energy for an embedded calculation
    1606              : !> \param force_env ...
    1607              : !> \author Vladimir Rybkin
    1608              : ! **************************************************************************************************
    1609           24 :    SUBROUTINE embed_energy(force_env)
    1610              : 
    1611              :       TYPE(force_env_type), POINTER                      :: force_env
    1612              : 
    1613              :       INTEGER                                            :: iforce_eval, iparticle, jparticle, &
    1614              :                                                             my_group, natom, nforce_eval
    1615           24 :       INTEGER, DIMENSION(:), POINTER                     :: glob_natoms, map_index
    1616              :       LOGICAL                                            :: converged_embed
    1617              :       REAL(KIND=dp)                                      :: energy
    1618              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energies
    1619              :       TYPE(cell_type), POINTER                           :: cell_embed
    1620              :       TYPE(cp_logger_type), POINTER                      :: logger, my_logger
    1621           24 :       TYPE(cp_result_p_type), DIMENSION(:), POINTER      :: results
    1622              :       TYPE(cp_result_type), POINTER                      :: loc_results, results_embed
    1623           24 :       TYPE(cp_subsys_p_type), DIMENSION(:), POINTER      :: subsystems
    1624              :       TYPE(cp_subsys_type), POINTER                      :: subsys_embed
    1625              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1626           24 :       TYPE(particle_list_p_type), DIMENSION(:), POINTER  :: particles
    1627              :       TYPE(particle_list_type), POINTER                  :: particles_embed
    1628              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1629              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1630              :       TYPE(pw_r3d_rs_type), POINTER                      :: embed_pot, spin_embed_pot
    1631              :       TYPE(section_vals_type), POINTER                   :: embed_section, force_env_section, &
    1632              :                                                             mapping_section, root_section
    1633              : 
    1634           48 :       logger => cp_get_default_logger()
    1635           24 :       CPASSERT(ASSOCIATED(force_env))
    1636              :       ! Get infos about the embedding subsys
    1637              :       CALL force_env_get(force_env=force_env, &
    1638              :                          subsys=subsys_embed, &
    1639              :                          force_env_section=force_env_section, &
    1640              :                          root_section=root_section, &
    1641           24 :                          cell=cell_embed)
    1642              :       CALL cp_subsys_get(subsys=subsys_embed, &
    1643              :                          particles=particles_embed, &
    1644           24 :                          results=results_embed)
    1645           24 :       NULLIFY (map_index, glob_natoms)
    1646              : 
    1647           24 :       nforce_eval = SIZE(force_env%sub_force_env)
    1648           24 :       embed_section => section_vals_get_subs_vals(force_env_section, "EMBED")
    1649           24 :       mapping_section => section_vals_get_subs_vals(embed_section, "MAPPING")
    1650              :       ! Global Info
    1651          168 :       ALLOCATE (subsystems(nforce_eval))
    1652          144 :       ALLOCATE (particles(nforce_eval))
    1653              :       ! Local Info to sync
    1654           48 :       ALLOCATE (energies(nforce_eval))
    1655           72 :       ALLOCATE (glob_natoms(nforce_eval))
    1656          144 :       ALLOCATE (results(nforce_eval))
    1657          120 :       energies = 0.0_dp
    1658          120 :       glob_natoms = 0
    1659              : 
    1660          120 :       DO iforce_eval = 1, nforce_eval
    1661           96 :          NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
    1662           96 :          NULLIFY (results(iforce_eval)%results)
    1663           96 :          CALL cp_result_create(results(iforce_eval)%results)
    1664           96 :          IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) CYCLE
    1665              :          ! From this point on the error is the sub_error
    1666           96 :          my_group = force_env%embed_env%group_distribution(force_env%para_env%mepos)
    1667           96 :          my_logger => force_env%embed_env%sub_logger(my_group + 1)%p
    1668              :          ! Copy iterations info (they are updated only in the main embed_env)
    1669           96 :          CALL cp_iteration_info_copy_iter(logger%iter_info, my_logger%iter_info)
    1670           96 :          CALL cp_add_default_logger(my_logger)
    1671              : 
    1672              :          ! Get all available subsys
    1673              :          CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
    1674           96 :                             subsys=subsystems(iforce_eval)%subsys)
    1675              : 
    1676              :          ! Check if we import density from previous force calculations
    1677              :          ! Only for QUICKSTEP
    1678           96 :          IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env%qs_env)) THEN
    1679           96 :             NULLIFY (dft_control)
    1680           96 :             CALL get_qs_env(force_env%sub_force_env(iforce_eval)%force_env%qs_env, dft_control=dft_control)
    1681           96 :             IF (dft_control%qs_control%ref_embed_subsys) THEN
    1682           24 :                IF (iforce_eval == 2) CPABORT("Density importing force_eval can't be the first.")
    1683              :             END IF
    1684              :          END IF
    1685              : 
    1686              :          ! all force_env share the same cell
    1687           96 :          CALL cp_subsys_set(subsystems(iforce_eval)%subsys, cell=cell_embed)
    1688              : 
    1689              :          ! Get available particles
    1690              :          CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
    1691           96 :                             particles=particles(iforce_eval)%list)
    1692              : 
    1693              :          ! Get Mapping index array
    1694           96 :          natom = SIZE(particles(iforce_eval)%list%els)
    1695              : 
    1696              :          CALL get_subsys_map_index(mapping_section, natom, iforce_eval, nforce_eval, &
    1697           96 :                                    map_index, .TRUE.)
    1698              : 
    1699              :          ! Mapping particles from iforce_eval environment to the embed env
    1700          310 :          DO iparticle = 1, natom
    1701          214 :             jparticle = map_index(iparticle)
    1702         1594 :             particles(iforce_eval)%list%els(iparticle)%r = particles_embed%els(jparticle)%r
    1703              :          END DO
    1704              : 
    1705              :          ! Calculate energy and forces for each sub_force_env
    1706              :          CALL force_env_calc_energy_force(force_env%sub_force_env(iforce_eval)%force_env, &
    1707              :                                           calc_force=.FALSE., &
    1708           96 :                                           skip_external_control=.TRUE.)
    1709              : 
    1710              :          ! Call DFT embedding
    1711           96 :          IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env%qs_env)) THEN
    1712           96 :             NULLIFY (dft_control)
    1713           96 :             CALL get_qs_env(force_env%sub_force_env(iforce_eval)%force_env%qs_env, dft_control=dft_control)
    1714           96 :             IF (dft_control%qs_control%ref_embed_subsys) THEN
    1715              :                ! Now we can optimize the embedding potential
    1716           24 :                CALL dft_embedding(force_env, iforce_eval, energies, converged_embed)
    1717           24 :                IF (.NOT. converged_embed) CPABORT("Embedding potential optimization not converged.")
    1718              :             END IF
    1719              :             ! Deallocate embedding potential on the high-level subsystem
    1720           96 :             IF (dft_control%qs_control%high_level_embed_subsys) THEN
    1721              :                CALL get_qs_env(qs_env=force_env%sub_force_env(iforce_eval)%force_env%qs_env, &
    1722           24 :                                embed_pot=embed_pot, spin_embed_pot=spin_embed_pot, pw_env=pw_env)
    1723           24 :                CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
    1724           24 :                CALL auxbas_pw_pool%give_back_pw(embed_pot)
    1725           24 :                IF (ASSOCIATED(embed_pot)) THEN
    1726           24 :                   CALL embed_pot%release()
    1727           24 :                   DEALLOCATE (embed_pot)
    1728              :                END IF
    1729           24 :                IF (ASSOCIATED(spin_embed_pot)) THEN
    1730           12 :                   CALL auxbas_pw_pool%give_back_pw(spin_embed_pot)
    1731           12 :                   CALL spin_embed_pot%release()
    1732           12 :                   DEALLOCATE (spin_embed_pot)
    1733              :                END IF
    1734              :             END IF
    1735              :          END IF
    1736              : 
    1737              :          ! Only the rank 0 process collect info for each computation
    1738           96 :          IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
    1739              :             CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, &
    1740           48 :                                potential_energy=energy)
    1741              :             CALL cp_subsys_get(subsystems(iforce_eval)%subsys, &
    1742           48 :                                results=loc_results)
    1743           48 :             energies(iforce_eval) = energy
    1744           48 :             glob_natoms(iforce_eval) = natom
    1745           48 :             CALL cp_result_copy(loc_results, results(iforce_eval)%results)
    1746              :          END IF
    1747              :          ! Deallocate map_index array
    1748           96 :          IF (ASSOCIATED(map_index)) THEN
    1749           96 :             DEALLOCATE (map_index)
    1750              :          END IF
    1751          120 :          CALL cp_rm_default_logger()
    1752              :       END DO
    1753              : 
    1754              :       ! Handling Parallel execution
    1755           24 :       CALL force_env%para_env%sync()
    1756              :       ! Let's transfer energy, natom
    1757          216 :       CALL force_env%para_env%sum(energies)
    1758          216 :       CALL force_env%para_env%sum(glob_natoms)
    1759              : 
    1760          216 :       force_env%embed_env%energies = energies
    1761              : 
    1762              :       !NB if the first system has fewer atoms than the second)
    1763          112 :       DO iparticle = 1, SIZE(particles_embed%els)
    1764          376 :          particles_embed%els(iparticle)%f(:) = 0.0_dp
    1765              :       END DO
    1766              : 
    1767              :       ! ONIOM type of mixing in embedding: E = E_total + E_cluster_high - E_cluster
    1768           24 :       force_env%embed_env%pot_energy = energies(3) + energies(4) - energies(2)
    1769              : 
    1770              :       !Simply deallocate and loose the pointer references..
    1771          120 :       DO iforce_eval = 1, nforce_eval
    1772          120 :          CALL cp_result_release(results(iforce_eval)%results)
    1773              :       END DO
    1774           24 :       DEALLOCATE (subsystems)
    1775           24 :       DEALLOCATE (particles)
    1776           24 :       DEALLOCATE (energies)
    1777           24 :       DEALLOCATE (glob_natoms)
    1778           24 :       DEALLOCATE (results)
    1779              : 
    1780           24 :    END SUBROUTINE embed_energy
    1781              : 
    1782              : ! **************************************************************************************************
    1783              : !> \brief ...
    1784              : !> \param force_env ...
    1785              : !> \param ref_subsys_number ...
    1786              : !> \param energies ...
    1787              : !> \param converged_embed ...
    1788              : ! **************************************************************************************************
    1789           48 :    SUBROUTINE dft_embedding(force_env, ref_subsys_number, energies, converged_embed)
    1790              :       TYPE(force_env_type), POINTER                      :: force_env
    1791              :       INTEGER                                            :: ref_subsys_number
    1792              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energies
    1793              :       LOGICAL                                            :: converged_embed
    1794              : 
    1795              :       INTEGER                                            :: embed_method
    1796              :       TYPE(section_vals_type), POINTER                   :: embed_section, force_env_section
    1797              : 
    1798              :       ! Find out which embedding scheme is used
    1799              :       CALL force_env_get(force_env=force_env, &
    1800           24 :                          force_env_section=force_env_section)
    1801           24 :       embed_section => section_vals_get_subs_vals(force_env_section, "EMBED")
    1802              : 
    1803           24 :       CALL section_vals_val_get(embed_section, "EMBED_METHOD", i_val=embed_method)
    1804           24 :       SELECT CASE (embed_method)
    1805              :       CASE (dfet)
    1806              :          ! Density functional embedding
    1807           24 :          CALL dfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
    1808              :       CASE (dmfet)
    1809              :          ! Density matrix embedding theory
    1810           24 :          CALL dmfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
    1811              :       END SELECT
    1812              : 
    1813           24 :    END SUBROUTINE dft_embedding
    1814              : ! **************************************************************************************************
    1815              : !> \brief ... Main driver for DFT embedding
    1816              : !> \param force_env ...
    1817              : !> \param ref_subsys_number ...
    1818              : !> \param energies ...
    1819              : !> \param converged_embed ...
    1820              : !> \author Vladimir Rybkin
    1821              : ! **************************************************************************************************
    1822           24 :    SUBROUTINE dfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
    1823              :       TYPE(force_env_type), POINTER                      :: force_env
    1824              :       INTEGER                                            :: ref_subsys_number
    1825              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energies
    1826              :       LOGICAL                                            :: converged_embed
    1827              : 
    1828              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'dfet_embedding'
    1829              : 
    1830              :       INTEGER                                            :: cluster_subsys_num, handle, &
    1831              :                                                             i_force_eval, i_iter, i_spin, &
    1832              :                                                             nforce_eval, nspins, nspins_subsys, &
    1833              :                                                             output_unit
    1834              :       REAL(KIND=dp)                                      :: cluster_energy
    1835           24 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rhs
    1836              :       TYPE(cp_logger_type), POINTER                      :: logger
    1837              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1838           24 :       TYPE(opt_embed_pot_type)                           :: opt_embed
    1839              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1840              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1841              :       TYPE(pw_r3d_rs_type)                               :: diff_rho_r, diff_rho_spin
    1842           24 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r_ref, rho_r_subsys
    1843              :       TYPE(pw_r3d_rs_type), POINTER                      :: embed_pot, embed_pot_subsys, &
    1844              :                                                             spin_embed_pot, spin_embed_pot_subsys
    1845              :       TYPE(qs_energy_type), POINTER                      :: energy
    1846              :       TYPE(qs_rho_type), POINTER                         :: rho, subsys_rho
    1847              :       TYPE(section_vals_type), POINTER                   :: dft_section, embed_section, &
    1848              :                                                             force_env_section, input, &
    1849              :                                                             mapping_section, opt_embed_section
    1850              : 
    1851           24 :       CALL timeset(routineN, handle)
    1852              : 
    1853           24 :       CALL cite_reference(Huang2011)
    1854           24 :       CALL cite_reference(Heaton_Burgess2007)
    1855              : 
    1856           24 :       CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
    1857              : 
    1858              :       ! Reveal input file
    1859           24 :       NULLIFY (logger)
    1860           24 :       logger => cp_get_default_logger()
    1861              :       output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
    1862           24 :                                          extension=".Log")
    1863              : 
    1864           24 :       NULLIFY (dft_section, input, opt_embed_section)
    1865           24 :       NULLIFY (energy, dft_control)
    1866              : 
    1867              :       CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    1868              :                       pw_env=pw_env, dft_control=dft_control, rho=rho, energy=energy, &
    1869           24 :                       input=input)
    1870           24 :       nspins = dft_control%nspins
    1871              : 
    1872           24 :       dft_section => section_vals_get_subs_vals(input, "DFT")
    1873              :       opt_embed_section => section_vals_get_subs_vals(input, &
    1874           24 :                                                       "DFT%QS%OPT_EMBED")
    1875              :       ! Rho_r is the reference
    1876           24 :       CALL qs_rho_get(rho_struct=rho, rho_r=rho_r_ref)
    1877              : 
    1878              :       ! We need to understand how to treat spins states
    1879              :       CALL understand_spin_states(force_env, ref_subsys_number, opt_embed%change_spin, opt_embed%open_shell_embed, &
    1880           24 :                                   opt_embed%all_nspins)
    1881              : 
    1882              :       ! Prepare everything for the potential maximization
    1883              :       CALL prepare_embed_opt(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, opt_embed, &
    1884           24 :                              opt_embed_section)
    1885              : 
    1886              :       ! Initialize embedding potential
    1887              :       CALL init_embed_pot(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, embed_pot, &
    1888              :                           opt_embed%add_const_pot, opt_embed%Fermi_Amaldi, opt_embed%const_pot, &
    1889              :                           opt_embed%open_shell_embed, spin_embed_pot, &
    1890           24 :                           opt_embed%pot_diff, opt_embed%Coulomb_guess, opt_embed%grid_opt)
    1891              : 
    1892              :       ! Read embedding potential vector from the file
    1893           24 :       IF (opt_embed%read_embed_pot .OR. opt_embed%read_embed_pot_cube) CALL read_embed_pot( &
    1894              :          force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, embed_pot, spin_embed_pot, &
    1895            6 :          opt_embed_section, opt_embed)
    1896              : 
    1897              :       ! Prepare the pw object to store density differences
    1898           24 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
    1899           24 :       CALL auxbas_pw_pool%create_pw(diff_rho_r)
    1900           24 :       CALL pw_zero(diff_rho_r)
    1901           24 :       IF (opt_embed%open_shell_embed) THEN
    1902           12 :          CALL auxbas_pw_pool%create_pw(diff_rho_spin)
    1903           12 :          CALL pw_zero(diff_rho_spin)
    1904              :       END IF
    1905              : 
    1906              :       ! Check the preliminary density differences
    1907           58 :       DO i_spin = 1, nspins
    1908           58 :          CALL pw_axpy(rho_r_ref(i_spin), diff_rho_r, -1.0_dp)
    1909              :       END DO
    1910           24 :       IF (opt_embed%open_shell_embed) THEN ! Spin part
    1911           12 :          IF (nspins == 2) THEN ! Reference systems has an open shell, else the reference diff_rho_spin is zero
    1912           10 :             CALL pw_axpy(rho_r_ref(1), diff_rho_spin, -1.0_dp)
    1913           10 :             CALL pw_axpy(rho_r_ref(2), diff_rho_spin, 1.0_dp)
    1914              :          END IF
    1915              :       END IF
    1916              : 
    1917           72 :       DO i_force_eval = 1, ref_subsys_number - 1
    1918           48 :          NULLIFY (subsys_rho, rho_r_subsys, dft_control)
    1919              :          CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, rho=subsys_rho, energy=energy, &
    1920           48 :                          dft_control=dft_control)
    1921           48 :          nspins_subsys = dft_control%nspins
    1922              :          ! Add subsystem densities
    1923           48 :          CALL qs_rho_get(rho_struct=subsys_rho, rho_r=rho_r_subsys)
    1924          120 :          DO i_spin = 1, nspins_subsys
    1925          120 :             CALL pw_axpy(rho_r_subsys(i_spin), diff_rho_r, allow_noncompatible_grids=.TRUE.)
    1926              :          END DO
    1927           72 :          IF (opt_embed%open_shell_embed) THEN ! Spin part
    1928           24 :             IF (nspins_subsys == 2) THEN ! The subsystem makes contribution if it is spin-polarized
    1929              :                ! We may need to change spin ONLY FOR THE SECOND SUBSYSTEM: that's the internal convention
    1930           24 :                IF ((i_force_eval == 2) .AND. (opt_embed%change_spin)) THEN
    1931            2 :                   CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.TRUE.)
    1932            2 :                   CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.TRUE.)
    1933              :                ELSE
    1934              :                   ! First subsystem (always) and second subsystem (without spin change)
    1935           22 :                   CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.TRUE.)
    1936           22 :                   CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.TRUE.)
    1937              :                END IF
    1938              :             END IF
    1939              :          END IF
    1940              :       END DO
    1941              : 
    1942              :       ! Print density difference
    1943           24 :       CALL print_rho_diff(diff_rho_r, 0, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .FALSE.)
    1944           24 :       IF (opt_embed%open_shell_embed) THEN ! Spin part
    1945           12 :          CALL print_rho_spin_diff(diff_rho_spin, 0, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .FALSE.)
    1946              :       END IF
    1947              : 
    1948              :       ! Construct electrostatic guess if needed
    1949           24 :       IF (opt_embed%Coulomb_guess) THEN
    1950              :          ! Reveal resp charges for total system
    1951            2 :          nforce_eval = SIZE(force_env%sub_force_env)
    1952            2 :          NULLIFY (rhs)
    1953            2 :          CALL get_qs_env(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, rhs=rhs)
    1954              :          ! Get the mapping
    1955              :          CALL force_env_get(force_env=force_env, &
    1956            2 :                             force_env_section=force_env_section)
    1957            2 :          embed_section => section_vals_get_subs_vals(force_env_section, "EMBED")
    1958            2 :          mapping_section => section_vals_get_subs_vals(embed_section, "MAPPING")
    1959              : 
    1960            6 :          DO i_force_eval = 1, ref_subsys_number - 1
    1961            6 :             IF (i_force_eval == 1) THEN
    1962              :                CALL Coulomb_guess(embed_pot, rhs, mapping_section, &
    1963            2 :                                   force_env%sub_force_env(i_force_eval)%force_env%qs_env, nforce_eval, i_force_eval, opt_embed%eta)
    1964              :             ELSE
    1965              :                CALL Coulomb_guess(opt_embed%pot_diff, rhs, mapping_section, &
    1966            2 :                                   force_env%sub_force_env(i_force_eval)%force_env%qs_env, nforce_eval, i_force_eval, opt_embed%eta)
    1967              :             END IF
    1968              :          END DO
    1969            2 :          CALL pw_axpy(opt_embed%pot_diff, embed_pot)
    1970            2 :          IF (.NOT. opt_embed%grid_opt) CALL pw_copy(embed_pot, opt_embed%const_pot)
    1971              : 
    1972              :       END IF
    1973              : 
    1974              :       ! Difference guess
    1975           24 :       IF (opt_embed%diff_guess) THEN
    1976            2 :          CALL pw_copy(diff_rho_r, embed_pot)
    1977            2 :          IF (.NOT. opt_embed%grid_opt) CALL pw_copy(embed_pot, opt_embed%const_pot)
    1978              :          ! Open shell
    1979            2 :          IF (opt_embed%open_shell_embed) CALL pw_copy(diff_rho_spin, spin_embed_pot)
    1980              :       END IF
    1981              : 
    1982              :       ! Calculate subsystems with trial embedding potential
    1983           48 :       DO i_iter = 1, opt_embed%n_iter
    1984           48 :          opt_embed%i_iter = i_iter
    1985              : 
    1986              :          ! Set the density difference as the negative reference one
    1987           48 :          CALL pw_zero(diff_rho_r)
    1988           48 :          CALL get_qs_env(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, dft_control=dft_control)
    1989           48 :          nspins = dft_control%nspins
    1990          116 :          DO i_spin = 1, nspins
    1991          116 :             CALL pw_axpy(rho_r_ref(i_spin), diff_rho_r, -1.0_dp)
    1992              :          END DO
    1993           48 :          IF (opt_embed%open_shell_embed) THEN ! Spin part
    1994           26 :             CALL pw_zero(diff_rho_spin)
    1995           26 :             IF (nspins == 2) THEN ! Reference systems has an open shell, else the reference diff_rho_spin is zero
    1996           20 :                CALL pw_axpy(rho_r_ref(1), diff_rho_spin, -1.0_dp)
    1997           20 :                CALL pw_axpy(rho_r_ref(2), diff_rho_spin, 1.0_dp)
    1998              :             END IF
    1999              :          END IF
    2000              : 
    2001          144 :          DO i_force_eval = 1, ref_subsys_number - 1
    2002           96 :             NULLIFY (dft_control)
    2003           96 :             CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, dft_control=dft_control)
    2004           96 :             nspins_subsys = dft_control%nspins
    2005              : 
    2006           96 :             IF ((i_force_eval == 2) .AND. (opt_embed%change_spin)) THEN
    2007              :                ! Here we change the sign of the spin embedding potential due to spin change:
    2008              :                ! only in spin_embed_subsys
    2009              :                CALL make_subsys_embed_pot(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
    2010              :                                           embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, &
    2011            6 :                                           opt_embed%open_shell_embed, .TRUE.)
    2012              :             ELSE ! Regular case
    2013              :                CALL make_subsys_embed_pot(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
    2014              :                                           embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, &
    2015           90 :                                           opt_embed%open_shell_embed, .FALSE.)
    2016              :             END IF
    2017              : 
    2018              :             ! Switch on external potential in the subsystems
    2019           96 :             dft_control%apply_embed_pot = .TRUE.
    2020              : 
    2021              :             ! Add the embedding potential
    2022           96 :             CALL set_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, embed_pot=embed_pot_subsys)
    2023           96 :             IF ((opt_embed%open_shell_embed) .AND. (nspins_subsys == 2)) THEN ! Spin part
    2024              :                CALL set_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
    2025           52 :                                spin_embed_pot=spin_embed_pot_subsys)
    2026              :             END IF
    2027              : 
    2028              :             ! Get the previous subsystem densities
    2029           96 :             CALL get_prev_density(opt_embed, force_env%sub_force_env(i_force_eval)%force_env, i_force_eval)
    2030              : 
    2031              :             ! Calculate the new density
    2032              :             CALL force_env_calc_energy_force(force_env=force_env%sub_force_env(i_force_eval)%force_env, &
    2033              :                                              calc_force=.FALSE., &
    2034           96 :                                              skip_external_control=.TRUE.)
    2035              : 
    2036           96 :             CALL get_max_subsys_diff(opt_embed, force_env%sub_force_env(i_force_eval)%force_env, i_force_eval)
    2037              : 
    2038              :             ! Extract subsystem density and energy
    2039           96 :             NULLIFY (rho_r_subsys, energy)
    2040              : 
    2041              :             CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, rho=subsys_rho, &
    2042           96 :                             energy=energy)
    2043           96 :             opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) + energy%total
    2044              : 
    2045              :             ! Find out which subsystem is the cluster
    2046           96 :             IF (dft_control%qs_control%cluster_embed_subsys) THEN
    2047           48 :                cluster_subsys_num = i_force_eval
    2048           48 :                cluster_energy = energy%total
    2049              :             END IF
    2050              : 
    2051              :             ! Add subsystem densities
    2052           96 :             CALL qs_rho_get(rho_struct=subsys_rho, rho_r=rho_r_subsys)
    2053          244 :             DO i_spin = 1, nspins_subsys
    2054          244 :                CALL pw_axpy(rho_r_subsys(i_spin), diff_rho_r, allow_noncompatible_grids=.TRUE.)
    2055              :             END DO
    2056           96 :             IF (opt_embed%open_shell_embed) THEN ! Spin part
    2057           52 :                IF (nspins_subsys == 2) THEN ! The subsystem makes contribution if it is spin-polarized
    2058              :                   ! We may need to change spin ONLY FOR THE SECOND SUBSYSTEM: that's the internal convention
    2059           52 :                   IF ((i_force_eval == 2) .AND. (opt_embed%change_spin)) THEN
    2060            6 :                      CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.TRUE.)
    2061            6 :                      CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.TRUE.)
    2062              :                   ELSE
    2063              :                      ! First subsystem (always) and second subsystem (without spin change)
    2064           46 :                      CALL pw_axpy(rho_r_subsys(1), diff_rho_spin, 1.0_dp, allow_noncompatible_grids=.TRUE.)
    2065           46 :                      CALL pw_axpy(rho_r_subsys(2), diff_rho_spin, -1.0_dp, allow_noncompatible_grids=.TRUE.)
    2066              :                   END IF
    2067              :                END IF
    2068              :             END IF
    2069              : 
    2070              :             ! Release embedding potential for subsystem
    2071           96 :             CALL embed_pot_subsys%release()
    2072           96 :             DEALLOCATE (embed_pot_subsys)
    2073          144 :             IF (opt_embed%open_shell_embed) THEN
    2074           52 :                CALL spin_embed_pot_subsys%release()
    2075           52 :                DEALLOCATE (spin_embed_pot_subsys)
    2076              :             END IF
    2077              : 
    2078              :          END DO ! i_force_eval
    2079              : 
    2080              :          ! Print embedding potential for restart
    2081              :          CALL print_embed_restart(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2082              :                                   opt_embed%dimen_aux, opt_embed%embed_pot_coef, embed_pot, i_iter, &
    2083           48 :                                   spin_embed_pot, opt_embed%open_shell_embed, opt_embed%grid_opt, .FALSE.)
    2084              :          CALL print_pot_simple_grid(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2085              :                                     embed_pot, spin_embed_pot, i_iter, opt_embed%open_shell_embed, .FALSE., &
    2086           48 :                                     force_env%sub_force_env(cluster_subsys_num)%force_env%qs_env)
    2087              : 
    2088              :          ! Integrate the potential over density differences and add to w functional; also add regularization contribution
    2089          116 :          DO i_spin = 1, nspins ! Sum over nspins for the reference system, not subsystem!
    2090          116 :             opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) - pw_integral_ab(embed_pot, rho_r_ref(i_spin))
    2091              :          END DO
    2092              :          ! Spin part
    2093           48 :          IF (opt_embed%open_shell_embed) THEN
    2094              :             ! If reference system is not spin-polarized then it does not make a contribution to W functional
    2095           26 :             IF (nspins == 2) THEN
    2096              :                opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) &
    2097              :                                           - pw_integral_ab(spin_embed_pot, rho_r_ref(1)) &
    2098           20 :                                           + pw_integral_ab(spin_embed_pot, rho_r_ref(2))
    2099              :             END IF
    2100              :          END IF
    2101              :          ! Finally, add the regularization term
    2102           48 :          opt_embed%w_func(i_iter) = opt_embed%w_func(i_iter) + opt_embed%reg_term
    2103              : 
    2104              :          ! Print information and check convergence
    2105           48 :          CALL print_emb_opt_info(output_unit, i_iter, opt_embed)
    2106           48 :          CALL conv_check_embed(opt_embed, diff_rho_r, diff_rho_spin, output_unit)
    2107           48 :          IF (opt_embed%converged) EXIT
    2108              : 
    2109              :          ! Update the trust radius and control the step
    2110           24 :          IF ((i_iter > 1) .AND. (.NOT. opt_embed%steep_desc)) CALL step_control(opt_embed)
    2111              : 
    2112              :          ! Print density difference
    2113           24 :          CALL print_rho_diff(diff_rho_r, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .FALSE.)
    2114           24 :          IF (opt_embed%open_shell_embed) THEN ! Spin part
    2115           14 :             CALL print_rho_spin_diff(diff_rho_spin, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .FALSE.)
    2116              :          END IF
    2117              : 
    2118              :          ! Calculate potential gradient if the step has been accepted. Otherwise, we reuse the previous one
    2119              : 
    2120           24 :          IF (opt_embed%accept_step .AND. (.NOT. opt_embed%grid_opt)) &
    2121              :             CALL calculate_embed_pot_grad(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2122           16 :                                           diff_rho_r, diff_rho_spin, opt_embed)
    2123              :          ! Take the embedding step
    2124              :          CALL opt_embed_step(diff_rho_r, diff_rho_spin, opt_embed, embed_pot, spin_embed_pot, rho_r_ref, &
    2125           48 :                              force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
    2126              : 
    2127              :       END DO ! i_iter
    2128              : 
    2129              :       ! Print final embedding potential for restart
    2130              :       CALL print_embed_restart(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2131              :                                opt_embed%dimen_aux, opt_embed%embed_pot_coef, embed_pot, i_iter, &
    2132           24 :                                spin_embed_pot, opt_embed%open_shell_embed, opt_embed%grid_opt, .TRUE.)
    2133              :       CALL print_pot_simple_grid(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2134              :                                  embed_pot, spin_embed_pot, i_iter, opt_embed%open_shell_embed, .TRUE., &
    2135           24 :                                  force_env%sub_force_env(cluster_subsys_num)%force_env%qs_env)
    2136              : 
    2137              :       ! Print final density difference
    2138              :       !CALL print_rho_diff(diff_rho_r, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .TRUE.)
    2139           24 :       IF (opt_embed%open_shell_embed) THEN ! Spin part
    2140           12 :          CALL print_rho_spin_diff(diff_rho_spin, i_iter, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, .TRUE.)
    2141              :       END IF
    2142              : 
    2143              :       ! Give away plane waves pools
    2144           24 :       CALL diff_rho_r%release()
    2145           24 :       IF (opt_embed%open_shell_embed) THEN
    2146           12 :          CALL diff_rho_spin%release()
    2147              :       END IF
    2148              : 
    2149              :       CALL cp_print_key_finished_output(output_unit, logger, force_env%force_env_section, &
    2150           24 :                                         "PRINT%PROGRAM_RUN_INFO")
    2151              : 
    2152              :       ! If converged send the embedding potential to the higher-level calculation.
    2153           24 :       IF (opt_embed%converged) THEN
    2154              :          CALL get_qs_env(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, dft_control=dft_control, &
    2155           24 :                          pw_env=pw_env)
    2156           24 :          nspins_subsys = dft_control%nspins
    2157           24 :          dft_control%apply_embed_pot = .TRUE.
    2158              :          ! The embedded subsystem corresponds to subsystem #2, where spin change is possible
    2159              :          CALL make_subsys_embed_pot(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, &
    2160              :                                     embed_pot, embed_pot_subsys, spin_embed_pot, spin_embed_pot_subsys, &
    2161           24 :                                     opt_embed%open_shell_embed, opt_embed%change_spin)
    2162              : 
    2163           24 :          IF (opt_embed%Coulomb_guess) THEN
    2164            2 :             CALL pw_axpy(opt_embed%pot_diff, embed_pot_subsys, -1.0_dp, allow_noncompatible_grids=.TRUE.)
    2165              :          END IF
    2166              : 
    2167           24 :          CALL set_qs_env(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, embed_pot=embed_pot_subsys)
    2168              : 
    2169           24 :          IF ((opt_embed%open_shell_embed) .AND. (nspins_subsys == 2)) THEN
    2170              :             CALL set_qs_env(force_env%sub_force_env(ref_subsys_number + 1)%force_env%qs_env, &
    2171           12 :                             spin_embed_pot=spin_embed_pot_subsys)
    2172              :          END IF
    2173              : 
    2174              :          ! Substitute the correct energy in energies: only on rank 0
    2175           24 :          IF (force_env%sub_force_env(cluster_subsys_num)%force_env%para_env%is_source()) THEN
    2176           12 :             energies(cluster_subsys_num) = cluster_energy
    2177              :          END IF
    2178              :       END IF
    2179              : 
    2180              :       ! Deallocate and release opt_embed content
    2181           24 :       CALL release_opt_embed(opt_embed)
    2182              : 
    2183              :       ! Deallocate embedding potential
    2184           24 :       CALL embed_pot%release()
    2185           24 :       DEALLOCATE (embed_pot)
    2186           24 :       IF (opt_embed%open_shell_embed) THEN
    2187           12 :          CALL spin_embed_pot%release()
    2188           12 :          DEALLOCATE (spin_embed_pot)
    2189              :       END IF
    2190              : 
    2191           24 :       converged_embed = opt_embed%converged
    2192              : 
    2193           24 :       CALL timestop(handle)
    2194              : 
    2195           48 :    END SUBROUTINE dfet_embedding
    2196              : 
    2197              : ! **************************************************************************************************
    2198              : !> \brief Main driver for the DMFET embedding
    2199              : !> \param force_env ...
    2200              : !> \param ref_subsys_number ...
    2201              : !> \param energies ...
    2202              : !> \param converged_embed ...
    2203              : !> \author Vladimir Rybkin
    2204              : ! **************************************************************************************************
    2205            0 :    SUBROUTINE dmfet_embedding(force_env, ref_subsys_number, energies, converged_embed)
    2206              :       TYPE(force_env_type), POINTER                      :: force_env
    2207              :       INTEGER                                            :: ref_subsys_number
    2208              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: energies
    2209              :       LOGICAL                                            :: converged_embed
    2210              : 
    2211              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'dmfet_embedding'
    2212              : 
    2213              :       INTEGER                                            :: cluster_subsys_num, handle, &
    2214              :                                                             i_force_eval, i_iter, output_unit
    2215              :       LOGICAL                                            :: subsys_open_shell
    2216              :       REAL(KIND=dp)                                      :: cluster_energy
    2217              :       TYPE(cp_logger_type), POINTER                      :: logger
    2218              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2219              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2220            0 :       TYPE(opt_dmfet_pot_type)                           :: opt_dmfet
    2221              :       TYPE(qs_energy_type), POINTER                      :: energy
    2222              :       TYPE(section_vals_type), POINTER                   :: dft_section, input, opt_dmfet_section
    2223              : 
    2224            0 :       CALL timeset(routineN, handle)
    2225              : 
    2226              :       CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2227            0 :                       para_env=para_env)
    2228              : 
    2229              :       ! Reveal input file
    2230            0 :       NULLIFY (logger)
    2231            0 :       logger => cp_get_default_logger()
    2232              :       output_unit = cp_print_key_unit_nr(logger, force_env%force_env_section, "PRINT%PROGRAM_RUN_INFO", &
    2233            0 :                                          extension=".Log")
    2234              : 
    2235            0 :       NULLIFY (dft_section, input, opt_dmfet_section)
    2236            0 :       NULLIFY (energy)
    2237              : 
    2238              :       CALL get_qs_env(qs_env=force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2239            0 :                       energy=energy, input=input)
    2240              : 
    2241            0 :       dft_section => section_vals_get_subs_vals(input, "DFT")
    2242              :       opt_dmfet_section => section_vals_get_subs_vals(input, &
    2243            0 :                                                       "DFT%QS%OPT_DMFET")
    2244              : 
    2245              :       ! We need to understand how to treat spins states
    2246              :       CALL understand_spin_states(force_env, ref_subsys_number, opt_dmfet%change_spin, opt_dmfet%open_shell_embed, &
    2247            0 :                                   opt_dmfet%all_nspins)
    2248              : 
    2249              :       ! Prepare for the potential optimization
    2250              :       CALL prepare_dmfet_opt(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2251            0 :                              opt_dmfet, opt_dmfet_section)
    2252              : 
    2253              :       ! Get the reference density matrix/matrices
    2254            0 :       subsys_open_shell = subsys_spin(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
    2255              :       CALL build_full_dm(force_env%sub_force_env(ref_subsys_number)%force_env%qs_env, &
    2256            0 :                          opt_dmfet%dm_total, subsys_open_shell, opt_dmfet%open_shell_embed, opt_dmfet%dm_total_beta)
    2257              : 
    2258              :       ! Check the preliminary DM difference
    2259            0 :       CALL cp_fm_copy_general(opt_dmfet%dm_total, opt_dmfet%dm_diff, para_env)
    2260            0 :       IF (opt_dmfet%open_shell_embed) CALL cp_fm_copy_general(opt_dmfet%dm_total_beta, &
    2261            0 :                                                               opt_dmfet%dm_diff_beta, para_env)
    2262              : 
    2263            0 :       DO i_force_eval = 1, ref_subsys_number - 1
    2264              : 
    2265              :          ! Get the subsystem density matrix/matrices
    2266            0 :          subsys_open_shell = subsys_spin(force_env%sub_force_env(i_force_eval)%force_env%qs_env)
    2267              : 
    2268              :          CALL build_full_dm(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
    2269              :                             opt_dmfet%dm_subsys, subsys_open_shell, opt_dmfet%open_shell_embed, &
    2270            0 :                             opt_dmfet%dm_subsys_beta)
    2271              : 
    2272            0 :          CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys)
    2273              : 
    2274            0 :          IF (opt_dmfet%open_shell_embed) CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff_beta, &
    2275            0 :                                                                   1.0_dp, opt_dmfet%dm_subsys_beta)
    2276              : 
    2277              :       END DO
    2278              : 
    2279              :       ! Main loop of iterative matrix potential optimization
    2280            0 :       DO i_iter = 1, opt_dmfet%n_iter
    2281              : 
    2282            0 :          opt_dmfet%i_iter = i_iter
    2283              : 
    2284              :          ! Set the dm difference as the reference one
    2285            0 :          CALL cp_fm_copy_general(opt_dmfet%dm_total, opt_dmfet%dm_diff, para_env)
    2286              : 
    2287            0 :          IF (opt_dmfet%open_shell_embed) CALL cp_fm_copy_general(opt_dmfet%dm_total_beta, &
    2288            0 :                                                                  opt_dmfet%dm_diff_beta, para_env)
    2289              : 
    2290              :          ! Loop over force evaluations
    2291            0 :          DO i_force_eval = 1, ref_subsys_number - 1
    2292              : 
    2293              :             ! Switch on external potential in the subsystems
    2294            0 :             NULLIFY (dft_control)
    2295            0 :             CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, dft_control=dft_control)
    2296            0 :             dft_control%apply_dmfet_pot = .TRUE.
    2297              : 
    2298              :             ! Calculate the new density
    2299              :             CALL force_env_calc_energy_force(force_env=force_env%sub_force_env(i_force_eval)%force_env, &
    2300              :                                              calc_force=.FALSE., &
    2301            0 :                                              skip_external_control=.TRUE.)
    2302              : 
    2303              :             ! Extract subsystem density matrix and energy
    2304            0 :             NULLIFY (energy)
    2305              : 
    2306            0 :             CALL get_qs_env(force_env%sub_force_env(i_force_eval)%force_env%qs_env, energy=energy)
    2307            0 :             opt_dmfet%w_func(i_iter) = opt_dmfet%w_func(i_iter) + energy%total
    2308              : 
    2309              :             ! Find out which subsystem is the cluster
    2310            0 :             IF (dft_control%qs_control%cluster_embed_subsys) THEN
    2311            0 :                cluster_subsys_num = i_force_eval
    2312            0 :                cluster_energy = energy%total
    2313              :             END IF
    2314              : 
    2315              :             ! Add subsystem density matrices
    2316            0 :             subsys_open_shell = subsys_spin(force_env%sub_force_env(i_force_eval)%force_env%qs_env)
    2317              : 
    2318              :             CALL build_full_dm(force_env%sub_force_env(i_force_eval)%force_env%qs_env, &
    2319              :                                opt_dmfet%dm_subsys, subsys_open_shell, opt_dmfet%open_shell_embed, &
    2320            0 :                                opt_dmfet%dm_subsys_beta)
    2321              : 
    2322            0 :             IF (opt_dmfet%open_shell_embed) THEN ! Open-shell embedding
    2323              :                ! We may need to change spin ONLY FOR THE SECOND SUBSYSTEM: that's the internal convention
    2324            0 :                IF ((i_force_eval == 2) .AND. (opt_dmfet%change_spin)) THEN
    2325            0 :                   CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff_beta, 1.0_dp, opt_dmfet%dm_subsys)
    2326            0 :                   CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys_beta)
    2327              :                ELSE
    2328            0 :                   CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys)
    2329            0 :                   CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff_beta, 1.0_dp, opt_dmfet%dm_subsys_beta)
    2330              :                END IF
    2331              :             ELSE ! Closed-shell embedding
    2332            0 :                CALL cp_fm_scale_and_add(-1.0_dp, opt_dmfet%dm_diff, 1.0_dp, opt_dmfet%dm_subsys)
    2333              :             END IF
    2334              : 
    2335              :          END DO ! i_force_eval
    2336              : 
    2337            0 :          CALL check_dmfet(opt_dmfet, force_env%sub_force_env(ref_subsys_number)%force_env%qs_env)
    2338              : 
    2339              :       END DO ! i_iter
    2340              : 
    2341              :       ! Substitute the correct energy in energies: only on rank 0
    2342            0 :       IF (force_env%sub_force_env(cluster_subsys_num)%force_env%para_env%is_source()) THEN
    2343            0 :          energies(cluster_subsys_num) = cluster_energy
    2344              :       END IF
    2345              : 
    2346            0 :       CALL release_dmfet_opt(opt_dmfet)
    2347              : 
    2348            0 :       converged_embed = .FALSE.
    2349              : 
    2350            0 :    END SUBROUTINE dmfet_embedding
    2351              : 
    2352              : END MODULE force_env_methods
        

Generated by: LCOV version 2.0-1