(git:58e3e09)
pint_pile.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Methods to apply a simple Lagevin thermostat to PI runs.
10 !> v_new = c1*vold + SQRT(kT/m)*c2*random
11 !> \author Felix Uhl
12 !> \par History
13 !> 10.2014 created [Felix Uhl]
14 ! **************************************************************************************************
15 MODULE pint_pile
19  section_vals_type,&
21  USE kinds, ONLY: dp
22  USE parallel_rng_types, ONLY: gaussian,&
24  rng_stream_type,&
26  USE pint_types, ONLY: normalmode_env_type,&
27  pile_therm_type,&
28  pint_env_type
29 #include "../base/base_uses.f90"
30 
31  IMPLICIT NONE
32 
33  PRIVATE
34 
35  PUBLIC :: pint_pile_step, &
39 
40  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pint_pile'
41 
42 CONTAINS
43 
44 ! ***************************************************************************
45 !> \brief initializes the data for a pile run
46 !> \param pile_therm ...
47 !> \param pint_env ...
48 !> \param normalmode_env ...
49 !> \param section ...
50 !> \author Felix Uhl
51 ! **************************************************************************************************
52  SUBROUTINE pint_pile_init(pile_therm, pint_env, normalmode_env, section)
53  TYPE(pile_therm_type), INTENT(OUT) :: pile_therm
54  TYPE(pint_env_type), INTENT(INOUT) :: pint_env
55  TYPE(normalmode_env_type), POINTER :: normalmode_env
56  TYPE(section_vals_type), POINTER :: section
57 
58  CHARACTER(LEN=rng_record_length) :: rng_record
59  INTEGER :: i, i_propagator, j, p
60  LOGICAL :: explicit
61  REAL(kind=dp) :: dti2, ex
62  REAL(kind=dp), DIMENSION(3, 2) :: initial_seed
63  TYPE(section_vals_type), POINTER :: pint_section, rng_section
64 
65  pint_env%e_pile = 0.0_dp
66  pile_therm%thermostat_energy = 0.0_dp
67  !Get input parameter
68  CALL section_vals_val_get(section, "TAU", r_val=pile_therm%tau)
69  CALL section_vals_val_get(section, "LAMBDA", r_val=pile_therm%lamb)
70  CALL section_vals_val_get(section, "THERMOSTAT_ENERGY", r_val=pile_therm%thermostat_energy)
71  pint_section => section_vals_get_subs_vals(pint_env%input, "MOTION%PINT")
72  CALL section_vals_val_get(pint_section, "PROPAGATOR", i_val=i_propagator)
73 
74  IF (i_propagator == propagator_cmd) THEN
75  pile_therm%tau = 0.0_dp
76  END IF
77 
78  p = pint_env%p
79  dti2 = 0.5_dp*pint_env%dt
80  ALLOCATE (pile_therm%c1(p))
81  ALLOCATE (pile_therm%c2(p))
82  ALLOCATE (pile_therm%g_fric(p))
83  ALLOCATE (pile_therm%massfact(p, pint_env%ndim))
84  !Initialize everything
85  ! If tau is negative or zero the thermostat does not act on the centroid
86  ! (TRPMD)
87  IF (pile_therm%tau <= 0.0_dp) THEN
88  pile_therm%g_fric(1) = 0.0_dp
89  ELSE
90  pile_therm%g_fric(1) = 1.0_dp/pile_therm%tau
91  END IF
92  DO i = 2, p
93  pile_therm%g_fric(i) = 2.0_dp*pile_therm%lamb*sqrt(normalmode_env%lambda(i))
94  END DO
95  DO i = 1, p
96  ex = -dti2*pile_therm%g_fric(i)
97  pile_therm%c1(i) = exp(ex)
98  ex = pile_therm%c1(i)*pile_therm%c1(i)
99  pile_therm%c2(i) = sqrt(1.0_dp - ex)
100  END DO
101  DO j = 1, pint_env%ndim
102  DO i = 1, pint_env%p
103  pile_therm%massfact(i, j) = sqrt(pint_env%kT/pint_env%mass_fict(i, j))
104  END DO
105  END DO
106 
107  !prepare Random number generator
108  NULLIFY (rng_section)
109  rng_section => section_vals_get_subs_vals(section, &
110  subsection_name="RNG_INIT")
111  CALL section_vals_get(rng_section, explicit=explicit)
112  IF (explicit) THEN
113  CALL section_vals_val_get(rng_section, "_DEFAULT_KEYWORD_", &
114  i_rep_val=1, c_val=rng_record)
115 
116  pile_therm%gaussian_rng_stream = rng_stream_type_from_record(rng_record)
117  ELSE
118  initial_seed(:, :) = real(pint_env%thermostat_rng_seed, dp)
119  pile_therm%gaussian_rng_stream = rng_stream_type( &
120  name="pile_rng_gaussian", distribution_type=gaussian, &
121  extended_precision=.true., &
122  seed=initial_seed)
123  END IF
124 
125  END SUBROUTINE pint_pile_init
126 
127 ! **************************************************************************************************
128 !> \brief ...
129 !> \param vold ...
130 !> \param vnew ...
131 !> \param p ...
132 !> \param ndim ...
133 !> \param first_mode ...
134 !> \param masses ...
135 !> \param pile_therm ...
136 ! **************************************************************************************************
137  SUBROUTINE pint_pile_step(vold, vnew, p, ndim, first_mode, masses, pile_therm)
138  REAL(kind=dp), DIMENSION(:, :), POINTER :: vold, vnew
139  INTEGER, INTENT(IN) :: p, ndim, first_mode
140  REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: masses
141  TYPE(pile_therm_type), POINTER :: pile_therm
142 
143  CHARACTER(len=*), PARAMETER :: routinen = 'pint_pile_step'
144 
145  INTEGER :: handle, ibead, idim
146  REAL(kind=dp) :: delta_ekin
147 
148  CALL timeset(routinen, handle)
149  delta_ekin = 0.0_dp
150  DO idim = 1, ndim
151  DO ibead = first_mode, p
152  vnew(ibead, idim) = pile_therm%c1(ibead)*vold(ibead, idim) + &
153  pile_therm%massfact(ibead, idim)*pile_therm%c2(ibead)* &
154  pile_therm%gaussian_rng_stream%next()
155  delta_ekin = delta_ekin + masses(ibead, idim)*( &
156  vnew(ibead, idim)*vnew(ibead, idim) - &
157  vold(ibead, idim)*vold(ibead, idim))
158  END DO
159  END DO
160  pile_therm%thermostat_energy = pile_therm%thermostat_energy - 0.5_dp*delta_ekin
161 
162  CALL timestop(handle)
163  END SUBROUTINE pint_pile_step
164 
165 ! ***************************************************************************
166 !> \brief releases the pile environment
167 !> \param pile_therm pile data to be released
168 !> \author Felix Uhl
169 ! **************************************************************************************************
170  SUBROUTINE pint_pile_release(pile_therm)
171 
172  TYPE(pile_therm_type), INTENT(INOUT) :: pile_therm
173 
174  DEALLOCATE (pile_therm%c1)
175  DEALLOCATE (pile_therm%c2)
176  DEALLOCATE (pile_therm%g_fric)
177  DEALLOCATE (pile_therm%massfact)
178 
179  END SUBROUTINE pint_pile_release
180 
181 ! ***************************************************************************
182 !> \brief returns the pile kinetic energy contribution
183 !> \param pint_env ...
184 !> \author Felix Uhl
185 ! **************************************************************************************************
186  SUBROUTINE pint_calc_pile_energy(pint_env)
187  TYPE(pint_env_type), INTENT(INOUT) :: pint_env
188 
189  IF (ASSOCIATED(pint_env%pile_therm)) THEN
190  pint_env%e_pile = pint_env%pile_therm%thermostat_energy
191  END IF
192 
193  END SUBROUTINE pint_calc_pile_energy
194 END MODULE
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public propagator_cmd
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
type(rng_stream_type) function, public rng_stream_type_from_record(rng_record)
Create a RNG stream from a record given as an internal file (string).
integer, parameter, public rng_record_length
integer, parameter, public gaussian
Methods to apply a simple Lagevin thermostat to PI runs. v_new = c1*vold + SQRT(kT/m)*c2*random.
Definition: pint_pile.F:15
subroutine, public pint_pile_step(vold, vnew, p, ndim, first_mode, masses, pile_therm)
...
Definition: pint_pile.F:138
subroutine, public pint_pile_init(pile_therm, pint_env, normalmode_env, section)
initializes the data for a pile run
Definition: pint_pile.F:53
subroutine, public pint_pile_release(pile_therm)
releases the pile environment
Definition: pint_pile.F:171
subroutine, public pint_calc_pile_energy(pint_env)
returns the pile kinetic energy contribution
Definition: pint_pile.F:187