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

Generated by: LCOV version 2.0-1