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

Generated by: LCOV version 2.0-1