LCOV - code coverage report
Current view: top level - src/motion/thermostat - extended_system_mapping.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 51.1 % 184 94
Test Date: 2026-07-25 06:35:44 Functions: 57.1 % 7 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              : !> \par History
      10              : !>      CJM, 20-Feb-01
      11              : !>      JGH (10-Mar-2001)
      12              : !>      CJM (10-Apr-2001)
      13              : !> \author CJM
      14              : ! **************************************************************************************************
      15              : MODULE extended_system_mapping
      16              : 
      17              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      18              :    USE extended_system_types,           ONLY: debug_isotropic_limit,&
      19              :                                               lnhc_parameters_type,&
      20              :                                               map_info_type
      21              :    USE input_constants,                 ONLY: &
      22              :         do_thermo_communication, do_thermo_no_communication, do_thermo_only_master, &
      23              :         isokin_ensemble, langevin_ensemble, npe_f_ensemble, npe_i_ensemble, &
      24              :         nph_uniaxial_damped_ensemble, nph_uniaxial_ensemble, npt_f_ensemble, npt_i_ensemble, &
      25              :         npt_ia_ensemble, nve_ensemble, nvt_adiabatic_ensemble, nvt_ensemble, reftraj_ensemble
      26              :    USE kinds,                           ONLY: dp
      27              :    USE message_passing,                 ONLY: mp_para_env_type
      28              :    USE molecule_kind_types,             ONLY: molecule_kind_type
      29              :    USE molecule_types,                  ONLY: global_constraint_type,&
      30              :                                               molecule_type
      31              :    USE simpar_types,                    ONLY: simpar_type
      32              :    USE thermostat_mapping,              ONLY: adiabatic_mapping_region,&
      33              :                                               init_baro_map_info,&
      34              :                                               thermostat_mapping_region
      35              :    USE thermostat_types,                ONLY: thermostat_info_type
      36              : #include "../../base/base_uses.f90"
      37              : 
      38              :    IMPLICIT NONE
      39              : 
      40              :    PRIVATE
      41              : 
      42              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'extended_system_mapping'
      43              : 
      44              :    PUBLIC :: nhc_to_particle_mapping, nhc_to_barostat_mapping, &
      45              :              nhc_to_shell_mapping, nhc_to_particle_mapping_fast, &
      46              :              nhc_to_particle_mapping_slow
      47              : 
      48              : CONTAINS
      49              : 
      50              : ! **************************************************************************************************
      51              : !> \brief Creates the thermostatting for the barostat
      52              : !> \param simpar ...
      53              : !> \param nhc ...
      54              : !> \par History
      55              : !>      CJM, 20-Feb-01  : nhc structure allocated to zero when not in use
      56              : !>      JGH (10-Mar-2001) : set nhc variables to zero when not in use
      57              : !> \author CJM
      58              : ! **************************************************************************************************
      59          120 :    SUBROUTINE nhc_to_barostat_mapping(simpar, nhc)
      60              : 
      61              :       TYPE(simpar_type), POINTER                         :: simpar
      62              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
      63              : 
      64              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'nhc_to_barostat_mapping'
      65              : 
      66              :       INTEGER                                            :: handle, i, number
      67              :       TYPE(map_info_type), POINTER                       :: map_info
      68              : 
      69          120 :       CALL timeset(routineN, handle)
      70              : 
      71          120 :       SELECT CASE (simpar%ensemble)
      72              :       CASE DEFAULT
      73            0 :          CPABORT('Never reach this point!')
      74              :       CASE (npt_i_ensemble, npt_f_ensemble, npt_ia_ensemble)
      75          120 :          map_info => nhc%map_info
      76          120 :          map_info%dis_type = do_thermo_only_master
      77              : 
      78              :          ! Counting the total number of thermostats ( 1 for NPT_I, NPT_IA, and NPT_F )
      79          120 :          nhc%loc_num_nhc = 1
      80          120 :          nhc%glob_num_nhc = 1
      81          120 :          IF (simpar%ensemble == npt_f_ensemble) THEN
      82           42 :             number = 9
      83              :          ELSE
      84           78 :             number = 1
      85              :          END IF
      86              : 
      87          120 :          CALL init_baro_map_info(map_info, number, nhc%loc_num_nhc)
      88              : 
      89          968 :          ALLOCATE (nhc%nvt(nhc%nhc_len, nhc%loc_num_nhc))
      90              :          ! Now that we know how many there are stick this into nhc % nkt
      91              :          ! (number of degrees of freedom times k_B T )
      92          240 :          DO i = 1, nhc%loc_num_nhc
      93          120 :             nhc%nvt(1, i)%nkt = simpar%temp_ext*number
      94          120 :             nhc%nvt(1, i)%degrees_of_freedom = number
      95          120 :             IF (debug_isotropic_limit) THEN
      96              :                nhc%nvt(1, i)%nkt = simpar%temp_ext
      97              :             END IF
      98              :          END DO
      99              : 
     100              :          ! getting the number of degrees of freedom times k_B T for the rest of the chain
     101          368 :          DO i = 2, nhc%nhc_len
     102          616 :             nhc%nvt(i, :)%nkt = simpar%temp_ext
     103              :          END DO
     104              : 
     105              :          ! Let's clean the arrays
     106          240 :          map_info%s_kin = 0.0_dp
     107          360 :          map_info%v_scale = 0.0_dp
     108              :       END SELECT
     109              : 
     110          120 :       CALL timestop(handle)
     111              : 
     112          120 :    END SUBROUTINE nhc_to_barostat_mapping
     113              : 
     114              : ! **************************************************************************************************
     115              : !> \brief Creates the thermostatting maps
     116              : !> \param thermostat_info ...
     117              : !> \param simpar ...
     118              : !> \param local_molecules ...
     119              : !> \param molecule_set ...
     120              : !> \param molecule_kind_set ...
     121              : !> \param nhc ...
     122              : !> \param para_env ...
     123              : !> \param gci ...
     124              : !> \par History
     125              : !>      29-Nov-00 (JGH) correct counting of DOF if constraints are off
     126              : !>      CJM, 20-Feb-01  : nhc structure allocated to zero when not in use
     127              : !>      JGH (10-Mar-2001) : set nhc variables to zero when not in use
     128              : !>      CJM(10-NOV-2001) : New parallelization with new molecule structures
     129              : !>      Teodoro Laino 09.2007 [tlaino] - University of Zurich - cleaning and updating
     130              : !> \author CJM
     131              : ! **************************************************************************************************
     132          376 :    SUBROUTINE nhc_to_particle_mapping(thermostat_info, simpar, local_molecules, &
     133              :                                       molecule_set, molecule_kind_set, nhc, para_env, gci)
     134              : 
     135              :       TYPE(thermostat_info_type), POINTER                :: thermostat_info
     136              :       TYPE(simpar_type), POINTER                         :: simpar
     137              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     138              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     139              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     140              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
     141              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     142              :       TYPE(global_constraint_type), POINTER              :: gci
     143              : 
     144              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'nhc_to_particle_mapping'
     145              : 
     146              :       INTEGER                                            :: handle, i, imap, j, natoms_local, &
     147              :                                                             sum_of_thermostats
     148          376 :       INTEGER, DIMENSION(:), POINTER                     :: deg_of_freedom, massive_atom_list
     149              :       REAL(KIND=dp)                                      :: fac
     150              :       TYPE(map_info_type), POINTER                       :: map_info
     151              : 
     152          376 :       CALL timeset(routineN, handle)
     153              : 
     154          376 :       NULLIFY (massive_atom_list, deg_of_freedom)
     155              : 
     156          376 :       SELECT CASE (simpar%ensemble)
     157              :       CASE DEFAULT
     158            0 :          CPABORT('Unknown ensemble!')
     159              :       CASE (nve_ensemble, isokin_ensemble, npe_f_ensemble, npe_i_ensemble, nph_uniaxial_ensemble, &
     160              :             nph_uniaxial_damped_ensemble, reftraj_ensemble, langevin_ensemble)
     161            0 :          CPABORT('Never reach this point!')
     162              :       CASE (nvt_ensemble, npt_i_ensemble, npt_f_ensemble, npt_ia_ensemble)
     163              : 
     164              :          CALL setup_nhc_thermostat(nhc, thermostat_info, deg_of_freedom, massive_atom_list, &
     165              :                                    molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, &
     166          376 :                                    simpar, sum_of_thermostats, gci)
     167              : 
     168              :          ! Sum up the number of degrees of freedom on each thermostat.
     169              :          ! first: initialize the target
     170          376 :          map_info => nhc%map_info
     171        21375 :          map_info%s_kin = 0.0_dp
     172         1504 :          DO i = 1, 3
     173       109957 :             DO j = 1, natoms_local
     174       109581 :                map_info%p_kin(i, j)%point = map_info%p_kin(i, j)%point + 1
     175              :             END DO
     176              :          END DO
     177              : 
     178              :          ! if thermostats are replicated but molecules distributed, we have to
     179              :          ! sum s_kin over all processors
     180          800 :          IF (map_info%dis_type == do_thermo_communication) CALL para_env%sum(map_info%s_kin)
     181              : 
     182              :          ! We know the total number of system thermostats.
     183          376 :          IF ((sum_of_thermostats == 1) .AND. (map_info%dis_type /= do_thermo_no_communication)) THEN
     184          184 :             fac = map_info%s_kin(1) - deg_of_freedom(1) - simpar%nfree_rot_transl
     185          184 :             IF (fac == 0.0_dp) THEN
     186            0 :                CPABORT('Zero degrees of freedom. Nothing to thermalize!')
     187              :             END IF
     188          184 :             nhc%nvt(1, 1)%nkt = simpar%temp_ext*fac
     189          184 :             nhc%nvt(1, 1)%degrees_of_freedom = FLOOR(fac)
     190              :          ELSE
     191        21003 :             DO i = 1, nhc%loc_num_nhc
     192        20811 :                imap = map_info%map_index(i)
     193        20811 :                fac = (map_info%s_kin(imap) - deg_of_freedom(i))
     194        20811 :                nhc%nvt(1, i)%nkt = simpar%temp_ext*fac
     195        21003 :                nhc%nvt(1, i)%degrees_of_freedom = FLOOR(fac)
     196              :             END DO
     197              :          END IF
     198              : 
     199              :          ! Getting the number of degrees of freedom times k_B T for the rest
     200              :          ! of the chain
     201         1222 :          DO i = 2, nhc%nhc_len
     202        42008 :             nhc%nvt(i, :)%nkt = simpar%temp_ext
     203        42384 :             nhc%nvt(i, :)%degrees_of_freedom = 1
     204              :          END DO
     205          376 :          DEALLOCATE (deg_of_freedom)
     206          376 :          DEALLOCATE (massive_atom_list)
     207              : 
     208              :          ! Let's clean the arrays
     209        21375 :          map_info%s_kin = 0.0_dp
     210        21751 :          map_info%v_scale = 0.0_dp
     211              :       END SELECT
     212              : 
     213          376 :       CALL timestop(handle)
     214              : 
     215          376 :    END SUBROUTINE nhc_to_particle_mapping
     216              : 
     217              : ! **************************************************************************************************
     218              : !> \brief Main general setup for Adiabatic Nose-Hoover thermostats
     219              : !> \param nhc ...
     220              : !> \param thermostat_info ...
     221              : !> \param deg_of_freedom ...
     222              : !> \param massive_atom_list ...
     223              : !> \param molecule_kind_set ...
     224              : !> \param local_molecules ...
     225              : !> \param molecule_set ...
     226              : !> \param para_env ...
     227              : !> \param natoms_local ...
     228              : !> \param simpar ...
     229              : !> \param sum_of_thermostats ...
     230              : !> \param gci ...
     231              : !> \param shell ...
     232              : !> \author CJM -PNNL -2011
     233              : ! **************************************************************************************************
     234            0 :    SUBROUTINE setup_adiabatic_thermostat(nhc, thermostat_info, deg_of_freedom, &
     235              :                                          massive_atom_list, molecule_kind_set, local_molecules, molecule_set, &
     236              :                                          para_env, natoms_local, simpar, sum_of_thermostats, gci, shell)
     237              : 
     238              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
     239              :       TYPE(thermostat_info_type), POINTER                :: thermostat_info
     240              :       INTEGER, DIMENSION(:), POINTER                     :: deg_of_freedom, massive_atom_list
     241              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     242              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     243              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     244              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     245              :       INTEGER, INTENT(OUT)                               :: natoms_local
     246              :       TYPE(simpar_type), POINTER                         :: simpar
     247              :       INTEGER, INTENT(OUT)                               :: sum_of_thermostats
     248              :       TYPE(global_constraint_type), POINTER              :: gci
     249              :       LOGICAL, INTENT(IN), OPTIONAL                      :: shell
     250              : 
     251              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'setup_adiabatic_thermostat'
     252              : 
     253              :       INTEGER                                            :: handle, nkind, number, region
     254              :       LOGICAL                                            :: do_shell
     255              :       TYPE(map_info_type), POINTER                       :: map_info
     256              : 
     257            0 :       CALL timeset(routineN, handle)
     258              : 
     259            0 :       do_shell = .FALSE.
     260            0 :       IF (PRESENT(shell)) do_shell = shell
     261            0 :       map_info => nhc%map_info
     262              : 
     263            0 :       nkind = SIZE(molecule_kind_set)
     264            0 :       sum_of_thermostats = thermostat_info%sum_of_thermostats
     265            0 :       map_info%dis_type = thermostat_info%dis_type
     266            0 :       number = thermostat_info%number_of_thermostats
     267            0 :       region = nhc%region
     268              : 
     269              :       CALL adiabatic_mapping_region(map_info, deg_of_freedom, massive_atom_list, &
     270              :                                     molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, &
     271              :                                     simpar, number, region, gci, do_shell, thermostat_info%map_loc_thermo_gen, &
     272            0 :                                     sum_of_thermostats)
     273            0 :       ALLOCATE (nhc%nvt(nhc%nhc_len, number))
     274              : 
     275              :       ! Now that we know how many there are stick this into nhc%nkt
     276              :       ! (number of degrees of freedom times k_B T for the first thermostat
     277              :       !  on the chain)
     278            0 :       nhc%loc_num_nhc = number
     279            0 :       nhc%glob_num_nhc = sum_of_thermostats
     280              : 
     281            0 :       CALL timestop(handle)
     282              : 
     283            0 :    END SUBROUTINE setup_adiabatic_thermostat
     284              : 
     285              : ! **************************************************************************************************
     286              : !> \brief Creates the thermostatting maps
     287              : !> \param thermostat_info ...
     288              : !> \param simpar ...
     289              : !> \param local_molecules ...
     290              : !> \param molecule_set ...
     291              : !> \param molecule_kind_set ...
     292              : !> \param nhc ...
     293              : !> \param para_env ...
     294              : !> \param gci ...
     295              : !> \par History
     296              : !> \author CJM
     297              : ! **************************************************************************************************
     298            0 :    SUBROUTINE nhc_to_particle_mapping_slow(thermostat_info, simpar, local_molecules, &
     299              :                                            molecule_set, molecule_kind_set, nhc, para_env, gci)
     300              : 
     301              :       TYPE(thermostat_info_type), POINTER                :: thermostat_info
     302              :       TYPE(simpar_type), POINTER                         :: simpar
     303              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     304              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     305              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     306              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
     307              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     308              :       TYPE(global_constraint_type), POINTER              :: gci
     309              : 
     310              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'nhc_to_particle_mapping_slow'
     311              : 
     312              :       INTEGER                                            :: handle, i, imap, j, natoms_local, &
     313              :                                                             sum_of_thermostats
     314            0 :       INTEGER, DIMENSION(:), POINTER                     :: deg_of_freedom, massive_atom_list
     315              :       REAL(KIND=dp)                                      :: fac
     316              :       TYPE(map_info_type), POINTER                       :: map_info
     317              : 
     318            0 :       CALL timeset(routineN, handle)
     319              : 
     320            0 :       NULLIFY (massive_atom_list, deg_of_freedom)
     321              : 
     322            0 :       SELECT CASE (simpar%ensemble)
     323              :       CASE DEFAULT
     324            0 :          CPABORT('Unknown ensemble!')
     325              :       CASE (nvt_adiabatic_ensemble)
     326              :          CALL setup_adiabatic_thermostat(nhc, thermostat_info, deg_of_freedom, massive_atom_list, &
     327              :                                          molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, &
     328            0 :                                          simpar, sum_of_thermostats, gci)
     329              : 
     330              :          ! Sum up the number of degrees of freedom on each thermostat.
     331              :          ! first: initialize the target
     332            0 :          map_info => nhc%map_info
     333            0 :          map_info%s_kin = 0.0_dp
     334            0 :          DO i = 1, 3
     335            0 :             DO j = 1, natoms_local
     336            0 :                IF (ASSOCIATED(map_info%p_kin(i, j)%point)) THEN
     337            0 :                   map_info%p_kin(i, j)%point = map_info%p_kin(i, j)%point + 1
     338              :                END IF
     339              :             END DO
     340              :          END DO
     341              : 
     342              :          ! if thermostats are replicated but molecules distributed, we have to
     343              :          ! sum s_kin over all processors
     344            0 :          IF (map_info%dis_type == do_thermo_communication) CALL para_env%sum(map_info%s_kin)
     345              : 
     346              :          ! We know the total number of system thermostats.
     347            0 :          IF ((sum_of_thermostats == 1) .AND. (map_info%dis_type /= do_thermo_no_communication)) THEN
     348            0 :             fac = map_info%s_kin(1) - deg_of_freedom(1) - simpar%nfree_rot_transl
     349            0 :             IF (fac == 0.0_dp) THEN
     350            0 :                CPABORT('Zero degrees of freedom. Nothing to thermalize!')
     351              :             END IF
     352            0 :             nhc%nvt(1, 1)%nkt = simpar%temp_slow*fac
     353            0 :             nhc%nvt(1, 1)%degrees_of_freedom = FLOOR(fac)
     354              :          ELSE
     355            0 :             DO i = 1, nhc%loc_num_nhc
     356            0 :                imap = map_info%map_index(i)
     357            0 :                fac = (map_info%s_kin(imap) - deg_of_freedom(i))
     358            0 :                nhc%nvt(1, i)%nkt = simpar%temp_slow*fac
     359            0 :                nhc%nvt(1, i)%degrees_of_freedom = FLOOR(fac)
     360              :             END DO
     361              :          END IF
     362              : 
     363              :          ! Getting the number of degrees of freedom times k_B T for the rest
     364              :          ! of the chain
     365            0 :          DO i = 2, nhc%nhc_len
     366            0 :             nhc%nvt(i, :)%nkt = simpar%temp_slow
     367            0 :             nhc%nvt(i, :)%degrees_of_freedom = 1
     368              :          END DO
     369            0 :          DEALLOCATE (deg_of_freedom)
     370            0 :          DEALLOCATE (massive_atom_list)
     371              : 
     372              :          ! Let's clean the arrays
     373            0 :          map_info%s_kin = 0.0_dp
     374            0 :          map_info%v_scale = 0.0_dp
     375              :       END SELECT
     376              : 
     377            0 :       CALL timestop(handle)
     378              : 
     379            0 :    END SUBROUTINE nhc_to_particle_mapping_slow
     380              : 
     381              : ! **************************************************************************************************
     382              : !> \brief Creates the thermostatting maps
     383              : !> \param thermostat_info ...
     384              : !> \param simpar ...
     385              : !> \param local_molecules ...
     386              : !> \param molecule_set ...
     387              : !> \param molecule_kind_set ...
     388              : !> \param nhc ...
     389              : !> \param para_env ...
     390              : !> \param gci ...
     391              : !> \par History
     392              : !> \author CJM
     393              : ! **************************************************************************************************
     394            0 :    SUBROUTINE nhc_to_particle_mapping_fast(thermostat_info, simpar, local_molecules, &
     395              :                                            molecule_set, molecule_kind_set, nhc, para_env, gci)
     396              : 
     397              :       TYPE(thermostat_info_type), POINTER                :: thermostat_info
     398              :       TYPE(simpar_type), POINTER                         :: simpar
     399              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     400              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     401              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     402              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
     403              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     404              :       TYPE(global_constraint_type), POINTER              :: gci
     405              : 
     406              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'nhc_to_particle_mapping_fast'
     407              : 
     408              :       INTEGER                                            :: handle, i, imap, j, natoms_local, &
     409              :                                                             sum_of_thermostats
     410            0 :       INTEGER, DIMENSION(:), POINTER                     :: deg_of_freedom, massive_atom_list
     411              :       REAL(KIND=dp)                                      :: fac
     412              :       TYPE(map_info_type), POINTER                       :: map_info
     413              : 
     414            0 :       CALL timeset(routineN, handle)
     415              : 
     416            0 :       NULLIFY (massive_atom_list, deg_of_freedom)
     417              : 
     418            0 :       SELECT CASE (simpar%ensemble)
     419              :       CASE DEFAULT
     420            0 :          CPABORT('Unknown ensemble!')
     421              :       CASE (nvt_adiabatic_ensemble)
     422              :          CALL setup_adiabatic_thermostat(nhc, thermostat_info, deg_of_freedom, massive_atom_list, &
     423              :                                          molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, &
     424            0 :                                          simpar, sum_of_thermostats, gci)
     425              : 
     426              :          ! Sum up the number of degrees of freedom on each thermostat.
     427              :          ! first: initialize the target
     428            0 :          map_info => nhc%map_info
     429            0 :          map_info%s_kin = 0.0_dp
     430            0 :          DO i = 1, 3
     431            0 :             DO j = 1, natoms_local
     432            0 :                IF (ASSOCIATED(map_info%p_kin(i, j)%point)) THEN
     433            0 :                   map_info%p_kin(i, j)%point = map_info%p_kin(i, j)%point + 1
     434              :                END IF
     435              :             END DO
     436              :          END DO
     437              : 
     438              :          ! if thermostats are replicated but molecules distributed, we have to
     439              :          ! sum s_kin over all processors
     440            0 :          IF (map_info%dis_type == do_thermo_communication) CALL para_env%sum(map_info%s_kin)
     441              : 
     442              :          ! We know the total number of system thermostats.
     443            0 :          IF ((sum_of_thermostats == 1) .AND. (map_info%dis_type /= do_thermo_no_communication)) THEN
     444            0 :             fac = map_info%s_kin(1) - deg_of_freedom(1) - simpar%nfree_rot_transl
     445            0 :             IF (fac == 0.0_dp) THEN
     446            0 :                CPABORT('Zero degrees of freedom. Nothing to thermalize!')
     447              :             END IF
     448            0 :             nhc%nvt(1, 1)%nkt = simpar%temp_fast*fac
     449            0 :             nhc%nvt(1, 1)%degrees_of_freedom = FLOOR(fac)
     450              :          ELSE
     451            0 :             DO i = 1, nhc%loc_num_nhc
     452            0 :                imap = map_info%map_index(i)
     453            0 :                fac = (map_info%s_kin(imap) - deg_of_freedom(i))
     454            0 :                nhc%nvt(1, i)%nkt = simpar%temp_fast*fac
     455            0 :                nhc%nvt(1, i)%degrees_of_freedom = FLOOR(fac)
     456              :             END DO
     457              :          END IF
     458              : 
     459              :          ! Getting the number of degrees of freedom times k_B T for the rest
     460              :          ! of the chain
     461            0 :          DO i = 2, nhc%nhc_len
     462            0 :             nhc%nvt(i, :)%nkt = simpar%temp_fast
     463            0 :             nhc%nvt(i, :)%degrees_of_freedom = 1
     464              :          END DO
     465            0 :          DEALLOCATE (deg_of_freedom)
     466            0 :          DEALLOCATE (massive_atom_list)
     467              : 
     468              :          ! Let's clean the arrays
     469            0 :          map_info%s_kin = 0.0_dp
     470            0 :          map_info%v_scale = 0.0_dp
     471              :       END SELECT
     472              : 
     473            0 :       CALL timestop(handle)
     474              : 
     475            0 :    END SUBROUTINE nhc_to_particle_mapping_fast
     476              : 
     477              : ! **************************************************************************************************
     478              : !> \brief Main general setup for Nose-Hoover thermostats
     479              : !> \param nhc ...
     480              : !> \param thermostat_info ...
     481              : !> \param deg_of_freedom ...
     482              : !> \param massive_atom_list ...
     483              : !> \param molecule_kind_set ...
     484              : !> \param local_molecules ...
     485              : !> \param molecule_set ...
     486              : !> \param para_env ...
     487              : !> \param natoms_local ...
     488              : !> \param simpar ...
     489              : !> \param sum_of_thermostats ...
     490              : !> \param gci ...
     491              : !> \param shell ...
     492              : !> \author Teodoro Laino [tlaino] - University of Zurich - 10.2007
     493              : ! **************************************************************************************************
     494          416 :    SUBROUTINE setup_nhc_thermostat(nhc, thermostat_info, deg_of_freedom, &
     495              :                                    massive_atom_list, molecule_kind_set, local_molecules, molecule_set, &
     496              :                                    para_env, natoms_local, simpar, sum_of_thermostats, gci, shell)
     497              : 
     498              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
     499              :       TYPE(thermostat_info_type), POINTER                :: thermostat_info
     500              :       INTEGER, DIMENSION(:), POINTER                     :: deg_of_freedom, massive_atom_list
     501              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     502              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     503              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     504              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     505              :       INTEGER, INTENT(OUT)                               :: natoms_local
     506              :       TYPE(simpar_type), POINTER                         :: simpar
     507              :       INTEGER, INTENT(OUT)                               :: sum_of_thermostats
     508              :       TYPE(global_constraint_type), POINTER              :: gci
     509              :       LOGICAL, INTENT(IN), OPTIONAL                      :: shell
     510              : 
     511              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'setup_nhc_thermostat'
     512              : 
     513              :       INTEGER                                            :: handle, nkind, number, region
     514              :       LOGICAL                                            :: do_shell
     515              :       TYPE(map_info_type), POINTER                       :: map_info
     516              : 
     517          416 :       CALL timeset(routineN, handle)
     518              : 
     519          416 :       do_shell = .FALSE.
     520          416 :       IF (PRESENT(shell)) do_shell = shell
     521          416 :       map_info => nhc%map_info
     522              : 
     523          416 :       nkind = SIZE(molecule_kind_set)
     524          416 :       sum_of_thermostats = thermostat_info%sum_of_thermostats
     525          416 :       map_info%dis_type = thermostat_info%dis_type
     526          416 :       number = thermostat_info%number_of_thermostats
     527          416 :       region = nhc%region
     528              : 
     529              :       CALL thermostat_mapping_region(map_info, deg_of_freedom, massive_atom_list, &
     530              :                                      molecule_kind_set, local_molecules, molecule_set, para_env, natoms_local, &
     531              :                                      simpar, number, region, gci, do_shell, thermostat_info%map_loc_thermo_gen, &
     532          416 :                                      sum_of_thermostats)
     533              : 
     534       109462 :       ALLOCATE (nhc%nvt(nhc%nhc_len, number))
     535              : 
     536              :       ! Now that we know how many there are stick this into nhc%nkt
     537              :       ! (number of degrees of freedom times k_B T for the first thermostat
     538              :       !  on the chain)
     539          416 :       nhc%loc_num_nhc = number
     540          416 :       nhc%glob_num_nhc = sum_of_thermostats
     541              : 
     542          416 :       CALL timestop(handle)
     543              : 
     544          832 :    END SUBROUTINE setup_nhc_thermostat
     545              : 
     546              : ! **************************************************************************************************
     547              : !> \brief ...
     548              : !> \param thermostat_info ...
     549              : !> \param simpar ...
     550              : !> \param local_molecules ...
     551              : !> \param molecule_set ...
     552              : !> \param molecule_kind_set ...
     553              : !> \param nhc ...
     554              : !> \param para_env ...
     555              : !> \param gci ...
     556              : ! **************************************************************************************************
     557           40 :    SUBROUTINE nhc_to_shell_mapping(thermostat_info, simpar, local_molecules, &
     558              :                                    molecule_set, molecule_kind_set, nhc, para_env, gci)
     559              : 
     560              :       TYPE(thermostat_info_type), POINTER                :: thermostat_info
     561              :       TYPE(simpar_type), POINTER                         :: simpar
     562              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     563              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     564              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     565              :       TYPE(lnhc_parameters_type), POINTER                :: nhc
     566              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     567              :       TYPE(global_constraint_type), POINTER              :: gci
     568              : 
     569              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'nhc_to_shell_mapping'
     570              : 
     571              :       INTEGER                                            :: handle, i, imap, j, nshell_local, &
     572              :                                                             sum_of_thermostats
     573           40 :       INTEGER, DIMENSION(:), POINTER                     :: deg_of_freedom, massive_shell_list
     574              :       TYPE(map_info_type), POINTER                       :: map_info
     575              : 
     576           40 :       CALL timeset(routineN, handle)
     577              : 
     578           40 :       NULLIFY (massive_shell_list, deg_of_freedom)
     579              : 
     580           40 :       SELECT CASE (simpar%ensemble)
     581              :       CASE DEFAULT
     582            0 :          CPABORT('Unknown ensemble!')
     583              :       CASE (isokin_ensemble, nph_uniaxial_ensemble, &
     584              :             nph_uniaxial_damped_ensemble, reftraj_ensemble, langevin_ensemble)
     585            0 :          CPABORT('Never reach this point!')
     586              :       CASE (nve_ensemble, nvt_ensemble, npe_f_ensemble, npe_i_ensemble, npt_i_ensemble, npt_f_ensemble, &
     587              :             npt_ia_ensemble)
     588              : 
     589              :          CALL setup_nhc_thermostat(nhc, thermostat_info, deg_of_freedom, massive_shell_list, &
     590              :                                    molecule_kind_set, local_molecules, molecule_set, para_env, nshell_local, &
     591           40 :                                    simpar, sum_of_thermostats, gci, shell=.TRUE.)
     592              : 
     593           40 :          map_info => nhc%map_info
     594              :          ! Sum up the number of degrees of freedom on each thermostat.
     595              :          ! first: initialize the target, via p_kin init s_kin
     596         4178 :          map_info%s_kin = 0.0_dp
     597         1960 :          DO j = 1, nshell_local
     598         7720 :             DO i = 1, 3
     599         7680 :                map_info%p_kin(i, j)%point = map_info%p_kin(i, j)%point + 1
     600              :             END DO
     601              :          END DO
     602              : 
     603              :          ! If thermostats are replicated but molecules distributed, we have to
     604              :          ! sum s_kin over all processors
     605           60 :          IF (map_info%dis_type == do_thermo_communication) CALL para_env%sum(map_info%s_kin)
     606              : 
     607              :          ! Now that we know how many there are stick this into nhc%nkt
     608              :          ! (number of degrees of freedom times k_B T )
     609         4178 :          DO i = 1, nhc%loc_num_nhc
     610         4138 :             imap = map_info%map_index(i)
     611         4138 :             nhc%nvt(1, i)%nkt = simpar%temp_sh_ext*map_info%s_kin(imap)
     612         4178 :             nhc%nvt(1, i)%degrees_of_freedom = INT(map_info%s_kin(imap))
     613              :          END DO
     614              : 
     615              :          ! Getting the number of degrees of freedom times k_B T for the rest of the chain
     616          210 :          DO i = 2, nhc%nhc_len
     617        16540 :             nhc%nvt(i, :)%nkt = simpar%temp_sh_ext
     618        16580 :             nhc%nvt(i, :)%degrees_of_freedom = 1
     619              :          END DO
     620           40 :          DEALLOCATE (deg_of_freedom)
     621           40 :          DEALLOCATE (massive_shell_list)
     622              : 
     623              :          ! Let's clean the arrays
     624         4178 :          map_info%s_kin = 0.0_dp
     625         4218 :          map_info%v_scale = 0.0_dp
     626              :       END SELECT
     627              : 
     628           40 :       CALL timestop(handle)
     629              : 
     630           40 :    END SUBROUTINE nhc_to_shell_mapping
     631              : 
     632              : END MODULE extended_system_mapping
        

Generated by: LCOV version 2.0-1