LCOV - code coverage report
Current view: top level - src/motion - pint_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:7641cd9) Lines: 85.4 % 1252 1069
Test Date: 2026-05-25 07:16:39 Functions: 90.5 % 21 19

            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  Methods to performs a path integral run
      10              : !> \author fawzi
      11              : !> \par History
      12              : !>      02.2005 created [fawzi]
      13              : !>           11.2006 modified so it might actually work [hforbert]
      14              : !>           10.2015 added RPMD propagator
      15              : !>           10.2015 added exact harmonic integrator [Felix Uhl]
      16              : !> \note   quick & dirty rewrite of my python program
      17              : ! **************************************************************************************************
      18              : MODULE pint_methods
      19              : 
      20              :    USE atomic_kind_list_types,          ONLY: atomic_kind_list_type
      21              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      22              :                                               get_atomic_kind
      23              :    USE bibliography,                    ONLY: Brieuc2016,&
      24              :                                               Ceriotti2010,&
      25              :                                               Ceriotti2012,&
      26              :                                               Shiga2022,&
      27              :                                               cite_reference
      28              :    USE cell_types,                      ONLY: cell_type
      29              :    USE constraint,                      ONLY: rattle_control,&
      30              :                                               shake_control,&
      31              :                                               shake_update_targets
      32              :    USE constraint_util,                 ONLY: getold
      33              :    USE cp_external_control,             ONLY: external_control
      34              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      35              :                                               cp_logger_get_default_io_unit,&
      36              :                                               cp_logger_type,&
      37              :                                               cp_to_string
      38              :    USE cp_output_handling,              ONLY: cp_add_iter_level,&
      39              :                                               cp_iterate,&
      40              :                                               cp_p_file,&
      41              :                                               cp_print_key_finished_output,&
      42              :                                               cp_print_key_should_output,&
      43              :                                               cp_print_key_unit_nr,&
      44              :                                               cp_rm_iter_level
      45              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      46              :                                               cp_subsys_type
      47              :    USE cp_units,                        ONLY: cp_unit_from_cp2k,&
      48              :                                               cp_unit_to_cp2k
      49              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      50              :    USE f77_interface,                   ONLY: f_env_add_defaults,&
      51              :                                               f_env_rm_defaults,&
      52              :                                               f_env_type
      53              :    USE force_env_types,                 ONLY: force_env_get
      54              :    USE gle_system_dynamics,             ONLY: gle_cholesky_stab,&
      55              :                                               gle_matrix_exp,&
      56              :                                               restart_gle
      57              :    USE gle_system_types,                ONLY: gle_dealloc,&
      58              :                                               gle_init,&
      59              :                                               gle_thermo_create
      60              :    USE global_types,                    ONLY: global_environment_type
      61              :    USE helium_interactions,             ONLY: helium_intpot_scan
      62              :    USE helium_io,                       ONLY: helium_write_cubefile
      63              :    USE helium_methods,                  ONLY: helium_create,&
      64              :                                               helium_init,&
      65              :                                               helium_release
      66              :    USE helium_sampling,                 ONLY: helium_do_run,&
      67              :                                               helium_step
      68              :    USE helium_types,                    ONLY: helium_solvent_p_type
      69              :    USE input_constants,                 ONLY: integrate_exact,&
      70              :                                               integrate_numeric,&
      71              :                                               propagator_bcmd,&
      72              :                                               propagator_cmd,&
      73              :                                               propagator_rpmd,&
      74              :                                               transformation_normal,&
      75              :                                               transformation_stage
      76              :    USE input_cp2k_restarts,             ONLY: write_restart
      77              :    USE input_section_types,             ONLY: &
      78              :         section_type, section_vals_add_values, section_vals_get, section_vals_get_subs_vals, &
      79              :         section_vals_release, section_vals_retain, section_vals_type, section_vals_val_get, &
      80              :         section_vals_val_set, section_vals_val_unset
      81              :    USE kinds,                           ONLY: default_path_length,&
      82              :                                               default_string_length,&
      83              :                                               dp
      84              :    USE machine,                         ONLY: m_flush,&
      85              :                                               m_walltime
      86              :    USE mathconstants,                   ONLY: twopi
      87              :    USE mathlib,                         ONLY: gcd
      88              :    USE message_passing,                 ONLY: mp_comm_self,&
      89              :                                               mp_para_env_type
      90              :    USE molecule_kind_list_types,        ONLY: molecule_kind_list_type
      91              :    USE molecule_kind_types,             ONLY: molecule_kind_type
      92              :    USE molecule_list_types,             ONLY: molecule_list_type
      93              :    USE molecule_types,                  ONLY: global_constraint_type,&
      94              :                                               molecule_type
      95              :    USE parallel_rng_types,              ONLY: GAUSSIAN,&
      96              :                                               rng_stream_type
      97              :    USE particle_list_types,             ONLY: particle_list_type
      98              :    USE particle_types,                  ONLY: particle_type
      99              :    USE pint_gle,                        ONLY: pint_calc_gle_energy,&
     100              :                                               pint_gle_init,&
     101              :                                               pint_gle_step
     102              :    USE pint_io,                         ONLY: pint_write_action,&
     103              :                                               pint_write_centroids,&
     104              :                                               pint_write_com,&
     105              :                                               pint_write_ener,&
     106              :                                               pint_write_line,&
     107              :                                               pint_write_rgyr,&
     108              :                                               pint_write_step_info,&
     109              :                                               pint_write_trajectory
     110              :    USE pint_normalmode,                 ONLY: normalmode_calc_uf_h,&
     111              :                                               normalmode_env_create,&
     112              :                                               normalmode_init_masses,&
     113              :                                               normalmode_release
     114              :    USE pint_piglet,                     ONLY: pint_calc_piglet_energy,&
     115              :                                               pint_piglet_create,&
     116              :                                               pint_piglet_init,&
     117              :                                               pint_piglet_release,&
     118              :                                               pint_piglet_step
     119              :    USE pint_pile,                       ONLY: pint_calc_pile_energy,&
     120              :                                               pint_pile_init,&
     121              :                                               pint_pile_release,&
     122              :                                               pint_pile_step
     123              :    USE pint_public,                     ONLY: pint_levy_walk
     124              :    USE pint_qtb,                        ONLY: pint_calc_qtb_energy,&
     125              :                                               pint_qtb_init,&
     126              :                                               pint_qtb_release,&
     127              :                                               pint_qtb_step
     128              :    USE pint_staging,                    ONLY: staging_calc_uf_h,&
     129              :                                               staging_env_create,&
     130              :                                               staging_init_masses,&
     131              :                                               staging_release
     132              :    USE pint_transformations,            ONLY: pint_f2uf,&
     133              :                                               pint_u2x,&
     134              :                                               pint_x2u
     135              :    USE pint_types,                      ONLY: &
     136              :         e_conserved_id, e_kin_thermo_id, e_kin_virial_id, e_potential_id, pint_env_type, &
     137              :         thermostat_gle, thermostat_none, thermostat_nose, thermostat_piglet, thermostat_pile, &
     138              :         thermostat_qtb
     139              :    USE replica_methods,                 ONLY: rep_env_calc_e_f,&
     140              :                                               rep_env_create
     141              :    USE replica_types,                   ONLY: rep_env_release,&
     142              :                                               replica_env_type
     143              :    USE simpar_types,                    ONLY: create_simpar_type,&
     144              :                                               release_simpar_type
     145              : #include "../base/base_uses.f90"
     146              : 
     147              :    IMPLICIT NONE
     148              :    PRIVATE
     149              : 
     150              :    LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .TRUE.
     151              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pint_methods'
     152              : 
     153              :    PUBLIC :: do_pint_run
     154              : 
     155              : CONTAINS
     156              : 
     157              : ! ***************************************************************************
     158              : !> \brief  Create a path integral environment
     159              : !> \param pint_env ...
     160              : !> \param input ...
     161              : !> \param input_declaration ...
     162              : !> \param para_env ...
     163              : !> \par    History
     164              : !>           Fixed some bugs [hforbert]
     165              : !>           Added normal mode transformation [hforbert]
     166              : !>           10.2015 Added RPMD propagator and harmonic integrator [Felix Uhl]
     167              : !>           10.2018 Added centroid constraints [cschran+rperez]
     168              : !>           10.2021 Added beadwise constraints [lduran]
     169              : !> \author fawzi
     170              : !> \note   Might return an unassociated pointer in parallel on the processors
     171              : !>         that are not needed.
     172              : ! **************************************************************************************************
     173         1682 :    SUBROUTINE pint_create(pint_env, input, input_declaration, para_env)
     174              : 
     175              :       TYPE(pint_env_type), INTENT(OUT)                   :: pint_env
     176              :       TYPE(section_vals_type), POINTER                   :: input
     177              :       TYPE(section_type), POINTER                        :: input_declaration
     178              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     179              : 
     180              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'pint_create'
     181              : 
     182              :       CHARACTER(len=2*default_string_length)             :: msg
     183              :       CHARACTER(len=default_path_length)                 :: output_file_name, project_name
     184              :       INTEGER                                            :: handle, iat, ibead, icont, idim, idir, &
     185              :                                                             ierr, ig, itmp, nrep, prep, stat
     186              :       LOGICAL                                            :: explicit, ltmp
     187              :       REAL(kind=dp)                                      :: dt, mass, omega
     188              :       TYPE(cp_subsys_type), POINTER                      :: subsys
     189              :       TYPE(f_env_type), POINTER                          :: f_env
     190              :       TYPE(global_constraint_type), POINTER              :: gci
     191              :       TYPE(particle_list_type), POINTER                  :: particles
     192              :       TYPE(replica_env_type), POINTER                    :: rep_env
     193              :       TYPE(section_vals_type), POINTER :: constraint_section, gle_section, nose_section, &
     194              :          piglet_section, pile_section, pint_section, qtb_section, transform_section
     195              : 
     196           58 :       CALL timeset(routineN, handle)
     197              : 
     198           58 :       NULLIFY (f_env, subsys, particles, nose_section, gle_section, gci)
     199              : 
     200           58 :       CPASSERT(ASSOCIATED(input))
     201           58 :       CPASSERT(input%ref_count > 0)
     202           58 :       NULLIFY (rep_env)
     203           58 :       pint_section => section_vals_get_subs_vals(input, "MOTION%PINT")
     204           58 :       CALL section_vals_val_get(pint_section, "p", i_val=nrep)
     205              :       CALL section_vals_val_get(pint_section, "proc_per_replica", &
     206           58 :                                 i_val=prep)
     207              :       ! Maybe let the user have his/her way as long as prep is
     208              :       ! within the bounds of number of CPUs??
     209           58 :       IF ((prep < 1) .OR. (prep > para_env%num_pe) .OR. &
     210              :           (MOD(prep*nrep, para_env%num_pe) /= 0)) THEN
     211            2 :          prep = para_env%num_pe/gcd(para_env%num_pe, nrep)
     212            2 :          IF (para_env%is_source()) THEN
     213            1 :             WRITE (UNIT=msg, FMT=*) "PINT WARNING: Adjusting number of processors per replica to ", prep
     214           57 :             CPWARN(msg)
     215              :          END IF
     216              :       END IF
     217              : 
     218              :       ! replica_env modifies the global input structure - which is wrong - one
     219              :       ! of the side effects is the inifite adding of the -r-N string to the
     220              :       ! project name and the output file name, which corrupts restart files.
     221              :       ! For now: save the project name and output file name and restore them
     222              :       ! after the rep_env_create has executed - the initialization of the
     223              :       ! replicas will run correctly anyways.
     224              :       ! TODO: modify rep_env so that it behaves better
     225           58 :       CALL section_vals_val_get(input, "GLOBAL%PROJECT_NAME", c_val=project_name)
     226           58 :       CALL section_vals_val_get(input, "GLOBAL%OUTPUT_FILE_NAME", c_val=output_file_name)
     227              :       CALL rep_env_create(rep_env, para_env=para_env, input=input, &
     228           58 :                           input_declaration=input_declaration, nrep=nrep, prep=prep, row_force=.TRUE.)
     229           58 :       CALL section_vals_val_set(input, "GLOBAL%PROJECT_NAME", c_val=TRIM(project_name))
     230           58 :       IF (LEN_TRIM(output_file_name) > 0) THEN
     231            0 :          CALL section_vals_val_set(input, "GLOBAL%OUTPUT_FILE_NAME", c_val=TRIM(output_file_name))
     232              :       ELSE
     233           58 :          CALL section_vals_val_unset(input, "GLOBAL%OUTPUT_FILE_NAME")
     234              :       END IF
     235           58 :       IF (.NOT. ASSOCIATED(rep_env)) RETURN
     236              : 
     237           58 :       NULLIFY (pint_env%logger)
     238           58 :       pint_env%logger => cp_get_default_logger()
     239           58 :       CALL cp_add_iter_level(pint_env%logger%iter_info, "PINT")
     240              : 
     241           58 :       NULLIFY (pint_env%replicas, pint_env%input, pint_env%staging_env, &
     242           58 :                pint_env%normalmode_env, pint_env%propagator)
     243           58 :       pint_env%p = nrep
     244           58 :       pint_env%replicas => rep_env
     245           58 :       pint_env%ndim = rep_env%ndim
     246           58 :       pint_env%input => input
     247              : 
     248           58 :       CALL section_vals_retain(pint_env%input)
     249              : 
     250              :       ! get first step, last step, number of steps, etc
     251              :       CALL section_vals_val_get(input, "MOTION%PINT%ITERATION", &
     252           58 :                                 i_val=itmp)
     253           58 :       pint_env%first_step = itmp
     254              :       CALL section_vals_val_get(input, "MOTION%PINT%MAX_STEP", &
     255           58 :                                 explicit=explicit)
     256           58 :       IF (explicit) THEN
     257              :          CALL section_vals_val_get(input, "MOTION%PINT%MAX_STEP", &
     258            0 :                                    i_val=itmp)
     259            0 :          pint_env%last_step = itmp
     260            0 :          pint_env%num_steps = pint_env%last_step - pint_env%first_step
     261              :       ELSE
     262              :          CALL section_vals_val_get(input, "MOTION%PINT%NUM_STEPS", &
     263           58 :                                    i_val=itmp)
     264           58 :          pint_env%num_steps = itmp
     265           58 :          pint_env%last_step = pint_env%first_step + pint_env%num_steps
     266              :       END IF
     267              : 
     268              :       CALL section_vals_val_get(pint_section, "DT", &
     269           58 :                                 r_val=pint_env%dt)
     270           58 :       pint_env%t = pint_env%first_step*pint_env%dt
     271              : 
     272           58 :       CALL section_vals_val_get(pint_section, "nrespa", i_val=pint_env%nrespa)
     273           58 :       CALL section_vals_val_get(pint_section, "Temp", r_val=pint_env%kT)
     274              :       CALL section_vals_val_get(pint_section, "T_TOL", &
     275           58 :                                 r_val=pint_env%t_tol)
     276              : 
     277           58 :       CALL section_vals_val_get(pint_section, "HARM_INT", i_val=pint_env%harm_integrator)
     278              : 
     279           58 :       ALLOCATE (pint_env%propagator)
     280              :       CALL section_vals_val_get(pint_section, "propagator", &
     281           58 :                                 i_val=pint_env%propagator%prop_kind)
     282              :       !Initialize simulation temperature depending on the propagator
     283              :       !As well as the scaling factor for the physical potential
     284           58 :       IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
     285           18 :          pint_env%propagator%temp_phys2sim = REAL(pint_env%p, dp)
     286           18 :          pint_env%propagator%physpotscale = 1.0_dp
     287              :       ELSE
     288           40 :          pint_env%propagator%temp_phys2sim = 1.0_dp
     289           40 :          pint_env%propagator%physpotscale = 1.0_dp/REAL(pint_env%p, dp)
     290              :       END IF
     291           58 :       pint_env%propagator%temp_sim2phys = 1.0_dp/pint_env%propagator%temp_phys2sim
     292           58 :       pint_env%kT = pint_env%kT*pint_env%propagator%temp_phys2sim
     293              : 
     294              :       CALL section_vals_val_get(pint_section, "transformation", &
     295           58 :                                 i_val=pint_env%transform)
     296              : 
     297           58 :       IF ((pint_env%propagator%prop_kind == propagator_cmd) .AND. &
     298              :           (pint_env%transform /= transformation_normal)) THEN
     299            0 :          CPABORT("CMD propagator without normal modes not implemented!")
     300              :       END IF
     301              : 
     302           58 :       IF ((pint_env%propagator%prop_kind == propagator_bcmd) .AND. &
     303              :           (pint_env%transform /= transformation_normal)) THEN
     304            0 :          CPABORT("BCMD propagator without normal modes not implemented!")
     305              :       END IF
     306              : 
     307           58 :       NULLIFY (pint_env%tx, pint_env%tv, pint_env%tv_t, pint_env%tv_old, pint_env%tv_new, pint_env%tf)
     308              : 
     309           58 :       pint_env%nnos = 0
     310           58 :       pint_env%pimd_thermostat = thermostat_none
     311           58 :       nose_section => section_vals_get_subs_vals(input, "MOTION%PINT%NOSE")
     312           58 :       CALL section_vals_get(nose_section, explicit=explicit)
     313           58 :       IF (explicit) THEN
     314           26 :          IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
     315            0 :             CPABORT("RPMD propagator with Nose-thermostat not implemented!")
     316              :          END IF
     317           26 :          IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
     318            0 :             CPABORT("BCMD propagator with Nose-thermostat not implemented!")
     319              :          END IF
     320           26 :          CALL section_vals_val_get(nose_section, "nnos", i_val=pint_env%nnos)
     321           26 :          IF (pint_env%nnos > 0) THEN
     322           26 :             pint_env%pimd_thermostat = thermostat_nose
     323              :             ALLOCATE ( &
     324              :                pint_env%tx(pint_env%nnos, pint_env%p, pint_env%ndim), &
     325              :                pint_env%tv(pint_env%nnos, pint_env%p, pint_env%ndim), &
     326              :                pint_env%tv_t(pint_env%nnos, pint_env%p, pint_env%ndim), &
     327              :                pint_env%tv_old(pint_env%nnos, pint_env%p, pint_env%ndim), &
     328              :                pint_env%tv_new(pint_env%nnos, pint_env%p, pint_env%ndim), &
     329          520 :                pint_env%tf(pint_env%nnos, pint_env%p, pint_env%ndim))
     330        88244 :             pint_env%tx = 0._dp
     331        88244 :             pint_env%tv = 0._dp
     332        88244 :             pint_env%tv_t = 0._dp
     333        88244 :             pint_env%tv_old = 0._dp
     334        88244 :             pint_env%tv_new = 0._dp
     335        88244 :             pint_env%tf = 0._dp
     336              :          END IF
     337              :       END IF
     338              : 
     339           58 :       pint_env%beta = 1._dp/(pint_env%kT*pint_env%propagator%temp_sim2phys)
     340              : !TODO
     341              : ! v_tol not in current input structure
     342              : ! should also probably be part of nose_section
     343              : !       CALL section_vals_val_get(transform_section,"v_tol_nose",r_val=pint_env%v_tol)
     344              : !MK ... but we have to initialise v_tol
     345           58 :       pint_env%v_tol = 0.0_dp ! to be fixed
     346              : 
     347              :       pint_env%randomG = rng_stream_type( &
     348              :                          name="pint_randomG", &
     349              :                          distribution_type=GAUSSIAN, &
     350           58 :                          extended_precision=.TRUE.)
     351              : 
     352          174 :       ALLOCATE (pint_env%e_pot_bead(pint_env%p))
     353          410 :       pint_env%e_pot_bead = 0._dp
     354           58 :       pint_env%e_pot_h = 0._dp
     355           58 :       pint_env%e_kin_beads = 0._dp
     356           58 :       pint_env%e_pot_t = 0._dp
     357           58 :       pint_env%e_gle = 0._dp
     358           58 :       pint_env%e_pile = 0._dp
     359           58 :       pint_env%e_piglet = 0._dp
     360           58 :       pint_env%e_qtb = 0._dp
     361           58 :       pint_env%e_kin_t = 0._dp
     362          290 :       pint_env%energy(:) = 0.0_dp
     363              : 
     364              : !TODO: rearrange to use standard nose hoover chain functions/data types
     365              : 
     366              :       ALLOCATE ( &
     367              :          pint_env%x(pint_env%p, pint_env%ndim), &
     368              :          pint_env%v(pint_env%p, pint_env%ndim), &
     369              :          pint_env%f(pint_env%p, pint_env%ndim), &
     370              :          pint_env%external_f(pint_env%p, pint_env%ndim), &
     371              :          pint_env%ux(pint_env%p, pint_env%ndim), &
     372              :          pint_env%ux_t(pint_env%p, pint_env%ndim), &
     373              :          pint_env%uv(pint_env%p, pint_env%ndim), &
     374              :          pint_env%uv_t(pint_env%p, pint_env%ndim), &
     375              :          pint_env%uv_new(pint_env%p, pint_env%ndim), &
     376              :          pint_env%uf(pint_env%p, pint_env%ndim), &
     377              :          pint_env%uf_h(pint_env%p, pint_env%ndim), &
     378              :          pint_env%centroid(pint_env%ndim), &
     379              :          pint_env%rtmp_ndim(pint_env%ndim), &
     380              :          pint_env%rtmp_natom(pint_env%ndim/3), &
     381         1682 :          STAT=stat)
     382           58 :       CPASSERT(stat == 0)
     383       362632 :       pint_env%x = 0._dp
     384       362632 :       pint_env%v = 0._dp
     385       362632 :       pint_env%f = 0._dp
     386       362632 :       pint_env%external_f = 0._dp
     387       362632 :       pint_env%ux = 0._dp
     388       362632 :       pint_env%ux_t = 0._dp
     389       362632 :       pint_env%uv = 0._dp
     390       362632 :       pint_env%uv_t = 0._dp
     391       362632 :       pint_env%uv_new = 0._dp
     392       362632 :       pint_env%uf = 0._dp
     393       362632 :       pint_env%uf_h = 0._dp
     394        64984 :       pint_env%centroid(:) = 0.0_dp
     395        64984 :       pint_env%rtmp_ndim = 0._dp
     396        21700 :       pint_env%rtmp_natom = 0._dp
     397           58 :       pint_env%time_per_step = 0.0_dp
     398              : 
     399           58 :       IF (pint_env%transform == transformation_stage) THEN
     400              :          transform_section => section_vals_get_subs_vals(input, &
     401            0 :                                                          "MOTION%PINT%STAGING")
     402            0 :          ALLOCATE (pint_env%staging_env)
     403              :          CALL staging_env_create(pint_env%staging_env, transform_section, &
     404            0 :                                  p=pint_env%p, kT=pint_env%kT)
     405              :       ELSE
     406              :          transform_section => section_vals_get_subs_vals(input, &
     407           58 :                                                          "MOTION%PINT%NORMALMODE")
     408           58 :          IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
     409            2 :             CALL section_vals_val_get(transform_section, "GAMMA", explicit=explicit)
     410            2 :             IF (explicit) THEN
     411              :                CALL section_vals_val_set(transform_section, "GAMMA", &
     412            0 :                                          r_val=SQRT(2.0_dp/(pint_env%p*pint_env%dt*pint_env%kT)))
     413              :             ELSE
     414              :                CALL section_vals_val_set(transform_section, "MODEFACTOR", &
     415            2 :                                          r_val=0.5_dp*pint_env%p*pint_env%dt*pint_env%kT)
     416              :             END IF
     417              :          END IF
     418           58 :          ALLOCATE (pint_env%normalmode_env)
     419              :          CALL normalmode_env_create(pint_env%normalmode_env, &
     420           58 :                                     transform_section, p=pint_env%p, kT=pint_env%kT, propagator=pint_env%propagator%prop_kind)
     421           58 :          IF (para_env%is_source()) THEN
     422           29 :             IF (pint_env%harm_integrator == integrate_numeric) THEN
     423           97 :                IF (10.0_dp*pint_env%dt/REAL(pint_env%nrespa, dp) > &
     424              :                    twopi/(pint_env%p*SQRT(MAXVAL(pint_env%normalmode_env%lambda))* &
     425              :                           pint_env%normalmode_env%modefactor)) THEN
     426              :                   msg = "PINT WARNING| Number of RESPA steps to small "// &
     427            0 :                         "to integrate the harmonic springs."
     428            0 :                   CPWARN(msg)
     429              :                END IF
     430              :             END IF
     431              :          END IF
     432              :       END IF
     433          174 :       ALLOCATE (pint_env%mass(pint_env%ndim))
     434              :       CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, &
     435           58 :                               f_env=f_env)
     436           58 :       CALL force_env_get(force_env=f_env%force_env, subsys=subsys)
     437           58 :       CALL cp_subsys_get(subsys, particles=particles, gci=gci)
     438              : 
     439              : !TODO length of pint_env%mass is redundant
     440           58 :       idim = 0
     441        21700 :       DO iat = 1, pint_env%ndim/3
     442        21642 :          CALL get_atomic_kind(particles%els(iat)%atomic_kind, mass=mass)
     443        86626 :          DO idir = 1, 3
     444        64926 :             idim = idim + 1
     445        86568 :             pint_env%mass(idim) = mass
     446              :          END DO
     447              :       END DO
     448           58 :       CALL f_env_rm_defaults(f_env, ierr)
     449           58 :       CPASSERT(ierr == 0)
     450              : 
     451              :       ALLOCATE (pint_env%Q(pint_env%p), &
     452              :                 pint_env%mass_beads(pint_env%p, pint_env%ndim), &
     453          464 :                 pint_env%mass_fict(pint_env%p, pint_env%ndim))
     454           58 :       IF (pint_env%transform == transformation_stage) THEN
     455              :          CALL staging_init_masses(pint_env%staging_env, mass=pint_env%mass, &
     456              :                                   mass_beads=pint_env%mass_beads, mass_fict=pint_env%mass_fict, &
     457            0 :                                   Q=pint_env%Q)
     458              :       ELSE
     459              :          CALL normalmode_init_masses(pint_env%normalmode_env, &
     460              :                                      mass=pint_env%mass, mass_beads=pint_env%mass_beads, &
     461           58 :                                      mass_fict=pint_env%mass_fict, Q=pint_env%Q)
     462              :       END IF
     463              : 
     464           58 :       NULLIFY (pint_env%gle)
     465           58 :       gle_section => section_vals_get_subs_vals(input, "MOTION%PINT%GLE")
     466           58 :       CALL section_vals_get(gle_section, explicit=explicit)
     467           58 :       IF (explicit) THEN
     468            2 :          ALLOCATE (pint_env%gle)
     469              :          CALL gle_init(pint_env%gle, dt=pint_env%dt/pint_env%nrespa, temp=pint_env%kT, &
     470            2 :                        section=gle_section)
     471            2 :          IF (pint_env%pimd_thermostat == thermostat_none .AND. pint_env%gle%ndim > 0) THEN
     472            2 :             pint_env%pimd_thermostat = thermostat_gle
     473              : 
     474              :             ! initialize a GLE with ALL degrees of freedom on node 0,
     475              :             ! as it seems to me that here everything but force eval is replicated
     476            2 :             pint_env%gle%loc_num_gle = pint_env%p*pint_env%ndim
     477            2 :             pint_env%gle%glob_num_gle = pint_env%gle%loc_num_gle
     478            6 :             ALLOCATE (pint_env%gle%map_info%index(pint_env%gle%loc_num_gle))
     479            2 :             CPASSERT(stat == 0)
     480        18434 :             DO itmp = 1, pint_env%gle%loc_num_gle
     481        18434 :                pint_env%gle%map_info%index(itmp) = itmp
     482              :             END DO
     483            2 :             CALL gle_thermo_create(pint_env%gle, pint_env%gle%loc_num_gle)
     484              : 
     485              :             ! here we should have read a_mat and c_mat;
     486              :             !we can therefore compute the matrices needed for the propagator
     487              :             ! deterministic part of the propagator
     488              :             CALL gle_matrix_exp((-pint_env%dt/pint_env%nrespa*0.5_dp)*pint_env%gle%a_mat, &
     489           62 :                                 pint_env%gle%ndim, 15, 15, pint_env%gle%gle_t)
     490              :             ! stochastic part
     491            8 :             CALL gle_cholesky_stab(pint_env%gle%c_mat - MATMUL(pint_env%gle%gle_t, &
     492            8 :                                                                MATMUL(pint_env%gle%c_mat, TRANSPOSE(pint_env%gle%gle_t))), &
     493         2184 :                                    pint_env%gle%gle_s, pint_env%gle%ndim)
     494              :             ! and initialize the additional momenta
     495            2 :             CALL pint_gle_init(pint_env)
     496              :          END IF
     497              :       END IF
     498              : 
     499              :       !Setup pile thermostat
     500           58 :       NULLIFY (pint_env%pile_therm)
     501           58 :       pile_section => section_vals_get_subs_vals(input, "MOTION%PINT%PILE")
     502           58 :       CALL section_vals_get(pile_section, explicit=explicit)
     503           58 :       IF (explicit) THEN
     504           10 :          CALL cite_reference(Ceriotti2010)
     505              :          CALL section_vals_val_get(pint_env%input, &
     506              :                                    "MOTION%PINT%INIT%THERMOSTAT_SEED", &
     507           10 :                                    i_val=pint_env%thermostat_rng_seed)
     508           10 :          IF (pint_env%pimd_thermostat == thermostat_none) THEN
     509           10 :             pint_env%pimd_thermostat = thermostat_pile
     510          250 :             ALLOCATE (pint_env%pile_therm)
     511              :             CALL pint_pile_init(pile_therm=pint_env%pile_therm, &
     512              :                                 pint_env=pint_env, &
     513              :                                 normalmode_env=pint_env%normalmode_env, &
     514           10 :                                 section=pile_section)
     515              :          ELSE
     516            0 :             CPABORT("PILE thermostat can't be used with another thermostat.")
     517              :          END IF
     518              :       END IF
     519              : 
     520              :       !Setup PIGLET thermostat
     521           58 :       NULLIFY (pint_env%piglet_therm)
     522           58 :       piglet_section => section_vals_get_subs_vals(input, "MOTION%PINT%PIGLET")
     523           58 :       CALL section_vals_get(piglet_section, explicit=explicit)
     524           58 :       IF (explicit) THEN
     525            2 :          CALL cite_reference(Ceriotti2012)
     526              :          CALL section_vals_val_get(pint_env%input, &
     527              :                                    "MOTION%PINT%INIT%THERMOSTAT_SEED", &
     528            2 :                                    i_val=pint_env%thermostat_rng_seed)
     529            2 :          IF (pint_env%pimd_thermostat == thermostat_none) THEN
     530            2 :             pint_env%pimd_thermostat = thermostat_piglet
     531           50 :             ALLOCATE (pint_env%piglet_therm)
     532              :             CALL pint_piglet_create(pint_env%piglet_therm, &
     533              :                                     pint_env, &
     534            2 :                                     piglet_section)
     535              :             CALL pint_piglet_init(pint_env%piglet_therm, &
     536              :                                   pint_env, &
     537              :                                   piglet_section, &
     538            2 :                                   dt=pint_env%dt, para_env=para_env)
     539              :          ELSE
     540            0 :             CPABORT("PIGLET thermostat can't be used with another thermostat.")
     541              :          END IF
     542              :       END IF
     543              : 
     544              :       !Setup qtb thermostat
     545           58 :       NULLIFY (pint_env%qtb_therm)
     546           58 :       qtb_section => section_vals_get_subs_vals(input, "MOTION%PINT%QTB")
     547           58 :       CALL section_vals_get(qtb_section, explicit=explicit)
     548           58 :       IF (explicit) THEN
     549            6 :          CALL cite_reference(Brieuc2016)
     550              :          CALL section_vals_val_get(pint_env%input, &
     551              :                                    "MOTION%PINT%INIT%THERMOSTAT_SEED", &
     552            6 :                                    i_val=pint_env%thermostat_rng_seed)
     553            6 :          IF (pint_env%pimd_thermostat == thermostat_none) THEN
     554            6 :             pint_env%pimd_thermostat = thermostat_qtb
     555              :             CALL pint_qtb_init(qtb_therm=pint_env%qtb_therm, &
     556              :                                pint_env=pint_env, &
     557              :                                normalmode_env=pint_env%normalmode_env, &
     558            6 :                                section=qtb_section)
     559              :          ELSE
     560            0 :             CPABORT("QTB thermostat can't be used with another thermostat.")
     561              :          END IF
     562              :       END IF
     563              : 
     564              :       ! force PILE for BCMD
     565           58 :       IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
     566            2 :          IF (pint_env%pimd_thermostat == thermostat_none) THEN
     567              :             !crate section
     568            2 :             pile_section => section_vals_get_subs_vals(input, "MOTION%PINT%PILE")
     569            2 :             CALL section_vals_get(pile_section, explicit=explicit)
     570            2 :             IF (.NOT. explicit) THEN
     571            2 :                CALL section_vals_add_values(pile_section)
     572              :             END IF
     573              :             CALL section_vals_val_get(pint_env%input, &
     574              :                                       "MOTION%PINT%INIT%THERMOSTAT_SEED", &
     575            2 :                                       i_val=pint_env%thermostat_rng_seed)
     576            2 :             pint_env%pimd_thermostat = thermostat_pile
     577           50 :             ALLOCATE (pint_env%pile_therm)
     578              :             CALL pint_pile_init(pile_therm=pint_env%pile_therm, &
     579              :                                 pint_env=pint_env, &
     580              :                                 normalmode_env=pint_env%normalmode_env, &
     581            2 :                                 section=pile_section)
     582              :          END IF
     583            2 :          IF (pint_env%pimd_thermostat /= thermostat_pile) THEN
     584            0 :             CPABORT("PILE/no thermostat currently needed for BCMD")
     585              :          END IF
     586            2 :          CALL cite_reference(Shiga2022)
     587              :       END IF
     588              : 
     589              :       !Initialize integrator scheme
     590           58 :       CALL section_vals_val_get(pint_section, "HARM_INT", i_val=pint_env%harm_integrator)
     591           58 :       IF (pint_env%harm_integrator == integrate_exact) THEN
     592           24 :          IF (pint_env%pimd_thermostat == thermostat_nose) THEN
     593              :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| Nose Thermostat only available in "// &
     594            0 :                "the numeric harmonic integrator. Switching to numeric harmonic integrator."
     595            0 :             CPWARN(msg)
     596            0 :             pint_env%harm_integrator = integrate_numeric
     597              :          END IF
     598           24 :          IF (pint_env%pimd_thermostat == thermostat_gle) THEN
     599              :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| GLE Thermostat only available in "// &
     600            0 :                "the numeric harmonic integrator. Switching to numeric harmonic integrator."
     601            0 :             CPWARN(msg)
     602            0 :             pint_env%harm_integrator = integrate_numeric
     603              :          END IF
     604           34 :       ELSE IF (pint_env%harm_integrator == integrate_numeric) THEN
     605           34 :          IF (pint_env%pimd_thermostat == thermostat_pile) THEN
     606              :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| PILE Thermostat only available in "// &
     607            2 :                "the exact harmonic integrator. Switching to exact harmonic integrator."
     608            2 :             CPWARN(msg)
     609            2 :             pint_env%harm_integrator = integrate_exact
     610              :          END IF
     611           34 :          IF (pint_env%pimd_thermostat == thermostat_piglet) THEN
     612              :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| PIGLET Thermostat only available in "// &
     613            0 :                "the exact harmonic integrator. Switching to exact harmonic integrator."
     614            0 :             CPWARN(msg)
     615            0 :             pint_env%harm_integrator = integrate_exact
     616              :          END IF
     617           34 :          IF (pint_env%pimd_thermostat == thermostat_qtb) THEN
     618              :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| QTB Thermostat only available in "// &
     619            0 :                "the exact harmonic integrator. Switching to exact harmonic integrator."
     620            0 :             CPWARN(msg)
     621            0 :             pint_env%harm_integrator = integrate_exact
     622              :          END IF
     623           34 :          IF (pint_env%propagator%prop_kind == propagator_bcmd) THEN
     624              :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| BCMD needs the exact harmonic "// &
     625            0 :                "integrator. Switching to exact harmonic integrator."
     626            0 :             CPWARN(msg)
     627            0 :             pint_env%harm_integrator = integrate_exact
     628              :          END IF
     629              :       END IF
     630              : 
     631           58 :       IF (pint_env%harm_integrator == integrate_exact) THEN
     632           26 :          IF (pint_env%nrespa /= 1) THEN
     633           18 :             pint_env%nrespa = 1
     634           18 :             WRITE (UNIT=msg, FMT=*) "PINT WARNING| Adjusting NRESPA to 1 for exact harmonic integration."
     635           18 :             CPWARN(msg)
     636              :          END IF
     637           26 :          NULLIFY (pint_env%wsinex)
     638           78 :          ALLOCATE (pint_env%wsinex(pint_env%p))
     639           26 :          NULLIFY (pint_env%iwsinex)
     640           52 :          ALLOCATE (pint_env%iwsinex(pint_env%p))
     641           26 :          NULLIFY (pint_env%cosex)
     642           52 :          ALLOCATE (pint_env%cosex(pint_env%p))
     643           26 :          dt = pint_env%dt/REAL(pint_env%nrespa, KIND=dp)
     644              :          !Centroid mode shoud not be propagated
     645           26 :          pint_env%wsinex(1) = 0.0_dp
     646           26 :          pint_env%iwsinex(1) = dt
     647           26 :          pint_env%cosex(1) = 1.0_dp
     648          212 :          DO ibead = 2, pint_env%p
     649          186 :             omega = SQRT(pint_env%normalmode_env%lambda(ibead))
     650          186 :             pint_env%wsinex(ibead) = SIN(omega*dt)*omega
     651          186 :             pint_env%iwsinex(ibead) = SIN(omega*dt)/omega
     652          212 :             pint_env%cosex(ibead) = COS(omega*dt)
     653              :          END DO
     654              :       END IF
     655              : 
     656              :       CALL section_vals_val_get(pint_section, "FIX_CENTROID_POS", &
     657           58 :                                 l_val=ltmp)
     658           58 :       IF (ltmp .AND. (pint_env%transform == transformation_normal)) THEN
     659            0 :          pint_env%first_propagated_mode = 2
     660              :       ELSE
     661           58 :          pint_env%first_propagated_mode = 1
     662              :       END IF
     663              : 
     664              :       ! Constraint information:
     665           58 :       NULLIFY (pint_env%simpar)
     666              :       constraint_section => section_vals_get_subs_vals(pint_env%input, &
     667           58 :                                                        "MOTION%CONSTRAINT")
     668           58 :       CALL section_vals_get(constraint_section, explicit=explicit)
     669           58 :       CALL create_simpar_type(pint_env%simpar)
     670           58 :       pint_env%simpar%constraint = explicit
     671           58 :       pint_env%kTcorr = 1.0_dp
     672              : 
     673              :       ! Determine if beadwise constraints are activated
     674           58 :       pint_env%beadwise_constraints = .FALSE.
     675              :       CALL section_vals_val_get(constraint_section, "PIMD_BEADWISE_CONSTRAINT", &
     676           58 :                                 l_val=pint_env%beadwise_constraints)
     677           58 :       IF (pint_env%simpar%constraint) THEN
     678            6 :          IF (pint_env%beadwise_constraints) THEN
     679            2 :             CALL pint_write_line("Using beadwise constraints")
     680              :          ELSE
     681            4 :             CALL pint_write_line("Using centroid constraints")
     682              :          END IF
     683              :       END IF
     684              : 
     685           58 :       IF (explicit) THEN
     686              :          ! Staging not supported yet, since lowest mode is assumed
     687              :          ! to be related to centroid
     688            6 :          IF (pint_env%transform == transformation_stage) THEN
     689            0 :             CPABORT("Constraints are not supported for staging transformation")
     690              :          END IF
     691              : 
     692              :          ! Check thermostats that are not supported:
     693            6 :          IF (pint_env%pimd_thermostat == thermostat_gle) THEN
     694              :             WRITE (UNIT=msg, FMT=*) "GLE Thermostat not supported for "// &
     695            0 :                "constraints. Switch to NOSE for numeric integration."
     696            0 :             CPABORT(msg)
     697              :          END IF
     698              :          ! Warn for NOSE
     699            6 :          IF (pint_env%pimd_thermostat == thermostat_nose) THEN
     700              :             !Beadwise constraints not supported
     701            2 :             IF (pint_env%beadwise_constraints) THEN
     702            0 :                CPABORT("Beadwise constraints are not supported for NOSE Thermostat.")
     703              :                !Centroid constraints supported
     704              :             ELSE
     705              :                WRITE (UNIT=msg, FMT=*) "PINT WARNING| Nose Thermostat set to "// &
     706            2 :                   "zero for constrained atoms. Careful interpretation of temperature."
     707            2 :                CPWARN(msg)
     708              :                WRITE (UNIT=msg, FMT=*) "PINT WARNING| Lagrange multipliers are "// &
     709            2 :                   "are printed every RESPA step and need to be treated carefully."
     710            2 :                CPWARN(msg)
     711              :             END IF
     712              :          END IF
     713              : 
     714              :          CALL section_vals_val_get(constraint_section, "SHAKE_TOLERANCE", &
     715            6 :                                    r_val=pint_env%simpar%shake_tol)
     716              :          pint_env%simpar%info_constraint = cp_print_key_unit_nr(pint_env%logger, &
     717              :                                                                 constraint_section, &
     718              :                                                                 "CONSTRAINT_INFO", &
     719              :                                                                 extension=".shakeLog", &
     720            6 :                                                                 log_filename=.FALSE.)
     721              :          pint_env%simpar%lagrange_multipliers = cp_print_key_unit_nr(pint_env%logger, &
     722              :                                                                      constraint_section, &
     723              :                                                                      "LAGRANGE_MULTIPLIERS", &
     724              :                                                                      extension=".LagrangeMultLog", &
     725            6 :                                                                      log_filename=.FALSE.)
     726              :          pint_env%simpar%dump_lm = &
     727              :             BTEST(cp_print_key_should_output(pint_env%logger%iter_info, &
     728              :                                              constraint_section, &
     729            6 :                                              "LAGRANGE_MULTIPLIERS"), cp_p_file)
     730              : 
     731              :          ! Determine constrained atoms:
     732            6 :          pint_env%n_atoms_constraints = 0
     733           12 :          DO ig = 1, gci%ncolv%ntot
     734              :             ! Double counts, if the same atom is involved in different collective variables
     735           12 :             pint_env%n_atoms_constraints = pint_env%n_atoms_constraints + SIZE(gci%colv_list(ig)%i_atoms)
     736              :          END DO
     737              : 
     738           18 :          ALLOCATE (pint_env%atoms_constraints(pint_env%n_atoms_constraints))
     739            6 :          icont = 0
     740           12 :          DO ig = 1, gci%ncolv%ntot
     741           24 :             DO iat = 1, SIZE(gci%colv_list(ig)%i_atoms)
     742           12 :                icont = icont + 1
     743           18 :                pint_env%atoms_constraints(icont) = gci%colv_list(ig)%i_atoms(iat)
     744              :             END DO
     745              :          END DO
     746              : 
     747              :          ! Set the correction to the temperature due to the frozen degrees of freedom in NOSE:
     748              :          CALL section_vals_val_get(pint_section, "kT_CORRECTION", &
     749            6 :                                    l_val=ltmp)
     750            6 :          IF (ltmp) THEN
     751            0 :             pint_env%kTcorr = 1.0_dp + REAL(3*pint_env%n_atoms_constraints, dp)/(REAL(pint_env%ndim, dp)*REAL(pint_env%p, dp))
     752              :          END IF
     753              :       END IF
     754              : 
     755           58 :       CALL timestop(handle)
     756              : 
     757          638 :    END SUBROUTINE pint_create
     758              : 
     759              : ! ***************************************************************************
     760              : !> \brief Release a path integral environment
     761              : !> \param pint_env the pint_env to release
     762              : !> \par History
     763              : !>      Added normal mode transformation [hforbert]
     764              : !> \author Fawzi Mohamed
     765              : ! **************************************************************************************************
     766           58 :    SUBROUTINE pint_release(pint_env)
     767              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
     768              : 
     769           58 :       CALL rep_env_release(pint_env%replicas)
     770           58 :       CALL section_vals_release(pint_env%input)
     771           58 :       IF (ASSOCIATED(pint_env%staging_env)) THEN
     772            0 :          CALL staging_release(pint_env%staging_env)
     773            0 :          DEALLOCATE (pint_env%staging_env)
     774              :       END IF
     775           58 :       IF (ASSOCIATED(pint_env%normalmode_env)) THEN
     776           58 :          CALL normalmode_release(pint_env%normalmode_env)
     777           58 :          DEALLOCATE (pint_env%normalmode_env)
     778              :       END IF
     779              : 
     780           58 :       DEALLOCATE (pint_env%mass)
     781           58 :       DEALLOCATE (pint_env%e_pot_bead)
     782              : 
     783           58 :       DEALLOCATE (pint_env%x)
     784           58 :       DEALLOCATE (pint_env%v)
     785           58 :       DEALLOCATE (pint_env%f)
     786           58 :       DEALLOCATE (pint_env%external_f)
     787           58 :       DEALLOCATE (pint_env%mass_beads)
     788           58 :       DEALLOCATE (pint_env%mass_fict)
     789           58 :       DEALLOCATE (pint_env%ux)
     790           58 :       DEALLOCATE (pint_env%ux_t)
     791           58 :       DEALLOCATE (pint_env%uv)
     792           58 :       DEALLOCATE (pint_env%uv_t)
     793           58 :       DEALLOCATE (pint_env%uv_new)
     794           58 :       DEALLOCATE (pint_env%uf)
     795           58 :       DEALLOCATE (pint_env%uf_h)
     796           58 :       DEALLOCATE (pint_env%centroid)
     797           58 :       DEALLOCATE (pint_env%rtmp_ndim)
     798           58 :       DEALLOCATE (pint_env%rtmp_natom)
     799           58 :       DEALLOCATE (pint_env%propagator)
     800              : 
     801           58 :       IF (pint_env%simpar%constraint) THEN
     802            6 :          DEALLOCATE (pint_env%atoms_constraints)
     803              :       END IF
     804           58 :       CALL release_simpar_type(pint_env%simpar)
     805              : 
     806           58 :       IF (pint_env%harm_integrator == integrate_exact) THEN
     807           26 :          DEALLOCATE (pint_env%wsinex)
     808           26 :          DEALLOCATE (pint_env%iwsinex)
     809           26 :          DEALLOCATE (pint_env%cosex)
     810              :       END IF
     811              : 
     812           84 :       SELECT CASE (pint_env%pimd_thermostat)
     813              :       CASE (thermostat_nose)
     814           26 :          DEALLOCATE (pint_env%tx)
     815           26 :          DEALLOCATE (pint_env%tv)
     816           26 :          DEALLOCATE (pint_env%tv_t)
     817           26 :          DEALLOCATE (pint_env%tv_old)
     818           26 :          DEALLOCATE (pint_env%tv_new)
     819           26 :          DEALLOCATE (pint_env%tf)
     820              :       CASE (thermostat_gle)
     821            2 :          CALL gle_dealloc(pint_env%gle)
     822              :       CASE (thermostat_pile)
     823           12 :          CALL pint_pile_release(pint_env%pile_therm)
     824           12 :          DEALLOCATE (pint_env%pile_therm)
     825              :       CASE (thermostat_piglet)
     826            2 :          CALL pint_piglet_release(pint_env%piglet_therm)
     827            2 :          DEALLOCATE (pint_env%piglet_therm)
     828              :       CASE (thermostat_qtb)
     829            6 :          CALL pint_qtb_release(pint_env%qtb_therm)
     830           64 :          DEALLOCATE (pint_env%qtb_therm)
     831              :       END SELECT
     832              : 
     833           58 :       DEALLOCATE (pint_env%Q)
     834              : 
     835           58 :    END SUBROUTINE pint_release
     836              : 
     837              : ! ***************************************************************************
     838              : !> \brief Tests the path integral methods
     839              : !> \param para_env parallel environment
     840              : !> \param input the input to test
     841              : !> \param input_declaration ...
     842              : !> \author fawzi
     843              : ! **************************************************************************************************
     844            0 :    SUBROUTINE pint_test(para_env, input, input_declaration)
     845              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     846              :       TYPE(section_vals_type), POINTER                   :: input
     847              :       TYPE(section_type), POINTER                        :: input_declaration
     848              : 
     849              :       INTEGER                                            :: i, ib, idim, unit_nr
     850              :       REAL(kind=dp)                                      :: c, e_h, err
     851            0 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :)        :: x1
     852              :       TYPE(pint_env_type)                                :: pint_env
     853              : 
     854            0 :       CPASSERT(ASSOCIATED(para_env))
     855            0 :       CPASSERT(ASSOCIATED(input))
     856            0 :       CPASSERT(para_env%is_valid())
     857            0 :       CPASSERT(input%ref_count > 0)
     858            0 :       unit_nr = cp_logger_get_default_io_unit()
     859            0 :       CALL pint_create(pint_env, input, input_declaration, para_env)
     860            0 :       ALLOCATE (x1(pint_env%ndim, pint_env%p))
     861            0 :       x1(:, :) = pint_env%x
     862            0 :       CALL pint_x2u(pint_env)
     863            0 :       pint_env%x = 0._dp
     864            0 :       CALL pint_u2x(pint_env)
     865            0 :       err = 0._dp
     866            0 :       DO i = 1, pint_env%ndim
     867            0 :          err = MAX(err, ABS(x1(1, i) - pint_env%x(1, i)))
     868              :       END DO
     869            0 :       IF (unit_nr > 0) WRITE (unit_nr, *) "diff_r1="//cp_to_string(err)
     870              : 
     871            0 :       CALL pint_calc_uf_h(pint_env, e_h=e_h)
     872            0 :       c = -pint_env%staging_env%w_p**2
     873            0 :       pint_env%f = 0._dp
     874            0 :       DO idim = 1, pint_env%ndim
     875            0 :          DO ib = 1, pint_env%p
     876              :             pint_env%f(ib, idim) = pint_env%f(ib, idim) + &
     877              :                                    c*(2._dp*pint_env%x(ib, idim) &
     878              :                                       - pint_env%x(MODULO(ib - 2, pint_env%p) + 1, idim) &
     879            0 :                                       - pint_env%x(MODULO(ib, pint_env%p) + 1, idim))
     880              :          END DO
     881              :       END DO
     882            0 :       CALL pint_f2uf(pint_env)
     883            0 :       err = 0._dp
     884            0 :       DO idim = 1, pint_env%ndim
     885            0 :          DO ib = 1, pint_env%p
     886            0 :             err = MAX(err, ABS(pint_env%uf(ib, idim) - pint_env%uf_h(ib, idim)))
     887              :          END DO
     888              :       END DO
     889            0 :       IF (unit_nr > 0) WRITE (unit_nr, *) "diff_f_h="//cp_to_string(err)
     890              : 
     891            0 :    END SUBROUTINE pint_test
     892              : 
     893              : ! ***************************************************************************
     894              : !> \brief  Perform a path integral simulation
     895              : !> \param  para_env parallel environment
     896              : !> \param  input the input to test
     897              : !> \param input_declaration ...
     898              : !> \param globenv ...
     899              : !> \par    History
     900              : !>         2003-11 created [fawzi]
     901              : !>         2009-12-14 globenv parameter added to handle soft exit
     902              : !>           requests [lwalewski]
     903              : !>         2016-07-14 Modified to work with independent helium_env [cschran]
     904              : !> \author Fawzi Mohamed
     905              : ! **************************************************************************************************
     906          204 :    SUBROUTINE do_pint_run(para_env, input, input_declaration, globenv)
     907              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     908              :       TYPE(section_vals_type), POINTER                   :: input
     909              :       TYPE(section_type), POINTER                        :: input_declaration
     910              :       TYPE(global_environment_type), POINTER             :: globenv
     911              : 
     912              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'do_pint_run'
     913              :       INTEGER, PARAMETER                                 :: helium_only_mid = 1, &
     914              :                                                             int_pot_scan_mid = 4, &
     915              :                                                             solute_only_mid = 2, &
     916              :                                                             solute_with_helium_mid = 3
     917              : 
     918              :       CHARACTER(len=default_string_length)               :: stmp
     919              :       INTEGER                                            :: handle, mode
     920              :       LOGICAL                                            :: explicit, helium_only, int_pot_scan, &
     921              :                                                             solvent_present
     922           68 :       TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
     923              :       TYPE(pint_env_type)                                :: pint_env
     924              :       TYPE(section_vals_type), POINTER                   :: helium_section
     925              : 
     926           68 :       CALL timeset(routineN, handle)
     927              : 
     928           68 :       CPASSERT(ASSOCIATED(para_env))
     929           68 :       CPASSERT(ASSOCIATED(input))
     930           68 :       CPASSERT(para_env%is_valid())
     931           68 :       CPASSERT(input%ref_count > 0)
     932              : 
     933              :       ! check if helium solvent is present
     934           68 :       NULLIFY (helium_section)
     935              :       helium_section => section_vals_get_subs_vals(input, &
     936           68 :                                                    "MOTION%PINT%HELIUM")
     937           68 :       CALL section_vals_get(helium_section, explicit=explicit)
     938           68 :       IF (explicit) THEN
     939              :          CALL section_vals_val_get(helium_section, "_SECTION_PARAMETERS_", &
     940           26 :                                    l_val=solvent_present)
     941              :       ELSE
     942           42 :          solvent_present = .FALSE.
     943              :       END IF
     944              : 
     945              :       ! check if there is anything but helium
     946           68 :       IF (solvent_present) THEN
     947              :          CALL section_vals_val_get(helium_section, "HELIUM_ONLY", &
     948           26 :                                    l_val=helium_only)
     949              :       ELSE
     950           42 :          helium_only = .FALSE.
     951              :       END IF
     952              : 
     953              :       ! check wheather to perform solute-helium interaction pot scan
     954           68 :       IF (solvent_present) THEN
     955              :          CALL section_vals_val_get(helium_section, "INTERACTION_POT_SCAN", &
     956           26 :                                    l_val=int_pot_scan)
     957              :       ELSE
     958           42 :          int_pot_scan = .FALSE.
     959              :       END IF
     960              : 
     961              :       ! input consistency check
     962           68 :       IF (helium_only .AND. int_pot_scan) THEN
     963            0 :          stmp = "Options HELIUM_ONLY and INTERACTION_POT_SCAN are exclusive"
     964            0 :          CPABORT(stmp)
     965              :       END IF
     966              : 
     967              :       ! select mode of operation
     968              :       mode = 0
     969           68 :       IF (solvent_present) THEN
     970           26 :          IF (helium_only) THEN
     971           10 :             mode = helium_only_mid
     972              :          ELSE
     973           16 :             IF (int_pot_scan) THEN
     974            0 :                mode = int_pot_scan_mid
     975              :             ELSE
     976           16 :                mode = solute_with_helium_mid
     977              :             END IF
     978              :          END IF
     979              :       ELSE
     980           42 :          mode = solute_only_mid
     981              :       END IF
     982              : 
     983              :       ! perform the simulation according to the chosen mode
     984           10 :       SELECT CASE (mode)
     985              : 
     986              :       CASE (helium_only_mid)
     987           10 :          CALL helium_create(helium_env, input)
     988           10 :          CALL helium_init(helium_env, pint_env)
     989           10 :          CALL helium_do_run(helium_env, globenv)
     990           10 :          CALL helium_release(helium_env)
     991              : 
     992              :       CASE (solute_only_mid)
     993           42 :          CALL pint_create(pint_env, input, input_declaration, para_env)
     994           42 :          CALL pint_init(pint_env)
     995           42 :          CALL pint_do_run(pint_env, globenv)
     996           42 :          CALL pint_release(pint_env)
     997              : 
     998              :       CASE (int_pot_scan_mid)
     999            0 :          CALL pint_create(pint_env, input, input_declaration, para_env)
    1000              : ! TODO only initialization of positions is necessary, but rep_env_calc_e_f called
    1001              : ! from within pint_init_f does something to the replica environments which can not be
    1002              : ! avoided (has something to do with f_env_add_defaults) so leaving for now..
    1003            0 :          CALL pint_init(pint_env)
    1004            0 :          CALL helium_create(helium_env, input, solute=pint_env)
    1005            0 :          CALL pint_run_scan(pint_env, helium_env)
    1006            0 :          CALL helium_release(helium_env)
    1007            0 :          CALL pint_release(pint_env)
    1008              : 
    1009              :       CASE (solute_with_helium_mid)
    1010           16 :          CALL pint_create(pint_env, input, input_declaration, para_env)
    1011              :          ! init pint without helium forces (they are not yet initialized)
    1012           16 :          CALL pint_init(pint_env)
    1013              :          ! init helium with solute's positions (they are already initialized)
    1014           16 :          CALL helium_create(helium_env, input, solute=pint_env)
    1015           16 :          CALL helium_init(helium_env, pint_env)
    1016              :          ! reinit pint forces with helium forces (they are now initialized)
    1017           16 :          CALL pint_init_f(pint_env, helium_env=helium_env)
    1018              : 
    1019           16 :          CALL pint_do_run(pint_env, globenv, helium_env=helium_env)
    1020           16 :          CALL helium_release(helium_env)
    1021           16 :          CALL pint_release(pint_env)
    1022              : 
    1023              :       CASE DEFAULT
    1024           68 :          CPABORT("Unknown mode ("//TRIM(ADJUSTL(cp_to_string(mode)))//")")
    1025              :       END SELECT
    1026              : 
    1027           68 :       CALL timestop(handle)
    1028              : 
    1029         1972 :    END SUBROUTINE do_pint_run
    1030              : 
    1031              : ! ***************************************************************************
    1032              : !> \brief  Reads the restart, initializes the beads, etc.
    1033              : !> \param pint_env ...
    1034              : !> \par    History
    1035              : !>           11.2003 created [fawzi]
    1036              : !>           actually ASSIGN input pointer [hforbert]
    1037              : !>           2010-12-16 turned into a wrapper routine [lwalewski]
    1038              : !> \author Fawzi Mohamed
    1039              : ! **************************************************************************************************
    1040           58 :    SUBROUTINE pint_init(pint_env)
    1041              : 
    1042              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1043              : 
    1044           58 :       CALL pint_init_x(pint_env)
    1045           58 :       CALL pint_init_v(pint_env)
    1046           58 :       CALL pint_init_t(pint_env)
    1047           58 :       CALL pint_init_f(pint_env)
    1048              : 
    1049           58 :    END SUBROUTINE pint_init
    1050              : 
    1051              : ! ***************************************************************************
    1052              : !> \brief  Assign initial postions to the beads.
    1053              : !> \param pint_env ...
    1054              : !> \date   2010-12-15
    1055              : !> \author Lukasz Walewski
    1056              : !> \note  Initialization is done in the following way:
    1057              : !>           1. assign all beads with the same classical positions from
    1058              : !>              FORCE_EVAL (hot start)
    1059              : !>           2. spread the beads around classical positions as if they were
    1060              : !>              free particles (if requested)
    1061              : !>           3. replace positions generated in steps 1-2 with the explicit
    1062              : !>              ones if they are explicitly given in the input structure
    1063              : !>           4. apply Gaussian noise to the positions generated so far (if
    1064              : !>              requested)
    1065              : ! **************************************************************************************************
    1066           58 :    SUBROUTINE pint_init_x(pint_env)
    1067              : 
    1068              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1069              : 
    1070              :       CHARACTER(len=5*default_string_length)             :: msg, tmp
    1071              :       INTEGER                                            :: ia, ib, ic, idim, input_seed, n_rep_val
    1072              :       LOGICAL                                            :: done_init, done_levy, done_rand, &
    1073              :                                                             explicit, levycorr, ltmp
    1074              :       REAL(kind=dp)                                      :: tcorr, var
    1075              :       REAL(kind=dp), DIMENSION(3)                        :: x0
    1076              :       REAL(kind=dp), DIMENSION(3, 2)                     :: seed
    1077           58 :       REAL(kind=dp), DIMENSION(:), POINTER               :: bx, r_vals
    1078           58 :       TYPE(rng_stream_type), ALLOCATABLE                 :: rng_gaussian
    1079              :       TYPE(section_vals_type), POINTER                   :: input_section
    1080              : 
    1081        64984 :       DO idim = 1, pint_env%ndim
    1082       362632 :          DO ib = 1, pint_env%p
    1083       362574 :             pint_env%x(ib, idim) = pint_env%replicas%r(idim, ib)
    1084              :          END DO
    1085              :       END DO
    1086              : 
    1087           58 :       done_levy = .FALSE.
    1088              :       CALL section_vals_val_get(pint_env%input, &
    1089              :                                 "MOTION%PINT%INIT%LEVY_POS_SAMPLE", &
    1090           58 :                                 l_val=ltmp)
    1091              :       CALL section_vals_val_get(pint_env%input, &
    1092              :                                 "MOTION%PINT%INIT%LEVY_TEMP_FACTOR", &
    1093           58 :                                 r_val=tcorr)
    1094           58 :       IF (ltmp) THEN
    1095              : 
    1096            0 :          IF (pint_env%beadwise_constraints) THEN
    1097              :             WRITE (UNIT=msg, FMT=*) "Beadwise constraints are not supported for "// &
    1098              :                "the initialization of the beads as free particles. "// &
    1099            0 :                "Please use hot start (default)."
    1100            0 :             CPABORT(msg)
    1101              :          END IF
    1102              : 
    1103            0 :          NULLIFY (bx)
    1104            0 :          ALLOCATE (bx(3*pint_env%p))
    1105              :          CALL section_vals_val_get(pint_env%input, &
    1106            0 :                                    "MOTION%PINT%INIT%LEVY_SEED", i_val=input_seed)
    1107            0 :          seed(:, :) = REAL(input_seed, KIND=dp)
    1108              : !      seed(:,:) = next_rng_seed()
    1109              :          rng_gaussian = rng_stream_type( &
    1110              :                         name="tmp_rng_gaussian", &
    1111              :                         distribution_type=GAUSSIAN, &
    1112              :                         extended_precision=.TRUE., &
    1113            0 :                         seed=seed)
    1114              : 
    1115              :          CALL section_vals_val_get(pint_env%input, &
    1116              :                                    "MOTION%PINT%INIT%LEVY_CORRELATED", &
    1117            0 :                                    l_val=levycorr)
    1118              : 
    1119            0 :          IF (levycorr) THEN
    1120              : 
    1121              :             ! correlated Levy walk - the same path for all atoms
    1122            0 :             x0 = [0.0_dp, 0.0_dp, 0.0_dp]
    1123            0 :             CALL pint_levy_walk(x0, pint_env%p, 1.0_dp, bx, rng_gaussian)
    1124            0 :             idim = 0
    1125            0 :             DO ia = 1, pint_env%ndim/3
    1126            0 :                var = SQRT(1.0_dp/(pint_env%kT*tcorr*pint_env%mass(3*ia)))
    1127            0 :                DO ic = 1, 3
    1128            0 :                   idim = idim + 1
    1129            0 :                   DO ib = 1, pint_env%p
    1130            0 :                      pint_env%x(ib, idim) = pint_env%x(ib, idim) + bx(3*(ib - 1) + ic)*var
    1131              :                   END DO
    1132              :                END DO
    1133              :             END DO
    1134              : 
    1135              :          ELSE
    1136              : 
    1137              :             ! uncorrelated bead initialization - distinct Levy walk for each atom
    1138            0 :             idim = 0
    1139            0 :             DO ia = 1, pint_env%ndim/3
    1140            0 :                x0(1) = pint_env%x(1, 3*(ia - 1) + 1)
    1141            0 :                x0(2) = pint_env%x(1, 3*(ia - 1) + 2)
    1142            0 :                x0(3) = pint_env%x(1, 3*(ia - 1) + 3)
    1143            0 :                var = SQRT(1.0_dp/(pint_env%kT*tcorr*pint_env%mass(3*ia)))
    1144            0 :                CALL pint_levy_walk(x0, pint_env%p, var, bx, rng_gaussian)
    1145            0 :                DO ic = 1, 3
    1146            0 :                   idim = idim + 1
    1147            0 :                   DO ib = 1, pint_env%p
    1148            0 :                      pint_env%x(ib, idim) = pint_env%x(ib, idim) + bx(3*(ib - 1) + ic)
    1149              :                   END DO
    1150              :                END DO
    1151              :             END DO
    1152              : 
    1153              :          END IF
    1154              : 
    1155            0 :          DEALLOCATE (bx)
    1156            0 :          done_levy = .TRUE.
    1157              :       END IF
    1158              : 
    1159           58 :       done_init = .FALSE.
    1160           58 :       NULLIFY (input_section)
    1161              :       input_section => section_vals_get_subs_vals(pint_env%input, &
    1162           58 :                                                   "MOTION%PINT%BEADS%COORD")
    1163           58 :       CALL section_vals_get(input_section, explicit=explicit)
    1164           58 :       IF (explicit) THEN
    1165              :          CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1166            8 :                                    n_rep_val=n_rep_val)
    1167            8 :          IF (n_rep_val > 0) THEN
    1168            8 :             CPASSERT(n_rep_val == 1)
    1169              :             CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1170            8 :                                       r_vals=r_vals)
    1171            8 :             IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim) &
    1172            0 :                CPABORT("Invalid size of MOTION%PINT%BEADS%COORD")
    1173            8 :             ic = 0
    1174         9278 :             DO idim = 1, pint_env%ndim
    1175        46358 :                DO ib = 1, pint_env%p
    1176        37080 :                   ic = ic + 1
    1177        46350 :                   pint_env%x(ib, idim) = r_vals(ic)
    1178              :                END DO
    1179              :             END DO
    1180              :             done_init = .TRUE.
    1181              :          END IF
    1182              :       END IF
    1183              : 
    1184           58 :       done_rand = .FALSE.
    1185              :       CALL section_vals_val_get(pint_env%input, &
    1186              :                                 "MOTION%PINT%INIT%RANDOMIZE_POS", &
    1187           58 :                                 l_val=ltmp)
    1188           58 :       IF (ltmp) THEN
    1189              : 
    1190            0 :          IF (pint_env%beadwise_constraints) THEN
    1191              :             WRITE (UNIT=msg, FMT=*) "Beadwise constraints are not supported if "// &
    1192              :                "a random noise is applied to the initialization of the bead positions. "// &
    1193            0 :                "Please use hot start (default)."
    1194            0 :             CPABORT(msg)
    1195              :          END IF
    1196              : 
    1197            0 :          DO idim = 1, pint_env%ndim
    1198            0 :             DO ib = 1, pint_env%p
    1199              :                pint_env%x(ib, idim) = pint_env%x(ib, idim) + &
    1200              :                                       pint_env%randomG%next(variance=pint_env%beta/ &
    1201            0 :                                                             SQRT(12.0_dp*pint_env%mass(idim)))
    1202              :             END DO
    1203              :          END DO
    1204              :          done_rand = .TRUE.
    1205              :       END IF
    1206              : 
    1207           58 :       WRITE (tmp, '(A)') "Bead positions initialization:"
    1208           58 :       IF (done_init) THEN
    1209            8 :          WRITE (msg, '(A,A)') TRIM(tmp), " input structure"
    1210           50 :       ELSE IF (done_levy) THEN
    1211            0 :          WRITE (msg, '(A,A)') TRIM(tmp), " Levy random walk"
    1212              :       ELSE
    1213           50 :          WRITE (msg, '(A,A)') TRIM(tmp), " hot start"
    1214              :       END IF
    1215           58 :       CALL pint_write_line(msg)
    1216              : 
    1217           58 :       IF (done_levy) THEN
    1218            0 :          WRITE (msg, '(A,F6.3)') "Levy walk at effective temperature: ", tcorr
    1219              :       END IF
    1220              : 
    1221           58 :       IF (done_rand) THEN
    1222            0 :          WRITE (msg, '(A)') "Added gaussian noise to the positions of the beads."
    1223            0 :          CALL pint_write_line(msg)
    1224              :       END IF
    1225              : 
    1226          116 :    END SUBROUTINE pint_init_x
    1227              : 
    1228              : ! ***************************************************************************
    1229              : !> \brief  Initialize velocities
    1230              : !> \param  pint_env the pint env in which you should initialize the
    1231              : !>         velocity
    1232              : !> \par    History
    1233              : !>         2010-12-16 gathered all velocity-init code here [lwalewski]
    1234              : !>         2011-04-05 added centroid velocity initialization [lwalewski]
    1235              : !>         2011-12-19 removed optional parameter kT, target temperature is
    1236              : !>                    now determined from the input directly [lwalewski]
    1237              : !> \author fawzi
    1238              : !> \note   Initialization is done according to the following protocol:
    1239              : !>         1. set all the velocities to FORCE_EVAL%SUBSYS%VELOCITY if present
    1240              : !>         2. scale the velocities according to the actual temperature
    1241              : !>            (has no effect if vels not present in 1.)
    1242              : !>         3. draw vels for the remaining dof from MB distribution
    1243              : !>            (all or non-centroid modes only depending on 1.)
    1244              : !>         4. add random noise to the centroid vels if CENTROID_SPEED == T
    1245              : !>         5. set the vels for all dof to 0.0 if VELOCITY_QUENCH == T
    1246              : !>         6. set the vels according to the explicit values from the input
    1247              : !>            if present
    1248              : ! **************************************************************************************************
    1249           58 :    SUBROUTINE pint_init_v(pint_env)
    1250              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1251              : 
    1252              :       CHARACTER(len=default_string_length)               :: msg, stmp, stmp1, stmp2, unit_str
    1253              :       INTEGER                                            :: first_mode, i, ia, ib, ic, idim, ierr, &
    1254              :                                                             itmp, j, n_rep_val, nparticle, &
    1255              :                                                             nparticle_kind
    1256              :       LOGICAL                                            :: done_init, done_quench, done_scale, &
    1257              :                                                             done_sped, explicit, ltmp, vels_present
    1258              :       REAL(kind=dp)                                      :: actual_t, ek, factor, rtmp, target_t, &
    1259              :                                                             unit_conv
    1260           58 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: vel
    1261           58 :       REAL(kind=dp), DIMENSION(:), POINTER               :: r_vals
    1262              :       TYPE(atomic_kind_list_type), POINTER               :: atomic_kinds
    1263           58 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1264              :       TYPE(cell_type), POINTER                           :: cell
    1265              :       TYPE(cp_logger_type), POINTER                      :: logger
    1266              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1267              :       TYPE(distribution_1d_type), POINTER                :: local_molecules, local_particles
    1268              :       TYPE(f_env_type), POINTER                          :: f_env
    1269              :       TYPE(global_constraint_type), POINTER              :: gci
    1270              :       TYPE(molecule_kind_list_type), POINTER             :: molecule_kinds
    1271           58 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1272              :       TYPE(molecule_list_type), POINTER                  :: molecules
    1273           58 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1274              :       TYPE(particle_list_type), POINTER                  :: particles
    1275           58 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1276              :       TYPE(section_vals_type), POINTER                   :: input_section
    1277              : 
    1278           58 :       NULLIFY (logger)
    1279          116 :       logger => cp_get_default_logger()
    1280              : 
    1281              :       ! Get constraint info, if needed
    1282              :       ! Create a force environment which will be identical to
    1283              :       ! the bead that is being processed by the processor.
    1284           58 :       IF (pint_env%simpar%constraint) THEN
    1285            6 :          NULLIFY (subsys, cell)
    1286            6 :          NULLIFY (atomic_kinds, local_particles, particles)
    1287            6 :          NULLIFY (local_molecules, molecules, molecule_kinds, gci)
    1288            6 :          NULLIFY (atomic_kind_set, molecule_kind_set, particle_set, molecule_set)
    1289              : 
    1290            6 :          CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, f_env=f_env)
    1291            6 :          CALL force_env_get(force_env=f_env%force_env, subsys=subsys)
    1292            6 :          CALL f_env_rm_defaults(f_env, ierr)
    1293            6 :          CPASSERT(ierr == 0)
    1294              : 
    1295              :          ! Get gci and more from subsys
    1296              :          CALL cp_subsys_get(subsys=subsys, &
    1297              :                             cell=cell, &
    1298              :                             atomic_kinds=atomic_kinds, &
    1299              :                             local_particles=local_particles, &
    1300              :                             particles=particles, &
    1301              :                             local_molecules=local_molecules, &
    1302              :                             molecules=molecules, &
    1303              :                             molecule_kinds=molecule_kinds, &
    1304            6 :                             gci=gci)
    1305              : 
    1306            6 :          nparticle_kind = atomic_kinds%n_els
    1307            6 :          atomic_kind_set => atomic_kinds%els
    1308            6 :          molecule_kind_set => molecule_kinds%els
    1309            6 :          nparticle = particles%n_els
    1310            6 :          particle_set => particles%els
    1311            6 :          molecule_set => molecules%els
    1312              : 
    1313              :          ! Allocate work storage
    1314           18 :          ALLOCATE (vel(3, nparticle))
    1315            6 :          vel(:, :) = 0.0_dp
    1316              :          CALL getold(gci, local_molecules, molecule_set, &
    1317           12 :                      molecule_kind_set, particle_set, cell)
    1318              :       END IF
    1319              : 
    1320              :       ! read the velocities from the input file if they are given explicitly
    1321           58 :       vels_present = .FALSE.
    1322           58 :       NULLIFY (input_section)
    1323              :       input_section => section_vals_get_subs_vals(pint_env%input, &
    1324           58 :                                                   "FORCE_EVAL%SUBSYS%VELOCITY")
    1325           58 :       CALL section_vals_get(input_section, explicit=explicit)
    1326           58 :       IF (explicit) THEN
    1327              : 
    1328              :          CALL section_vals_val_get(input_section, "PINT_UNIT", &
    1329            2 :                                    c_val=unit_str)
    1330            2 :          unit_conv = cp_unit_to_cp2k(1.0_dp, TRIM(unit_str))
    1331              : 
    1332              :          ! assign all the beads with the same velocities from FORCE_EVAL%SUBSYS%VELOCITY
    1333            2 :          NULLIFY (r_vals)
    1334              :          CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1335            2 :                                    n_rep_val=n_rep_val)
    1336            2 :          stmp = ""
    1337            2 :          WRITE (stmp, *) n_rep_val
    1338              :          msg = "Invalid number of atoms in FORCE_EVAL%SUBSYS%VELOCITY ("// &
    1339            2 :                TRIM(ADJUSTL(stmp))//")."
    1340            2 :          IF (3*n_rep_val /= pint_env%ndim) &
    1341            0 :             CPABORT(msg)
    1342           14 :          DO ia = 1, pint_env%ndim/3
    1343              :             CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1344           12 :                                       i_rep_val=ia, r_vals=r_vals)
    1345           12 :             itmp = SIZE(r_vals)
    1346           12 :             stmp = ""
    1347           12 :             WRITE (stmp, *) itmp
    1348              :             msg = "Number of coordinates != 3 in FORCE_EVAL%SUBSYS%VELOCITY ("// &
    1349           12 :                   TRIM(ADJUSTL(stmp))//")."
    1350           12 :             IF (itmp /= 3) &
    1351            0 :                CPABORT(msg)
    1352          110 :             DO ib = 1, pint_env%p
    1353          396 :                DO ic = 1, 3
    1354          288 :                   idim = 3*(ia - 1) + ic
    1355          384 :                   pint_env%v(ib, idim) = r_vals(ic)*unit_conv
    1356              :                END DO
    1357              :             END DO
    1358              :          END DO
    1359              : 
    1360              :          vels_present = .TRUE.
    1361              :       END IF
    1362              : 
    1363              :       ! set the actual temperature...
    1364              :       IF (vels_present) THEN
    1365              :          ! ...from the initial velocities
    1366            2 :          ek = 0.0_dp
    1367           14 :          DO ia = 1, pint_env%ndim/3
    1368              :             rtmp = 0.0_dp
    1369           48 :             DO ic = 1, 3
    1370           36 :                idim = 3*(ia - 1) + ic
    1371           48 :                rtmp = rtmp + pint_env%v(1, idim)*pint_env%v(1, idim)
    1372              :             END DO
    1373           14 :             ek = ek + 0.5_dp*pint_env%mass(idim)*rtmp
    1374              :          END DO
    1375            2 :          actual_t = 2.0_dp*ek/pint_env%ndim
    1376              :       ELSE
    1377              :          ! ...using the temperature value from the input
    1378           56 :          actual_t = pint_env%kT
    1379              :       END IF
    1380              : 
    1381              :       ! set the target temperature
    1382           58 :       target_t = pint_env%kT
    1383              :       CALL section_vals_val_get(pint_env%input, &
    1384              :                                 "MOTION%PINT%INIT%VELOCITY_SCALE", &
    1385           58 :                                 l_val=done_scale)
    1386           58 :       IF (vels_present) THEN
    1387            2 :          IF (done_scale) THEN
    1388              :             ! rescale the velocities to match the target temperature
    1389            2 :             rtmp = SQRT(target_t/actual_t)
    1390           14 :             DO ia = 1, pint_env%ndim/3
    1391          110 :                DO ib = 1, pint_env%p
    1392          396 :                   DO ic = 1, 3
    1393          288 :                      idim = 3*(ia - 1) + ic
    1394          384 :                      pint_env%v(ib, idim) = rtmp*pint_env%v(ib, idim)
    1395              :                   END DO
    1396              :                END DO
    1397              :             END DO
    1398              :          ELSE
    1399              :             target_t = actual_t
    1400              :          END IF
    1401              :       END IF
    1402              : 
    1403              :       ! draw velocities from the M-B distribution...
    1404              :       IF (vels_present) THEN
    1405              :          ! ...for non-centroid modes only
    1406            2 :          CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
    1407            2 :          first_mode = 2
    1408              :       ELSE
    1409              :          ! ...for all the modes
    1410              :          first_mode = 1
    1411              :       END IF
    1412        64984 :       DO idim = 1, SIZE(pint_env%uv, 2)
    1413       362596 :          DO ib = first_mode, SIZE(pint_env%uv, 1)
    1414              :             pint_env%uv(ib, idim) = &
    1415       362538 :                pint_env%randomG%next(variance=target_t/pint_env%mass_fict(ib, idim))
    1416              :          END DO
    1417              :       END DO
    1418              : 
    1419              :       ! add random component to the centroid velocity if requested
    1420           58 :       done_sped = .FALSE.
    1421              :       CALL section_vals_val_get(pint_env%input, &
    1422              :                                 "MOTION%PINT%INIT%CENTROID_SPEED", &
    1423           58 :                                 l_val=ltmp)
    1424           58 :       IF (ltmp) THEN
    1425            0 :          CALL pint_u2x(pint_env, ux=pint_env%uv, x=pint_env%v)
    1426            0 :          DO idim = 1, pint_env%ndim
    1427              :             rtmp = pint_env%randomG%next(variance=pint_env%mass(idim)*pint_env%kT) &
    1428            0 :                    /pint_env%mass(idim)
    1429            0 :             DO ib = 1, pint_env%p
    1430            0 :                pint_env%v(ib, idim) = pint_env%v(ib, idim) + rtmp
    1431              :             END DO
    1432              :          END DO
    1433            0 :          CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
    1434            0 :          done_sped = .TRUE.
    1435              :       END IF
    1436              : 
    1437              :       ! quench (set to zero) velocities for all the modes if requested
    1438              :       ! (disregard all the initialization done so far)
    1439           58 :       done_quench = .FALSE.
    1440              :       CALL section_vals_val_get(pint_env%input, &
    1441              :                                 "MOTION%PINT%INIT%VELOCITY_QUENCH", &
    1442           58 :                                 l_val=ltmp)
    1443           58 :       IF (ltmp) THEN
    1444            0 :          DO idim = 1, pint_env%ndim
    1445            0 :             DO ib = 1, pint_env%p
    1446            0 :                pint_env%v(ib, idim) = 0.0_dp
    1447              :             END DO
    1448              :          END DO
    1449            0 :          CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
    1450            0 :          done_quench = .TRUE.
    1451              :       END IF
    1452              : 
    1453              :       ! set the velocities to the values from the input if they are explicit
    1454              :       ! (disregard all the initialization done so far)
    1455           58 :       done_init = .FALSE.
    1456           58 :       NULLIFY (input_section)
    1457              :       input_section => section_vals_get_subs_vals(pint_env%input, &
    1458           58 :                                                   "MOTION%PINT%BEADS%VELOCITY")
    1459           58 :       CALL section_vals_get(input_section, explicit=explicit)
    1460           58 :       IF (explicit) THEN
    1461              :          CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1462            8 :                                    n_rep_val=n_rep_val)
    1463            8 :          IF (n_rep_val > 0) THEN
    1464            8 :             CPASSERT(n_rep_val == 1)
    1465              :             CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1466            8 :                                       r_vals=r_vals)
    1467            8 :             IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim) &
    1468            0 :                CPABORT("Invalid size of MOTION%PINT%BEAD%VELOCITY")
    1469            8 :             itmp = 0
    1470         9278 :             DO idim = 1, pint_env%ndim
    1471        46358 :                DO ib = 1, pint_env%p
    1472        37080 :                   itmp = itmp + 1
    1473        46350 :                   pint_env%v(ib, idim) = r_vals(itmp)
    1474              :                END DO
    1475              :             END DO
    1476            8 :             CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
    1477            8 :             done_init = .TRUE.
    1478              :          END IF
    1479              :       END IF
    1480              : 
    1481           58 :       unit_conv = cp_unit_from_cp2k(1.0_dp, "K")
    1482           58 :       WRITE (stmp1, '(F10.2)') target_t*pint_env%propagator%temp_sim2phys*unit_conv
    1483           58 :       msg = "Bead velocities initialization:"
    1484           58 :       IF (done_init) THEN
    1485            8 :          msg = TRIM(msg)//" input structure"
    1486           50 :       ELSE IF (done_quench) THEN
    1487            0 :          msg = TRIM(msg)//" quenching (set to 0.0)"
    1488              :       ELSE
    1489           50 :          IF (vels_present) THEN
    1490            2 :             msg = TRIM(ADJUSTL(msg))//" centroid +"
    1491              :          END IF
    1492           50 :          msg = TRIM(ADJUSTL(msg))//" Maxwell-Boltzmann at "//TRIM(ADJUSTL(stmp1))//" K."
    1493              :       END IF
    1494           58 :       CALL pint_write_line(msg)
    1495              : 
    1496           58 :       IF (done_init .AND. done_quench) THEN
    1497            0 :          msg = "WARNING: exclusive options requested (velocity restart and quenching)"
    1498            0 :          CPWARN(msg)
    1499            0 :          msg = "WARNING: velocity restart took precedence"
    1500            0 :          CPWARN(msg)
    1501              :       END IF
    1502              : 
    1503           58 :       IF ((.NOT. done_init) .AND. (.NOT. done_quench)) THEN
    1504           50 :          IF (vels_present .AND. done_scale) THEN
    1505            2 :             WRITE (stmp1, '(F10.2)') actual_t*unit_conv
    1506            2 :             WRITE (stmp2, '(F10.2)') target_t*unit_conv
    1507              :             msg = "Scaled initial velocities from "//TRIM(ADJUSTL(stmp1))// &
    1508            2 :                   " to "//TRIM(ADJUSTL(stmp2))//" K as requested."
    1509            2 :             CPWARN(msg)
    1510              :          END IF
    1511           50 :          IF (done_sped) THEN
    1512            0 :             msg = "Added random component to the initial centroid velocities."
    1513            0 :             CPWARN(msg)
    1514              :          END IF
    1515              :       END IF
    1516              : 
    1517              :       ! Apply constraints to the initial velocities
    1518           58 :       IF (pint_env%simpar%constraint) THEN
    1519            6 :          IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
    1520              :             ! Multiply with 1/SQRT(n_beads) due to normal mode transformation in RPMD
    1521            0 :             factor = SQRT(REAL(pint_env%p, dp))
    1522              :          ELSE
    1523              :             ! lowest NM is centroid
    1524              :             factor = 1.0_dp
    1525              :          END IF
    1526              :          ! Beadwise constraints
    1527            6 :          IF (pint_env%beadwise_constraints) THEN
    1528            2 :             IF (pint_env%logger%para_env%is_source()) THEN
    1529            1 :                CALL pint_u2x(pint_env, ux=pint_env%uv, x=pint_env%v)
    1530            5 :                DO ib = 1, pint_env%p
    1531           16 :                   DO i = 1, nparticle
    1532           52 :                      DO j = 1, 3
    1533              :                         ! Centroid is also constrained. This has to be changed if the initialization
    1534              :                         ! of the positions of the beads is done as free particles (LEVY_POS_SAMPLE)
    1535              :                         ! or if a Gaussian noise is added (RANDOMIZE_POS)
    1536           36 :                         particle_set(i)%r(j) = pint_env%x(1, j + (i - 1)*3)/factor
    1537           48 :                         vel(j, i) = pint_env%v(ib, j + (i - 1)*3)
    1538              :                      END DO
    1539              :                   END DO
    1540              :                   ! Possibly update the target values
    1541              :                   CALL shake_update_targets(gci, local_molecules, molecule_set, &
    1542              :                                             molecule_kind_set, pint_env%dt, &
    1543            4 :                                             f_env%force_env%root_section)
    1544              :                   CALL rattle_control(gci, local_molecules, molecule_set, &
    1545              :                                       molecule_kind_set, particle_set, &
    1546              :                                       vel, pint_env%dt, pint_env%simpar%shake_tol, &
    1547              :                                       pint_env%simpar%info_constraint, &
    1548              :                                       pint_env%simpar%lagrange_multipliers, &
    1549              :                                       .FALSE., &
    1550              :                                       cell, mp_comm_self, &
    1551            4 :                                       local_particles)
    1552           17 :                   DO i = 1, nparticle
    1553           52 :                      DO j = 1, 3
    1554           48 :                         pint_env%v(ib, j + (i - 1)*3) = vel(j, i)
    1555              :                      END DO
    1556              :                   END DO
    1557              :                END DO
    1558              :                ! Transform back to normal modes:
    1559            1 :                CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
    1560              :             END IF
    1561              :             ! Broadcast updated velocities to other nodes
    1562          182 :             CALL pint_env%logger%para_env%bcast(pint_env%uv)
    1563              :             ! Centroid constraints
    1564              :          ELSE
    1565              :             ! Transform positions and velocities to Cartesian coordinates:
    1566            4 :             IF (pint_env%logger%para_env%is_source()) THEN
    1567            8 :                DO i = 1, nparticle
    1568           26 :                   DO j = 1, 3
    1569           18 :                      particle_set(i)%r(j) = pint_env%x(1, j + (i - 1)*3)/factor
    1570           24 :                      vel(j, i) = pint_env%uv(1, j + (i - 1)*3)/factor
    1571              :                   END DO
    1572              :                END DO
    1573              :                ! Possibly update the target values
    1574              :                CALL shake_update_targets(gci, local_molecules, molecule_set, &
    1575              :                                          molecule_kind_set, pint_env%dt, &
    1576            2 :                                          f_env%force_env%root_section)
    1577              :                CALL rattle_control(gci, local_molecules, molecule_set, &
    1578              :                                    molecule_kind_set, particle_set, &
    1579              :                                    vel, pint_env%dt, pint_env%simpar%shake_tol, &
    1580              :                                    pint_env%simpar%info_constraint, &
    1581              :                                    pint_env%simpar%lagrange_multipliers, &
    1582              :                                    .FALSE., &
    1583              :                                    cell, mp_comm_self, &
    1584            2 :                                    local_particles)
    1585              :             END IF
    1586              :             ! Broadcast updated velocities to other nodes
    1587            4 :             CALL pint_env%logger%para_env%bcast(vel)
    1588              :             ! Transform back to normal modes
    1589           16 :             DO i = 1, nparticle
    1590           52 :                DO j = 1, 3
    1591           48 :                   pint_env%uv(1, j + (i - 1)*3) = vel(j, i)*factor
    1592              :                END DO
    1593              :             END DO
    1594              :          END IF
    1595              :       END IF
    1596              : 
    1597          116 :    END SUBROUTINE pint_init_v
    1598              : 
    1599              : ! ***************************************************************************
    1600              : !> \brief  Assign initial postions and velocities to the thermostats.
    1601              : !> \param pint_env ...
    1602              : !> \param kT ...
    1603              : !> \date   2010-12-15
    1604              : !> \author Lukasz Walewski
    1605              : !> \note   Extracted from pint_init
    1606              : ! **************************************************************************************************
    1607           58 :    SUBROUTINE pint_init_t(pint_env, kT)
    1608              : 
    1609              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1610              :       REAL(kind=dp), INTENT(in), OPTIONAL                :: kT
    1611              : 
    1612              :       INTEGER                                            :: ib, idim, ii, inos, n_rep_val
    1613              :       LOGICAL                                            :: explicit, gle_restart
    1614              :       REAL(kind=dp)                                      :: mykt
    1615           58 :       REAL(kind=dp), DIMENSION(:), POINTER               :: r_vals
    1616              :       TYPE(section_vals_type), POINTER                   :: input_section
    1617              : 
    1618          110 :       IF (pint_env%pimd_thermostat == thermostat_nose) THEN
    1619              : 
    1620           26 :          mykt = pint_env%kT
    1621           26 :          IF (PRESENT(kT)) mykt = kT
    1622         9476 :          DO idim = 1, SIZE(pint_env%tv, 3)
    1623        29096 :             DO ib = 1, SIZE(pint_env%tv, 2)
    1624        88218 :                DO inos = 1, SIZE(pint_env%tv, 1)
    1625              :                   pint_env%tv(inos, ib, idim) = &
    1626        78768 :                      pint_env%randomG%next(variance=mykt/pint_env%Q(ib))
    1627              :                END DO
    1628              :             END DO
    1629              :          END DO
    1630           26 :          IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    1631           74 :             pint_env%tv(:, 1, :) = 0.0_dp
    1632              :          END IF
    1633              : 
    1634           26 :          NULLIFY (input_section)
    1635              :          input_section => section_vals_get_subs_vals(pint_env%input, &
    1636           26 :                                                      "MOTION%PINT%NOSE%COORD")
    1637           26 :          CALL section_vals_get(input_section, explicit=explicit)
    1638           26 :          IF (explicit) THEN
    1639              :             CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1640            6 :                                       n_rep_val=n_rep_val)
    1641            6 :             IF (n_rep_val > 0) THEN
    1642            6 :                CPASSERT(n_rep_val == 1)
    1643              :                CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1644            6 :                                          r_vals=r_vals)
    1645            6 :                IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim*pint_env%nnos) &
    1646            0 :                   CPABORT("Invalid size of MOTION%PINT%NOSE%COORD")
    1647            6 :                ii = 0
    1648           60 :                DO idim = 1, pint_env%ndim
    1649          276 :                   DO ib = 1, pint_env%p
    1650          918 :                      DO inos = 1, pint_env%nnos
    1651          648 :                         ii = ii + 1
    1652          864 :                         pint_env%tx(inos, ib, idim) = r_vals(ii)
    1653              :                      END DO
    1654              :                   END DO
    1655              :                END DO
    1656              :             END IF
    1657              :          END IF
    1658           26 :          IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    1659           74 :             pint_env%tx(:, 1, :) = 0.0_dp
    1660              :          END IF
    1661              : 
    1662           26 :          NULLIFY (input_section)
    1663              :          input_section => section_vals_get_subs_vals(pint_env%input, &
    1664           26 :                                                      "MOTION%PINT%NOSE%VELOCITY")
    1665           26 :          CALL section_vals_get(input_section, explicit=explicit)
    1666           26 :          IF (explicit) THEN
    1667              :             CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1668            6 :                                       n_rep_val=n_rep_val)
    1669            6 :             IF (n_rep_val > 0) THEN
    1670            6 :                CPASSERT(n_rep_val == 1)
    1671              :                CALL section_vals_val_get(input_section, "_DEFAULT_KEYWORD_", &
    1672            6 :                                          r_vals=r_vals)
    1673            6 :                IF (SIZE(r_vals) /= pint_env%p*pint_env%ndim*pint_env%nnos) &
    1674            0 :                   CPABORT("Invalid size of MOTION%PINT%NOSE%VELOCITY")
    1675            6 :                ii = 0
    1676           60 :                DO idim = 1, pint_env%ndim
    1677          276 :                   DO ib = 1, pint_env%p
    1678          918 :                      DO inos = 1, pint_env%nnos
    1679          648 :                         ii = ii + 1
    1680          864 :                         pint_env%tv(inos, ib, idim) = r_vals(ii)
    1681              :                      END DO
    1682              :                   END DO
    1683              :                END DO
    1684              :             END IF
    1685            6 :             IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    1686            0 :                pint_env%tv(:, 1, :) = 0.0_dp
    1687              :             END IF
    1688              :          END IF
    1689              : 
    1690           32 :       ELSEIF (pint_env%pimd_thermostat == thermostat_gle) THEN
    1691            2 :          NULLIFY (input_section)
    1692              :          input_section => section_vals_get_subs_vals(pint_env%input, &
    1693            2 :                                                      "MOTION%PINT%GLE")
    1694            2 :          CALL section_vals_get(input_section, explicit=explicit)
    1695            2 :          IF (explicit) THEN
    1696              :             CALL restart_gle(pint_env%gle, input_section, save_mem=.FALSE., &
    1697            2 :                              restart=gle_restart)
    1698              :          END IF
    1699              :       END IF
    1700              : 
    1701           58 :    END SUBROUTINE pint_init_t
    1702              : 
    1703              : ! ***************************************************************************
    1704              : !> \brief  Prepares the forces, etc. to perform an PIMD step
    1705              : !> \param pint_env ...
    1706              : !> \param helium_env ...
    1707              : !> \par    History
    1708              : !>           Added nh_energy calculation [hforbert]
    1709              : !>           Bug fixes for no thermostats [hforbert]
    1710              : !>           2016-07-14 Modified to work with independent helium_env [cschran]
    1711              : !> \author fawzi
    1712              : ! **************************************************************************************************
    1713          148 :    SUBROUTINE pint_init_f(pint_env, helium_env)
    1714              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1715              :       TYPE(helium_solvent_p_type), DIMENSION(:), &
    1716              :          OPTIONAL, POINTER                               :: helium_env
    1717              : 
    1718              :       INTEGER                                            :: ib, idim, inos
    1719              :       REAL(kind=dp)                                      :: e_h
    1720              :       TYPE(cp_logger_type), POINTER                      :: logger
    1721              : 
    1722           74 :       NULLIFY (logger)
    1723           74 :       logger => cp_get_default_logger()
    1724              : 
    1725              :       ! initialize iteration info
    1726           74 :       CALL cp_iterate(logger%iter_info, iter_nr=pint_env%first_step)
    1727           74 :       CALL cp_iterate(pint_env%logger%iter_info, iter_nr=pint_env%first_step)
    1728              : 
    1729           74 :       CALL pint_x2u(pint_env)
    1730           74 :       CALL pint_calc_uf_h(pint_env=pint_env, e_h=e_h)
    1731           74 :       CALL pint_calc_f(pint_env)
    1732              : 
    1733              :       ! add helium forces to the solute's internal ones
    1734              :       ! Assume that helium has been already initialized and helium_env(1)
    1735              :       ! contains proper forces in force_avrg array at ionode
    1736           74 :       IF (PRESENT(helium_env)) THEN
    1737           16 :          IF (logger%para_env%is_source()) THEN
    1738          728 :             pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
    1739              :          END IF
    1740         2896 :          CALL logger%para_env%bcast(pint_env%f)
    1741              :       END IF
    1742           74 :       CALL pint_f2uf(pint_env)
    1743              : 
    1744              :       ! set the centroid forces to 0 if FIX_CENTROID_POS
    1745           74 :       IF (pint_env%first_propagated_mode == 2) THEN
    1746            0 :          pint_env%uf(1, :) = 0.0_dp
    1747              :       END IF
    1748              : 
    1749           74 :       CALL pint_calc_e_kin_beads_u(pint_env)
    1750           74 :       CALL pint_calc_e_vir(pint_env)
    1751        65144 :       DO idim = 1, SIZE(pint_env%uf_h, 2)
    1752       364088 :          DO ib = pint_env%first_propagated_mode, SIZE(pint_env%uf_h, 1)
    1753       364014 :             pint_env%uf(ib, idim) = REAL(pint_env%nrespa, dp)*pint_env%uf(ib, idim)
    1754              :          END DO
    1755              :       END DO
    1756              : 
    1757           74 :       IF (pint_env%nnos > 0) THEN
    1758         9576 :          DO idim = 1, SIZE(pint_env%uf_h, 2)
    1759        29556 :             DO ib = 1, SIZE(pint_env%uf_h, 1)
    1760              :                pint_env%tf(1, ib, idim) = (pint_env%mass_fict(ib, idim)* &
    1761        29520 :                                            pint_env%uv(ib, idim)**2 - pint_env%kT)/pint_env%Q(ib)
    1762              :             END DO
    1763              :          END DO
    1764              : 
    1765         9576 :          DO idim = 1, pint_env%ndim
    1766        29556 :             DO ib = 1, pint_env%p
    1767        60228 :                DO inos = 1, pint_env%nnos - 1
    1768              :                   pint_env%tf(inos + 1, ib, idim) = pint_env%tv(inos, ib, idim)**2 - &
    1769        60228 :                                                     pint_env%kT/pint_env%Q(ib)
    1770              :                END DO
    1771        69768 :                DO inos = 1, pint_env%nnos - 1
    1772              :                   pint_env%tf(inos, ib, idim) = pint_env%tf(inos, ib, idim) &
    1773        60228 :                                                 - pint_env%tv(inos, ib, idim)*pint_env%tv(inos + 1, ib, idim)
    1774              :                END DO
    1775              :             END DO
    1776              :          END DO
    1777           36 :          CALL pint_calc_nh_energy(pint_env)
    1778              :       END IF
    1779              : 
    1780           74 :    END SUBROUTINE pint_init_f
    1781              : 
    1782              : ! ***************************************************************************
    1783              : !> \brief  Perform the PIMD simulation (main MD loop)
    1784              : !> \param pint_env ...
    1785              : !> \param globenv ...
    1786              : !> \param helium_env ...
    1787              : !> \par    History
    1788              : !>         2003-11 created [fawzi]
    1789              : !>         renamed from pint_run to pint_do_run because of conflicting name
    1790              : !>           of pint_run in input_constants [hforbert]
    1791              : !>         2009-12-14 globenv parameter added to handle soft exit
    1792              : !>           requests [lwalewski]
    1793              : !>         2016-07-14 Modified to work with independent helium_env [cschran]
    1794              : !> \author Fawzi Mohamed
    1795              : !> \note   Everything should be read for an md step.
    1796              : ! **************************************************************************************************
    1797           58 :    SUBROUTINE pint_do_run(pint_env, globenv, helium_env)
    1798              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1799              :       TYPE(global_environment_type), POINTER             :: globenv
    1800              :       TYPE(helium_solvent_p_type), DIMENSION(:), &
    1801              :          OPTIONAL, POINTER                               :: helium_env
    1802              : 
    1803              :       INTEGER                                            :: k, step
    1804              :       LOGICAL                                            :: should_stop
    1805              :       REAL(kind=dp)                                      :: scal
    1806              :       TYPE(cp_logger_type), POINTER                      :: logger
    1807              :       TYPE(f_env_type), POINTER                          :: f_env
    1808              : 
    1809              :       ! initialize iteration info
    1810           58 :       CALL cp_iterate(pint_env%logger%iter_info, iter_nr=pint_env%first_step)
    1811              : 
    1812              :       ! iterate replica pint counter by accessing the globally saved
    1813              :       ! force environment error/logger variables and setting them
    1814              :       ! explicitly to the pimd "PINT" step value
    1815              :       CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, &
    1816           58 :                               f_env=f_env)
    1817           58 :       NULLIFY (logger)
    1818           58 :       logger => cp_get_default_logger()
    1819              :       CALL cp_iterate(logger%iter_info, &
    1820           58 :                       iter_nr=pint_env%first_step)
    1821           58 :       CALL f_env_rm_defaults(f_env)
    1822              : 
    1823           58 :       pint_env%iter = pint_env%first_step
    1824              : 
    1825           58 :       IF (PRESENT(helium_env)) THEN
    1826           16 :          IF (ASSOCIATED(helium_env)) THEN
    1827              :             ! set the properties accumulated over the whole MC process to 0
    1828           36 :             DO k = 1, SIZE(helium_env)
    1829           84 :                helium_env(k)%helium%proarea%accu(:) = 0.0_dp
    1830           84 :                helium_env(k)%helium%prarea2%accu(:) = 0.0_dp
    1831           84 :                helium_env(k)%helium%wnmber2%accu(:) = 0.0_dp
    1832           84 :                helium_env(k)%helium%mominer%accu(:) = 0.0_dp
    1833           21 :                IF (helium_env(k)%helium%rho_present) THEN
    1834            0 :                   helium_env(k)%helium%rho_accu(:, :, :, :) = 0.0_dp
    1835              :                END IF
    1836           36 :                IF (helium_env(k)%helium%rdf_present) THEN
    1837            0 :                   helium_env(k)%helium%rdf_accu(:, :) = 0.0_dp
    1838              :                END IF
    1839              :             END DO
    1840              :          END IF
    1841              :       END IF
    1842              : 
    1843              :       ! write the properties at 0-th step
    1844           58 :       CALL pint_calc_energy(pint_env)
    1845           58 :       CALL pint_calc_total_action(pint_env)
    1846           58 :       CALL pint_write_ener(pint_env)
    1847           58 :       CALL pint_write_action(pint_env)
    1848           58 :       CALL pint_write_centroids(pint_env)
    1849           58 :       CALL pint_write_trajectory(pint_env)
    1850           58 :       CALL pint_write_com(pint_env)
    1851           58 :       CALL pint_write_rgyr(pint_env)
    1852              : 
    1853              :       ! main PIMD loop
    1854          696 :       DO step = 1, pint_env%num_steps
    1855              : 
    1856          638 :          pint_env%iter = pint_env%iter + 1
    1857              :          CALL cp_iterate(pint_env%logger%iter_info, &
    1858              :                          last=(step == pint_env%num_steps), &
    1859          638 :                          iter_nr=pint_env%iter)
    1860              :          CALL cp_iterate(logger%iter_info, &
    1861              :                          last=(step == pint_env%num_steps), &
    1862          638 :                          iter_nr=pint_env%iter)
    1863          638 :          pint_env%t = pint_env%t + pint_env%dt
    1864              : 
    1865          638 :          IF (pint_env%t_tol > 0.0_dp) THEN
    1866            0 :             IF (ABS(2._dp*pint_env%e_kin_beads/(pint_env%p*pint_env%ndim) &
    1867              :                     - pint_env%kT) > pint_env%t_tol) THEN
    1868            0 :                scal = SQRT(pint_env%kT*(pint_env%p*pint_env%ndim)/(2.0_dp*pint_env%e_kin_beads))
    1869            0 :                pint_env%uv = scal*pint_env%uv
    1870            0 :                CALL pint_init_f(pint_env, helium_env=helium_env)
    1871              :             END IF
    1872              :          END IF
    1873          638 :          CALL pint_step(pint_env, helium_env=helium_env)
    1874              : 
    1875          638 :          CALL pint_write_ener(pint_env)
    1876          638 :          CALL pint_write_action(pint_env)
    1877          638 :          CALL pint_write_centroids(pint_env)
    1878          638 :          CALL pint_write_trajectory(pint_env)
    1879          638 :          CALL pint_write_com(pint_env)
    1880          638 :          CALL pint_write_rgyr(pint_env)
    1881              : 
    1882              :          CALL write_restart(root_section=pint_env%input, &
    1883          638 :                             pint_env=pint_env, helium_env=helium_env)
    1884              : 
    1885              :          ! exit from the main loop if soft exit has been requested
    1886          638 :          CALL external_control(should_stop, "PINT", globenv=globenv)
    1887          696 :          IF (should_stop) EXIT
    1888              : 
    1889              :       END DO
    1890              : 
    1891              :       ! remove iteration level
    1892           58 :       CALL cp_rm_iter_level(pint_env%logger%iter_info, "PINT")
    1893              : 
    1894           58 :    END SUBROUTINE pint_do_run
    1895              : 
    1896              : ! ***************************************************************************
    1897              : !> \brief  Performs a scan of the helium-solute interaction energy
    1898              : !> \param pint_env ...
    1899              : !> \param helium_env ...
    1900              : !> \date   2013-11-26
    1901              : !> \parm   History
    1902              : !>         2016-07-14 Modified to work with independent helium_env [cschran]
    1903              : !> \author Lukasz Walewski
    1904              : ! **************************************************************************************************
    1905            0 :    SUBROUTINE pint_run_scan(pint_env, helium_env)
    1906              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1907              :       TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
    1908              : 
    1909              :       CHARACTER(len=default_string_length)               :: comment
    1910              :       INTEGER                                            :: unit_nr
    1911            0 :       REAL(kind=dp), DIMENSION(:, :, :), POINTER         :: DATA
    1912              :       TYPE(section_vals_type), POINTER                   :: print_key
    1913              : 
    1914            0 :       NULLIFY (pint_env%logger, print_key)
    1915            0 :       pint_env%logger => cp_get_default_logger()
    1916              : 
    1917              :       ! assume that ionode always has at least one helium_env
    1918            0 :       IF (pint_env%logger%para_env%is_source()) THEN
    1919              :          print_key => section_vals_get_subs_vals(helium_env(1)%helium%input, &
    1920            0 :                                                  "MOTION%PINT%HELIUM%PRINT%RHO")
    1921              :       END IF
    1922              : 
    1923              :       ! perform the actual scan wrt the COM of the solute
    1924            0 :       CALL helium_intpot_scan(pint_env, helium_env)
    1925              : 
    1926              :       ! output the interaction potential into a cubefile
    1927              :       ! assume that ionode always has at least one helium_env
    1928            0 :       IF (pint_env%logger%para_env%is_source()) THEN
    1929              : 
    1930              :          unit_nr = cp_print_key_unit_nr( &
    1931              :                    pint_env%logger, &
    1932              :                    print_key, &
    1933              :                    middle_name="helium-pot", &
    1934              :                    extension=".cube", &
    1935              :                    file_position="REWIND", &
    1936            0 :                    do_backup=.FALSE.)
    1937              : 
    1938            0 :          comment = "Solute - helium interaction potential"
    1939            0 :          NULLIFY (DATA)
    1940            0 :          DATA => helium_env(1)%helium%rho_inst(1, :, :, :)
    1941              :          CALL helium_write_cubefile( &
    1942              :             unit_nr, &
    1943              :             comment, &
    1944              :             helium_env(1)%helium%center - 0.5_dp* &
    1945              :             (helium_env(1)%helium%rho_maxr - helium_env(1)%helium%rho_delr), &
    1946              :             helium_env(1)%helium%rho_delr, &
    1947              :             helium_env(1)%helium%rho_nbin, &
    1948            0 :             DATA)
    1949              : 
    1950            0 :          CALL m_flush(unit_nr)
    1951            0 :          CALL cp_print_key_finished_output(unit_nr, pint_env%logger, print_key)
    1952              : 
    1953              :       END IF
    1954              : 
    1955              :       ! output solute positions
    1956            0 :       CALL pint_write_centroids(pint_env)
    1957            0 :       CALL pint_write_trajectory(pint_env)
    1958              : 
    1959            0 :    END SUBROUTINE pint_run_scan
    1960              : 
    1961              : ! ***************************************************************************
    1962              : !> \brief  Does an PINT step (and nrespa harmonic evaluations)
    1963              : !> \param pint_env ...
    1964              : !> \param helium_env ...
    1965              : !> \par    History
    1966              : !>           various bug fixes [hforbert]
    1967              : !>           10.2015 Added RPMD propagator and harmonic integrator [Felix Uhl]
    1968              : !>           04.2016 Changed to work with helium_env [cschran]
    1969              : !>           10.2018 Added centroid constraints [cschran+rperez]
    1970              : !>           10.2021 Added beadwise constraints [lduran]
    1971              : !> \author fawzi
    1972              : ! **************************************************************************************************
    1973          638 :    SUBROUTINE pint_step(pint_env, helium_env)
    1974              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    1975              :       TYPE(helium_solvent_p_type), DIMENSION(:), &
    1976              :          OPTIONAL, POINTER                               :: helium_env
    1977              : 
    1978              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'pint_step'
    1979              : 
    1980              :       INTEGER                                            :: handle, i, ia, ib, idim, ierr, inos, &
    1981              :                                                             iresp, j, k, nbeads, nparticle, &
    1982              :                                                             nparticle_kind
    1983              :       REAL(kind=dp)                                      :: dt_temp, dti, dti2, dti22, e_h, factor, &
    1984              :                                                             rn, tdti, time_start, time_stop, tol
    1985          638 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: pos, vel
    1986          638 :       REAL(kind=dp), DIMENSION(:, :, :), POINTER         :: tmp
    1987              :       TYPE(atomic_kind_list_type), POINTER               :: atomic_kinds
    1988          638 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1989              :       TYPE(cell_type), POINTER                           :: cell
    1990              :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1991              :       TYPE(distribution_1d_type), POINTER                :: local_molecules, local_particles
    1992              :       TYPE(f_env_type), POINTER                          :: f_env
    1993              :       TYPE(global_constraint_type), POINTER              :: gci
    1994              :       TYPE(molecule_kind_list_type), POINTER             :: molecule_kinds
    1995          638 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1996              :       TYPE(molecule_list_type), POINTER                  :: molecules
    1997          638 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1998              :       TYPE(particle_list_type), POINTER                  :: particles
    1999          638 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2000              : 
    2001          638 :       CALL timeset(routineN, handle)
    2002          638 :       time_start = m_walltime()
    2003              : 
    2004          638 :       rn = REAL(pint_env%nrespa, dp)
    2005          638 :       dti = pint_env%dt/rn
    2006          638 :       dti2 = dti/2._dp
    2007          638 :       tdti = 2.*dti
    2008          638 :       dti22 = dti**2/2._dp
    2009              : 
    2010              :       ! Get constraint info, if needed
    2011              :       ! Create a force environment which will be identical to
    2012              :       ! the bead that is being processed by the processor.
    2013          638 :       IF (pint_env%simpar%constraint) THEN
    2014           24 :          NULLIFY (subsys, cell)
    2015           24 :          NULLIFY (atomic_kinds, local_particles, particles)
    2016           24 :          NULLIFY (local_molecules, molecules, molecule_kinds, gci)
    2017           24 :          NULLIFY (atomic_kind_set, molecule_kind_set, particle_set, molecule_set)
    2018              : 
    2019           24 :          CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id, f_env=f_env)
    2020           24 :          CALL force_env_get(force_env=f_env%force_env, subsys=subsys)
    2021           24 :          CALL f_env_rm_defaults(f_env, ierr)
    2022           24 :          CPASSERT(ierr == 0)
    2023              : 
    2024              :          ! Get gci and more from subsys
    2025              :          CALL cp_subsys_get(subsys=subsys, &
    2026              :                             cell=cell, &
    2027              :                             atomic_kinds=atomic_kinds, &
    2028              :                             local_particles=local_particles, &
    2029              :                             particles=particles, &
    2030              :                             local_molecules=local_molecules, &
    2031              :                             molecules=molecules, &
    2032              :                             molecule_kinds=molecule_kinds, &
    2033           24 :                             gci=gci)
    2034              : 
    2035           24 :          nparticle_kind = atomic_kinds%n_els
    2036           24 :          atomic_kind_set => atomic_kinds%els
    2037           24 :          molecule_kind_set => molecule_kinds%els
    2038           24 :          nparticle = particles%n_els
    2039           24 :          nbeads = pint_env%p
    2040           24 :          particle_set => particles%els
    2041           24 :          molecule_set => molecules%els
    2042              : 
    2043              :          ! Allocate work storage
    2044           72 :          ALLOCATE (pos(3, nparticle))
    2045           48 :          ALLOCATE (vel(3, nparticle))
    2046           24 :          pos(:, :) = 0.0_dp
    2047           24 :          vel(:, :) = 0.0_dp
    2048              : 
    2049           24 :          IF (pint_env%propagator%prop_kind == propagator_rpmd) THEN
    2050              :             ! Multiply with 1/SQRT(n_beads) due to normal mode transformation in RPMD
    2051            0 :             factor = SQRT(REAL(pint_env%p, dp))
    2052              :          ELSE
    2053              :             factor = 1.0_dp
    2054              :          END IF
    2055              : 
    2056              :          CALL getold(gci, local_molecules, molecule_set, &
    2057           48 :                      molecule_kind_set, particle_set, cell)
    2058              :       END IF
    2059              : 
    2060          900 :       SELECT CASE (pint_env%harm_integrator)
    2061              :       CASE (integrate_numeric)
    2062              : 
    2063          938 :          DO iresp = 1, pint_env%nrespa
    2064              : 
    2065              :             ! integrate bead positions, first_propagated_mode = { 1, 2 }
    2066              :             ! Nose needs an extra step
    2067          676 :             IF (pint_env%pimd_thermostat == thermostat_nose) THEN
    2068              : 
    2069              :                !Set thermostat action of constrained DoF to zero:
    2070          616 :                IF (pint_env%simpar%constraint) THEN
    2071           48 :                   DO k = 1, pint_env%n_atoms_constraints
    2072           32 :                      ia = pint_env%atoms_constraints(k)
    2073          144 :                      DO j = 3*(ia - 1) + 1, 3*ia
    2074          416 :                         pint_env%tv(:, 1, j) = 0.0_dp
    2075              :                      END DO
    2076              :                   END DO
    2077              :                END IF
    2078              : 
    2079              :                ! Exempt centroid from thermostat for CMD
    2080          616 :                IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2081         5920 :                   pint_env%tx(:, 1, :) = 0.0_dp
    2082         5920 :                   pint_env%tv(:, 1, :) = 0.0_dp
    2083         5920 :                   pint_env%tf(:, 1, :) = 0.0_dp
    2084              :                END IF
    2085              : 
    2086         4832 :                DO i = pint_env%first_propagated_mode, pint_env%p
    2087              :                   pint_env%ux(i, :) = pint_env%ux(i, :) - &
    2088        93968 :                                       dti22*pint_env%uv(i, :)*pint_env%tv(1, i, :)
    2089              :                END DO
    2090       411700 :                pint_env%tx = pint_env%tx + dti*pint_env%tv + dti22*pint_env%tf
    2091              : 
    2092          616 :                IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2093         5920 :                   pint_env%tx(:, 1, :) = 0.0_dp
    2094         5920 :                   pint_env%tv(:, 1, :) = 0.0_dp
    2095         5920 :                   pint_env%tf(:, 1, :) = 0.0_dp
    2096              :                END IF
    2097              : 
    2098              :             END IF
    2099              :             !Integrate position in harmonic springs (uf_h) and physical potential
    2100              :             !(uf)
    2101         5124 :             DO i = pint_env%first_propagated_mode, pint_env%p
    2102              :                pint_env%ux_t(i, :) = pint_env%ux(i, :) + &
    2103              :                                      dti*pint_env%uv(i, :) + &
    2104              :                                      dti22*(pint_env%uf_h(i, :) + &
    2105       133140 :                                             pint_env%uf(i, :))
    2106              :             END DO
    2107              : 
    2108              :             ! apply thermostats to velocities
    2109         1292 :             SELECT CASE (pint_env%pimd_thermostat)
    2110              :             CASE (thermostat_nose)
    2111              : 
    2112          616 :                IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2113         5920 :                   pint_env%tx(:, 1, :) = 0.0_dp
    2114         5920 :                   pint_env%tv(:, 1, :) = 0.0_dp
    2115         5920 :                   pint_env%tf(:, 1, :) = 0.0_dp
    2116              :                END IF
    2117              : 
    2118              :                pint_env%uv_t = pint_env%uv - dti2* &
    2119       230368 :                                pint_env%uv*pint_env%tv(1, :, :)
    2120          616 :                tmp => pint_env%tv_t
    2121          616 :                pint_env%tv_t => pint_env%tv
    2122          616 :                pint_env%tv => tmp
    2123       411700 :                pint_env%tv = pint_env%tv_old + tdti*pint_env%tf
    2124       411700 :                pint_env%tv_old = pint_env%tv_t
    2125       411700 :                pint_env%tv_t = pint_env%tv_t + dti2*pint_env%tf
    2126              :             CASE DEFAULT
    2127        58492 :                pint_env%uv_t = pint_env%uv
    2128              :             END SELECT
    2129              : 
    2130              :             !Set thermostat action of constrained DoF to zero:
    2131          676 :             IF (pint_env%simpar%constraint) THEN
    2132           48 :                DO k = 1, pint_env%n_atoms_constraints
    2133           32 :                   ia = pint_env%atoms_constraints(k)
    2134          144 :                   DO j = 3*(ia - 1) + 1, 3*ia
    2135          384 :                      pint_env%tv(:, 1, j) = 0.0_dp
    2136          416 :                      pint_env%tv_t(:, 1, j) = 0.0_dp
    2137              :                   END DO
    2138              :                END DO
    2139              :             END IF
    2140              : 
    2141              :             ! Exempt centroid from thermostat for CMD
    2142          676 :             IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2143         5920 :                pint_env%tx(:, 1, :) = 0.0_dp
    2144         5920 :                pint_env%tv(:, 1, :) = 0.0_dp
    2145         5920 :                pint_env%tf(:, 1, :) = 0.0_dp
    2146              :             END IF
    2147              : 
    2148              :             !Integrate harmonic velocities and physical velocities
    2149       173368 :             pint_env%uv_t = pint_env%uv_t + dti2*(pint_env%uf_h + pint_env%uf)
    2150              : 
    2151              :             ! physical forces are only applied in first respa step.
    2152       173368 :             pint_env%uf = 0.0_dp
    2153              :             ! calc harmonic forces at new pos
    2154       173368 :             pint_env%ux = pint_env%ux_t
    2155              : 
    2156              :             ! Apply centroid constraints (SHAKE)
    2157          676 :             IF (pint_env%simpar%constraint) THEN
    2158           16 :                IF (pint_env%logger%para_env%is_source()) THEN
    2159           32 :                   DO i = 1, nparticle
    2160          104 :                      DO j = 1, 3
    2161           72 :                         pos(j, i) = pint_env%ux(1, j + (i - 1)*3)
    2162           96 :                         vel(j, i) = pint_env%uv_t(1, j + (i - 1)*3)
    2163              :                      END DO
    2164              :                   END DO
    2165              : 
    2166              :                   ! Possibly update the target values
    2167              :                   CALL shake_update_targets(gci, local_molecules, molecule_set, &
    2168              :                                             molecule_kind_set, dti, &
    2169            8 :                                             f_env%force_env%root_section)
    2170              :                   CALL shake_control(gci, local_molecules, molecule_set, &
    2171              :                                      molecule_kind_set, particle_set, &
    2172              :                                      pos, vel, dti, pint_env%simpar%shake_tol, &
    2173              :                                      pint_env%simpar%info_constraint, &
    2174              :                                      pint_env%simpar%lagrange_multipliers, &
    2175              :                                      pint_env%simpar%dump_lm, cell, &
    2176            8 :                                      mp_comm_self, local_particles)
    2177              :                END IF
    2178              :                ! Positions and velocities of centroid were constrained by SHAKE
    2179           16 :                CALL pint_env%logger%para_env%bcast(pos)
    2180           16 :                CALL pint_env%logger%para_env%bcast(vel)
    2181              :                ! Transform back to normal modes:
    2182           64 :                DO i = 1, nparticle
    2183          208 :                   DO j = 1, 3
    2184          144 :                      pint_env%ux(1, j + (i - 1)*3) = pos(j, i)
    2185          192 :                      pint_env%uv_t(1, j + (i - 1)*3) = vel(j, i)
    2186              :                   END DO
    2187              :                END DO
    2188              : 
    2189              :             END IF
    2190              :             ! Exempt centroid from thermostat for CMD
    2191          676 :             IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2192         5920 :                pint_env%tx(:, 1, :) = 0.0_dp
    2193         5920 :                pint_env%tv(:, 1, :) = 0.0_dp
    2194         5920 :                pint_env%tf(:, 1, :) = 0.0_dp
    2195              :             END IF
    2196              : 
    2197          676 :             CALL pint_calc_uf_h(pint_env=pint_env, e_h=e_h)
    2198       173368 :             pint_env%uv_t = pint_env%uv_t + dti2*(pint_env%uf_h + pint_env%uf)
    2199              : 
    2200              :             ! For last respa step include integration of physical and helium
    2201              :             ! forces
    2202          676 :             IF (iresp == pint_env%nrespa) THEN
    2203          262 :                CALL pint_u2x(pint_env)
    2204          262 :                CALL pint_calc_f(pint_env)
    2205              :                ! perform helium step and add helium forces
    2206          262 :                IF (PRESENT(helium_env)) THEN
    2207           50 :                   CALL helium_step(helium_env, pint_env)
    2208              :                   !Update force of solute in pint_env
    2209           50 :                   IF (pint_env%logger%para_env%is_source()) THEN
    2210         1150 :                      pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
    2211              :                   END IF
    2212         4550 :                   CALL pint_env%logger%para_env%bcast(pint_env%f)
    2213              :                END IF
    2214              : 
    2215          262 :                CALL pint_f2uf(pint_env)
    2216              :                ! set the centroid forces to 0 if FIX_CENTROID_POS
    2217          262 :                IF (pint_env%first_propagated_mode == 2) THEN
    2218            0 :                   pint_env%uf(1, :) = 0.0_dp
    2219              :                END IF
    2220              :                !Scale physical forces and integrate velocities with physical
    2221              :                !forces
    2222       128944 :                pint_env%uf = pint_env%uf*rn
    2223       128944 :                pint_env%uv_t = pint_env%uv_t + dti2*pint_env%uf
    2224              : 
    2225              :             END IF
    2226              : 
    2227              :             ! Apply second half of thermostats
    2228          938 :             SELECT CASE (pint_env%pimd_thermostat)
    2229              :             CASE (thermostat_nose)
    2230              :                ! Exempt centroid from thermostat for CMD
    2231          616 :                IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2232         5920 :                   pint_env%tx(:, 1, :) = 0.0_dp
    2233         5920 :                   pint_env%tv(:, 1, :) = 0.0_dp
    2234         5920 :                   pint_env%tf(:, 1, :) = 0.0_dp
    2235              :                END IF
    2236         3756 :                DO i = 1, 6
    2237         3378 :                   tol = 0._dp
    2238      1353270 :                   pint_env%uv_new = pint_env%uv_t/(1.+dti2*pint_env%tv(1, :, :))
    2239       154956 :                   DO idim = 1, pint_env%ndim
    2240       678324 :                      DO ib = 1, pint_env%p
    2241              :                         pint_env%tf(1, ib, idim) = (pint_env%mass_fict(ib, idim)* &
    2242              :                                                     pint_env%uv_new(ib, idim)**2 - pint_env%kT*pint_env%kTcorr)/ &
    2243       674946 :                                                    pint_env%Q(ib)
    2244              :                      END DO
    2245              :                   END DO
    2246              : 
    2247              :                   !Set thermostat action of constrained DoF to zero:
    2248         3378 :                   IF (pint_env%simpar%constraint) THEN
    2249          288 :                      DO k = 1, pint_env%n_atoms_constraints
    2250          192 :                         ia = pint_env%atoms_constraints(k)
    2251          864 :                         DO j = 3*(ia - 1) + 1, 3*ia
    2252         2496 :                            pint_env%tf(:, 1, j) = 0.0_dp
    2253              :                         END DO
    2254              :                      END DO
    2255              :                   END IF
    2256              : 
    2257              :                   ! Exempt centroid from thermostat for CMD
    2258         3378 :                   IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2259        35520 :                      pint_env%tx(:, 1, :) = 0.0_dp
    2260        35520 :                      pint_env%tv(:, 1, :) = 0.0_dp
    2261        35520 :                      pint_env%tf(:, 1, :) = 0.0_dp
    2262              :                   END IF
    2263              : 
    2264       154956 :                   DO idim = 1, pint_env%ndim
    2265       678324 :                      DO ib = 1, pint_env%p
    2266      1742904 :                         DO inos = 1, pint_env%nnos - 1
    2267              :                            pint_env%tv_new(inos, ib, idim) = &
    2268              :                               (pint_env%tv_t(inos, ib, idim) + dti2*pint_env%tf(inos, ib, idim))/ &
    2269      1219536 :                               (1._dp + dti2*pint_env%tv(inos + 1, ib, idim))
    2270              :                            pint_env%tf(inos + 1, ib, idim) = &
    2271              :                               (pint_env%tv_new(inos, ib, idim)**2 - &
    2272      1219536 :                                pint_env%kT*pint_env%kTcorr/pint_env%Q(ib))
    2273              :                            tol = MAX(tol, ABS(pint_env%tv(inos, ib, idim) &
    2274      1742904 :                                               - pint_env%tv_new(inos, ib, idim)))
    2275              :                         END DO
    2276              :                         !Set thermostat action of constrained DoF to zero:
    2277       523368 :                         IF (pint_env%simpar%constraint) THEN
    2278        10368 :                            DO k = 1, pint_env%n_atoms_constraints
    2279         6912 :                               ia = pint_env%atoms_constraints(k)
    2280        31104 :                               DO j = 3*(ia - 1) + 1, 3*ia
    2281        82944 :                                  pint_env%tv_new(:, 1, j) = 0.0_dp
    2282        89856 :                                  pint_env%tf(:, 1, j) = 0.0_dp
    2283              :                               END DO
    2284              :                            END DO
    2285              :                         END IF
    2286              : 
    2287              :                         ! Exempt centroid from thermostat for CMD
    2288       523368 :                         IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2289      3196800 :                            pint_env%tx(:, 1, :) = 0.0_dp
    2290      3196800 :                            pint_env%tv(:, 1, :) = 0.0_dp
    2291      3196800 :                            pint_env%tf(:, 1, :) = 0.0_dp
    2292              :                         END IF
    2293              : 
    2294              :                         pint_env%tv_new(pint_env%nnos, ib, idim) = &
    2295              :                            pint_env%tv_t(pint_env%nnos, ib, idim) + &
    2296       523368 :                            dti2*pint_env%tf(pint_env%nnos, ib, idim)
    2297              :                         tol = MAX(tol, ABS(pint_env%tv(pint_env%nnos, ib, idim) &
    2298       523368 :                                            - pint_env%tv_new(pint_env%nnos, ib, idim)))
    2299              :                         tol = MAX(tol, ABS(pint_env%uv(ib, idim) &
    2300       523368 :                                            - pint_env%uv_new(ib, idim)))
    2301              :                         !Set thermostat action of constrained DoF to zero:
    2302       523368 :                         IF (pint_env%simpar%constraint) THEN
    2303        10368 :                            DO k = 1, pint_env%n_atoms_constraints
    2304         6912 :                               ia = pint_env%atoms_constraints(k)
    2305        31104 :                               DO j = 3*(ia - 1) + 1, 3*ia
    2306        89856 :                                  pint_env%tv_new(:, 1, j) = 0.0_dp
    2307              :                               END DO
    2308              :                            END DO
    2309              :                         END IF
    2310              :                         ! Exempt centroid from thermostat for CMD
    2311       674946 :                         IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2312      3196800 :                            pint_env%tx(:, 1, :) = 0.0_dp
    2313      3196800 :                            pint_env%tv(:, 1, :) = 0.0_dp
    2314      3196800 :                            pint_env%tf(:, 1, :) = 0.0_dp
    2315              :                         END IF
    2316              : 
    2317              :                      END DO
    2318              :                   END DO
    2319              : 
    2320       678324 :                   pint_env%uv = pint_env%uv_new
    2321      2421228 :                   pint_env%tv = pint_env%tv_new
    2322         3378 :                   IF (tol <= pint_env%v_tol) EXIT
    2323              :                   ! Exempt centroid from thermostat for CMD
    2324         3756 :                   IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2325        35520 :                      pint_env%tx(:, 1, :) = 0.0_dp
    2326        35520 :                      pint_env%tv(:, 1, :) = 0.0_dp
    2327        35520 :                      pint_env%tf(:, 1, :) = 0.0_dp
    2328              :                   END IF
    2329              :                END DO
    2330              : 
    2331              :                ! Apply centroid constraints (RATTLE)
    2332          616 :                IF (pint_env%simpar%constraint) THEN
    2333           16 :                   IF (pint_env%logger%para_env%is_source()) THEN
    2334              :                      ! Reset particle r, due to force calc:
    2335           32 :                      DO i = 1, nparticle
    2336          104 :                         DO j = 1, 3
    2337           72 :                            vel(j, i) = pint_env%uv(1, j + (i - 1)*3)
    2338           96 :                            particle_set(i)%r(j) = pint_env%ux(1, j + (i - 1)*3)
    2339              :                         END DO
    2340              :                      END DO
    2341              : 
    2342              :                      ! Small time step for all small integrations steps
    2343              :                      ! Big step for last RESPA
    2344            8 :                      IF (iresp == pint_env%nrespa) THEN
    2345            4 :                         dt_temp = dti
    2346              :                      ELSE
    2347            4 :                         dt_temp = dti*rn
    2348              :                      END IF
    2349              :                      CALL rattle_control(gci, local_molecules, molecule_set, &
    2350              :                                          molecule_kind_set, particle_set, &
    2351              :                                          vel, dt_temp, pint_env%simpar%shake_tol, &
    2352              :                                          pint_env%simpar%info_constraint, &
    2353              :                                          pint_env%simpar%lagrange_multipliers, &
    2354              :                                          pint_env%simpar%dump_lm, cell, &
    2355            8 :                                          mp_comm_self, local_particles)
    2356              :                   END IF
    2357              :                   ! Velocities of centroid were constrained by RATTLE
    2358              :                   ! Broadcast updated velocities to other nodes
    2359           16 :                   CALL pint_env%logger%para_env%bcast(vel)
    2360              : 
    2361           64 :                   DO i = 1, nparticle
    2362          208 :                      DO j = 1, 3
    2363          192 :                         pint_env%uv(1, j + (i - 1)*3) = vel(j, i)
    2364              :                      END DO
    2365              :                   END DO
    2366              :                END IF
    2367              : 
    2368         2048 :                DO inos = 1, pint_env%nnos - 1
    2369              :                   pint_env%tf(inos, :, :) = pint_env%tf(inos, :, :) &
    2370       264200 :                                             - pint_env%tv(inos, :, :)*pint_env%tv(inos + 1, :, :)
    2371              :                END DO
    2372              : 
    2373              :                ! Exempt centroid from thermostat for CMD
    2374          616 :                IF (pint_env%propagator%prop_kind == propagator_cmd) THEN
    2375         5920 :                   pint_env%tx(:, 1, :) = 0.0_dp
    2376         5920 :                   pint_env%tv(:, 1, :) = 0.0_dp
    2377         5920 :                   pint_env%tf(:, 1, :) = 0.0_dp
    2378              :                END IF
    2379              : 
    2380              :             CASE (thermostat_gle)
    2381            4 :                CALL pint_gle_step(pint_env)
    2382        55300 :                pint_env%uv = pint_env%uv_t
    2383              :             CASE DEFAULT
    2384         3196 :                pint_env%uv = pint_env%uv_t
    2385              :             END SELECT
    2386              :          END DO
    2387              : 
    2388              :       CASE (integrate_exact)
    2389              :          ! The Liouvillian splitting is as follows:
    2390              :          ! 1. Thermostat
    2391              :          ! 2. 0.5*physical integration
    2392              :          ! 3. Exact harmonic integration + apply constraints (SHAKE)
    2393              :          ! 4. 0.5*physical integration
    2394              :          ! 5. Thermostat + apply constraints (RATTLE)
    2395              : 
    2396              :          ! 1. Apply thermostats
    2397          688 :          SELECT CASE (pint_env%pimd_thermostat)
    2398              :          CASE (thermostat_pile)
    2399              :             CALL pint_pile_step(vold=pint_env%uv, &
    2400              :                                 vnew=pint_env%uv_t, &
    2401              :                                 p=pint_env%p, &
    2402              :                                 ndim=pint_env%ndim, &
    2403              :                                 first_mode=pint_env%first_propagated_mode, &
    2404              :                                 masses=pint_env%mass_fict, &
    2405          312 :                                 pile_therm=pint_env%pile_therm)
    2406              :          CASE (thermostat_piglet)
    2407              :             CALL pint_piglet_step(vold=pint_env%uv, &
    2408              :                                   vnew=pint_env%uv_t, &
    2409              :                                   first_mode=pint_env%first_propagated_mode, &
    2410              :                                   masses=pint_env%mass_fict, &
    2411           10 :                                   piglet_therm=pint_env%piglet_therm)
    2412              :          CASE (thermostat_qtb)
    2413              :             CALL pint_qtb_step(vold=pint_env%uv, &
    2414              :                                vnew=pint_env%uv_t, &
    2415              :                                p=pint_env%p, &
    2416              :                                ndim=pint_env%ndim, &
    2417              :                                masses=pint_env%mass_fict, &
    2418           30 :                                qtb_therm=pint_env%qtb_therm)
    2419              :          CASE DEFAULT
    2420         1456 :             pint_env%uv_t = pint_env%uv
    2421              :          END SELECT
    2422              : 
    2423              :          ! 2. 1/2*Physical integration
    2424      1542598 :          pint_env%uv_t = pint_env%uv_t + dti2*pint_env%uf
    2425              : 
    2426              :          ! 3. Exact harmonic integration
    2427          376 :          IF (pint_env%first_propagated_mode == 1) THEN
    2428              :             ! The centroid is integrated via standard velocity-verlet
    2429              :             ! Commented out code is only there to show similarities to
    2430              :             ! Numeric integrator
    2431              :             pint_env%ux_t(1, :) = pint_env%ux(1, :) + &
    2432       233710 :                                   dti*pint_env%uv_t(1, :) !+ &
    2433              :             !                      dti22*pint_env%uf_h(1, :)
    2434              :             !pint_env%uv_t(1, :) = pint_env%uv_t(1, :)+ &
    2435              :             !                      dti2*pint_env%uf_h(1, :)
    2436              :          ELSE
    2437              :             ! set velocities to zero for fixed centroids
    2438            0 :             pint_env%ux_t(1, :) = pint_env%ux(1, :)
    2439            0 :             pint_env%uv_t(1, :) = 0.0_dp
    2440              :          END IF
    2441              :          ! Other modes are integrated exactly
    2442         2352 :          DO i = 2, pint_env%p
    2443              :             pint_env%ux_t(i, :) = pint_env%cosex(i)*pint_env%ux(i, :) &
    2444      1077530 :                                   + pint_env%iwsinex(i)*pint_env%uv_t(i, :)
    2445              :             pint_env%uv_t(i, :) = pint_env%cosex(i)*pint_env%uv_t(i, :) &
    2446      1077906 :                                   - pint_env%wsinex(i)*pint_env%ux(i, :)
    2447              :          END DO
    2448              : 
    2449              :          ! Apply constraints (SHAKE)
    2450          376 :          IF (pint_env%simpar%constraint) THEN
    2451              :             ! Beadwise constraints
    2452           16 :             IF (pint_env%beadwise_constraints) THEN
    2453            8 :                IF (pint_env%logger%para_env%is_source()) THEN
    2454              :                   ! Transform positions and velocities to Cartesian coordinates:
    2455            4 :                   CALL pint_u2x(pint_env, ux=pint_env%ux_t, x=pint_env%x)
    2456            4 :                   CALL pint_u2x(pint_env, ux=pint_env%uv_t, x=pint_env%v)
    2457           20 :                   DO ib = 1, nbeads
    2458           64 :                      DO i = 1, nparticle
    2459          208 :                         DO j = 1, 3
    2460          144 :                            pos(j, i) = pint_env%x(ib, j + (i - 1)*3)
    2461          192 :                            vel(j, i) = pint_env%v(ib, j + (i - 1)*3)
    2462              :                         END DO
    2463              :                      END DO
    2464              :                      ! Possibly update the target values
    2465              :                      CALL shake_update_targets(gci, local_molecules, molecule_set, &
    2466              :                                                molecule_kind_set, dti, &
    2467           16 :                                                f_env%force_env%root_section)
    2468              :                      CALL shake_control(gci, local_molecules, molecule_set, &
    2469              :                                         molecule_kind_set, particle_set, &
    2470              :                                         pos, vel, dti, pint_env%simpar%shake_tol, &
    2471              :                                         pint_env%simpar%info_constraint, &
    2472              :                                         pint_env%simpar%lagrange_multipliers, &
    2473              :                                         pint_env%simpar%dump_lm, cell, &
    2474           16 :                                         mp_comm_self, local_particles)
    2475           68 :                      DO i = 1, nparticle
    2476          208 :                         DO j = 1, 3
    2477          144 :                            pint_env%x(ib, j + (i - 1)*3) = pos(j, i)
    2478          192 :                            pint_env%v(ib, j + (i - 1)*3) = vel(j, i)
    2479              :                         END DO
    2480              :                      END DO
    2481              :                   END DO
    2482              :                   ! Transform back to normal modes:
    2483            4 :                   CALL pint_x2u(pint_env, ux=pint_env%ux_t, x=pint_env%x)
    2484            4 :                   CALL pint_x2u(pint_env, ux=pint_env%uv_t, x=pint_env%v)
    2485              :                END IF
    2486              :                ! Broadcast positions and velocities to all nodes
    2487          728 :                CALL pint_env%logger%para_env%bcast(pint_env%ux_t)
    2488          728 :                CALL pint_env%logger%para_env%bcast(pint_env%uv_t)
    2489              :                ! Centroid constraints
    2490              :             ELSE
    2491            8 :                IF (pint_env%logger%para_env%is_source()) THEN
    2492              :                   ! Transform positions and velocities to Cartesian coordinates:
    2493           16 :                   DO i = 1, nparticle
    2494           52 :                      DO j = 1, 3
    2495           36 :                         pos(j, i) = pint_env%ux_t(1, j + (i - 1)*3)/factor
    2496           48 :                         vel(j, i) = pint_env%uv_t(1, j + (i - 1)*3)/factor
    2497              :                      END DO
    2498              :                   END DO
    2499              :                   ! Possibly update the target values
    2500              :                   CALL shake_update_targets(gci, local_molecules, molecule_set, &
    2501              :                                             molecule_kind_set, dti, &
    2502            4 :                                             f_env%force_env%root_section)
    2503              :                   CALL shake_control(gci, local_molecules, molecule_set, &
    2504              :                                      molecule_kind_set, particle_set, &
    2505              :                                      pos, vel, dti, pint_env%simpar%shake_tol, &
    2506              :                                      pint_env%simpar%info_constraint, &
    2507              :                                      pint_env%simpar%lagrange_multipliers, &
    2508              :                                      pint_env%simpar%dump_lm, cell, &
    2509            4 :                                      mp_comm_self, local_particles)
    2510              :                END IF
    2511              :                ! Broadcast positions and velocities to all nodes
    2512            8 :                CALL pint_env%logger%para_env%bcast(pos)
    2513            8 :                CALL pint_env%logger%para_env%bcast(vel)
    2514              :                ! Transform back to normal modes:
    2515           32 :                DO i = 1, nparticle
    2516          104 :                   DO j = 1, 3
    2517           72 :                      pint_env%ux_t(1, j + (i - 1)*3) = pos(j, i)*factor
    2518           96 :                      pint_env%uv_t(1, j + (i - 1)*3) = vel(j, i)*factor
    2519              :                   END DO
    2520              :                END DO
    2521              :             END IF
    2522              :             ! Positions and velocities were constrained by SHAKE
    2523              :          END IF
    2524              :          ! Update positions
    2525      1542598 :          pint_env%ux = pint_env%ux_t
    2526              : 
    2527              :          ! 4. 1/2*Physical integration
    2528      1542598 :          pint_env%uf = 0.0_dp
    2529          376 :          CALL pint_u2x(pint_env)
    2530          376 :          CALL pint_calc_f(pint_env)
    2531              :          ! perform helium step and add helium forces
    2532          376 :          IF (PRESENT(helium_env)) THEN
    2533           22 :             CALL helium_step(helium_env, pint_env)
    2534              :             !Update force of solute in pint_env
    2535           22 :             IF (pint_env%logger%para_env%is_source()) THEN
    2536         1802 :                pint_env%f(:, :) = pint_env%f(:, :) + helium_env(1)%helium%force_avrg(:, :)
    2537              :             END IF
    2538         7186 :             CALL pint_env%logger%para_env%bcast(pint_env%f)
    2539              :          END IF
    2540          376 :          CALL pint_f2uf(pint_env)
    2541              :          ! set the centroid forces to 0 if FIX_CENTROID_POS
    2542          376 :          IF (pint_env%first_propagated_mode == 2) THEN
    2543            0 :             pint_env%uf(1, :) = 0.0_dp
    2544              :          END IF
    2545      1542598 :          pint_env%uv_t = pint_env%uv_t + dti2*pint_env%uf
    2546              : 
    2547              :          ! 5. Apply thermostats
    2548          688 :          SELECT CASE (pint_env%pimd_thermostat)
    2549              :          CASE (thermostat_pile)
    2550              :             CALL pint_pile_step(vold=pint_env%uv_t, &
    2551              :                                 vnew=pint_env%uv, &
    2552              :                                 p=pint_env%p, &
    2553              :                                 ndim=pint_env%ndim, &
    2554              :                                 first_mode=pint_env%first_propagated_mode, &
    2555              :                                 masses=pint_env%mass_fict, &
    2556          312 :                                 pile_therm=pint_env%pile_therm)
    2557              :          CASE (thermostat_piglet)
    2558              :             CALL pint_piglet_step(vold=pint_env%uv_t, &
    2559              :                                   vnew=pint_env%uv, &
    2560              :                                   first_mode=pint_env%first_propagated_mode, &
    2561              :                                   masses=pint_env%mass_fict, &
    2562           10 :                                   piglet_therm=pint_env%piglet_therm)
    2563              :          CASE (thermostat_qtb)
    2564              :             CALL pint_qtb_step(vold=pint_env%uv_t, &
    2565              :                                vnew=pint_env%uv, &
    2566              :                                p=pint_env%p, &
    2567              :                                ndim=pint_env%ndim, &
    2568              :                                masses=pint_env%mass_fict, &
    2569           30 :                                qtb_therm=pint_env%qtb_therm)
    2570              :          CASE DEFAULT
    2571         1456 :             pint_env%uv = pint_env%uv_t
    2572              :          END SELECT
    2573              : 
    2574              :          ! Apply constraints (RATTLE)
    2575         1014 :          IF (pint_env%simpar%constraint) THEN
    2576              :             ! Beadwise constraints
    2577           16 :             IF (pint_env%beadwise_constraints) THEN
    2578            8 :                IF (pint_env%logger%para_env%is_source()) THEN
    2579              :                   ! Transform positions and velocities to Cartesian coordinates:
    2580              :                   ! Reset particle r, due to force calc:
    2581            4 :                   CALL pint_u2x(pint_env, ux=pint_env%ux, x=pint_env%x)
    2582            4 :                   CALL pint_u2x(pint_env, ux=pint_env%uv, x=pint_env%v)
    2583           20 :                   DO ib = 1, nbeads
    2584           64 :                      DO i = 1, nparticle
    2585          208 :                         DO j = 1, 3
    2586          144 :                            particle_set(i)%r(j) = pint_env%x(ib, j + (i - 1)*3)
    2587          192 :                            vel(j, i) = pint_env%v(ib, j + (i - 1)*3)
    2588              :                         END DO
    2589              :                      END DO
    2590              :                      CALL rattle_control(gci, local_molecules, &
    2591              :                                          molecule_set, molecule_kind_set, &
    2592              :                                          particle_set, vel, dti, &
    2593              :                                          pint_env%simpar%shake_tol, &
    2594              :                                          pint_env%simpar%info_constraint, &
    2595              :                                          pint_env%simpar%lagrange_multipliers, &
    2596              :                                          pint_env%simpar%dump_lm, cell, &
    2597           16 :                                          mp_comm_self, local_particles)
    2598           68 :                      DO i = 1, nparticle
    2599          208 :                         DO j = 1, 3
    2600          192 :                            pint_env%v(ib, j + (i - 1)*3) = vel(j, i)
    2601              :                         END DO
    2602              :                      END DO
    2603              :                   END DO
    2604              :                   ! Transform back to normal modes:
    2605            4 :                   CALL pint_x2u(pint_env, ux=pint_env%uv, x=pint_env%v)
    2606              :                END IF
    2607          728 :                CALL pint_env%logger%para_env%bcast(pint_env%uv)
    2608              :                ! Centroid constraints
    2609              :             ELSE
    2610            8 :                IF (pint_env%logger%para_env%is_source()) THEN
    2611              :                   ! Transform positions and velocities to Cartesian coordinates:
    2612              :                   ! Reset particle r, due to force calc:
    2613           16 :                   DO i = 1, nparticle
    2614           52 :                      DO j = 1, 3
    2615           36 :                         vel(j, i) = pint_env%uv(1, j + (i - 1)*3)/factor
    2616           48 :                         particle_set(i)%r(j) = pint_env%ux(1, j + (i - 1)*3)/factor
    2617              :                      END DO
    2618              :                   END DO
    2619              :                   CALL rattle_control(gci, local_molecules, &
    2620              :                                       molecule_set, molecule_kind_set, &
    2621              :                                       particle_set, vel, dti, &
    2622              :                                       pint_env%simpar%shake_tol, &
    2623              :                                       pint_env%simpar%info_constraint, &
    2624              :                                       pint_env%simpar%lagrange_multipliers, &
    2625              :                                       pint_env%simpar%dump_lm, cell, &
    2626            4 :                                       mp_comm_self, local_particles)
    2627              :                END IF
    2628              :                ! Velocities of centroid were constrained by RATTLE
    2629              :                ! Broadcast updated velocities to other nodes
    2630            8 :                CALL pint_env%logger%para_env%bcast(vel)
    2631              : 
    2632              :                ! Transform back to normal modes:
    2633              :                ! Multiply with SQRT(n_beads) due to normal mode transformation
    2634           32 :                DO i = 1, nparticle
    2635          104 :                   DO j = 1, 3
    2636           96 :                      pint_env%uv(1, j + (i - 1)*3) = vel(j, i)*factor
    2637              :                   END DO
    2638              :                END DO
    2639              :             END IF
    2640              :          END IF
    2641              : 
    2642              :       END SELECT
    2643              : 
    2644          638 :       IF (pint_env%simpar%constraint) THEN
    2645           24 :          DEALLOCATE (pos, vel)
    2646              :       END IF
    2647              : 
    2648              :       ! calculate the energy components
    2649          638 :       CALL pint_calc_energy(pint_env)
    2650          638 :       CALL pint_calc_total_action(pint_env)
    2651              : 
    2652              :       ! check that the number of PINT steps matches
    2653              :       ! the number of force evaluations done so far
    2654              : !TODO make this check valid if we start from ITERATION != 0
    2655              : !     CALL f_env_add_defaults(f_env_id=pint_env%replicas%f_env_id,&
    2656              : !          f_env=f_env,new_error=new_error)
    2657              : !     NULLIFY(logger)
    2658              : !     logger => cp_error_get_logger(new_error)
    2659              : !     IF(logger%iter_info%iteration(2)/=pint_env%iter+1)&
    2660              : !        CPABORT("md & force_eval lost sychro")
    2661              : !     CALL f_env_rm_defaults(f_env,new_error,ierr)
    2662              : 
    2663          638 :       time_stop = m_walltime()
    2664          638 :       pint_env%time_per_step = time_stop - time_start
    2665          638 :       CALL pint_write_step_info(pint_env)
    2666          638 :       CALL timestop(handle)
    2667              : 
    2668         1276 :    END SUBROUTINE pint_step
    2669              : 
    2670              : ! ***************************************************************************
    2671              : !> \brief  Calculate the energy components (private wrapper function)
    2672              : !> \param pint_env ...
    2673              : !> \date   2011-01-07
    2674              : !> \author Lukasz Walewski
    2675              : ! **************************************************************************************************
    2676         1392 :    SUBROUTINE pint_calc_energy(pint_env)
    2677              : 
    2678              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    2679              : 
    2680              :       REAL(KIND=dp)                                      :: e_h
    2681              : 
    2682          696 :       CALL pint_calc_e_kin_beads_u(pint_env)
    2683          696 :       CALL pint_calc_e_vir(pint_env)
    2684              : 
    2685          696 :       CALL pint_calc_uf_h(pint_env, e_h=e_h)
    2686          696 :       pint_env%e_pot_h = e_h
    2687              : 
    2688          952 :       SELECT CASE (pint_env%pimd_thermostat)
    2689              :       CASE (thermostat_nose)
    2690          256 :          CALL pint_calc_nh_energy(pint_env)
    2691              :       CASE (thermostat_gle)
    2692            6 :          CALL pint_calc_gle_energy(pint_env)
    2693              :       CASE (thermostat_pile)
    2694          324 :          CALL pint_calc_pile_energy(pint_env)
    2695              :       CASE (thermostat_qtb)
    2696           36 :          CALL pint_calc_qtb_energy(pint_env)
    2697              :       CASE (thermostat_piglet)
    2698          696 :          CALL pint_calc_piglet_energy(pint_env)
    2699              :       END SELECT
    2700              : 
    2701              :       pint_env%energy(e_kin_thermo_id) = &
    2702              :          (0.5_dp*REAL(pint_env%p, dp)*REAL(pint_env%ndim, dp)*pint_env%kT - &
    2703          696 :           pint_env%e_pot_h)*pint_env%propagator%temp_sim2phys
    2704              : 
    2705         4992 :       pint_env%energy(e_potential_id) = SUM(pint_env%e_pot_bead)
    2706              : 
    2707              :       pint_env%energy(e_conserved_id) = &
    2708              :          pint_env%energy(e_potential_id)*pint_env%propagator%physpotscale + &
    2709              :          pint_env%e_pot_h + &
    2710              :          pint_env%e_kin_beads + &
    2711              :          pint_env%e_pot_t + &
    2712              :          pint_env%e_kin_t + &
    2713          696 :          pint_env%e_gle + pint_env%e_pile + pint_env%e_piglet + pint_env%e_qtb
    2714              : 
    2715              :       pint_env%energy(e_potential_id) = &
    2716          696 :          pint_env%energy(e_potential_id)/REAL(pint_env%p, dp)
    2717              : 
    2718          696 :    END SUBROUTINE pint_calc_energy
    2719              : 
    2720              : ! ***************************************************************************
    2721              : !> \brief  Calculate the harmonic force in the u basis
    2722              : !> \param  pint_env the path integral environment in which the harmonic
    2723              : !>         forces should be calculated
    2724              : !> \param e_h ...
    2725              : !> \par    History
    2726              : !>           Added normal mode transformation [hforbert]
    2727              : !> \author fawzi
    2728              : ! **************************************************************************************************
    2729         1446 :    SUBROUTINE pint_calc_uf_h(pint_env, e_h)
    2730              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    2731              :       REAL(KIND=dp), INTENT(OUT)                         :: e_h
    2732              : 
    2733         1446 :       IF (pint_env%transform == transformation_stage) THEN
    2734              :          CALL staging_calc_uf_h(pint_env%staging_env, &
    2735              :                                 pint_env%mass_beads, &
    2736              :                                 pint_env%ux, &
    2737              :                                 pint_env%uf_h, &
    2738            0 :                                 pint_env%e_pot_h)
    2739              :       ELSE
    2740              :          CALL normalmode_calc_uf_h(pint_env%normalmode_env, &
    2741              :                                    pint_env%mass_beads, &
    2742              :                                    pint_env%ux, &
    2743              :                                    pint_env%uf_h, &
    2744         1446 :                                    pint_env%e_pot_h)
    2745              :       END IF
    2746         1446 :       e_h = pint_env%e_pot_h
    2747      2571630 :       pint_env%uf_h = pint_env%uf_h/pint_env%mass_fict
    2748         1446 :    END SUBROUTINE pint_calc_uf_h
    2749              : 
    2750              : ! ***************************************************************************
    2751              : !> \brief calculates the force (and energy) in each bead, returns the sum
    2752              : !>      of the potential energy
    2753              : !> \param pint_env path integral environment on which you want to calculate
    2754              : !>        the forces
    2755              : !> \param x positions at which you want to evaluate the forces
    2756              : !> \param f the forces
    2757              : !> \param e potential energy on each bead
    2758              : !> \par    History
    2759              : !>           2009-06-15 moved helium calls out from here [lwalewski]
    2760              : !> \author fawzi
    2761              : ! **************************************************************************************************
    2762          712 :    SUBROUTINE pint_calc_f(pint_env, x, f, e)
    2763              :       TYPE(pint_env_type), INTENT(IN)                    :: pint_env
    2764              :       REAL(kind=dp), DIMENSION(:, :), INTENT(in), &
    2765              :          OPTIONAL, TARGET                                :: x
    2766              :       REAL(kind=dp), DIMENSION(:, :), INTENT(out), &
    2767              :          OPTIONAL, TARGET                                :: f
    2768              :       REAL(kind=dp), DIMENSION(:), INTENT(out), &
    2769              :          OPTIONAL, TARGET                                :: e
    2770              : 
    2771              :       INTEGER                                            :: ib, idim
    2772          712 :       REAL(kind=dp), DIMENSION(:), POINTER               :: my_e
    2773          712 :       REAL(kind=dp), DIMENSION(:, :), POINTER            :: my_f, my_x
    2774              : 
    2775          712 :       my_x => pint_env%x
    2776            0 :       IF (PRESENT(x)) my_x => x
    2777          712 :       my_f => pint_env%f
    2778          712 :       IF (PRESENT(f)) my_f => f
    2779          712 :       my_e => pint_env%e_pot_bead
    2780          712 :       IF (PRESENT(e)) my_e => e
    2781       338446 :       DO idim = 1, pint_env%ndim
    2782      2035630 :          DO ib = 1, pint_env%p
    2783      2034918 :             pint_env%replicas%r(idim, ib) = my_x(ib, idim)
    2784              :          END DO
    2785              :       END DO
    2786          712 :       CALL rep_env_calc_e_f(pint_env%replicas, calc_f=.TRUE.)
    2787       338446 :       DO idim = 1, pint_env%ndim
    2788      2035630 :          DO ib = 1, pint_env%p
    2789              :             !ljw: is that fine ? - idim <-> ib
    2790      2034918 :             my_f(ib, idim) = pint_env%replicas%f(idim, ib)
    2791              :          END DO
    2792              :       END DO
    2793         5152 :       my_e = pint_env%replicas%f(SIZE(pint_env%replicas%f, 1), :)
    2794              : 
    2795          712 :    END SUBROUTINE pint_calc_f
    2796              : 
    2797              : ! ***************************************************************************
    2798              : !> \brief  Calculate the kinetic energy of the beads (in the u variables)
    2799              : !> \param pint_env ...
    2800              : !> \param uv ...
    2801              : !> \param e_k ...
    2802              : !> \par    History
    2803              : !>         Bug fix to give my_uv a default location if not given in call [hforbert]
    2804              : !> \author fawzi
    2805              : ! **************************************************************************************************
    2806          770 :    SUBROUTINE pint_calc_e_kin_beads_u(pint_env, uv, e_k)
    2807              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    2808              :       REAL(kind=dp), DIMENSION(:, :), INTENT(in), &
    2809              :          OPTIONAL, TARGET                                :: uv
    2810              :       REAL(kind=dp), INTENT(out), OPTIONAL               :: e_k
    2811              : 
    2812              :       INTEGER                                            :: ib, idim
    2813              :       REAL(kind=dp)                                      :: res
    2814          770 :       REAL(kind=dp), DIMENSION(:, :), POINTER            :: my_uv
    2815              : 
    2816          770 :       res = -1.0_dp
    2817          770 :       my_uv => pint_env%uv
    2818            0 :       IF (PRESENT(uv)) my_uv => uv
    2819          770 :       res = 0._dp
    2820       403430 :       DO idim = 1, pint_env%ndim
    2821      2398262 :          DO ib = 1, pint_env%p
    2822      2397492 :             res = res + pint_env%mass_fict(ib, idim)*my_uv(ib, idim)**2
    2823              :          END DO
    2824              :       END DO
    2825          770 :       res = res*0.5
    2826          770 :       IF (.NOT. PRESENT(uv)) pint_env%e_kin_beads = res
    2827          770 :       IF (PRESENT(e_k)) e_k = res
    2828          770 :    END SUBROUTINE pint_calc_e_kin_beads_u
    2829              : 
    2830              : ! ***************************************************************************
    2831              : !> \brief  Calculate the virial estimator of the real (quantum) kinetic energy
    2832              : !> \param pint_env ...
    2833              : !> \param e_vir ...
    2834              : !> \author hforbert
    2835              : !> \note   This subroutine modifies pint_env%energy(e_kin_virial_id) global
    2836              : !>         variable [lwalewski]
    2837              : ! **************************************************************************************************
    2838          770 :    ELEMENTAL SUBROUTINE pint_calc_e_vir(pint_env, e_vir)
    2839              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    2840              :       REAL(kind=dp), INTENT(out), OPTIONAL               :: e_vir
    2841              : 
    2842              :       INTEGER                                            :: ib, idim
    2843              :       REAL(kind=dp)                                      :: res, xcentroid
    2844              : 
    2845              :       res = -1.0_dp
    2846          770 :       res = 0._dp
    2847       403430 :       DO idim = 1, pint_env%ndim
    2848              :          ! calculate the centroid
    2849       402660 :          xcentroid = 0._dp
    2850      2397492 :          DO ib = 1, pint_env%p
    2851      2397492 :             xcentroid = xcentroid + pint_env%x(ib, idim)
    2852              :          END DO
    2853       402660 :          xcentroid = xcentroid/REAL(pint_env%p, dp)
    2854      2398262 :          DO ib = 1, pint_env%p
    2855      2397492 :             res = res + (pint_env%x(ib, idim) - xcentroid)*pint_env%f(ib, idim)
    2856              :          END DO
    2857              :       END DO
    2858              :       res = 0.5_dp*(REAL(pint_env%ndim, dp)* &
    2859          770 :                     (pint_env%kT*pint_env%propagator%temp_sim2phys) - res/REAL(pint_env%p, dp))
    2860          770 :       pint_env%energy(e_kin_virial_id) = res
    2861          770 :       IF (PRESENT(e_vir)) e_vir = res
    2862          770 :    END SUBROUTINE pint_calc_e_vir
    2863              : 
    2864              : ! ***************************************************************************
    2865              : !> \brief calculates the energy (potential and kinetic) of the Nose-Hoover
    2866              : !>      chain thermostats
    2867              : !> \param pint_env the path integral environment
    2868              : !> \author fawzi
    2869              : ! **************************************************************************************************
    2870          292 :    ELEMENTAL SUBROUTINE pint_calc_nh_energy(pint_env)
    2871              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    2872              : 
    2873              :       INTEGER                                            :: ib, idim, inos
    2874              :       REAL(kind=dp)                                      :: ekin, epot
    2875              : 
    2876          292 :       ekin = 0._dp
    2877        39928 :       DO idim = 1, pint_env%ndim
    2878       131008 :          DO ib = 1, pint_env%p
    2879       407412 :             DO inos = 1, pint_env%nnos
    2880       367776 :                ekin = ekin + pint_env%Q(ib)*pint_env%tv(inos, ib, idim)**2
    2881              :             END DO
    2882              :          END DO
    2883              :       END DO
    2884          292 :       pint_env%e_kin_t = 0.5_dp*ekin
    2885          292 :       epot = 0._dp
    2886        39928 :       DO idim = 1, pint_env%ndim
    2887       131008 :          DO ib = 1, pint_env%p
    2888       407412 :             DO inos = 1, pint_env%nnos
    2889       367776 :                epot = epot + pint_env%tx(inos, ib, idim)
    2890              :             END DO
    2891              :          END DO
    2892              :       END DO
    2893          292 :       pint_env%e_pot_t = pint_env%kT*epot
    2894          292 :    END SUBROUTINE pint_calc_nh_energy
    2895              : 
    2896              : ! ***************************************************************************
    2897              : !> \brief calculates the total link action of the PI system (excluding helium)
    2898              : !> \param pint_env the path integral environment
    2899              : !> \return ...
    2900              : !> \author Felix Uhl
    2901              : ! **************************************************************************************************
    2902          696 :    ELEMENTAL FUNCTION pint_calc_total_link_action(pint_env) RESULT(link_action)
    2903              :       TYPE(pint_env_type), INTENT(IN)                    :: pint_env
    2904              :       REAL(KIND=dp)                                      :: link_action
    2905              : 
    2906              :       INTEGER                                            :: iatom, ibead, idim, indx
    2907              :       REAL(KIND=dp)                                      :: hb2m, tau, tmp_link_action
    2908              :       REAL(KIND=dp), DIMENSION(3)                        :: r
    2909              : 
    2910              :       !tau = 1/(k_B T p)
    2911          696 :       tau = pint_env%beta/REAL(pint_env%p, dp)
    2912              : 
    2913          696 :       link_action = 0.0_dp
    2914       113226 :       DO iatom = 1, pint_env%ndim/3
    2915              :          ! hbar / (2.0*m)
    2916       112530 :          hb2m = 1.0_dp/pint_env%mass((iatom - 1)*3 + 1)
    2917       112530 :          tmp_link_action = 0.0_dp
    2918       565296 :          DO ibead = 1, pint_env%p - 1
    2919      1811064 :             DO idim = 1, 3
    2920      1358298 :                indx = (iatom - 1)*3 + idim
    2921      1811064 :                r(idim) = pint_env%x(ibead, indx) - pint_env%x(ibead + 1, indx)
    2922              :             END DO
    2923       565296 :             tmp_link_action = tmp_link_action + (r(1)*r(1) + r(2)*r(2) + r(3)*r(3))
    2924              :          END DO
    2925       450120 :          DO idim = 1, 3
    2926       337590 :             indx = (iatom - 1)*3 + idim
    2927       450120 :             r(idim) = pint_env%x(pint_env%p, indx) - pint_env%x(1, indx)
    2928              :          END DO
    2929       112530 :          tmp_link_action = tmp_link_action + (r(1)*r(1) + r(2)*r(2) + r(3)*r(3))
    2930       113226 :          link_action = link_action + tmp_link_action/hb2m
    2931              :       END DO
    2932              : 
    2933          696 :       link_action = link_action/(2.0_dp*tau)
    2934              : 
    2935          696 :    END FUNCTION pint_calc_total_link_action
    2936              : 
    2937              : ! ***************************************************************************
    2938              : !> \brief calculates the potential action of the PI system (excluding helium)
    2939              : !> \param pint_env the path integral environment
    2940              : !> \return ...
    2941              : !> \author Felix Uhl
    2942              : ! **************************************************************************************************
    2943          696 :    ELEMENTAL FUNCTION pint_calc_total_pot_action(pint_env) RESULT(pot_action)
    2944              :       TYPE(pint_env_type), INTENT(IN)                    :: pint_env
    2945              :       REAL(KIND=dp)                                      :: pot_action
    2946              : 
    2947              :       REAL(KIND=dp)                                      :: tau
    2948              : 
    2949          696 :       tau = pint_env%beta/REAL(pint_env%p, dp)
    2950         4992 :       pot_action = tau*SUM(pint_env%e_pot_bead)
    2951              : 
    2952          696 :    END FUNCTION pint_calc_total_pot_action
    2953              : 
    2954              : ! ***************************************************************************
    2955              : !> \brief calculates the total action of the PI system (excluding helium)
    2956              : !> \param pint_env the path integral environment
    2957              : !> \author Felix Uhl
    2958              : ! **************************************************************************************************
    2959          696 :    ELEMENTAL SUBROUTINE pint_calc_total_action(pint_env)
    2960              :       TYPE(pint_env_type), INTENT(INOUT)                 :: pint_env
    2961              : 
    2962          696 :       pint_env%pot_action = pint_calc_total_pot_action(pint_env)
    2963          696 :       pint_env%link_action = pint_calc_total_link_action(pint_env)
    2964              : 
    2965          696 :    END SUBROUTINE pint_calc_total_action
    2966              : 
    2967            2 : END MODULE pint_methods
        

Generated by: LCOV version 2.0-1