(git:374b731)
Loading...
Searching...
No Matches
pint_staging.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 Data type and methods dealing with PI calcs in staging coordinates
10!> \author fawzi
11!> \par History
12!> 2006-02 created
13!> 2006-11 modified so it might actually work [hforbert]
14!> 2009-04-07 moved from pint_types module to a separate file [lwalewski]
15! **************************************************************************************************
19 USE kinds, ONLY: dp
21#include "../base/base_uses.f90"
22
23 IMPLICIT NONE
24 PRIVATE
25
26 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
27 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pint_staging'
28
33
34CONTAINS
35
36! ***************************************************************************
37!> \brief creates the data needed for a staging transformation
38!> \param staging_env ...
39!> \param staging_section ...
40!> \param p ...
41!> \param kT ...
42!> \author fawzi
43! **************************************************************************************************
44 SUBROUTINE staging_env_create(staging_env, staging_section, p, kT)
45 TYPE(staging_env_type), INTENT(OUT) :: staging_env
46 TYPE(section_vals_type), POINTER :: staging_section
47 INTEGER, INTENT(in) :: p
48 REAL(kind=dp), INTENT(in) :: kt
49
50 CALL section_vals_val_get(staging_section, "j", i_val=staging_env%j)
51 CALL section_vals_val_get(staging_section, "Q_end", i_val=staging_env%j)
52 staging_env%p = p
53 staging_env%nseg = staging_env%p/staging_env%j
54
55 staging_env%w_p = sqrt(real(staging_env%p, dp))*kt
56 staging_env%w_j = kt*sqrt(real(staging_env%nseg, dp))
57 staging_env%Q_stage = kt/staging_env%w_p**2
58 IF (staging_env%Q_end <= 0._dp) THEN
59 staging_env%Q_end = staging_env%j*staging_env%Q_stage
60 END IF
61 END SUBROUTINE staging_env_create
62
63! ***************************************************************************
64!> \brief releases the staging environment, kept for symmetry reasons with staging_env_create
65!> \param staging_env the staging_env to release
66!> \author Fawzi Mohamed
67! **************************************************************************************************
68 ELEMENTAL SUBROUTINE staging_release(staging_env)
69 TYPE(staging_env_type), INTENT(IN) :: staging_env
70
71 mark_used(staging_env)
72 END SUBROUTINE staging_release
73
74! ***************************************************************************
75!> \brief initializes the masses and fictitious masses compatibly with the
76!> staging information
77!> \param staging_env the definition of the staging transformation
78!> \param mass *input* the masses of the particles
79!> \param mass_beads masses of the beads
80!> \param mass_fict the fictitious masses
81!> \param Q masses of the nose thermostats
82!> \par History
83!> 11.2003 created [fawzi]
84!> \author Fawzi Mohamed
85! **************************************************************************************************
86 PURE SUBROUTINE staging_init_masses(staging_env, mass, mass_beads, mass_fict, &
87 Q)
88 TYPE(staging_env_type), INTENT(IN) :: staging_env
89 REAL(kind=dp), DIMENSION(:), INTENT(in) :: mass
90 REAL(kind=dp), DIMENSION(:, :), INTENT(out), &
91 OPTIONAL :: mass_beads, mass_fict
92 REAL(kind=dp), DIMENSION(:), INTENT(out), OPTIONAL :: q
93
94 INTEGER :: i, iat, ib, iseg
95 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: scal
96
97 IF (PRESENT(q)) THEN
98 q = staging_env%Q_stage
99 DO i = 1, staging_env%p, staging_env%j
100 q(i) = staging_env%Q_end
101 END DO
102 END IF
103 IF (PRESENT(mass_beads) .OR. PRESENT(mass_fict)) THEN
104
105 ALLOCATE (scal(staging_env%p))
106 DO iseg = 1, staging_env%nseg
107 DO i = 1, staging_env%j ! check order!!!
108 scal(staging_env%j*(iseg - 1) + i) = real(i, dp)/real(max(1, i - 1), dp)
109 END DO
110 END DO
111 ! scal=zeros(staging_env%j,Float64)
112 ! divide(arange(2,staging_env%j+1,typecode=Float64),
113 ! arange(1,staging_env%j,typecode=Float64),scal[1:])
114 ! scal[0]=1.
115 ! scal=outerproduct(ones(staging_env%nseg),scal)
116
117 IF (PRESENT(mass_beads)) THEN
118 DO iat = 1, SIZE(mass)
119 DO ib = 1, staging_env%p
120 mass_beads(ib, iat) = scal(ib)*mass(iat)
121 END DO
122 END DO
123 END IF
124 IF (PRESENT(mass_fict)) THEN
125 DO iat = 1, SIZE(mass)
126 DO ib = 1, staging_env%p
127 mass_fict(ib, iat) = scal(ib)*mass(iat)
128 END DO
129 END DO
130 END IF
131 END IF
132 END SUBROUTINE staging_init_masses
133
134! ***************************************************************************
135!> \brief Transforms from the x into the u variables using a staging
136!> transformation for the positions
137!> \param staging_env the environment for the staging transformation
138!> \param ux will contain the u variable
139!> \param x the positions to transform
140!> \author fawzi
141! **************************************************************************************************
142 PURE SUBROUTINE staging_x2u(staging_env, ux, x)
143 TYPE(staging_env_type), INTENT(IN) :: staging_env
144 REAL(kind=dp), DIMENSION(:, :), INTENT(out) :: ux
145 REAL(kind=dp), DIMENSION(:, :), INTENT(in) :: x
146
147 INTEGER :: k, s
148
149 ux = x
150 DO s = 0, staging_env%nseg - 1
151 DO k = 2, staging_env%j
152 ux(staging_env%j*s + k, :) = ux(staging_env%j*s + k, :) &
153 - ((real(k - 1, dp)/real(k, dp) &
154 *x(modulo((staging_env%j*s + k + 1), staging_env%p), :) + &
155 x(staging_env%j*s + 1, :)/real(k, dp)))
156 END DO
157 END DO
158 END SUBROUTINE staging_x2u
159
160! ***************************************************************************
161!> \brief transform from the u variable to the x (back staging transformation
162!> for the positions)
163!> \param staging_env the environment for the staging transformation
164!> \param ux the u variable (positions to be backtransformed)
165!> \param x will contain the positions
166!> \author fawzi
167! **************************************************************************************************
168 PURE SUBROUTINE staging_u2x(staging_env, ux, x)
169 TYPE(staging_env_type), INTENT(IN) :: staging_env
170 REAL(kind=dp), DIMENSION(:, :), INTENT(in) :: ux
171 REAL(kind=dp), DIMENSION(:, :), INTENT(out) :: x
172
173 INTEGER :: i, ist, j
174 INTEGER, ALLOCATABLE, DIMENSION(:) :: iii, jjj
175 REAL(kind=dp) :: const, const2
176
177 j = staging_env%j
178 const = real(j - 1, dp)/real(j, dp)
179 const2 = 1._dp/real(j, dp)
180 ALLOCATE (iii(staging_env%nseg), jjj(staging_env%nseg))
181 DO i = 1, staging_env%nseg
182 iii(i) = staging_env%j*(i - 1) + 1 !first el
183 END DO
184 DO i = 1, staging_env%nseg - 1
185 jjj(i) = iii(i) + j ! next first el (pbc)
186 END DO
187 jjj(staging_env%nseg) = 1
188
189 x = ux
190 DO i = 1, staging_env%nseg
191 x(j - 1 + iii(i), :) = x(j - 1 + iii(i), :) + &
192 const*ux(jjj(i), :) + ux(iii(i), :)*const2
193 END DO
194 DO ist = 1, staging_env%nseg
195 DO i = staging_env%j - 2, 2, -1
196 x(i + iii(ist), :) = x(i + iii(ist), :) + &
197 REAL(i - 1, dp)/REAL(i, dp)*x(i + iii(ist) + 1, :) &
198 + ux(iii(ist), :)/REAL(i, dp)
199 END DO
200 END DO
201 END SUBROUTINE staging_u2x
202
203! ***************************************************************************
204!> \brief staging transformation for the forces
205!> \param staging_env the environment for the staging transformation
206!> \param uf will contain the forces after for the transformed variable
207!> \param f the forces to transform
208!> \author fawzi
209! **************************************************************************************************
210 PURE SUBROUTINE staging_f2uf(staging_env, uf, f)
211 TYPE(staging_env_type), INTENT(IN) :: staging_env
212 REAL(kind=dp), DIMENSION(:, :), INTENT(out) :: uf
213 REAL(kind=dp), DIMENSION(:, :), INTENT(in) :: f
214
215 INTEGER :: i, idim, ij, ist, k
216 INTEGER, ALLOCATABLE, DIMENSION(:) :: iii, jjj, kkk
217 REAL(kind=dp) :: const, sum_f
218
219 const = real(staging_env%j - 1, dp)/real(staging_env%j, dp)
220 ALLOCATE (iii(staging_env%j), jjj(staging_env%j), &
221 kkk(staging_env%j))
222 DO ist = 1, staging_env%j - 1
223 iii(ist) = (ist - 1)*staging_env%j + 1 ! first el
224 jjj(ist) = iii(ist) + staging_env%j - 1 ! last el
225 kkk(ist) = iii(ist) - 1 ! prev el
226 END DO
227 kkk(1) = staging_env%p
228
229 uf = f
230 ! staging beads
231 DO k = 1, staging_env%nseg
232 DO i = 2, staging_env%j
233 uf(i + iii(k), :) = uf(i + iii(k), :) &
234 + real(i - 1, dp)/real(i, dp)*uf(i + iii(k) - 1, :)
235 END DO
236 END DO
237 ! end point beads
238 DO idim = 1, SIZE(uf, 2)
239 DO k = 1, staging_env%nseg
240 sum_f = 0._dp
241 DO ij = 2, staging_env%j - 1
242 sum_f = sum_f + uf((k - 1)*staging_env%j + ij, idim)
243 END DO
244 uf(iii(k), idim) = uf(iii(k), idim) + &
245 sum_f - const*(uf(jjj(k), idim) - uf(kkk(k), idim))
246 END DO
247 END DO
248 END SUBROUTINE staging_f2uf
249
250! ***************************************************************************
251!> \brief calculates the harmonic force in the staging basis
252!> \param staging_env the staging environment
253!> \param mass_beads the masses of the beads
254!> \param ux the positions of the beads in the staging basis
255!> \param uf_h the harmonic forces (not accelerations)
256!> \param e_h ...
257!> \author fawzi
258! **************************************************************************************************
259 PURE SUBROUTINE staging_calc_uf_h(staging_env, mass_beads, ux, uf_h, e_h)
260 TYPE(staging_env_type), INTENT(IN) :: staging_env
261 REAL(kind=dp), DIMENSION(:, :), POINTER :: mass_beads, ux, uf_h
262 REAL(kind=dp), INTENT(OUT) :: e_h
263
264 INTEGER :: idim, isg, ist
265 INTEGER, ALLOCATABLE, DIMENSION(:) :: iii, jjj, kkk
266 REAL(kind=dp) :: d, f
267
268 e_h = 0.0_dp
269
270 ALLOCATE (iii(staging_env%nseg), jjj(staging_env%nseg), &
271 kkk(staging_env%nseg))
272
273 DO ist = 1, staging_env%nseg
274 iii(ist) = (ist - 1)*staging_env%j + 1 ! first el
275 jjj(ist) = iii(ist) + staging_env%j ! next first (pbc)
276 kkk(ist) = iii(ist) - staging_env%j ! prev first el (pbc)
277 END DO
278 jjj(staging_env%nseg) = 1
279 kkk(1) = staging_env%p - staging_env%j
280
281 DO idim = 1, SIZE(mass_beads, 2)
282 DO ist = 1, staging_env%nseg
283 e_h = e_h + 0.5*mass_beads(1, idim)*staging_env%w_j**2* &
284 (ux(iii(ist), idim) - ux(jjj(ist), idim))**2
285 uf_h(iii(ist), idim) = mass_beads(1, idim)*staging_env%w_j**2*( &
286 2._dp*ux(iii(ist), idim) &
287 - ux(jjj(ist), idim) &
288 - ux(kkk(ist), idim) &
289 )
290 DO isg = 2, staging_env%j ! use 3 as start?
291 d = ux((ist - 1)*staging_env%j + isg, idim)
292 f = mass_beads((ist - 1)*staging_env%j + isg, idim)*staging_env%w_j**2*d
293 e_h = e_h + 0.5_dp*f*d
294 uf_h((ist - 1)*staging_env%j + isg, idim) = f
295 END DO
296 END DO
297 END DO
298 END SUBROUTINE staging_calc_uf_h
299
300END MODULE pint_staging
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
objects that represent the structure of input sections and the data contained in an input section
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
Data type and methods dealing with PI calcs in staging coordinates.
elemental subroutine, public staging_release(staging_env)
releases the staging environment, kept for symmetry reasons with staging_env_create
subroutine, public staging_env_create(staging_env, staging_section, p, kt)
creates the data needed for a staging transformation
pure subroutine, public staging_calc_uf_h(staging_env, mass_beads, ux, uf_h, e_h)
calculates the harmonic force in the staging basis
pure subroutine, public staging_init_masses(staging_env, mass, mass_beads, mass_fict, q)
initializes the masses and fictitious masses compatibly with the staging information
pure subroutine, public staging_x2u(staging_env, ux, x)
Transforms from the x into the u variables using a staging transformation for the positions.
pure subroutine, public staging_f2uf(staging_env, uf, f)
staging transformation for the forces
pure subroutine, public staging_u2x(staging_env, ux, x)
transform from the u variable to the x (back staging transformation for the positions)
data to perform the staging transformation
Definition pint_types.F:184