LCOV - code coverage report
Current view: top level - src - f77_interface.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 82.6 % 541 447
Test Date: 2026-11-04 00:58:17 Functions: 80.0 % 30 24

            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 to use cp2k as library
      10              : !> \note
      11              : !>      useful additions for the future would be:
      12              : !>      - string(path) based set/get of simple values (to change the new
      13              : !>        input during the run and extract more data (energy types for example).
      14              : !>      - set/get of a subset of atoms
      15              : !> \par History
      16              : !>      07.2004 created [fawzi]
      17              : !>      11.2004 parallel version [fawzi]
      18              : !> \author fawzi & Johanna
      19              : ! **************************************************************************************************
      20              : MODULE f77_interface
      21              :    USE base_hooks,                      ONLY: cp_abort_hook,&
      22              :                                               cp_warn_hook,&
      23              :                                               timeset_hook,&
      24              :                                               timestop_hook
      25              :    USE bibliography,                    ONLY: add_all_references
      26              :    USE cell_methods,                    ONLY: init_cell
      27              :    USE cell_types,                      ONLY: cell_type
      28              :    USE cp2k_info,                       ONLY: get_runtime_info
      29              :    USE cp_dbcsr_api,                    ONLY: dbcsr_finalize_lib,&
      30              :                                               dbcsr_init_lib
      31              :    USE cp_dlaf_utils_api,               ONLY: cp_dlaf_finalize,&
      32              :                                               cp_dlaf_free_all_grids
      33              :    USE cp_error_handling,               ONLY: cp_error_handling_setup
      34              :    USE cp_files,                        ONLY: open_file
      35              :    USE cp_log_handling,                 ONLY: &
      36              :         cp_add_default_logger, cp_default_logger_stack_size, cp_failure_level, &
      37              :         cp_get_default_logger, cp_logger_create, cp_logger_release, cp_logger_retain, &
      38              :         cp_logger_type, cp_rm_default_logger, cp_to_string
      39              :    USE cp_output_handling,              ONLY: cp_iterate
      40              :    USE cp_output_handling_openpmd,      ONLY: cp_openpmd_output_finalize
      41              :    USE cp_result_methods,               ONLY: get_results,&
      42              :                                               test_for_result
      43              :    USE cp_result_types,                 ONLY: cp_result_type
      44              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      45              :                                               cp_subsys_set,&
      46              :                                               cp_subsys_type,&
      47              :                                               unpack_subsys_particles
      48              :    USE dbm_api,                         ONLY: dbm_library_finalize,&
      49              :                                               dbm_library_init
      50              :    USE dbt_api,                         ONLY: dbt_library_finalize,&
      51              :                                               dbt_library_init
      52              :    USE eip_environment,                 ONLY: eip_init
      53              :    USE eip_environment_types,           ONLY: eip_env_create,&
      54              :                                               eip_environment_type
      55              :    USE embed_main,                      ONLY: embed_create_force_env
      56              :    USE embed_types,                     ONLY: embed_env_type
      57              :    USE environment,                     ONLY: cp2k_finalize,&
      58              :                                               cp2k_init,&
      59              :                                               cp2k_read,&
      60              :                                               cp2k_setup
      61              :    USE fist_main,                       ONLY: fist_create_force_env
      62              :    USE force_env_methods,               ONLY: force_env_calc_energy_force,&
      63              :                                               force_env_create
      64              :    USE force_env_types,                 ONLY: &
      65              :         force_env_get, force_env_get_frc, force_env_get_natom, force_env_get_nparticle, &
      66              :         force_env_get_pos, force_env_get_vel, force_env_release, force_env_retain, force_env_set, &
      67              :         force_env_type, multiple_fe_list
      68              :    USE fp_types,                        ONLY: fp_env_create,&
      69              :                                               fp_env_read,&
      70              :                                               fp_env_write,&
      71              :                                               fp_type
      72              :    USE global_types,                    ONLY: global_environment_type,&
      73              :                                               globenv_create,&
      74              :                                               globenv_release
      75              :    USE grid_api,                        ONLY: grid_library_finalize,&
      76              :                                               grid_library_init
      77              :    USE input_constants,                 ONLY: &
      78              :         do_eip, do_embed, do_fist, do_ipi, do_mixed, do_nnp, do_qmmm, do_qmmmx, do_qs, do_sirius
      79              :    USE input_cp2k_check,                ONLY: check_cp2k_input
      80              :    USE input_cp2k_force_eval,           ONLY: create_force_eval_section
      81              :    USE input_cp2k_read,                 ONLY: empty_initial_variables,&
      82              :                                               read_input
      83              :    USE input_enumeration_types,         ONLY: enum_i2c,&
      84              :                                               enumeration_type
      85              :    USE input_keyword_types,             ONLY: keyword_get,&
      86              :                                               keyword_type
      87              :    USE input_section_types,             ONLY: &
      88              :         section_get_keyword, section_release, section_type, section_vals_duplicate, &
      89              :         section_vals_get, section_vals_get_subs_vals, section_vals_release, &
      90              :         section_vals_remove_values, section_vals_retain, section_vals_type, section_vals_val_get, &
      91              :         section_vals_write
      92              :    USE ipi_environment,                 ONLY: ipi_init
      93              :    USE ipi_environment_types,           ONLY: ipi_environment_type
      94              :    USE kinds,                           ONLY: default_path_length,&
      95              :                                               default_string_length,&
      96              :                                               dp
      97              :    USE libint_wrapper,                  ONLY: cp_libint_static_cleanup,&
      98              :                                               cp_libint_static_init
      99              :    USE machine,                         ONLY: default_output_unit,&
     100              :                                               m_chdir,&
     101              :                                               m_getcwd,&
     102              :                                               m_memory
     103              :    USE message_passing,                 ONLY: mp_comm_type,&
     104              :                                               mp_comm_world,&
     105              :                                               mp_para_env_release,&
     106              :                                               mp_para_env_type,&
     107              :                                               mp_query_thread_level,&
     108              :                                               mp_world_finalize,&
     109              :                                               mp_world_init
     110              :    USE metadynamics_types,              ONLY: meta_env_type
     111              :    USE metadynamics_utils,              ONLY: metadyn_read
     112              :    USE mixed_environment_types,         ONLY: mixed_environment_type
     113              :    USE mixed_main,                      ONLY: mixed_create_force_env
     114              :    USE mp_perf_env,                     ONLY: add_mp_perf_env,&
     115              :                                               get_mp_perf_env,&
     116              :                                               mp_perf_env_release,&
     117              :                                               mp_perf_env_retain,&
     118              :                                               mp_perf_env_type,&
     119              :                                               rm_mp_perf_env
     120              :    USE nnp_environment,                 ONLY: nnp_init
     121              :    USE nnp_environment_types,           ONLY: nnp_type
     122              :    USE offload_api,                     ONLY: offload_get_chosen_device,&
     123              :                                               offload_get_device_count,&
     124              :                                               offload_init,&
     125              :                                               offload_set_chosen_device
     126              :    USE periodic_table,                  ONLY: init_periodic_table
     127              :    USE pw_fpga,                         ONLY: pw_fpga_finalize,&
     128              :                                               pw_fpga_init
     129              :    USE pw_gpu,                          ONLY: pw_gpu_finalize,&
     130              :                                               pw_gpu_init
     131              :    USE pwdft_environment,               ONLY: pwdft_init
     132              :    USE pwdft_environment_types,         ONLY: pwdft_env_create,&
     133              :                                               pwdft_environment_type
     134              :    USE qmmm_create,                     ONLY: qmmm_env_create
     135              :    USE qmmm_types,                      ONLY: qmmm_env_type
     136              :    USE qmmmx_create,                    ONLY: qmmmx_env_create
     137              :    USE qmmmx_types,                     ONLY: qmmmx_env_type
     138              :    USE qs_environment,                  ONLY: qs_init
     139              :    USE qs_environment_types,            ONLY: get_qs_env,&
     140              :                                               qs_env_create,&
     141              :                                               qs_environment_type
     142              :    USE reference_manager,               ONLY: remove_all_references
     143              :    USE sirius_interface,                ONLY: cp_sirius_finalize,&
     144              :                                               cp_sirius_init,&
     145              :                                               cp_sirius_is_initialized
     146              :    USE string_table,                    ONLY: string_table_allocate,&
     147              :                                               string_table_deallocate
     148              :    USE timings,                         ONLY: add_timer_env,&
     149              :                                               get_timer_env,&
     150              :                                               rm_timer_env,&
     151              :                                               timer_env_release,&
     152              :                                               timer_env_retain,&
     153              :                                               timings_register_hooks
     154              :    USE timings_types,                   ONLY: timer_env_type
     155              :    USE virial_types,                    ONLY: virial_type
     156              :    USE xc_gauxc_interface,              ONLY: cp_gauxc_status_type,&
     157              :                                               gauxc_check_status,&
     158              :                                               gauxc_finalize,&
     159              :                                               gauxc_init
     160              :    USE xc_libxc,                        ONLY: libxc_release_workers
     161              : #include "./base/base_uses.f90"
     162              : 
     163              :    IMPLICIT NONE
     164              :    PRIVATE
     165              : 
     166              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
     167              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'f77_interface'
     168              : 
     169              : ! **************************************************************************************************
     170              :    TYPE f_env_p_type
     171              :       TYPE(f_env_type), POINTER :: f_env => NULL()
     172              :    END TYPE f_env_p_type
     173              : 
     174              : ! **************************************************************************************************
     175              :    TYPE f_env_type
     176              :       INTEGER :: id_nr = 0
     177              :       LOGICAL :: is_dirty = .TRUE.
     178              :       TYPE(force_env_type), POINTER      :: force_env => NULL()
     179              :       TYPE(cp_logger_type), POINTER      :: logger => NULL()
     180              :       TYPE(timer_env_type), POINTER      :: timer_env => NULL()
     181              :       TYPE(mp_perf_env_type), POINTER    :: mp_perf_env => NULL()
     182              :       CHARACTER(len=default_path_length) :: my_path = "", old_path = ""
     183              :    END TYPE f_env_type
     184              : 
     185              :    TYPE(f_env_p_type), DIMENSION(:), POINTER, SAVE :: f_envs
     186              :    TYPE(mp_para_env_type), POINTER, SAVE :: default_para_env
     187              :    LOGICAL, SAVE :: module_initialized = .FALSE.
     188              :    INTEGER, SAVE :: last_f_env_id = 0, n_f_envs = 0
     189              : 
     190              :    PUBLIC :: default_para_env
     191              :    PUBLIC :: init_cp2k, finalize_cp2k, configure_dbcsr
     192              :    PUBLIC :: create_force_env, destroy_force_env, set_pos, get_pos, &
     193              :              get_force, calc_energy_force, get_energy, get_stress_tensor, &
     194              :              calc_energy, calc_force, check_input, get_natom, get_nparticle, &
     195              :              f_env_add_defaults, f_env_rm_defaults, f_env_type, &
     196              :              f_env_get_from_id, &
     197              :              set_vel, set_cell, get_cell, get_qmmm_cell, get_result_r1
     198              : CONTAINS
     199              : 
     200              : ! **************************************************************************************************
     201              : !> \brief returns the position of the force env corresponding to the given id
     202              : !> \param env_id the id of the requested environment
     203              : !> \return ...
     204              : !> \author fawzi
     205              : !> \note
     206              : !>      private utility function
     207              : ! **************************************************************************************************
     208       110165 :    FUNCTION get_pos_of_env(env_id) RESULT(res)
     209              :       INTEGER, INTENT(in)                                :: env_id
     210              :       INTEGER                                            :: res
     211              : 
     212              :       INTEGER                                            :: env_pos, isub
     213              : 
     214       110165 :       env_pos = -1
     215       267600 :       DO isub = 1, n_f_envs
     216       267600 :          IF (f_envs(isub)%f_env%id_nr == env_id) THEN
     217       110165 :             env_pos = isub
     218              :          END IF
     219              :       END DO
     220       110165 :       res = env_pos
     221       110165 :    END FUNCTION get_pos_of_env
     222              : 
     223              : ! **************************************************************************************************
     224              : !> \brief initializes cp2k, needs to be called once before using any of the
     225              : !>      other functions when using cp2k as library
     226              : !> \param init_mpi if the mpi environment should be initialized
     227              : !> \param ierr returns a number different from 0 if there was an error
     228              : !> \param mpi_comm an existing mpi communicator (if not given mp_comm_world
     229              : !>      will be used)
     230              : !> \author fawzi
     231              : ! **************************************************************************************************
     232         1472 :    SUBROUTINE init_cp2k(init_mpi, ierr, mpi_comm)
     233              :       LOGICAL, INTENT(in)                                :: init_mpi
     234              :       INTEGER, INTENT(out)                               :: ierr
     235              :       TYPE(mp_comm_type), INTENT(in), OPTIONAL           :: mpi_comm
     236              : 
     237              :       INTEGER                                            :: offload_chosen_device, &
     238              :                                                             offload_device_count, unit_nr
     239              :       TYPE(cp_gauxc_status_type)                         :: gauxc_status
     240              :       TYPE(cp_logger_type), POINTER                      :: logger
     241              : 
     242         1472 :       IF (.NOT. module_initialized) THEN
     243              :          ! install error handler hooks
     244         1472 :          CALL cp_error_handling_setup()
     245              : 
     246              :          ! install timming handler hooks
     247         1472 :          CALL timings_register_hooks()
     248              : 
     249              :          ! get runtime information
     250         1472 :          CALL get_runtime_info()
     251              : 
     252              :          ! Intialize CUDA/HIP before MPI
     253              :          ! Needed for HIP on ALPS & LUMI
     254         1472 :          CALL offload_init()
     255              : 
     256              :          ! re-create the para_env and log with correct (reordered) ranks
     257         1472 :          ALLOCATE (default_para_env)
     258         1472 :          IF (init_mpi) THEN
     259              :             ! get the default system wide communicator
     260         1472 :             CALL mp_world_init(default_para_env)
     261              :          ELSE
     262            0 :             CALL mp_query_thread_level()
     263            0 :             IF (PRESENT(mpi_comm)) THEN
     264            0 :                default_para_env = mpi_comm
     265              :             ELSE
     266            0 :                default_para_env = mp_comm_world
     267              :             END IF
     268              :          END IF
     269              : 
     270         1472 :          CALL string_table_allocate()
     271         1472 :          CALL add_mp_perf_env()
     272         1472 :          CALL add_timer_env()
     273              : 
     274         1472 :          IF (default_para_env%is_source()) THEN
     275          736 :             unit_nr = default_output_unit
     276              :          ELSE
     277          736 :             unit_nr = -1
     278              :          END IF
     279         1472 :          NULLIFY (logger)
     280              : 
     281              :          CALL cp_logger_create(logger, para_env=default_para_env, &
     282              :                                default_global_unit_nr=unit_nr, &
     283         1472 :                                close_global_unit_on_dealloc=.FALSE.)
     284         1472 :          CALL cp_add_default_logger(logger)
     285         1472 :          CALL cp_logger_release(logger)
     286              : 
     287         1472 :          ALLOCATE (f_envs(0))
     288         1472 :          module_initialized = .TRUE.
     289         1472 :          ierr = 0
     290              : 
     291              :          ! Initialize mathematical constants
     292         1472 :          CALL init_periodic_table()
     293              : 
     294              :          ! Init the bibliography
     295         1472 :          CALL add_all_references()
     296              : 
     297         1472 :          offload_device_count = offload_get_device_count()
     298              : 
     299              :          ! Select active offload device when available.
     300         1472 :          IF (offload_device_count > 0) THEN
     301            0 :             offload_chosen_device = MOD(default_para_env%mepos, offload_device_count)
     302            0 :             CALL offload_set_chosen_device(offload_chosen_device)
     303              :          END IF
     304              : 
     305         1472 :          CALL configure_dbcsr(default_para_env, unit_nr)
     306              : #if defined(__parallel)
     307         1472 :          CALL gauxc_init(default_para_env%get_handle(), gauxc_status)
     308              : #else
     309              :          CALL gauxc_init(status=gauxc_status)
     310              : #endif
     311         1472 :          CALL gauxc_check_status(gauxc_status)
     312         1472 :          CALL pw_fpga_init()
     313         1472 :          CALL pw_gpu_init()
     314         1472 :          CALL grid_library_init()
     315         1472 :          CALL dbm_library_init()
     316         1472 :          CALL dbt_library_init()
     317              : #if defined(__LIBINT)
     318         1472 :          CALL cp_libint_static_init()
     319              : #endif
     320              :       ELSE
     321            0 :          ierr = cp_failure_level
     322              :       END IF
     323              : 
     324              :       !sample peak memory
     325         1472 :       CALL m_memory()
     326              : 
     327         1472 :    END SUBROUTINE init_cp2k
     328              : 
     329              : ! **************************************************************************************************
     330              : !> \brief Configure DBCSR with CP2K's hooks and selected accelerator device.
     331              : !>        For an active library the DBCSR API only updates the output unit.
     332              : !>        Initialization belongs to init_cp2k, except for FARMING which must
     333              : !>        temporarily initialize DBCSR on each job's own MPI communicator.
     334              : !> \param mpi_comm communicator for initialization (ignored if already initialized)
     335              : !> \param output_unit diagnostic output unit, negative on non-I/O ranks
     336              : ! **************************************************************************************************
     337        23982 :    SUBROUTINE configure_dbcsr(mpi_comm, output_unit)
     338              :       CLASS(mp_comm_type), INTENT(IN)                    :: mpi_comm
     339              :       INTEGER, INTENT(IN)                                :: output_unit
     340              : 
     341              :       INTEGER, POINTER                                   :: active_device_id
     342              :       INTEGER, TARGET                                    :: chosen_device
     343              : 
     344        23982 :       NULLIFY (active_device_id)
     345        23982 :       IF (offload_get_device_count() > 0) THEN
     346            0 :          chosen_device = offload_get_chosen_device()
     347            0 :          active_device_id => chosen_device
     348              :       END IF
     349              :       CALL dbcsr_init_lib(mpi_comm%get_handle(), timeset_hook, timestop_hook, &
     350              :                           cp_abort_hook, cp_warn_hook, io_unit=output_unit, &
     351        23982 :                           accdrv_active_device_id=active_device_id)
     352        23982 :    END SUBROUTINE configure_dbcsr
     353              : 
     354              : ! **************************************************************************************************
     355              : !> \brief cleanup after you have finished using this interface
     356              : !> \param finalize_mpi if the mpi environment should be finalized
     357              : !> \param ierr returns a number different from 0 if there was an error
     358              : !> \author fawzi
     359              : ! **************************************************************************************************
     360         1472 :    SUBROUTINE finalize_cp2k(finalize_mpi, ierr)
     361              :       LOGICAL, INTENT(in)                                :: finalize_mpi
     362              :       INTEGER, INTENT(out)                               :: ierr
     363              : 
     364              :       INTEGER                                            :: ienv
     365              :       TYPE(cp_gauxc_status_type)                         :: gauxc_status
     366              : 
     367              : !sample peak memory
     368              : 
     369         1472 :       CALL m_memory()
     370              : 
     371         1472 :       IF (.NOT. module_initialized) THEN
     372            0 :          ierr = cp_failure_level
     373              :       ELSE
     374         1472 :          DO ienv = n_f_envs, 1, -1
     375            0 :             CALL destroy_force_env(f_envs(ienv)%f_env%id_nr, ierr=ierr)
     376         1472 :             CPASSERT(ierr == 0)
     377              :          END DO
     378         1472 :          DEALLOCATE (f_envs)
     379              : 
     380              : #if defined(__LIBINT)
     381         1472 :          CALL cp_libint_static_cleanup()
     382              : #endif
     383              : 
     384              :          ! Release the cached LibXC workers, because their device buffers are
     385              :          ! owned by the offload memory pool which is cleared below
     386         1472 :          CALL libxc_release_workers()
     387              : 
     388              :          ! Finalize libraries (Offload)
     389         1472 :          CALL dbt_library_finalize()
     390         1472 :          CALL dbm_library_finalize()
     391         1472 :          CALL grid_library_finalize()
     392         1472 :          CALL pw_gpu_finalize()
     393         1472 :          CALL pw_fpga_finalize()
     394         1472 :          IF (cp_sirius_is_initialized()) CALL cp_sirius_finalize()
     395         1472 :          CALL gauxc_finalize(gauxc_status)
     396         1472 :          CALL gauxc_check_status(gauxc_status)
     397              :          ! Finalize the DBCSR library
     398         1472 :          CALL dbcsr_finalize_lib()
     399              : 
     400              :          ! Finalize DLA-Future and pika runtime; if already finalized does nothing
     401         1472 :          CALL cp_dlaf_free_all_grids()
     402         1472 :          CALL cp_dlaf_finalize()
     403              : 
     404         1472 :          CALL mp_para_env_release(default_para_env)
     405         1472 :          CALL cp_rm_default_logger()
     406              : 
     407              :          ! Deallocate the bibliography
     408         1472 :          CALL remove_all_references()
     409         1472 :          CALL rm_timer_env()
     410         1472 :          CALL rm_mp_perf_env()
     411         1472 :          CALL string_table_deallocate(0)
     412         1472 :          CALL cp_openpmd_output_finalize()
     413         1472 :          IF (finalize_mpi) THEN
     414         1472 :             CALL mp_world_finalize()
     415              :          END IF
     416              : 
     417         1472 :          ierr = 0
     418              :       END IF
     419         1472 :    END SUBROUTINE finalize_cp2k
     420              : 
     421              : ! **************************************************************************************************
     422              : !> \brief deallocates a f_env
     423              : !> \param f_env the f_env to deallocate
     424              : !> \author fawzi
     425              : ! **************************************************************************************************
     426        11265 :    RECURSIVE SUBROUTINE f_env_dealloc(f_env)
     427              :       TYPE(f_env_type), POINTER                          :: f_env
     428              : 
     429              :       INTEGER                                            :: ierr
     430              : 
     431        11265 :       CPASSERT(ASSOCIATED(f_env))
     432        11265 :       CALL force_env_release(f_env%force_env)
     433        11265 :       CALL cp_logger_release(f_env%logger)
     434        11265 :       CALL timer_env_release(f_env%timer_env)
     435        11265 :       CALL mp_perf_env_release(f_env%mp_perf_env)
     436        11265 :       IF (f_env%old_path /= f_env%my_path) THEN
     437            0 :          CALL m_chdir(f_env%old_path, ierr)
     438            0 :          CPASSERT(ierr == 0)
     439              :       END IF
     440        11265 :    END SUBROUTINE f_env_dealloc
     441              : 
     442              : ! **************************************************************************************************
     443              : !> \brief createates a f_env
     444              : !> \param f_env the f_env to createate
     445              : !> \param force_env the force_environment to be stored
     446              : !> \param timer_env the timer env to be stored
     447              : !> \param mp_perf_env the mp performance environment to be stored
     448              : !> \param id_nr ...
     449              : !> \param logger ...
     450              : !> \param old_dir ...
     451              : !> \author fawzi
     452              : ! **************************************************************************************************
     453        11265 :    SUBROUTINE f_env_create(f_env, force_env, timer_env, mp_perf_env, id_nr, logger, old_dir)
     454              :       TYPE(f_env_type), POINTER                          :: f_env
     455              :       TYPE(force_env_type), POINTER                      :: force_env
     456              :       TYPE(timer_env_type), POINTER                      :: timer_env
     457              :       TYPE(mp_perf_env_type), POINTER                    :: mp_perf_env
     458              :       INTEGER, INTENT(in)                                :: id_nr
     459              :       TYPE(cp_logger_type), POINTER                      :: logger
     460              :       CHARACTER(len=*), INTENT(in)                       :: old_dir
     461              : 
     462            0 :       ALLOCATE (f_env)
     463        11265 :       f_env%force_env => force_env
     464        11265 :       CALL force_env_retain(f_env%force_env)
     465        11265 :       f_env%logger => logger
     466        11265 :       CALL cp_logger_retain(logger)
     467        11265 :       f_env%timer_env => timer_env
     468        11265 :       CALL timer_env_retain(f_env%timer_env)
     469        11265 :       f_env%mp_perf_env => mp_perf_env
     470        11265 :       CALL mp_perf_env_retain(f_env%mp_perf_env)
     471        11265 :       f_env%id_nr = id_nr
     472        11265 :       CALL m_getcwd(f_env%my_path)
     473        11265 :       f_env%old_path = old_dir
     474        11265 :    END SUBROUTINE f_env_create
     475              : 
     476              : ! **************************************************************************************************
     477              : !> \brief ...
     478              : !> \param f_env_id ...
     479              : !> \param f_env ...
     480              : ! **************************************************************************************************
     481          283 :    SUBROUTINE f_env_get_from_id(f_env_id, f_env)
     482              :       INTEGER, INTENT(in)                                :: f_env_id
     483              :       TYPE(f_env_type), POINTER                          :: f_env
     484              : 
     485              :       INTEGER                                            :: f_env_pos
     486              : 
     487          283 :       NULLIFY (f_env)
     488          283 :       f_env_pos = get_pos_of_env(f_env_id)
     489          283 :       IF (f_env_pos < 1) THEN
     490            0 :          CPABORT("invalid env_id "//cp_to_string(f_env_id))
     491              :       ELSE
     492          283 :          f_env => f_envs(f_env_pos)%f_env
     493              :       END IF
     494              : 
     495          283 :    END SUBROUTINE f_env_get_from_id
     496              : 
     497              : ! **************************************************************************************************
     498              : !> \brief adds the default environments of the f_env to the stack of the
     499              : !>      defaults, and returns a new error and sets failure to true if
     500              : !>      something went wrong
     501              : !> \param f_env_id the f_env from where to take the defaults
     502              : !> \param f_env will contain the f_env corresponding to f_env_id
     503              : !> \param handle ...
     504              : !> \author fawzi
     505              : !> \note
     506              : !>      The following routines need to be synchronized wrt. adding/removing
     507              : !>      of the default environments (logging, performance,error):
     508              : !>      environment:cp2k_init, environment:cp2k_finalize,
     509              : !>      f77_interface:f_env_add_defaults, f77_interface:f_env_rm_defaults,
     510              : !>      f77_interface:create_force_env, f77_interface:destroy_force_env
     511              : ! **************************************************************************************************
     512        98617 :    SUBROUTINE f_env_add_defaults(f_env_id, f_env, handle)
     513              :       INTEGER, INTENT(in)                                :: f_env_id
     514              :       TYPE(f_env_type), POINTER                          :: f_env
     515              :       INTEGER, INTENT(out), OPTIONAL                     :: handle
     516              : 
     517              :       INTEGER                                            :: f_env_pos, ierr
     518              :       TYPE(cp_logger_type), POINTER                      :: logger
     519              : 
     520        98617 :       NULLIFY (f_env)
     521        98617 :       f_env_pos = get_pos_of_env(f_env_id)
     522        98617 :       IF (f_env_pos < 1) THEN
     523            0 :          CPABORT("invalid env_id "//cp_to_string(f_env_id))
     524              :       ELSE
     525        98617 :          f_env => f_envs(f_env_pos)%f_env
     526        98617 :          logger => f_env%logger
     527        98617 :          CPASSERT(ASSOCIATED(logger))
     528        98617 :          CALL m_getcwd(f_env%old_path)
     529        98617 :          IF (f_env%old_path /= f_env%my_path) THEN
     530            0 :             CALL m_chdir(TRIM(f_env%my_path), ierr)
     531            0 :             CPASSERT(ierr == 0)
     532              :          END IF
     533        98617 :          CALL add_mp_perf_env(f_env%mp_perf_env)
     534        98617 :          CALL add_timer_env(f_env%timer_env)
     535        98617 :          CALL cp_add_default_logger(logger)
     536        98617 :          IF (PRESENT(handle)) handle = cp_default_logger_stack_size()
     537              :       END IF
     538        98617 :    END SUBROUTINE f_env_add_defaults
     539              : 
     540              : ! **************************************************************************************************
     541              : !> \brief removes the default environments of the f_env to the stack of the
     542              : !>      defaults, and sets ierr accordingly to the failuers stored in error
     543              : !>      It also releases the error
     544              : !> \param f_env the f_env from where to take the defaults
     545              : !> \param ierr variable that will be set to a number different from 0 if
     546              : !>        error contains an error (otherwise it will be set to 0)
     547              : !> \param handle ...
     548              : !> \author fawzi
     549              : !> \note
     550              : !>      The following routines need to be synchronized wrt. adding/removing
     551              : !>      of the default environments (logging, performance,error):
     552              : !>      environment:cp2k_init, environment:cp2k_finalize,
     553              : !>      f77_interface:f_env_add_defaults, f77_interface:f_env_rm_defaults,
     554              : !>      f77_interface:create_force_env, f77_interface:destroy_force_env
     555              : ! **************************************************************************************************
     556        98617 :    SUBROUTINE f_env_rm_defaults(f_env, ierr, handle)
     557              :       TYPE(f_env_type), POINTER                          :: f_env
     558              :       INTEGER, INTENT(out), OPTIONAL                     :: ierr
     559              :       INTEGER, INTENT(in), OPTIONAL                      :: handle
     560              : 
     561              :       INTEGER                                            :: ierr2
     562              :       TYPE(cp_logger_type), POINTER                      :: d_logger, logger
     563              :       TYPE(mp_perf_env_type), POINTER                    :: d_mp_perf_env
     564              :       TYPE(timer_env_type), POINTER                      :: d_timer_env
     565              : 
     566        98617 :       IF (ASSOCIATED(f_env)) THEN
     567        98617 :          IF (PRESENT(handle)) THEN
     568        17154 :             CPASSERT(handle == cp_default_logger_stack_size())
     569              :          END IF
     570              : 
     571        98617 :          logger => f_env%logger
     572        98617 :          d_logger => cp_get_default_logger()
     573        98617 :          d_timer_env => get_timer_env()
     574        98617 :          d_mp_perf_env => get_mp_perf_env()
     575        98617 :          CPASSERT(ASSOCIATED(logger))
     576        98617 :          CPASSERT(ASSOCIATED(d_logger))
     577        98617 :          CPASSERT(ASSOCIATED(d_timer_env))
     578        98617 :          CPASSERT(ASSOCIATED(d_mp_perf_env))
     579        98617 :          CPASSERT(ASSOCIATED(logger, d_logger))
     580              :          ! CPASSERT(ASSOCIATED(d_timer_env, f_env%timer_env))
     581        98617 :          CPASSERT(ASSOCIATED(d_mp_perf_env, f_env%mp_perf_env))
     582        98617 :          IF (f_env%old_path /= f_env%my_path) THEN
     583            0 :             CALL m_chdir(TRIM(f_env%old_path), ierr2)
     584            0 :             CPASSERT(ierr2 == 0)
     585              :          END IF
     586        98617 :          IF (PRESENT(ierr)) THEN
     587        98091 :             ierr = 0
     588              :          END IF
     589        98617 :          CALL cp_rm_default_logger()
     590        98617 :          CALL rm_timer_env()
     591        98617 :          CALL rm_mp_perf_env()
     592              :       ELSE
     593            0 :          IF (PRESENT(ierr)) THEN
     594            0 :             ierr = 0
     595              :          END IF
     596              :       END IF
     597        98617 :    END SUBROUTINE f_env_rm_defaults
     598              : 
     599              : ! **************************************************************************************************
     600              : !> \brief creates a new force environment using the given input, and writing
     601              : !>        the output to the given output unit
     602              : !> \param new_env_id will contain the id of the newly created environment
     603              : !> \param input_declaration ...
     604              : !> \param input_path where to read the input (if the input is given it can
     605              : !>        a virtual path)
     606              : !> \param output_path filename (or name of the unit) for the output
     607              : !> \param mpi_comm the mpi communicator to be used for this environment
     608              : !>        it will not be freed when you get rid of the force_env
     609              : !> \param output_unit if given it should be the unit for the output
     610              : !>        and no file is open (should be valid on the processor with rank 0)
     611              : !> \param owns_out_unit if the output unit should be closed upon destroing
     612              : !>        of the force_env (defaults to true if not default_output_unit)
     613              : !> \param input the parsed input, if given and valid it is used
     614              : !>        instead of parsing from file
     615              : !> \param ierr will return a number different from 0 if there was an error
     616              : !> \param work_dir ...
     617              : !> \param initial_variables key-value list of initial preprocessor variables
     618              : !> \author fawzi
     619              : !> \note
     620              : !>      The following routines need to be synchronized wrt. adding/removing
     621              : !>      of the default environments (logging, performance,error):
     622              : !>      environment:cp2k_init, environment:cp2k_finalize,
     623              : !>      f77_interface:f_env_add_defaults, f77_interface:f_env_rm_defaults,
     624              : !>      f77_interface:create_force_env, f77_interface:destroy_force_env
     625              : ! **************************************************************************************************
     626        11265 :    RECURSIVE SUBROUTINE create_force_env(new_env_id, input_declaration, input_path, &
     627              :                                          output_path, mpi_comm, output_unit, owns_out_unit, &
     628           86 :                                          input, ierr, work_dir, initial_variables)
     629              :       INTEGER, INTENT(out)                               :: new_env_id
     630              :       TYPE(section_type), POINTER                        :: input_declaration
     631              :       CHARACTER(len=*), INTENT(in)                       :: input_path
     632              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: output_path
     633              : 
     634              :       CLASS(mp_comm_type), INTENT(IN), OPTIONAL          :: mpi_comm
     635              :       INTEGER, INTENT(in), OPTIONAL                      :: output_unit
     636              :       LOGICAL, INTENT(in), OPTIONAL                      :: owns_out_unit
     637              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: input
     638              :       INTEGER, INTENT(out), OPTIONAL                     :: ierr
     639              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: work_dir
     640              :       CHARACTER(len=*), DIMENSION(:, :), OPTIONAL        :: initial_variables
     641              : 
     642              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'create_force_env'
     643              : 
     644              :       CHARACTER(len=default_path_length)                 :: old_dir, wdir
     645              :       INTEGER :: handle, i, ierr2, iforce_eval, isubforce_eval, k, method_name_id, my_group, &
     646              :                  nforce_eval, ngroups, nsubforce_size, unit_nr
     647        11265 :       INTEGER, DIMENSION(:), POINTER                     :: group_distribution, i_force_eval, &
     648        11265 :                                                             lgroup_distribution
     649              :       LOGICAL :: check, do_qmmm_force_mixing, multiple_subsys, my_owns_out_unit, &
     650              :                  use_motion_section, use_multiple_para_env
     651              :       TYPE(cp_logger_type), POINTER                      :: logger, my_logger
     652              :       TYPE(mp_para_env_type), POINTER                    :: my_para_env, para_env
     653              :       TYPE(eip_environment_type), POINTER                :: eip_env
     654              :       TYPE(embed_env_type), POINTER                      :: embed_env
     655              :       TYPE(enumeration_type), POINTER                    :: enum
     656        11265 :       TYPE(f_env_p_type), DIMENSION(:), POINTER          :: f_envs_old
     657              :       TYPE(force_env_type), POINTER                      :: force_env, my_force_env
     658              :       TYPE(fp_type), POINTER                             :: fp_env
     659              :       TYPE(global_environment_type), POINTER             :: globenv
     660              :       TYPE(ipi_environment_type), POINTER                :: ipi_env
     661              :       TYPE(keyword_type), POINTER                        :: keyword
     662              :       TYPE(meta_env_type), POINTER                       :: meta_env
     663              :       TYPE(mixed_environment_type), POINTER              :: mixed_env
     664              :       TYPE(mp_perf_env_type), POINTER                    :: mp_perf_env
     665              :       TYPE(nnp_type), POINTER                            :: nnp_env
     666              :       TYPE(pwdft_environment_type), POINTER              :: pwdft_env
     667              :       TYPE(qmmm_env_type), POINTER                       :: qmmm_env
     668              :       TYPE(qmmmx_env_type), POINTER                      :: qmmmx_env
     669              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     670              :       TYPE(section_type), POINTER                        :: section
     671              :       TYPE(section_vals_type), POINTER :: fe_section, force_env_section, force_env_sections, &
     672              :                                           fp_section, input_file, qmmm_section, qmmmx_section, root_section, subsys_section, &
     673              :                                           wrk_section
     674              :       TYPE(timer_env_type), POINTER                      :: timer_env
     675              : 
     676            0 :       CPASSERT(ASSOCIATED(input_declaration))
     677        11265 :       NULLIFY (para_env, force_env, timer_env, mp_perf_env, globenv, meta_env, &
     678        11265 :                fp_env, eip_env, pwdft_env, mixed_env, qs_env, qmmm_env, embed_env)
     679        11265 :       new_env_id = -1
     680        11265 :       IF (PRESENT(mpi_comm)) THEN
     681        11261 :          ALLOCATE (para_env)
     682        11261 :          para_env = mpi_comm
     683              :       ELSE
     684            4 :          para_env => default_para_env
     685            4 :          CALL para_env%retain()
     686              :       END IF
     687              : 
     688        11265 :       CALL timeset(routineN, handle)
     689              : 
     690        11265 :       CALL m_getcwd(old_dir)
     691        11265 :       wdir = old_dir
     692        11265 :       IF (PRESENT(work_dir)) THEN
     693            0 :          IF (work_dir /= " ") THEN
     694            0 :             CALL m_chdir(work_dir, ierr2)
     695            0 :             IF (ierr2 /= 0) THEN
     696            0 :                IF (PRESENT(ierr)) ierr = ierr2
     697            0 :                RETURN
     698              :             END IF
     699            0 :             wdir = work_dir
     700              :          END IF
     701              :       END IF
     702              : 
     703        11265 :       IF (PRESENT(output_unit)) THEN
     704        10989 :          unit_nr = output_unit
     705              :       ELSE
     706          276 :          IF (para_env%is_source()) THEN
     707          214 :             IF (output_path == "__STD_OUT__") THEN
     708            2 :                unit_nr = default_output_unit
     709              :             ELSE
     710              :                CALL open_file(file_name=output_path, &
     711              :                               file_status="UNKNOWN", &
     712              :                               file_action="WRITE", &
     713              :                               file_position="APPEND", &
     714          212 :                               unit_number=unit_nr)
     715              :             END IF
     716              :          ELSE
     717           62 :             unit_nr = -1
     718              :          END IF
     719              :       END IF
     720              : 
     721        11265 :       my_owns_out_unit = unit_nr /= default_output_unit
     722        11265 :       IF (PRESENT(owns_out_unit)) my_owns_out_unit = owns_out_unit
     723        11265 :       CALL globenv_create(globenv)
     724              :       CALL cp2k_init(para_env, output_unit=unit_nr, globenv=globenv, input_file_name=input_path, &
     725        11265 :                      wdir=wdir)
     726        11265 :       logger => cp_get_default_logger()
     727              :       ! warning this is dangerous, I did not check that all the subfunctions
     728              :       ! support it, the program might crash upon error
     729              : 
     730        11265 :       NULLIFY (input_file)
     731        11265 :       IF (PRESENT(input)) input_file => input
     732        11265 :       IF (.NOT. ASSOCIATED(input_file)) THEN
     733          477 :          IF (PRESENT(initial_variables)) THEN
     734           86 :             input_file => read_input(input_declaration, input_path, initial_variables, para_env=para_env)
     735              :          ELSE
     736          391 :             input_file => read_input(input_declaration, input_path, empty_initial_variables, para_env=para_env)
     737              :          END IF
     738              :       ELSE
     739        10788 :          CALL section_vals_retain(input_file)
     740              :       END IF
     741              : 
     742        11265 :       CALL check_cp2k_input(input_declaration, input_file, para_env=para_env, output_unit=unit_nr)
     743              : 
     744        11265 :       root_section => input_file
     745        11265 :       CALL section_vals_retain(root_section)
     746              : 
     747        11265 :       IF (n_f_envs + 1 > SIZE(f_envs)) THEN
     748         1341 :          f_envs_old => f_envs
     749        17433 :          ALLOCATE (f_envs(n_f_envs + 10))
     750         1341 :          DO i = 1, n_f_envs
     751         1341 :             f_envs(i)%f_env => f_envs_old(i)%f_env
     752              :          END DO
     753        14751 :          DO i = n_f_envs + 1, SIZE(f_envs)
     754        14751 :             NULLIFY (f_envs(i)%f_env)
     755              :          END DO
     756         1341 :          DEALLOCATE (f_envs_old)
     757              :       END IF
     758              : 
     759        11265 :       CALL cp2k_read(root_section, para_env, globenv)
     760              : 
     761        11265 :       CALL cp2k_setup(root_section, para_env, globenv)
     762              :       ! Group Distribution
     763        33795 :       ALLOCATE (group_distribution(0:para_env%num_pe - 1))
     764        33584 :       group_distribution = 0
     765        11265 :       lgroup_distribution => group_distribution
     766              :       ! Setup all possible force_env
     767        11265 :       force_env_sections => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
     768              :       CALL section_vals_val_get(root_section, "MULTIPLE_FORCE_EVALS%MULTIPLE_SUBSYS", &
     769        11265 :                                 l_val=multiple_subsys)
     770        11265 :       CALL multiple_fe_list(force_env_sections, root_section, i_force_eval, nforce_eval)
     771              :       ! Enforce the deletion of the subsys (unless not explicitly required)
     772        11265 :       IF (.NOT. multiple_subsys) THEN
     773        11479 :          DO iforce_eval = 2, nforce_eval
     774              :             wrk_section => section_vals_get_subs_vals(force_env_sections, "SUBSYS", &
     775          262 :                                                       i_rep_section=i_force_eval(iforce_eval))
     776        11479 :             CALL section_vals_remove_values(wrk_section)
     777              :          END DO
     778              :       END IF
     779        11265 :       nsubforce_size = nforce_eval - 1
     780        11265 :       use_multiple_para_env = .FALSE.
     781        11265 :       use_motion_section = .TRUE.
     782        22944 :       DO iforce_eval = 1, nforce_eval
     783        11679 :          NULLIFY (force_env_section, my_force_env, subsys_section)
     784              :          ! Reference subsys from the first ordered force_eval
     785        11679 :          IF (.NOT. multiple_subsys) THEN
     786              :             subsys_section => section_vals_get_subs_vals(force_env_sections, "SUBSYS", &
     787        11479 :                                                          i_rep_section=i_force_eval(1))
     788              :          END IF
     789              :          ! Handling para_env in case of multiple force_eval
     790        11679 :          IF (use_multiple_para_env) THEN
     791              :             ! Check that the order of the force_eval is the correct one
     792              :             CALL section_vals_val_get(force_env_sections, "METHOD", i_val=method_name_id, &
     793          404 :                                       i_rep_section=i_force_eval(1))
     794          404 :             IF ((method_name_id /= do_mixed) .AND. (method_name_id /= do_embed)) THEN
     795              :                CALL cp_abort(__LOCATION__, &
     796              :                              "In case of multiple force_eval the MAIN force_eval (the first in the list of FORCE_EVAL_ORDER or "// &
     797              :                              "the one omitted from that order list) must be a MIXED_ENV type calculation. Please check your "// &
     798            0 :                              "input file and possibly correct the MULTIPLE_FORCE_EVAL%FORCE_EVAL_ORDER. ")
     799              :             END IF
     800              : 
     801          404 :             IF (method_name_id == do_mixed) THEN
     802          308 :                check = ASSOCIATED(force_env%mixed_env%sub_para_env)
     803          308 :                CPASSERT(check)
     804          308 :                ngroups = force_env%mixed_env%ngroups
     805          308 :                my_group = lgroup_distribution(para_env%mepos)
     806          308 :                isubforce_eval = iforce_eval - 1
     807              :                ! If task not allocated on this procs skip setup..
     808          308 :                IF (MODULO(isubforce_eval - 1, ngroups) /= my_group) CYCLE
     809          222 :                my_para_env => force_env%mixed_env%sub_para_env(my_group + 1)%para_env
     810          222 :                my_logger => force_env%mixed_env%sub_logger(my_group + 1)%p
     811          222 :                CALL cp_rm_default_logger()
     812          222 :                CALL cp_add_default_logger(my_logger)
     813              :             END IF
     814          318 :             IF (method_name_id == do_embed) THEN
     815           96 :                check = ASSOCIATED(force_env%embed_env%sub_para_env)
     816           96 :                CPASSERT(check)
     817           96 :                ngroups = force_env%embed_env%ngroups
     818           96 :                my_group = lgroup_distribution(para_env%mepos)
     819           96 :                isubforce_eval = iforce_eval - 1
     820              :                ! If task not allocated on this procs skip setup..
     821           96 :                IF (MODULO(isubforce_eval - 1, ngroups) /= my_group) CYCLE
     822           96 :                my_para_env => force_env%embed_env%sub_para_env(my_group + 1)%para_env
     823           96 :                my_logger => force_env%embed_env%sub_logger(my_group + 1)%p
     824           96 :                CALL cp_rm_default_logger()
     825           96 :                CALL cp_add_default_logger(my_logger)
     826              :             END IF
     827              :          ELSE
     828        11275 :             my_para_env => para_env
     829              :          END IF
     830              : 
     831              :          ! Initialize force_env_section
     832              :          ! No need to allocate one more force_env_section if only 1 force_eval
     833              :          ! is provided.. this is in order to save memory..
     834        11593 :          IF (nforce_eval > 1) THEN
     835              :             CALL section_vals_duplicate(force_env_sections, force_env_section, &
     836          498 :                                         i_force_eval(iforce_eval), i_force_eval(iforce_eval))
     837          498 :             IF (iforce_eval /= 1) use_motion_section = .FALSE.
     838              :          ELSE
     839        11095 :             force_env_section => force_env_sections
     840        11095 :             use_motion_section = .TRUE.
     841              :          END IF
     842        11593 :          CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
     843              : 
     844        11593 :          IF (method_name_id == do_qmmm) THEN
     845          336 :             qmmmx_section => section_vals_get_subs_vals(force_env_section, "QMMM%FORCE_MIXING")
     846          336 :             CALL section_vals_get(qmmmx_section, explicit=do_qmmm_force_mixing)
     847          336 :             IF (do_qmmm_force_mixing) THEN
     848            8 :                method_name_id = do_qmmmx
     849              :             END IF ! QMMM Force-Mixing has its own (hidden) method_id
     850              :          END IF
     851              : 
     852         2303 :          SELECT CASE (method_name_id)
     853              :          CASE (do_fist)
     854              :             CALL fist_create_force_env(my_force_env, root_section, my_para_env, globenv, &
     855              :                                        force_env_section=force_env_section, subsys_section=subsys_section, &
     856         2303 :                                        use_motion_section=use_motion_section)
     857              : 
     858              :          CASE (do_qs)
     859       271064 :             ALLOCATE (qs_env)
     860         8744 :             CALL qs_env_create(qs_env, globenv)
     861              :             CALL qs_init(qs_env, my_para_env, root_section, globenv=globenv, force_env_section=force_env_section, &
     862         8744 :                          subsys_section=subsys_section, use_motion_section=use_motion_section)
     863              :             CALL force_env_create(my_force_env, root_section, qs_env=qs_env, para_env=my_para_env, globenv=globenv, &
     864         8744 :                                   force_env_section=force_env_section)
     865              : 
     866              :          CASE (do_qmmm)
     867          328 :             qmmm_section => section_vals_get_subs_vals(force_env_section, "QMMM")
     868          328 :             ALLOCATE (qmmm_env)
     869              :             CALL qmmm_env_create(qmmm_env, root_section, my_para_env, globenv, &
     870          328 :                                  force_env_section, qmmm_section, subsys_section, use_motion_section)
     871              :             CALL force_env_create(my_force_env, root_section, qmmm_env=qmmm_env, para_env=my_para_env, &
     872          328 :                                   globenv=globenv, force_env_section=force_env_section)
     873              : 
     874              :          CASE (do_qmmmx)
     875            8 :             ALLOCATE (qmmmx_env)
     876              :             CALL qmmmx_env_create(qmmmx_env, root_section, my_para_env, globenv, &
     877            8 :                                   force_env_section, subsys_section, use_motion_section)
     878              :             CALL force_env_create(my_force_env, root_section, qmmmx_env=qmmmx_env, para_env=my_para_env, &
     879            8 :                                   globenv=globenv, force_env_section=force_env_section)
     880              : 
     881              :          CASE (do_eip)
     882            8 :             ALLOCATE (eip_env)
     883            8 :             CALL eip_env_create(eip_env)
     884              :             CALL eip_init(eip_env, root_section, my_para_env, force_env_section=force_env_section, &
     885            8 :                           subsys_section=subsys_section)
     886              :             CALL force_env_create(my_force_env, root_section, eip_env=eip_env, para_env=my_para_env, &
     887            8 :                                   globenv=globenv, force_env_section=force_env_section)
     888              : 
     889              :          CASE (do_sirius)
     890           24 :             IF (.NOT. cp_sirius_is_initialized()) THEN
     891            2 :                IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T2,A)", ADVANCE="NO") "SIRIUS| "
     892            2 :                CALL cp_sirius_init()
     893              :             END IF
     894          696 :             ALLOCATE (pwdft_env)
     895           24 :             CALL pwdft_env_create(pwdft_env)
     896              :             CALL pwdft_init(pwdft_env, root_section, my_para_env, force_env_section=force_env_section, &
     897           24 :                             subsys_section=subsys_section, use_motion_section=use_motion_section)
     898              :             CALL force_env_create(my_force_env, root_section, pwdft_env=pwdft_env, para_env=my_para_env, &
     899           24 :                                   globenv=globenv, force_env_section=force_env_section)
     900              : 
     901              :          CASE (do_mixed)
     902          138 :             ALLOCATE (mixed_env)
     903              :             CALL mixed_create_force_env(mixed_env, root_section, my_para_env, &
     904              :                                         force_env_section=force_env_section, n_subforce_eval=nsubforce_size, &
     905          138 :                                         use_motion_section=use_motion_section)
     906              :             CALL force_env_create(my_force_env, root_section, mixed_env=mixed_env, para_env=my_para_env, &
     907          138 :                                   globenv=globenv, force_env_section=force_env_section)
     908              :             !TODO: the sub_force_envs should really be created via recursion
     909          138 :             use_multiple_para_env = .TRUE.
     910          138 :             CALL cp_add_default_logger(logger) ! just to get the logger swapping started
     911          138 :             lgroup_distribution => my_force_env%mixed_env%group_distribution
     912              : 
     913              :          CASE (do_embed)
     914           24 :             ALLOCATE (embed_env)
     915              :             CALL embed_create_force_env(embed_env, root_section, my_para_env, &
     916              :                                         force_env_section=force_env_section, n_subforce_eval=nsubforce_size, &
     917           24 :                                         use_motion_section=use_motion_section)
     918              :             CALL force_env_create(my_force_env, root_section, embed_env=embed_env, para_env=my_para_env, &
     919           24 :                                   globenv=globenv, force_env_section=force_env_section)
     920              :             !TODO: the sub_force_envs should really be created via recursion
     921           24 :             use_multiple_para_env = .TRUE.
     922           24 :             CALL cp_add_default_logger(logger) ! just to get the logger swapping started
     923           24 :             lgroup_distribution => my_force_env%embed_env%group_distribution
     924              : 
     925              :          CASE (do_nnp)
     926           16 :             ALLOCATE (nnp_env)
     927              :             CALL nnp_init(nnp_env, root_section, my_para_env, force_env_section=force_env_section, &
     928           16 :                           subsys_section=subsys_section, use_motion_section=use_motion_section)
     929              :             CALL force_env_create(my_force_env, root_section, nnp_env=nnp_env, para_env=my_para_env, &
     930           16 :                                   globenv=globenv, force_env_section=force_env_section)
     931              : 
     932              :          CASE (do_ipi)
     933            0 :             ALLOCATE (ipi_env)
     934              :             CALL ipi_init(ipi_env, root_section, my_para_env, force_env_section=force_env_section, &
     935            0 :                           subsys_section=subsys_section)
     936              :             CALL force_env_create(my_force_env, root_section, ipi_env=ipi_env, para_env=my_para_env, &
     937            0 :                                   globenv=globenv, force_env_section=force_env_section)
     938              : 
     939              :          CASE DEFAULT
     940            0 :             CALL create_force_eval_section(section)
     941            0 :             keyword => section_get_keyword(section, "METHOD")
     942            0 :             CALL keyword_get(keyword, enum=enum)
     943              :             CALL cp_abort(__LOCATION__, &
     944              :                           "Invalid METHOD <"//TRIM(enum_i2c(enum, method_name_id))// &
     945            0 :                           "> was specified, ")
     946        11985 :             CALL section_release(section)
     947              :          END SELECT
     948              : 
     949        11593 :          NULLIFY (meta_env, fp_env)
     950        11593 :          IF (use_motion_section) THEN
     951              :             ! Metadynamics Setup
     952        11265 :             fe_section => section_vals_get_subs_vals(root_section, "MOTION%FREE_ENERGY")
     953        11265 :             CALL metadyn_read(meta_env, my_force_env, root_section, my_para_env, fe_section)
     954        11265 :             CALL force_env_set(my_force_env, meta_env=meta_env)
     955              :             ! Flexible Partition Setup
     956        11265 :             fp_section => section_vals_get_subs_vals(root_section, "MOTION%FLEXIBLE_PARTITIONING")
     957        11265 :             ALLOCATE (fp_env)
     958        11265 :             CALL fp_env_create(fp_env)
     959        11265 :             CALL fp_env_read(fp_env, fp_section)
     960        11265 :             CALL fp_env_write(fp_env, fp_section)
     961        11265 :             CALL force_env_set(my_force_env, fp_env=fp_env)
     962              :          END IF
     963              :          ! Handle multiple force_eval
     964        11593 :          IF (nforce_eval > 1 .AND. iforce_eval == 1) THEN
     965          924 :             ALLOCATE (my_force_env%sub_force_env(nsubforce_size))
     966              :             ! Nullify subforce_env
     967          584 :             DO k = 1, nsubforce_size
     968          584 :                NULLIFY (my_force_env%sub_force_env(k)%force_env)
     969              :             END DO
     970              :          END IF
     971              :          ! Reference the right force_env
     972        11265 :          IF (iforce_eval == 1) THEN
     973        11265 :             force_env => my_force_env
     974              :          ELSE
     975          328 :             force_env%sub_force_env(iforce_eval - 1)%force_env => my_force_env
     976              :          END IF
     977              :          ! Multiple para env for sub_force_eval
     978        11593 :          IF (.NOT. use_multiple_para_env) THEN
     979        33128 :             lgroup_distribution = iforce_eval
     980              :          END IF
     981              :          ! Release force_env_section
     982        34451 :          IF (nforce_eval > 1) CALL section_vals_release(force_env_section)
     983              :       END DO
     984        11265 :       IF (use_multiple_para_env) THEN
     985          162 :          CALL cp_rm_default_logger()
     986              :       END IF
     987        11265 :       DEALLOCATE (group_distribution)
     988        11265 :       DEALLOCATE (i_force_eval)
     989        11265 :       timer_env => get_timer_env()
     990        11265 :       mp_perf_env => get_mp_perf_env()
     991        11265 :       CALL para_env%max(last_f_env_id)
     992        11265 :       last_f_env_id = last_f_env_id + 1
     993        11265 :       new_env_id = last_f_env_id
     994        11265 :       n_f_envs = n_f_envs + 1
     995              :       CALL f_env_create(f_envs(n_f_envs)%f_env, logger=logger, &
     996              :                         timer_env=timer_env, mp_perf_env=mp_perf_env, force_env=force_env, &
     997        11265 :                         id_nr=last_f_env_id, old_dir=old_dir)
     998        11265 :       CALL force_env_release(force_env)
     999        11265 :       CALL globenv_release(globenv)
    1000        11265 :       CALL section_vals_release(root_section)
    1001        11265 :       CALL mp_para_env_release(para_env)
    1002        11265 :       CALL f_env_rm_defaults(f_envs(n_f_envs)%f_env, ierr=ierr)
    1003        11265 :       CALL timestop(handle)
    1004              : 
    1005        45146 :    END SUBROUTINE create_force_env
    1006              : 
    1007              : ! **************************************************************************************************
    1008              : !> \brief deallocates the force_env with the given id
    1009              : !> \param env_id the id of the force_env to remove
    1010              : !> \param ierr will contain a number different from 0 if
    1011              : !> \param q_finalize ...
    1012              : !> \author fawzi
    1013              : !> \note
    1014              : !>      The following routines need to be synchronized wrt. adding/removing
    1015              : !>      of the default environments (logging, performance,error):
    1016              : !>      environment:cp2k_init, environment:cp2k_finalize,
    1017              : !>      f77_interface:f_env_add_defaults, f77_interface:f_env_rm_defaults,
    1018              : !>      f77_interface:create_force_env, f77_interface:destroy_force_env
    1019              : ! **************************************************************************************************
    1020        11265 :    RECURSIVE SUBROUTINE destroy_force_env(env_id, ierr, q_finalize)
    1021              :       INTEGER, INTENT(in)                                :: env_id
    1022              :       INTEGER, INTENT(out)                               :: ierr
    1023              :       LOGICAL, INTENT(IN), OPTIONAL                      :: q_finalize
    1024              : 
    1025              :       INTEGER                                            :: env_pos, i
    1026              :       TYPE(f_env_type), POINTER                          :: f_env
    1027              :       TYPE(global_environment_type), POINTER             :: globenv
    1028              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1029              :       TYPE(section_vals_type), POINTER                   :: root_section
    1030              : 
    1031        11265 :       NULLIFY (f_env)
    1032        11265 :       CALL f_env_add_defaults(env_id, f_env)
    1033        11265 :       env_pos = get_pos_of_env(env_id)
    1034        11265 :       n_f_envs = n_f_envs - 1
    1035        11270 :       DO i = env_pos, n_f_envs
    1036        11270 :          f_envs(i)%f_env => f_envs(i + 1)%f_env
    1037              :       END DO
    1038        11265 :       NULLIFY (f_envs(n_f_envs + 1)%f_env)
    1039              : 
    1040              :       CALL force_env_get(f_env%force_env, globenv=globenv, &
    1041        11265 :                          root_section=root_section, para_env=para_env)
    1042              : 
    1043        11265 :       CPASSERT(ASSOCIATED(globenv))
    1044        11265 :       NULLIFY (f_env%force_env%globenv)
    1045        11265 :       CALL f_env_dealloc(f_env)
    1046        11265 :       IF (PRESENT(q_finalize)) THEN
    1047          210 :          CALL cp2k_finalize(root_section, para_env, globenv, f_env%old_path, q_finalize)
    1048              :       ELSE
    1049        11055 :          CALL cp2k_finalize(root_section, para_env, globenv, f_env%old_path)
    1050              :       END IF
    1051        11265 :       CALL section_vals_release(root_section)
    1052        11265 :       CALL globenv_release(globenv)
    1053        11265 :       DEALLOCATE (f_env)
    1054        11265 :       ierr = 0
    1055        11265 :    END SUBROUTINE destroy_force_env
    1056              : 
    1057              : ! **************************************************************************************************
    1058              : !> \brief returns the number of atoms in the given force env
    1059              : !> \param env_id id of the force_env
    1060              : !> \param n_atom ...
    1061              : !> \param ierr will return a number different from 0 if there was an error
    1062              : !> \date   22.11.2010 (MK)
    1063              : !> \author fawzi
    1064              : ! **************************************************************************************************
    1065           40 :    SUBROUTINE get_natom(env_id, n_atom, ierr)
    1066              : 
    1067              :       INTEGER, INTENT(IN)                                :: env_id
    1068              :       INTEGER, INTENT(OUT)                               :: n_atom, ierr
    1069              : 
    1070              :       TYPE(f_env_type), POINTER                          :: f_env
    1071              : 
    1072           20 :       n_atom = 0
    1073           20 :       NULLIFY (f_env)
    1074           20 :       CALL f_env_add_defaults(env_id, f_env)
    1075           20 :       n_atom = force_env_get_natom(f_env%force_env)
    1076           20 :       CALL f_env_rm_defaults(f_env, ierr)
    1077              : 
    1078           20 :    END SUBROUTINE get_natom
    1079              : 
    1080              : ! **************************************************************************************************
    1081              : !> \brief returns the number of particles in the given force env
    1082              : !> \param env_id id of the force_env
    1083              : !> \param n_particle ...
    1084              : !> \param ierr will return a number different from 0 if there was an error
    1085              : !> \author Matthias Krack
    1086              : !>
    1087              : ! **************************************************************************************************
    1088          304 :    SUBROUTINE get_nparticle(env_id, n_particle, ierr)
    1089              : 
    1090              :       INTEGER, INTENT(IN)                                :: env_id
    1091              :       INTEGER, INTENT(OUT)                               :: n_particle, ierr
    1092              : 
    1093              :       TYPE(f_env_type), POINTER                          :: f_env
    1094              : 
    1095          152 :       n_particle = 0
    1096          152 :       NULLIFY (f_env)
    1097          152 :       CALL f_env_add_defaults(env_id, f_env)
    1098          152 :       n_particle = force_env_get_nparticle(f_env%force_env)
    1099          152 :       CALL f_env_rm_defaults(f_env, ierr)
    1100              : 
    1101          152 :    END SUBROUTINE get_nparticle
    1102              : 
    1103              : ! **************************************************************************************************
    1104              : !> \brief gets a cell
    1105              : !> \param env_id id of the force_env
    1106              : !> \param cell the array with the cell matrix
    1107              : !> \param per periodicity
    1108              : !> \param ierr will return a number different from 0 if there was an error
    1109              : !> \author Joost VandeVondele
    1110              : ! **************************************************************************************************
    1111            4 :    SUBROUTINE get_cell(env_id, cell, per, ierr)
    1112              : 
    1113              :       INTEGER, INTENT(IN)                                :: env_id
    1114              :       REAL(KIND=DP), DIMENSION(3, 3)                     :: cell
    1115              :       INTEGER, DIMENSION(3), OPTIONAL                    :: per
    1116              :       INTEGER, INTENT(OUT)                               :: ierr
    1117              : 
    1118              :       TYPE(cell_type), POINTER                           :: cell_full
    1119              :       TYPE(f_env_type), POINTER                          :: f_env
    1120              : 
    1121            2 :       NULLIFY (f_env)
    1122            2 :       CALL f_env_add_defaults(env_id, f_env)
    1123            2 :       NULLIFY (cell_full)
    1124            2 :       CALL force_env_get(f_env%force_env, cell=cell_full)
    1125            2 :       CPASSERT(ASSOCIATED(cell_full))
    1126           26 :       cell = cell_full%hmat
    1127            2 :       IF (PRESENT(per)) per(:) = cell_full%perd(:)
    1128            2 :       CALL f_env_rm_defaults(f_env, ierr)
    1129              : 
    1130            2 :    END SUBROUTINE get_cell
    1131              : 
    1132              : ! **************************************************************************************************
    1133              : !> \brief gets the qmmm cell
    1134              : !> \param env_id id of the force_env
    1135              : !> \param cell the array with the cell matrix
    1136              : !> \param ierr will return a number different from 0 if there was an error
    1137              : !> \author Holly Judge
    1138              : ! **************************************************************************************************
    1139            0 :    SUBROUTINE get_qmmm_cell(env_id, cell, ierr)
    1140              : 
    1141              :       INTEGER, INTENT(IN)                                :: env_id
    1142              :       REAL(KIND=DP), DIMENSION(3, 3)                     :: cell
    1143              :       INTEGER, INTENT(OUT)                               :: ierr
    1144              : 
    1145              :       TYPE(cell_type), POINTER                           :: cell_qmmm
    1146              :       TYPE(f_env_type), POINTER                          :: f_env
    1147              :       TYPE(qmmm_env_type), POINTER                       :: qmmm_env
    1148              : 
    1149            0 :       NULLIFY (f_env)
    1150            0 :       CALL f_env_add_defaults(env_id, f_env)
    1151            0 :       NULLIFY (cell_qmmm)
    1152            0 :       CALL force_env_get(f_env%force_env, qmmm_env=qmmm_env)
    1153            0 :       CALL get_qs_env(qmmm_env%qs_env, cell=cell_qmmm)
    1154            0 :       CPASSERT(ASSOCIATED(cell_qmmm))
    1155            0 :       cell = cell_qmmm%hmat
    1156            0 :       CALL f_env_rm_defaults(f_env, ierr)
    1157              : 
    1158            0 :    END SUBROUTINE get_qmmm_cell
    1159              : 
    1160              : ! **************************************************************************************************
    1161              : !> \brief gets a result from CP2K that is a real 1D array
    1162              : !> \param env_id id of the force_env
    1163              : !> \param description the tag of the result
    1164              : !> \param N ...
    1165              : !> \param RESULT ...
    1166              : !> \param res_exist ...
    1167              : !> \param ierr will return a number different from 0 if there was an error
    1168              : !> \author Joost VandeVondele
    1169              : ! **************************************************************************************************
    1170            0 :    SUBROUTINE get_result_r1(env_id, description, N, RESULT, res_exist, ierr)
    1171              :       INTEGER                                            :: env_id
    1172              :       CHARACTER(LEN=default_string_length)               :: description
    1173              :       INTEGER                                            :: N
    1174              :       REAL(KIND=dp), DIMENSION(1:N)                      :: RESULT
    1175              :       LOGICAL, OPTIONAL                                  :: res_exist
    1176              :       INTEGER                                            :: ierr
    1177              : 
    1178              :       INTEGER                                            :: nres
    1179              :       LOGICAL                                            :: exist_res
    1180              :       TYPE(cp_result_type), POINTER                      :: results
    1181              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1182              :       TYPE(f_env_type), POINTER                          :: f_env
    1183              : 
    1184            0 :       NULLIFY (f_env, subsys, results)
    1185            0 :       CALL f_env_add_defaults(env_id, f_env)
    1186              : 
    1187            0 :       CALL force_env_get(f_env%force_env, subsys=subsys)
    1188            0 :       CALL cp_subsys_get(subsys, results=results)
    1189              :       ! first test for the result
    1190            0 :       IF (PRESENT(res_exist)) THEN
    1191            0 :          res_exist = test_for_result(results, description=description)
    1192              :          exist_res = res_exist
    1193              :       ELSE
    1194              :          exist_res = .TRUE.
    1195              :       END IF
    1196              :       ! if existing (or assuming the existence) read the results
    1197            0 :       IF (exist_res) THEN
    1198            0 :          CALL get_results(results, description=description, n_rep=nres)
    1199            0 :          CALL get_results(results, description=description, values=RESULT, nval=nres)
    1200              :       END IF
    1201              : 
    1202            0 :       CALL f_env_rm_defaults(f_env, ierr)
    1203              : 
    1204            0 :    END SUBROUTINE get_result_r1
    1205              : 
    1206              : ! **************************************************************************************************
    1207              : !> \brief gets the forces of the particles
    1208              : !> \param env_id id of the force_env
    1209              : !> \param frc the array where to write the forces
    1210              : !> \param n_el number of positions (3*nparticle) just to check
    1211              : !> \param ierr will return a number different from 0 if there was an error
    1212              : !> \date   22.11.2010 (MK)
    1213              : !> \author fawzi
    1214              : ! **************************************************************************************************
    1215        19448 :    SUBROUTINE get_force(env_id, frc, n_el, ierr)
    1216              : 
    1217              :       INTEGER, INTENT(IN)                                :: env_id, n_el
    1218              :       REAL(KIND=dp), DIMENSION(1:n_el)                   :: frc
    1219              :       INTEGER, INTENT(OUT)                               :: ierr
    1220              : 
    1221              :       TYPE(f_env_type), POINTER                          :: f_env
    1222              : 
    1223         9724 :       NULLIFY (f_env)
    1224         9724 :       CALL f_env_add_defaults(env_id, f_env)
    1225         9724 :       CALL force_env_get_frc(f_env%force_env, frc, n_el)
    1226         9724 :       CALL f_env_rm_defaults(f_env, ierr)
    1227              : 
    1228         9724 :    END SUBROUTINE get_force
    1229              : 
    1230              : ! **************************************************************************************************
    1231              : !> \brief gets the stress tensor
    1232              : !> \param env_id id of the force_env
    1233              : !> \param stress_tensor the array where to write the stress tensor
    1234              : !> \param ierr will return a number different from 0 if there was an error
    1235              : !> \param available whether the potential stress was calculated
    1236              : !> \author Ole Schuett
    1237              : ! **************************************************************************************************
    1238            4 :    SUBROUTINE get_stress_tensor(env_id, stress_tensor, ierr, available)
    1239              : 
    1240              :       INTEGER, INTENT(IN)                                :: env_id
    1241              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(OUT)        :: stress_tensor
    1242              :       INTEGER, INTENT(OUT)                               :: ierr
    1243              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: available
    1244              : 
    1245              :       TYPE(cell_type), POINTER                           :: cell
    1246              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1247              :       TYPE(f_env_type), POINTER                          :: f_env
    1248              :       TYPE(virial_type), POINTER                         :: virial
    1249              : 
    1250            2 :       NULLIFY (f_env, subsys, virial, cell)
    1251            2 :       stress_tensor(:, :) = 0.0_dp
    1252              : 
    1253            2 :       CALL f_env_add_defaults(env_id, f_env)
    1254            2 :       CALL force_env_get(f_env%force_env, subsys=subsys, cell=cell)
    1255            2 :       CALL cp_subsys_get(subsys, virial=virial)
    1256            2 :       IF (PRESENT(available)) available = virial%pv_availability
    1257            2 :       IF (virial%pv_availability) THEN
    1258           26 :          stress_tensor(:, :) = virial%pv_virial(:, :)/cell%deth
    1259              :       END IF
    1260            2 :       CALL f_env_rm_defaults(f_env, ierr)
    1261              : 
    1262            2 :    END SUBROUTINE get_stress_tensor
    1263              : 
    1264              : ! **************************************************************************************************
    1265              : !> \brief gets the positions of the particles
    1266              : !> \param env_id id of the force_env
    1267              : !> \param pos the array where to write the positions
    1268              : !> \param n_el number of positions (3*nparticle) just to check
    1269              : !> \param ierr will return a number different from 0 if there was an error
    1270              : !> \date   22.11.2010 (MK)
    1271              : !> \author fawzi
    1272              : ! **************************************************************************************************
    1273          704 :    SUBROUTINE get_pos(env_id, pos, n_el, ierr)
    1274              : 
    1275              :       INTEGER, INTENT(IN)                                :: env_id, n_el
    1276              :       REAL(KIND=DP), DIMENSION(1:n_el)                   :: pos
    1277              :       INTEGER, INTENT(OUT)                               :: ierr
    1278              : 
    1279              :       TYPE(f_env_type), POINTER                          :: f_env
    1280              : 
    1281          352 :       NULLIFY (f_env)
    1282          352 :       CALL f_env_add_defaults(env_id, f_env)
    1283          352 :       CALL force_env_get_pos(f_env%force_env, pos, n_el)
    1284          352 :       CALL f_env_rm_defaults(f_env, ierr)
    1285              : 
    1286          352 :    END SUBROUTINE get_pos
    1287              : 
    1288              : ! **************************************************************************************************
    1289              : !> \brief gets the velocities of the particles
    1290              : !> \param env_id id of the force_env
    1291              : !> \param vel the array where to write the velocities
    1292              : !> \param n_el number of velocities (3*nparticle) just to check
    1293              : !> \param ierr will return a number different from 0 if there was an error
    1294              : !> \author fawzi
    1295              : !> date    22.11.2010 (MK)
    1296              : ! **************************************************************************************************
    1297            0 :    SUBROUTINE get_vel(env_id, vel, n_el, ierr)
    1298              : 
    1299              :       INTEGER, INTENT(IN)                                :: env_id, n_el
    1300              :       REAL(KIND=DP), DIMENSION(1:n_el)                   :: vel
    1301              :       INTEGER, INTENT(OUT)                               :: ierr
    1302              : 
    1303              :       TYPE(f_env_type), POINTER                          :: f_env
    1304              : 
    1305            0 :       NULLIFY (f_env)
    1306            0 :       CALL f_env_add_defaults(env_id, f_env)
    1307            0 :       CALL force_env_get_vel(f_env%force_env, vel, n_el)
    1308            0 :       CALL f_env_rm_defaults(f_env, ierr)
    1309              : 
    1310            0 :    END SUBROUTINE get_vel
    1311              : 
    1312              : ! **************************************************************************************************
    1313              : !> \brief sets a new cell
    1314              : !> \param env_id id of the force_env
    1315              : !> \param new_cell the array with the cell matrix
    1316              : !> \param ierr will return a number different from 0 if there was an error
    1317              : !> \author Joost VandeVondele
    1318              : ! **************************************************************************************************
    1319         8308 :    SUBROUTINE set_cell(env_id, new_cell, ierr)
    1320              : 
    1321              :       INTEGER, INTENT(IN)                                :: env_id
    1322              :       REAL(KIND=DP), DIMENSION(3, 3)                     :: new_cell
    1323              :       INTEGER, INTENT(OUT)                               :: ierr
    1324              : 
    1325              :       TYPE(cell_type), POINTER                           :: cell
    1326              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1327              :       TYPE(f_env_type), POINTER                          :: f_env
    1328              : 
    1329         4154 :       NULLIFY (f_env, cell, subsys)
    1330         4154 :       CALL f_env_add_defaults(env_id, f_env)
    1331         4154 :       f_env%is_dirty = .TRUE.
    1332         4154 :       NULLIFY (cell)
    1333         4154 :       CALL force_env_get(f_env%force_env, cell=cell)
    1334         4154 :       CPASSERT(ASSOCIATED(cell))
    1335        54002 :       cell%hmat = new_cell
    1336         4154 :       CALL init_cell(cell)
    1337         4154 :       CALL force_env_get(f_env%force_env, subsys=subsys)
    1338         4154 :       CALL cp_subsys_set(subsys, cell=cell)
    1339         4154 :       CALL f_env_rm_defaults(f_env, ierr)
    1340              : 
    1341         4154 :    END SUBROUTINE set_cell
    1342              : 
    1343              : ! **************************************************************************************************
    1344              : !> \brief sets the positions of the particles
    1345              : !> \param env_id id of the force_env
    1346              : !> \param new_pos the array with the new positions
    1347              : !> \param n_el number of positions (3*nparticle) just to check
    1348              : !> \param ierr will return a number different from 0 if there was an error
    1349              : !> \date   22.11.2010 updated (MK)
    1350              : !> \author fawzi
    1351              : ! **************************************************************************************************
    1352        26976 :    SUBROUTINE set_pos(env_id, new_pos, n_el, ierr)
    1353              : 
    1354              :       INTEGER, INTENT(IN)                                :: env_id, n_el
    1355              :       REAL(KIND=dp), DIMENSION(1:n_el)                   :: new_pos
    1356              :       INTEGER, INTENT(OUT)                               :: ierr
    1357              : 
    1358              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1359              :       TYPE(f_env_type), POINTER                          :: f_env
    1360              : 
    1361        13488 :       NULLIFY (f_env)
    1362        13488 :       CALL f_env_add_defaults(env_id, f_env)
    1363        13488 :       NULLIFY (subsys)
    1364        13488 :       CALL force_env_get(f_env%force_env, subsys=subsys)
    1365        13488 :       CALL unpack_subsys_particles(subsys=subsys, r=new_pos)
    1366        13488 :       f_env%is_dirty = .TRUE.
    1367        13488 :       CALL f_env_rm_defaults(f_env, ierr)
    1368              : 
    1369        13488 :    END SUBROUTINE set_pos
    1370              : 
    1371              : ! **************************************************************************************************
    1372              : !> \brief sets the velocities of the particles
    1373              : !> \param env_id id of the force_env
    1374              : !> \param new_vel the array with the new velocities
    1375              : !> \param n_el number of velocities (3*nparticle) just to check
    1376              : !> \param ierr will return a number different from 0 if there was an error
    1377              : !> \date   22.11.2010 updated (MK)
    1378              : !> \author fawzi
    1379              : ! **************************************************************************************************
    1380          308 :    SUBROUTINE set_vel(env_id, new_vel, n_el, ierr)
    1381              : 
    1382              :       INTEGER, INTENT(IN)                                :: env_id, n_el
    1383              :       REAL(kind=dp), DIMENSION(1:n_el)                   :: new_vel
    1384              :       INTEGER, INTENT(OUT)                               :: ierr
    1385              : 
    1386              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1387              :       TYPE(f_env_type), POINTER                          :: f_env
    1388              : 
    1389          154 :       NULLIFY (f_env)
    1390          154 :       CALL f_env_add_defaults(env_id, f_env)
    1391          154 :       NULLIFY (subsys)
    1392          154 :       CALL force_env_get(f_env%force_env, subsys=subsys)
    1393          154 :       CALL unpack_subsys_particles(subsys=subsys, v=new_vel)
    1394          154 :       f_env%is_dirty = .TRUE.
    1395          154 :       CALL f_env_rm_defaults(f_env, ierr)
    1396              : 
    1397          154 :    END SUBROUTINE set_vel
    1398              : 
    1399              : ! **************************************************************************************************
    1400              : !> \brief updates the energy and the forces of given force_env
    1401              : !> \param env_id id of the force_env that you want to update
    1402              : !> \param calc_force if the forces should be updated, if false the forces
    1403              : !>        might be wrong.
    1404              : !> \param ierr will return a number different from 0 if there was an error
    1405              : !> \author fawzi
    1406              : ! **************************************************************************************************
    1407        26844 :    RECURSIVE SUBROUTINE calc_energy_force(env_id, calc_force, ierr)
    1408              : 
    1409              :       INTEGER, INTENT(in)                                :: env_id
    1410              :       LOGICAL, INTENT(in)                                :: calc_force
    1411              :       INTEGER, INTENT(out)                               :: ierr
    1412              : 
    1413              :       TYPE(cp_logger_type), POINTER                      :: logger
    1414              :       TYPE(f_env_type), POINTER                          :: f_env
    1415              : 
    1416        13422 :       NULLIFY (f_env)
    1417        13422 :       CALL f_env_add_defaults(env_id, f_env)
    1418        13422 :       logger => cp_get_default_logger()
    1419        13422 :       CALL cp_iterate(logger%iter_info) ! add one to the iteration count
    1420        13422 :       f_env%is_dirty = .TRUE.
    1421        13422 :       CALL force_env_calc_energy_force(f_env%force_env, calc_force=calc_force)
    1422        13422 :       f_env%is_dirty = .FALSE.
    1423        13422 :       CALL f_env_rm_defaults(f_env, ierr)
    1424              : 
    1425        13422 :    END SUBROUTINE calc_energy_force
    1426              : 
    1427              : ! **************************************************************************************************
    1428              : !> \brief returns the energy of the last configuration calculated
    1429              : !> \param env_id id of the force_env that you want to update
    1430              : !> \param e_pot the potential energy of the system
    1431              : !> \param ierr will return a number different from 0 if there was an error
    1432              : !> \author fawzi
    1433              : ! **************************************************************************************************
    1434        40434 :    SUBROUTINE get_energy(env_id, e_pot, ierr)
    1435              : 
    1436              :       INTEGER, INTENT(in)                                :: env_id
    1437              :       REAL(kind=dp), INTENT(out)                         :: e_pot
    1438              :       INTEGER, INTENT(out)                               :: ierr
    1439              : 
    1440              :       TYPE(f_env_type), POINTER                          :: f_env
    1441              : 
    1442        13478 :       NULLIFY (f_env)
    1443        13478 :       CALL f_env_add_defaults(env_id, f_env)
    1444        13478 :       CALL force_env_get(f_env%force_env, potential_energy=e_pot)
    1445        13478 :       CALL f_env_rm_defaults(f_env, ierr)
    1446              : 
    1447        13478 :    END SUBROUTINE get_energy
    1448              : 
    1449              : ! **************************************************************************************************
    1450              : !> \brief returns the energy of the configuration given by the positions
    1451              : !>      passed as argument
    1452              : !> \param env_id id of the force_env that you want to update
    1453              : !> \param pos array with the positions
    1454              : !> \param n_el number of elements in pos (3*natom)
    1455              : !> \param e_pot the potential energy of the system
    1456              : !> \param ierr will return a number different from 0 if there was an error
    1457              : !> \author fawzi
    1458              : !> \note
    1459              : !>      utility call
    1460              : ! **************************************************************************************************
    1461         3750 :    RECURSIVE SUBROUTINE calc_energy(env_id, pos, n_el, e_pot, ierr)
    1462              : 
    1463              :       INTEGER, INTENT(IN)                                :: env_id, n_el
    1464              :       REAL(KIND=dp), DIMENSION(1:n_el), INTENT(IN)       :: pos
    1465              :       REAL(KIND=dp), INTENT(OUT)                         :: e_pot
    1466              :       INTEGER, INTENT(OUT)                               :: ierr
    1467              : 
    1468              :       REAL(KIND=dp), DIMENSION(1)                        :: dummy_f
    1469              : 
    1470         3750 :       CALL calc_force(env_id, pos, n_el, e_pot, dummy_f, 0, ierr)
    1471              : 
    1472         3750 :    END SUBROUTINE calc_energy
    1473              : 
    1474              : ! **************************************************************************************************
    1475              : !> \brief returns the energy of the configuration given by the positions
    1476              : !>      passed as argument
    1477              : !> \param env_id id of the force_env that you want to update
    1478              : !> \param pos array with the positions
    1479              : !> \param n_el_pos number of elements in pos (3*natom)
    1480              : !> \param e_pot the potential energy of the system
    1481              : !> \param force array that will contain the forces
    1482              : !> \param n_el_force number of elements in force (3*natom). If 0 the
    1483              : !>        forces are not calculated
    1484              : !> \param ierr will return a number different from 0 if there was an error
    1485              : !> \author fawzi
    1486              : !> \note
    1487              : !>      utility call, but actually it could be a better and more efficient
    1488              : !>      interface to connect to other codes if cp2k would be deeply
    1489              : !>      refactored
    1490              : ! **************************************************************************************************
    1491        13414 :    RECURSIVE SUBROUTINE calc_force(env_id, pos, n_el_pos, e_pot, force, n_el_force, ierr)
    1492              : 
    1493              :       INTEGER, INTENT(in)                                :: env_id, n_el_pos
    1494              :       REAL(kind=dp), DIMENSION(1:n_el_pos), INTENT(in)   :: pos
    1495              :       REAL(kind=dp), INTENT(out)                         :: e_pot
    1496              :       INTEGER, INTENT(in)                                :: n_el_force
    1497              :       REAL(kind=dp), DIMENSION(1:n_el_force), &
    1498              :          INTENT(inout)                                   :: force
    1499              :       INTEGER, INTENT(out)                               :: ierr
    1500              : 
    1501              :       LOGICAL                                            :: calc_f
    1502              : 
    1503        13414 :       calc_f = (n_el_force /= 0)
    1504        13414 :       CALL set_pos(env_id, pos, n_el_pos, ierr)
    1505        13414 :       IF (ierr == 0) CALL calc_energy_force(env_id, calc_f, ierr)
    1506        13414 :       IF (ierr == 0) CALL get_energy(env_id, e_pot, ierr)
    1507        13414 :       IF (calc_f .AND. (ierr == 0)) CALL get_force(env_id, force, n_el_force, ierr)
    1508              : 
    1509        13414 :    END SUBROUTINE calc_force
    1510              : 
    1511              : ! **************************************************************************************************
    1512              : !> \brief performs a check of the input
    1513              : !> \param input_declaration ...
    1514              : !> \param input_file_path the path of the input file to check
    1515              : !> \param output_file_path path of the output file (to which it is appended)
    1516              : !>        if it is "__STD_OUT__" the default_output_unit is used
    1517              : !> \param echo_input if the parsed input should be written out with all the
    1518              : !>        defaults made explicit
    1519              : !> \param mpi_comm the mpi communicator (if not given it uses the default
    1520              : !>        one)
    1521              : !> \param initial_variables key-value list of initial preprocessor variables
    1522              : !> \param ierr error control, if different from 0 there was an error
    1523              : !> \author fawzi
    1524              : ! **************************************************************************************************
    1525            0 :    SUBROUTINE check_input(input_declaration, input_file_path, output_file_path, &
    1526            0 :                           echo_input, mpi_comm, initial_variables, ierr)
    1527              :       TYPE(section_type), POINTER                        :: input_declaration
    1528              :       CHARACTER(len=*), INTENT(in)                       :: input_file_path, output_file_path
    1529              :       LOGICAL, INTENT(in), OPTIONAL                      :: echo_input
    1530              :       TYPE(mp_comm_type), INTENT(in), OPTIONAL           :: mpi_comm
    1531              :       CHARACTER(len=default_path_length), &
    1532              :          DIMENSION(:, :), INTENT(IN)                     :: initial_variables
    1533              :       INTEGER, INTENT(out)                               :: ierr
    1534              : 
    1535              :       INTEGER                                            :: unit_nr
    1536              :       LOGICAL                                            :: my_echo_input
    1537              :       TYPE(cp_logger_type), POINTER                      :: logger
    1538              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1539              :       TYPE(section_vals_type), POINTER                   :: input_file
    1540              : 
    1541            0 :       my_echo_input = .FALSE.
    1542            0 :       IF (PRESENT(echo_input)) my_echo_input = echo_input
    1543              : 
    1544            0 :       IF (PRESENT(mpi_comm)) THEN
    1545            0 :          ALLOCATE (para_env)
    1546            0 :          para_env = mpi_comm
    1547              :       ELSE
    1548            0 :          para_env => default_para_env
    1549            0 :          CALL para_env%retain()
    1550              :       END IF
    1551            0 :       IF (para_env%is_source()) THEN
    1552            0 :          IF (output_file_path == "__STD_OUT__") THEN
    1553            0 :             unit_nr = default_output_unit
    1554              :          ELSE
    1555              :             CALL open_file(file_name=output_file_path, file_status="UNKNOWN", &
    1556              :                            file_action="WRITE", file_position="APPEND", &
    1557            0 :                            unit_number=unit_nr)
    1558              :          END IF
    1559              :       ELSE
    1560            0 :          unit_nr = -1
    1561              :       END IF
    1562              : 
    1563            0 :       NULLIFY (logger)
    1564              :       CALL cp_logger_create(logger, para_env=para_env, &
    1565              :                             default_global_unit_nr=unit_nr, &
    1566            0 :                             close_global_unit_on_dealloc=.FALSE.)
    1567            0 :       CALL cp_add_default_logger(logger)
    1568            0 :       CALL cp_logger_release(logger)
    1569              : 
    1570              :       input_file => read_input(input_declaration, input_file_path, initial_variables=initial_variables, &
    1571            0 :                                para_env=para_env)
    1572            0 :       CALL check_cp2k_input(input_declaration, input_file, para_env=para_env, output_unit=unit_nr)
    1573            0 :       IF (my_echo_input .AND. (unit_nr > 0)) THEN
    1574              :          CALL section_vals_write(input_file, &
    1575              :                                  unit_nr=unit_nr, &
    1576              :                                  hide_root=.TRUE., &
    1577            0 :                                  hide_defaults=.FALSE.)
    1578              :       END IF
    1579            0 :       CALL section_vals_release(input_file)
    1580              : 
    1581            0 :       CALL cp_logger_release(logger)
    1582            0 :       CALL mp_para_env_release(para_env)
    1583            0 :       ierr = 0
    1584            0 :       CALL cp_rm_default_logger()
    1585              : 
    1586            0 :    END SUBROUTINE check_input
    1587              : 
    1588            0 : END MODULE f77_interface
        

Generated by: LCOV version 2.0-1