(git:ccc2433)
pint_public.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 Public path integral routines that can be called from other modules
10 !> \author Lukasz Walewski
11 !> \date 2009-07-24
12 !> \note Avoiding circular dependencies: please design new members of this
13 !> module in such a way that they use pint_types module only.
14 ! **************************************************************************************************
16 
17  USE kinds, ONLY: dp
18  USE parallel_rng_types, ONLY: rng_stream_type
19  USE pint_types, ONLY: pint_env_type
20 #include "../base/base_uses.f90"
21 
22  IMPLICIT NONE
23 
24  PRIVATE
25 
26  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
27  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pint_public'
28 
29  PUBLIC :: pint_com_pos
30  PUBLIC :: pint_levy_walk
31  PUBLIC :: pint_calc_centroid
32 
33 CONTAINS
34 
35 ! ***************************************************************************
36 !> \brief Return the center of mass of the PI system
37 !> \param pint_env ...
38 !> \return ...
39 !> \date 2009-07-24
40 !> \par History
41 !> 2009-11-30 fixed serious bug in pint_env%x indexing [lwalewski]
42 !> \author Lukasz Walewski
43 ! **************************************************************************************************
44  PURE FUNCTION pint_com_pos(pint_env) RESULT(com_r)
45 
46  TYPE(pint_env_type), INTENT(IN) :: pint_env
47  REAL(kind=dp), DIMENSION(3) :: com_r
48 
49  INTEGER :: ia, ib, ic
50  REAL(kind=dp) :: tmass
51 
52  tmass = 0.0_dp
53  com_r(:) = 0.0_dp
54  DO ia = 1, pint_env%ndim/3
55  DO ib = 1, pint_env%p
56  DO ic = 1, 3
57  com_r(ic) = com_r(ic) + &
58  pint_env%x(ib, (ia - 1)*3 + ic)*pint_env%mass((ia - 1)*3 + ic)
59  tmass = tmass + pint_env%mass((ia - 1)*3 + ic)
60  END DO
61  END DO
62  END DO
63  ! pint_env%mass is REAL, DIMENSION(NDIM) which means that each atom
64  ! has its mass defined three times - here we hope that all three
65  ! values are equal
66  tmass = tmass/3.0_dp
67  com_r(:) = com_r(:)/tmass
68  END FUNCTION pint_com_pos
69 
70 ! ***************************************************************************
71 !> \brief Return the center of geometry of the PI system
72 !> \param pint_env ...
73 !> \return ...
74 !> \date 2009-11-30
75 !> \author Lukasz Walewski
76 ! **************************************************************************************************
77  PURE FUNCTION pint_cog_pos(pint_env) RESULT(cntrd_r)
78 
79  TYPE(pint_env_type), INTENT(IN) :: pint_env
80  REAL(kind=dp), DIMENSION(3) :: cntrd_r
81 
82  INTEGER :: ia, ib, ic, natoms
83 
84  cntrd_r(:) = 0.0_dp
85  natoms = pint_env%ndim/3
86  DO ia = 1, natoms
87  DO ib = 1, pint_env%p
88  DO ic = 1, 3
89  cntrd_r(ic) = cntrd_r(ic) + pint_env%x(ib, (ia - 1)*3 + ic)
90  END DO
91  END DO
92  END DO
93  cntrd_r(:) = cntrd_r(:)/real(pint_env%p, dp)/real(natoms, dp)
94  END FUNCTION pint_cog_pos
95 
96 ! ***************************************************************************
97 !> \brief Given the number of beads n and the variance t returns the
98 !> positions of the beads for a non-interacting particle.
99 !> \param n ...
100 !> \param t ...
101 !> \param rng_gaussian ...
102 !> \param x ...
103 !> \param nout ...
104 !> \date 2010-12-13
105 !> \author Lukasz Walewski
106 !> \note This routine implements Levy argorithm (see e.g. Rev. Mod. Phys.
107 !> 67 (1995) 279, eq. 5.35) and requires that n is a power of 2. The
108 !> resulting bead positions are centered around (0,0,0).
109 ! **************************************************************************************************
110  SUBROUTINE pint_free_part_bead_x(n, t, rng_gaussian, x, nout)
111 !
112 !TODO this routine gives wrong spread of the particles, please fix before usage.
113 !
114  INTEGER, INTENT(IN) :: n
115  REAL(kind=dp), INTENT(IN) :: t
116  TYPE(rng_stream_type), INTENT(INOUT) :: rng_gaussian
117  REAL(kind=dp), DIMENSION(:), POINTER :: x
118  INTEGER, INTENT(OUT) :: nout
119 
120  INTEGER :: dl, i1, i2, ib, ic, il, ip, j, nlevels, &
121  np
122  REAL(kind=dp) :: rtmp, tcheck, vrnc, xc
123  REAL(kind=dp), DIMENSION(3) :: cntrd_r
124 
125  nout = 0
126 
127  IF (n < 1) THEN
128  RETURN
129  END IF
130 
131  ! if number of beads is not a power of 2 return
132  nlevels = nint(log(real(n, kind=dp))/log(2.0_dp))
133  rtmp = 2**nlevels
134  tcheck = abs(real(n, kind=dp) - rtmp)
135  IF (tcheck > 100.0_dp*epsilon(0.0_dp)) THEN
136  RETURN
137  END IF
138 
139  ! generate at least first point at (0,0,0)
140  DO ic = 1, 3
141  x(ic) = 0.0_dp
142  END DO
143  nout = 1
144 
145  ! loop over Levy levels
146  vrnc = 2.0_dp*t
147  DO il = 0, nlevels - 1
148 
149  np = 2**il ! number of points to be generated at this level
150  dl = n/(2*np) ! interval betw points (in index numbers)
151  vrnc = vrnc/2.0_dp; ! variance at this level (=t at level 0)
152 
153  ! loop over points added in this level
154  DO ip = 0, np - 1
155 
156  j = (2*ip + 1)*dl ! index of currently generated point
157 
158  ! indices of two points betw which to generate a new point
159  i1 = 2*dl*ip
160  i2 = 2*dl*(ip + 1)
161  IF (i2 .EQ. n) THEN
162  i2 = 0
163  END IF
164 
165  ! generate new point and save it under j
166  DO ic = 1, 3
167  xc = (x(3*i1 + ic) + x(3*i2 + ic))/2.0
168  xc = xc + rng_gaussian%next(variance=vrnc)
169  x(3*j + ic) = xc
170  END DO
171  nout = nout + 1
172 
173  END DO
174  END DO
175 
176  ! translate the centroid to the origin
177  cntrd_r(:) = 0.0_dp
178  DO ib = 1, n
179  DO ic = 1, 3
180  cntrd_r(ic) = cntrd_r(ic) + x((ib - 1)*3 + ic)
181  END DO
182  END DO
183  cntrd_r(:) = cntrd_r(:)/real(n, dp)
184  DO ib = 1, n
185  DO ic = 1, 3
186  x((ib - 1)*3 + ic) = x((ib - 1)*3 + ic) - cntrd_r(ic)
187  END DO
188  END DO
189 
190  END SUBROUTINE pint_free_part_bead_x
191 
192 ! ***************************************************************************
193 !> \brief Perform a Brownian walk of length n around x0 with the variance v.
194 !> \param x0 ...
195 !> \param n ...
196 !> \param v ...
197 !> \param x ...
198 !> \param rng_gaussian ...
199 !> \date 2011-01-06
200 !> \author Lukasz Walewski
201 !> \note This routine implements Levy argorithm (Phys. Rev. 143 (1966) 58)
202 ! **************************************************************************************************
203  SUBROUTINE pint_levy_walk(x0, n, v, x, rng_gaussian)
204 
205  REAL(kind=dp), DIMENSION(3), INTENT(IN) :: x0
206  INTEGER, INTENT(IN) :: n
207  REAL(kind=dp), INTENT(IN) :: v
208  REAL(kind=dp), DIMENSION(:), POINTER :: x
209  TYPE(rng_stream_type), INTENT(INOUT) :: rng_gaussian
210 
211  INTEGER :: ib, ic
212  REAL(kind=dp) :: r, tau_i, tau_i1
213  REAL(kind=dp), DIMENSION(3) :: cntrd_r
214 
215  x(1) = x0(1)
216  x(2) = x0(2)
217  x(3) = x0(3)
218  DO ib = 1, n - 1
219  DO ic = 1, 3
220  r = rng_gaussian%next(variance=1.0_dp)
221  tau_i = (real(ib, dp) - 1.0_dp)/real(n, dp)
222  tau_i1 = (real(ib + 1, dp) - 1.0_dp)/real(n, dp)
223  x(ib*3 + ic) = (x((ib - 1)*3 + ic)*(1.0_dp - tau_i1) + &
224  x(ic)*(tau_i1 - tau_i))/ &
225  (1.0_dp - tau_i) + &
226  r*v*sqrt( &
227  (tau_i1 - tau_i)* &
228  (1.0_dp - tau_i1)/ &
229  (1.0_dp - tau_i) &
230  )
231  END DO
232  END DO
233 
234  ! translate the centroid to the origin
235  cntrd_r(:) = 0.0_dp
236  DO ib = 1, n
237  DO ic = 1, 3
238  cntrd_r(ic) = cntrd_r(ic) + x((ib - 1)*3 + ic)
239  END DO
240  END DO
241  cntrd_r(:) = cntrd_r(:)/real(n, dp)
242  DO ib = 1, n
243  DO ic = 1, 3
244  x((ib - 1)*3 + ic) = x((ib - 1)*3 + ic) - cntrd_r(ic)
245  END DO
246  END DO
247 
248  END SUBROUTINE pint_levy_walk
249 
250 ! ***************************************************************************
251 !> \brief Calculate the centroid
252 !> \param pint_env path integral environment
253 !> \date 2013-02-10
254 !> \author lwalewski
255 ! **************************************************************************************************
256  PURE SUBROUTINE pint_calc_centroid(pint_env)
257 
258  TYPE(pint_env_type), INTENT(INOUT) :: pint_env
259 
260  INTEGER :: ia, ib
261  REAL(kind=dp) :: invp
262 
263  invp = 1.0_dp/pint_env%p
264  pint_env%centroid(:) = 0.0_dp
265  DO ia = 1, pint_env%ndim
266  DO ib = 1, pint_env%p
267  pint_env%centroid(ia) = pint_env%centroid(ia) + pint_env%x(ib, ia)
268  END DO
269  pint_env%centroid(ia) = pint_env%centroid(ia)*invp
270  END DO
271 
272  END SUBROUTINE pint_calc_centroid
273 
274 END MODULE pint_public
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.
Public path integral routines that can be called from other modules.
Definition: pint_public.F:15
pure real(kind=dp) function, dimension(3), public pint_com_pos(pint_env)
Return the center of mass of the PI system.
Definition: pint_public.F:45
subroutine, public pint_levy_walk(x0, n, v, x, rng_gaussian)
Perform a Brownian walk of length n around x0 with the variance v.
Definition: pint_public.F:204
pure subroutine, public pint_calc_centroid(pint_env)
Calculate the centroid.
Definition: pint_public.F:257
Exchange and Correlation functional calculations.
Definition: xc.F:17