LCOV - code coverage report
Current view: top level - src/motion - thermal_region_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:3db43b4) Lines: 82.8 % 169 140
Test Date: 2026-04-03 06:55:30 Functions: 100.0 % 4 4

            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 Setup of regions with different temperature
      10              : !> \par History
      11              : !>   - Added support for Langevin regions (2014/01/08, LT)
      12              : !>   - Added print subroutine for langevin regions (2014/02/04, LT)
      13              : !>   - Changed print_thermal_regions to print_thermal_regions_temperature
      14              : !>     (2014/02/04, LT)
      15              : !> \author MI
      16              : ! **************************************************************************************************
      17              : MODULE thermal_region_utils
      18              : 
      19              :    USE bibliography,                    ONLY: Kantorovich2008,&
      20              :                                               Kantorovich2008a,&
      21              :                                               cite_reference
      22              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      23              :                                               cp_logger_type,&
      24              :                                               cp_to_string
      25              :    USE cp_output_handling,              ONLY: cp_p_file,&
      26              :                                               cp_print_key_finished_output,&
      27              :                                               cp_print_key_should_output,&
      28              :                                               cp_print_key_unit_nr
      29              :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      30              :                                               cp_subsys_type
      31              :    USE cp_units,                        ONLY: cp_unit_from_cp2k,&
      32              :                                               cp_unit_to_cp2k
      33              :    USE force_env_types,                 ONLY: force_env_get,&
      34              :                                               force_env_type
      35              :    USE force_fields_util,               ONLY: get_generic_info
      36              :    USE fparser,                         ONLY: EvalErrType,&
      37              :                                               evalf,&
      38              :                                               finalizef,&
      39              :                                               initf,&
      40              :                                               parsef
      41              :    USE input_constants,                 ONLY: langevin_ensemble,&
      42              :                                               npt_f_ensemble,&
      43              :                                               npt_i_ensemble,&
      44              :                                               npt_ia_ensemble,&
      45              :                                               nvt_ensemble
      46              :    USE input_section_types,             ONLY: section_vals_get,&
      47              :                                               section_vals_get_subs_vals,&
      48              :                                               section_vals_type,&
      49              :                                               section_vals_val_get
      50              :    USE kinds,                           ONLY: default_string_length,&
      51              :                                               dp
      52              :    USE memory_utilities,                ONLY: reallocate
      53              :    USE particle_list_types,             ONLY: particle_list_type
      54              :    USE physcon,                         ONLY: femtoseconds,&
      55              :                                               kelvin
      56              :    USE simpar_types,                    ONLY: simpar_type
      57              :    USE string_utilities,                ONLY: integer_to_string
      58              :    USE thermal_region_types,            ONLY: allocate_thermal_regions,&
      59              :                                               release_thermal_regions,&
      60              :                                               thermal_region_type,&
      61              :                                               thermal_regions_type
      62              : #include "../base/base_uses.f90"
      63              : 
      64              :    IMPLICIT NONE
      65              : 
      66              :    PRIVATE
      67              :    PUBLIC :: create_thermal_regions, &
      68              :              print_thermal_regions_temperature, &
      69              :              print_thermal_regions_langevin, &
      70              :              update_thermal_regions_temp_expected
      71              : 
      72              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'thermal_region_utils'
      73              : 
      74              : CONTAINS
      75              : 
      76              : ! **************************************************************************************************
      77              : !> \brief create thermal_regions
      78              : !> \param thermal_regions ...
      79              : !> \param md_section ...
      80              : !> \param simpar ...
      81              : !> \param force_env ...
      82              : !> \par History
      83              : !>   - Added support for Langevin regions (2014/01/08, LT)
      84              : !> \author
      85              : ! **************************************************************************************************
      86         5364 :    SUBROUTINE create_thermal_regions(thermal_regions, md_section, simpar, force_env)
      87              :       TYPE(thermal_regions_type), POINTER                :: thermal_regions
      88              :       TYPE(section_vals_type), POINTER                   :: md_section
      89              :       TYPE(simpar_type), POINTER                         :: simpar
      90              :       TYPE(force_env_type), POINTER                      :: force_env
      91              : 
      92              :       CHARACTER(LEN=default_string_length)               :: my_region
      93              :       INTEGER                                            :: i, il, ipart, ireg, itimes, nlist, &
      94              :                                                             nregions
      95         1788 :       INTEGER, DIMENSION(:), POINTER                     :: tmplist
      96              :       LOGICAL                                            :: apply_thermostat, do_langevin, &
      97              :                                                             do_langevin_default, do_read_ngr, &
      98              :                                                             explicit, use_t, use_tfunc
      99              :       REAL(KIND=dp)                                      :: temp, temp_tol
     100              :       TYPE(cp_subsys_type), POINTER                      :: subsys
     101              :       TYPE(particle_list_type), POINTER                  :: particles
     102              :       TYPE(section_vals_type), POINTER                   :: region_sections, tfunc_section, &
     103              :                                                             thermal_region_section
     104              :       TYPE(thermal_region_type), POINTER                 :: t_region
     105              : 
     106         1788 :       NULLIFY (region_sections, t_region, tfunc_section, thermal_region_section, particles, subsys, tmplist)
     107            0 :       ALLOCATE (thermal_regions)
     108         1788 :       CALL allocate_thermal_regions(thermal_regions)
     109         1788 :       thermal_region_section => section_vals_get_subs_vals(md_section, "THERMAL_REGION")
     110         1788 :       CALL section_vals_get(thermal_region_section, explicit=explicit)
     111         1788 :       IF (explicit) THEN
     112              :          apply_thermostat = (simpar%ensemble == nvt_ensemble) .OR. &
     113              :                             (simpar%ensemble == npt_f_ensemble) .OR. &
     114              :                             (simpar%ensemble == npt_ia_ensemble) .OR. &
     115           14 :                             (simpar%ensemble == npt_i_ensemble)
     116              :          IF (apply_thermostat) THEN
     117              :             CALL cp_warn(__LOCATION__, &
     118              :                          "With the chosen ensemble the temperature is "// &
     119              :                          "controlled by thermostats. The definition of different thermal "// &
     120            0 :                          "regions might result inconsistent with the presence of thermostats.")
     121              :          END IF
     122           14 :          IF (simpar%temp_tol > 0.0_dp) THEN
     123              :             CALL cp_warn(__LOCATION__, &
     124              :                          "Control of the global temperature by rescaling of the velocity "// &
     125              :                          "is not consistent with the presence of different thermal regions. "// &
     126            0 :                          "The temperature of different regions is rescaled separatedly.")
     127              :          END IF
     128              :          CALL section_vals_val_get(thermal_region_section, "FORCE_RESCALING", &
     129           14 :                                    l_val=thermal_regions%force_rescaling)
     130              :          region_sections => section_vals_get_subs_vals(thermal_region_section, &
     131           14 :                                                        "DEFINE_REGION")
     132           14 :          CALL section_vals_get(region_sections, n_repetition=nregions)
     133           14 :          IF (nregions > 0) THEN
     134           14 :             thermal_regions%nregions = nregions
     135           14 :             thermal_regions%section => thermal_region_section
     136           62 :             ALLOCATE (thermal_regions%thermal_region(nregions))
     137           14 :             CALL force_env_get(force_env, subsys=subsys)
     138           14 :             CALL cp_subsys_get(subsys, particles=particles)
     139           14 :             IF (simpar%ensemble == langevin_ensemble) THEN
     140           12 :                CALL cite_reference(Kantorovich2008)
     141           12 :                CALL cite_reference(Kantorovich2008a)
     142              :                CALL section_vals_val_get(thermal_region_section, "DO_LANGEVIN_DEFAULT", &
     143           12 :                                          l_val=do_langevin_default)
     144           36 :                ALLOCATE (thermal_regions%do_langevin(particles%n_els))
     145           96 :                thermal_regions%do_langevin = do_langevin_default
     146              :             END IF
     147           34 :             DO ireg = 1, nregions
     148           20 :                NULLIFY (t_region)
     149           20 :                CALL integer_to_string(ireg, my_region)
     150           20 :                t_region => thermal_regions%thermal_region(ireg)
     151           20 :                t_region%region_index = ireg
     152              : 
     153              :                ! Determine t_region%npart
     154              :                CALL section_vals_val_get(region_sections, "LIST", &
     155           20 :                                          i_rep_section=ireg, n_rep_val=nlist)
     156           20 :                NULLIFY (t_region%part_index)
     157           20 :                t_region%npart = 0
     158           20 :                IF (simpar%ensemble == langevin_ensemble) THEN
     159              :                   CALL section_vals_val_get(region_sections, "DO_LANGEVIN", &
     160           16 :                                             i_rep_section=ireg, l_val=do_langevin)
     161              :                END IF
     162           42 :                DO il = 1, nlist
     163              :                   CALL section_vals_val_get(region_sections, "LIST", i_rep_section=ireg, &
     164           22 :                                             i_rep_val=il, i_vals=tmplist)
     165           22 :                   CALL reallocate(t_region%part_index, 1, t_region%npart + SIZE(tmplist))
     166          162 :                   DO i = 1, SIZE(tmplist)
     167          120 :                      ipart = tmplist(i)
     168          120 :                      CPASSERT(((ipart > 0) .AND. (ipart <= particles%n_els)))
     169          120 :                      t_region%npart = t_region%npart + 1
     170          120 :                      t_region%part_index(t_region%npart) = ipart
     171          120 :                      particles%els(ipart)%t_region_index = ireg
     172          142 :                      IF (simpar%ensemble == langevin_ensemble) THEN
     173           44 :                         thermal_regions%do_langevin(ipart) = do_langevin
     174              :                      END IF
     175              :                   END DO
     176              :                END DO
     177              : 
     178              :                ! Determine t_region%temp_expected
     179           20 :                tfunc_section => section_vals_get_subs_vals(region_sections, "TFUNC", i_rep_section=ireg)
     180           20 :                CALL section_vals_val_get(region_sections, "TEMPERATURE", i_rep_section=ireg, explicit=use_t)
     181           20 :                IF (use_t) CALL section_vals_val_get(region_sections, "TEMPERATURE", i_rep_section=ireg, r_val=temp)
     182           20 :                CALL section_vals_get(tfunc_section, explicit=use_tfunc)
     183           20 :                IF (use_tfunc) THEN
     184              :                   CALL get_generic_info(tfunc_section, "FUNCTION", &
     185              :                                         t_region%temperature_function, &
     186              :                                         t_region%temperature_function_parameters, &
     187              :                                         t_region%temperature_function_values, &
     188            0 :                                         input_variables=["S", "T"], i_rep_sec=1)
     189            0 :                   CALL initf(1)
     190              :                   CALL parsef(1, TRIM(t_region%temperature_function), &
     191            0 :                               t_region%temperature_function_parameters)
     192            0 :                   IF (.NOT. use_t) THEN ! Evaluate function for initial temperature
     193            0 :                      CALL section_vals_val_get(md_section, "STEP_START_VAL", i_val=itimes)
     194            0 :                      t_region%temperature_function_values(1) = itimes*1.0_dp
     195            0 :                      t_region%temperature_function_values(2) = 0.0_dp
     196            0 :                      temp = cp_unit_to_cp2k(evalf(1, t_region%temperature_function_values), "K")
     197            0 :                      CPASSERT(EvalErrType <= 0)
     198              :                   END IF
     199            0 :                   CALL finalizef()
     200              :                END IF
     201           20 :                IF (temp >= 0.0_dp) THEN ! Check for negative temperature in Kelvin
     202           20 :                   t_region%temp_expected = temp
     203              :                ELSE
     204              :                   CALL cp_abort(__LOCATION__, &
     205              :                                 "The initial temperature for region "//TRIM(my_region)//" is "// &
     206              :                                 TRIM(ADJUSTL(cp_to_string(cp_unit_from_cp2k(temp, "K"))))// &
     207            0 :                                 " K, which is negative and unphysical!")
     208              :                END IF
     209              : 
     210              :                CALL section_vals_val_get(region_sections, "TEMP_TOL", i_rep_section=ireg, &
     211           20 :                                          r_val=temp_tol)
     212           20 :                t_region%temp_tol = temp_tol
     213           20 :                CALL section_vals_val_get(region_sections, "NOISY_GAMMA_REGION", i_rep_section=ireg, explicit=do_read_ngr)
     214           94 :                IF (do_read_ngr) THEN
     215              :                   CALL section_vals_val_get(region_sections, "NOISY_GAMMA_REGION", i_rep_section=ireg, &
     216            6 :                                             r_val=t_region%noisy_gamma_region)
     217            6 :                   IF (simpar%ensemble == langevin_ensemble) THEN
     218            6 :                      IF (.NOT. do_langevin) THEN
     219              :                         CALL cp_warn(__LOCATION__, &
     220              :                                      "You provided NOISY_GAMMA_REGION but atoms in thermal region "//TRIM(my_region)// &
     221              :                                      " will not undergo Langevin MD. "// &
     222            0 :                                      "NOISY_GAMMA_REGION will be ignored and its value discarded!")
     223              :                      END IF
     224              :                   ELSE
     225              :                      CALL cp_warn(__LOCATION__, &
     226              :                                   "You provided NOISY_GAMMA_REGION but the Langevin Ensamble is not selected "// &
     227            0 :                                   "NOISY_GAMMA_REGION will be ignored and its value discarded!")
     228              :                   END IF
     229              :                ELSE
     230           14 :                   t_region%noisy_gamma_region = simpar%noisy_gamma
     231              :                END IF
     232              :             END DO
     233           14 :             simpar%do_thermal_region = .TRUE.
     234              :          ELSE
     235            0 :             CALL release_thermal_regions(thermal_regions)
     236            0 :             DEALLOCATE (thermal_regions)
     237            0 :             simpar%do_thermal_region = .FALSE.
     238              :          END IF
     239              :       ELSE
     240         1774 :          CALL release_thermal_regions(thermal_regions)
     241         1774 :          DEALLOCATE (thermal_regions)
     242         1774 :          simpar%do_thermal_region = .FALSE.
     243              :       END IF
     244              : 
     245         1788 :    END SUBROUTINE create_thermal_regions
     246              : 
     247              : ! **************************************************************************************************
     248              : !> \brief update_thermal_regions_temp_expected
     249              : !> \param itimes          : iteration number of the time step
     250              : !> \param thermal_regions : thermal regions type contains information
     251              : !>                          about the regions
     252              : !> \date   03.2026
     253              : !> \par    Note on units: t_region%temperature is updated by
     254              : !>         SUBROUTINE scale_velocity_region in md_vel_utils.F
     255              : !>         which is in Kelvin, but t_region%temp_expected is
     256              : !>         in cp2k internal units. See "Note the unit conversion
     257              : !>         here" in print_thermal_regions_temperature below.
     258              : !> \author HE Zilong
     259              : ! **************************************************************************************************
     260           96 :    SUBROUTINE update_thermal_regions_temp_expected(itimes, thermal_regions)
     261              :       INTEGER, INTENT(IN)                                :: itimes
     262              :       TYPE(thermal_regions_type), POINTER                :: thermal_regions
     263              : 
     264              :       CHARACTER(LEN=default_string_length)               :: my_region
     265              :       INTEGER                                            :: ireg
     266              :       TYPE(thermal_region_type), POINTER                 :: t_region
     267              : 
     268          256 :       DO ireg = 1, thermal_regions%nregions
     269          160 :          NULLIFY (t_region)
     270          160 :          t_region => thermal_regions%thermal_region(ireg)
     271          256 :          IF (LEN_TRIM(t_region%temperature_function) > 0) THEN
     272            0 :             CALL initf(1)
     273            0 :             CALL parsef(1, TRIM(t_region%temperature_function), t_region%temperature_function_parameters)
     274            0 :             t_region%temperature_function_values(1) = itimes*1.0_dp
     275            0 :             t_region%temperature_function_values(2) = t_region%temperature
     276            0 :             t_region%temp_expected = cp_unit_to_cp2k(evalf(1, t_region%temperature_function_values), "K")
     277            0 :             CPASSERT(EvalErrType <= 0)
     278            0 :             CALL finalizef()
     279            0 :             IF (t_region%temp_expected < 0.0_dp) THEN
     280            0 :                CALL integer_to_string(ireg, my_region)
     281              :                CALL cp_abort(__LOCATION__, &
     282              :                              "The temperature evaluated for region "//TRIM(my_region)//" is "// &
     283              :                              TRIM(ADJUSTL(cp_to_string(cp_unit_from_cp2k(t_region%temp_expected, "K"))))// &
     284            0 :                              " K, which is negative and unphysical!")
     285              :             END IF
     286              :          END IF
     287              :       END DO
     288              : 
     289           96 :    END SUBROUTINE update_thermal_regions_temp_expected
     290              : 
     291              : ! **************************************************************************************************
     292              : !> \brief print_thermal_regions_temperature
     293              : !> \param thermal_regions : thermal regions type contains information
     294              : !>                          about the regions
     295              : !> \param itimes          : iteration number of the time step
     296              : !> \param time            : simulation time of the time step
     297              : !> \param pos             : file position
     298              : !> \param act             : file action
     299              : !> \par History
     300              : !>   - added doxygen header and changed subroutine name from
     301              : !>     print_thermal_regions to print_thermal_regions_temperature
     302              : !>     (2014/02/04, LT)
     303              : !> \author
     304              : ! **************************************************************************************************
     305        43819 :    SUBROUTINE print_thermal_regions_temperature(thermal_regions, itimes, time, pos, act)
     306              :       TYPE(thermal_regions_type), POINTER                :: thermal_regions
     307              :       INTEGER, INTENT(IN)                                :: itimes
     308              :       REAL(KIND=dp), INTENT(IN)                          :: time
     309              :       CHARACTER(LEN=default_string_length)               :: pos, act
     310              : 
     311              :       CHARACTER(LEN=default_string_length)               :: fmd
     312              :       INTEGER                                            :: ireg, nregions, unit
     313              :       LOGICAL                                            :: new_file
     314        43819 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: temp, temp_tfunc
     315              :       TYPE(cp_logger_type), POINTER                      :: logger
     316              :       TYPE(section_vals_type), POINTER                   :: print_key
     317              : 
     318        43819 :       NULLIFY (logger)
     319        43819 :       logger => cp_get_default_logger()
     320              : 
     321        43819 :       IF (ASSOCIATED(thermal_regions)) THEN
     322          110 :          print_key => section_vals_get_subs_vals(thermal_regions%section, "PRINT%TEMPERATURE")
     323          110 :          IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
     324              :             unit = cp_print_key_unit_nr(logger, thermal_regions%section, "PRINT%TEMPERATURE", &
     325              :                                         extension=".tregion", file_position=pos, &
     326           42 :                                         file_action=act, is_new_file=new_file)
     327           42 :             IF (unit > 0) THEN
     328           21 :                IF (new_file) THEN
     329            1 :                   WRITE (unit, '(A)') "# Temperature per Region"
     330            1 :                   WRITE (unit, '("#",3X,A,2X,A,13X,A)') "Step Nr.", "Time[fs]", "Temp.[K] ...."
     331              :                END IF
     332           21 :                nregions = thermal_regions%nregions
     333           63 :                ALLOCATE (temp(0:nregions))
     334           63 :                ALLOCATE (temp_tfunc(1:nregions))
     335           84 :                temp = 0.0_dp
     336           21 :                temp(0) = thermal_regions%temp_reg0
     337           63 :                DO ireg = 1, nregions
     338              :                   ! Note the unit conversion here
     339           42 :                   temp(ireg) = thermal_regions%thermal_region(ireg)%temperature
     340           63 :                   temp_tfunc(ireg) = cp_unit_from_cp2k(thermal_regions%thermal_region(ireg)%temp_expected, "K")
     341              :                END DO
     342           21 :                fmd = "(I10,F20.3,"//TRIM(ADJUSTL(cp_to_string(2*nregions + 1)))//"F20.8)"
     343              :                fmd = TRIM(fmd)
     344           63 :                WRITE (UNIT=unit, FMT=fmd) itimes, time, temp(0), (temp_tfunc(ireg), temp(ireg), ireg=1, nregions)
     345           21 :                DEALLOCATE (temp)
     346           21 :                DEALLOCATE (temp_tfunc)
     347              :             END IF
     348           42 :             CALL cp_print_key_finished_output(unit, logger, thermal_regions%section, "PRINT%TEMPERATURE")
     349              :          END IF
     350              :       END IF
     351        43819 :    END SUBROUTINE print_thermal_regions_temperature
     352              : 
     353              : ! **************************************************************************************************
     354              : !> \brief print out information regarding to langevin regions defined in
     355              : !>        thermal_regions section
     356              : !> \param thermal_regions : thermal regions type containing the relevant
     357              : !>                          langevin regions information
     358              : !> \param simpar          : wrapper for simulation parameters
     359              : !> \param pos             : file position
     360              : !> \param act             : file action
     361              : !> \par History
     362              : !>   - created (2014/02/02, LT)
     363              : !> \author Lianheng Tong [LT] (tonglianheng@gmail.com)
     364              : ! **************************************************************************************************
     365           42 :    SUBROUTINE print_thermal_regions_langevin(thermal_regions, simpar, pos, act)
     366              :       TYPE(thermal_regions_type), POINTER                :: thermal_regions
     367              :       TYPE(simpar_type), POINTER                         :: simpar
     368              :       CHARACTER(LEN=default_string_length)               :: pos, act
     369              : 
     370              :       INTEGER                                            :: ipart, ipart_reg, ireg, natoms, &
     371              :                                                             print_unit
     372           42 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: region_id
     373              :       LOGICAL                                            :: new_file
     374           42 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: noisy_gamma_region, temperature
     375              :       TYPE(cp_logger_type), POINTER                      :: logger
     376              :       TYPE(section_vals_type), POINTER                   :: print_key
     377              : 
     378           42 :       NULLIFY (logger)
     379           42 :       logger => cp_get_default_logger()
     380              : 
     381           42 :       IF (ASSOCIATED(thermal_regions)) THEN
     382           12 :          IF (ASSOCIATED(thermal_regions%do_langevin)) THEN
     383              :             print_key => section_vals_get_subs_vals(thermal_regions%section, &
     384           12 :                                                     "PRINT%LANGEVIN_REGIONS")
     385           12 :             IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), &
     386              :                       cp_p_file)) THEN
     387              :                print_unit = cp_print_key_unit_nr(logger, thermal_regions%section, &
     388              :                                                  "PRINT%LANGEVIN_REGIONS", &
     389              :                                                  extension=".lgv_regions", &
     390              :                                                  file_position=pos, file_action=act, &
     391           12 :                                                  is_new_file=new_file)
     392           12 :                IF (print_unit > 0) THEN
     393            6 :                   IF (new_file) THEN
     394            6 :                      WRITE (print_unit, '(A)') "# Atoms Undergoing Langevin MD"
     395              :                      WRITE (print_unit, '(A,3X,A,3X,A,3X,A,3X,A,3X,A)') &
     396            6 :                         "#", "Atom_ID", "Region_ID", "Langevin(L)/NVE(N)", "Expected_T[K]", "[NoisyGamma]"
     397              :                   END IF
     398            6 :                   natoms = SIZE(thermal_regions%do_langevin)
     399           18 :                   ALLOCATE (temperature(natoms))
     400           18 :                   ALLOCATE (region_id(natoms))
     401           12 :                   ALLOCATE (noisy_gamma_region(natoms))
     402           42 :                   temperature(:) = simpar%temp_ext
     403           42 :                   region_id(:) = 0
     404           42 :                   noisy_gamma_region(:) = simpar%noisy_gamma
     405           14 :                   DO ireg = 1, thermal_regions%nregions
     406           36 :                      DO ipart_reg = 1, thermal_regions%thermal_region(ireg)%npart
     407           22 :                         ipart = thermal_regions%thermal_region(ireg)%part_index(ipart_reg)
     408           22 :                         temperature(ipart) = thermal_regions%thermal_region(ireg)%temp_expected
     409           22 :                         region_id(ipart) = thermal_regions%thermal_region(ireg)%region_index
     410           30 :                         noisy_gamma_region(ipart) = thermal_regions%thermal_region(ireg)%noisy_gamma_region
     411              :                      END DO
     412              :                   END DO
     413           42 :                   DO ipart = 1, natoms
     414           36 :                      WRITE (print_unit, '(1X,I10,2X)', advance='no') ipart
     415           36 :                      WRITE (print_unit, '(I10,3X)', advance='no') region_id(ipart)
     416           42 :                      IF (thermal_regions%do_langevin(ipart)) THEN
     417           24 :                         WRITE (print_unit, '(A,3X)', advance='no') "L"
     418           24 :                         IF (noisy_gamma_region(ipart) > 0._dp) THEN
     419           10 :                            WRITE (print_unit, '(10X,F20.3,3X,ES9.3)') temperature(ipart)*kelvin, &
     420           20 :                               noisy_gamma_region(ipart)/femtoseconds
     421              :                         ELSE
     422           14 :                            WRITE (print_unit, '(10X,F20.3)') temperature(ipart)*kelvin
     423              :                         END IF
     424              :                      ELSE
     425           12 :                         WRITE (print_unit, '(A,3X)', advance='no') "N"
     426           12 :                         WRITE (print_unit, '(18X,A)') "--"
     427              :                      END IF
     428              :                   END DO
     429            6 :                   DEALLOCATE (region_id)
     430            6 :                   DEALLOCATE (temperature)
     431            6 :                   DEALLOCATE (noisy_gamma_region)
     432              :                END IF
     433              :                CALL cp_print_key_finished_output(print_unit, logger, thermal_regions%section, &
     434           12 :                                                  "PRINT%LANGEVIN_REGIONS")
     435              :             END IF
     436              :          END IF
     437              :       END IF
     438           42 :    END SUBROUTINE print_thermal_regions_langevin
     439              : 
     440              : END MODULE thermal_region_utils
        

Generated by: LCOV version 2.0-1