(git:e7e05ae)
wiener_process.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 Handling of the Wiener process currently employed in turn of the
10 !> Langevin dynamics.
11 !> \par History
12 !> none
13 !> \author Matthias Krack (05.07.2005)
14 ! **************************************************************************************************
16 
17  USE atomic_kind_list_types, ONLY: atomic_kind_list_type
18  USE cp_subsys_types, ONLY: cp_subsys_get,&
19  cp_subsys_type
20  USE distribution_1d_types, ONLY: distribution_1d_type
21  USE force_env_types, ONLY: force_env_get,&
22  force_env_type
25  section_vals_type,&
27  USE kinds, ONLY: dp
28  USE md_environment_types, ONLY: get_md_env,&
29  md_environment_type,&
31  USE message_passing, ONLY: mp_para_env_type
32  USE metadynamics_types, ONLY: meta_env_type
33  USE parallel_rng_types, ONLY: gaussian,&
36  rng_stream_type,&
38  USE particle_list_types, ONLY: particle_list_type
39  USE simpar_types, ONLY: simpar_type
40  USE string_utilities, ONLY: compress
41 #include "../base/base_uses.f90"
42 
43  IMPLICIT NONE
44 
45  PRIVATE
46 
47  ! Global parameters in this module
48  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'wiener_process'
49 
50  ! Public subroutines
52 
53 CONTAINS
54 
55 ! **************************************************************************************************
56 !> \brief Create a Wiener process for Langevin dynamics and initialize an
57 !> independent random number generator for each atom in all force
58 !> environment and all the subsystems/fragments therein.
59 !> \param md_env ...
60 !> \par History
61 !> Creation (06.07.2005,MK)
62 ! **************************************************************************************************
63  SUBROUTINE create_wiener_process(md_env)
64 
65  TYPE(md_environment_type), POINTER :: md_env
66 
67  CHARACTER(LEN=40) :: name
68  INTEGER :: iparticle, iparticle_kind, &
69  iparticle_local, nparticle, &
70  nparticle_kind, nparticle_local
71  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: seed
72  TYPE(atomic_kind_list_type), POINTER :: atomic_kinds
73  TYPE(cp_subsys_type), POINTER :: subsys
74  TYPE(distribution_1d_type), POINTER :: local_particles
75  TYPE(force_env_type), POINTER :: force_env
76  TYPE(mp_para_env_type), POINTER :: para_env
77  TYPE(particle_list_type), POINTER :: particles
78  TYPE(section_vals_type), POINTER :: force_env_section, subsys_section, &
79  work_section
80  TYPE(simpar_type), POINTER :: simpar
81 
82  NULLIFY (work_section, force_env)
83  cpassert(ASSOCIATED(md_env))
84 
85  CALL get_md_env(md_env=md_env, force_env=force_env, para_env=para_env, &
86  simpar=simpar)
87 
88  ![NB] shouldn't the calling process know if it's needed
89  IF (need_per_atom_wiener_process(md_env)) THEN
90 
91  CALL force_env_get(force_env, force_env_section=force_env_section, &
92  subsys=subsys)
93 
94  subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
95 
96  CALL cp_subsys_get(subsys=subsys, atomic_kinds=atomic_kinds, local_particles=local_particles, &
97  particles=particles)
98 
99  nparticle_kind = atomic_kinds%n_els
100  nparticle = particles%n_els
101 
102  ! Allocate the (local) data structures for the Wiener process
103  ALLOCATE (local_particles%local_particle_set(nparticle_kind))
104 
105  DO iparticle_kind = 1, nparticle_kind
106  nparticle_local = local_particles%n_el(iparticle_kind)
107  ALLOCATE (local_particles%local_particle_set(iparticle_kind)%rng(nparticle_local))
108  DO iparticle_local = 1, nparticle_local
109  ALLOCATE (local_particles%local_particle_set(iparticle_kind)%rng(iparticle_local)%stream)
110  END DO
111  END DO
112 
113  ! Each process generates all seeds. The seed generation should be
114  ! quite fast and in this way a broadcast is avoided.
115  ALLOCATE (seed(3, 2, nparticle))
116 
117  ! Load initial seed (not needed for a restart)
118  seed(:, :, 1) = subsys%seed(:, :)
119 
120  DO iparticle = 2, nparticle
121  seed(:, :, iparticle) = next_rng_seed(seed(:, :, iparticle - 1))
122  END DO
123 
124  ! Update initial seed
125  subsys%seed(:, :) = next_rng_seed(seed(:, :, nparticle))
126 
127  ! Create a random number stream (Wiener process) for each particle
128  DO iparticle_kind = 1, nparticle_kind
129  nparticle_local = local_particles%n_el(iparticle_kind)
130  DO iparticle_local = 1, nparticle_local
131  iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
132  WRITE (unit=name, fmt="(A,I8)") "Wiener process for particle", iparticle
133  CALL compress(name)
134  local_particles%local_particle_set(iparticle_kind)%rng(iparticle_local)% &
135  stream = rng_stream_type(name=name, distribution_type=gaussian, &
136  extended_precision=.true., seed=seed(:, :, iparticle))
137  END DO
138  END DO
139 
140  DEALLOCATE (seed)
141 
142  ! Possibly restart Wiener process
143  NULLIFY (work_section)
144  work_section => section_vals_get_subs_vals(section_vals=subsys_section, &
145  subsection_name="RNG_INIT")
146  CALL init_local_particle_set(distribution_1d=local_particles, &
147  nparticle_kind=nparticle_kind, &
148  work_section=work_section)
149  END IF
150 
151  END SUBROUTINE create_wiener_process
152 
153 ! **************************************************************************************************
154 !> \brief Helper routine for create_wiener_process.
155 !> \param distribution_1d ...
156 !> \param nparticle_kind ...
157 !> \param work_section ...
158 !> \par History
159 !> 01.2014 moved from distribution_1d_types (Ole Schuett)
160 ! **************************************************************************************************
161  SUBROUTINE init_local_particle_set(distribution_1d, nparticle_kind, &
162  work_section)
163 
164  TYPE(distribution_1d_type), POINTER :: distribution_1d
165  INTEGER, INTENT(in) :: nparticle_kind
166  TYPE(section_vals_type), POINTER :: work_section
167 
168  CHARACTER(LEN=rng_record_length) :: rng_record
169  INTEGER :: iparticle, iparticle_kind, &
170  iparticle_local, nparticle_local
171  LOGICAL :: explicit
172 
173 ! -------------------------------------------------------------------------
174 
175  cpassert(ASSOCIATED(distribution_1d))
176 
177  IF (ASSOCIATED(work_section)) THEN
178  CALL section_vals_get(work_section, explicit=explicit)
179  IF (explicit) THEN
180  DO iparticle_kind = 1, nparticle_kind
181  nparticle_local = distribution_1d%n_el(iparticle_kind)
182  DO iparticle_local = 1, nparticle_local
183  iparticle = distribution_1d%list(iparticle_kind)%array(iparticle_local)
184  IF (iparticle == distribution_1d%list(iparticle_kind)%array(iparticle_local)) THEN
185  CALL section_vals_val_get(section_vals=work_section, &
186  keyword_name="_DEFAULT_KEYWORD_", &
187  i_rep_val=iparticle, &
188  c_val=rng_record)
189  distribution_1d%local_particle_set(iparticle_kind)%rng(iparticle_local)% &
190  stream = rng_stream_type_from_record(rng_record)
191  END IF
192  END DO
193  END DO
194  END IF
195  END IF
196 
197  END SUBROUTINE init_local_particle_set
198 
199 ! **************************************************************************************************
200 !> \brief Create a Wiener process for Langevin dynamics used for
201 !> metadynamics and initialize an
202 !> independent random number generator for each COLVAR.
203 !> \param meta_env ...
204 !> \date 01.2009
205 !> \author Fabio Sterpone
206 !>
207 ! **************************************************************************************************
208  SUBROUTINE create_wiener_process_cv(meta_env)
209 
210  TYPE(meta_env_type), POINTER :: meta_env
211 
212  CHARACTER(LEN=40) :: name
213  INTEGER :: i_c
214  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: seed
215  REAL(kind=dp), DIMENSION(3, 2) :: initial_seed
216 
217  IF (.NOT. ASSOCIATED(meta_env)) RETURN
218 
219  initial_seed = next_rng_seed()
220 
221  ! Each process generates all seeds. The seed generation should be
222  ! quite fast and in this way a broadcast is avoided.
223 
224  ALLOCATE (seed(3, 2, meta_env%n_colvar))
225 
226  seed(:, :, 1) = initial_seed
227  DO i_c = 2, meta_env%n_colvar
228  seed(:, :, i_c) = next_rng_seed(seed(:, :, i_c - 1))
229  END DO
230 
231  ! Update initial seed
232  initial_seed = next_rng_seed(seed(:, :, meta_env%n_colvar))
233 
234  ! Create a random number stream (Wiener process) for each particle
235  DO i_c = 1, meta_env%n_colvar
236  WRITE (unit=name, fmt="(A,I8)") "Wiener process for COLVAR", i_c
237  CALL compress(name)
238  meta_env%rng(i_c) = rng_stream_type(name=name, distribution_type=gaussian, &
239  extended_precision=.true., seed=seed(:, :, i_c))
240  END DO
241  DEALLOCATE (seed)
242 
243  END SUBROUTINE create_wiener_process_cv
244 
245 END MODULE wiener_process
represent a simple array based list of the given type
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env)
returns various attributes about the force environment
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
pure logical function, public need_per_atom_wiener_process(md_env)
...
subroutine, public get_md_env(md_env, itimes, constant, used_time, cell, simpar, npt, force_env, para_env, reftraj, t, init, first_time, fe_env, thermostats, barostat, thermostat_coeff, thermostat_part, thermostat_shell, thermostat_baro, thermostat_fast, thermostat_slow, md_ener, averages, thermal_regions, ehrenfest_md)
get components of MD environment type
Interface to the message passing library MPI.
defines types for metadynamics calculation
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).
real(kind=dp) function, dimension(3, 2), public next_rng_seed(seed)
Get the seed for the next RNG stream w.r.t. a given seed.
integer, parameter, public rng_record_length
integer, parameter, public gaussian
represent a simple array based list of the given type
Type for storing MD parameters.
Definition: simpar_types.F:14
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
Handling of the Wiener process currently employed in turn of the Langevin dynamics.
subroutine, public create_wiener_process(md_env)
Create a Wiener process for Langevin dynamics and initialize an independent random number generator f...
subroutine, public create_wiener_process_cv(meta_env)
Create a Wiener process for Langevin dynamics used for metadynamics and initialize an independent ran...