(git:ccc2433)
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 ! **************************************************************************************************
17  USE input_section_types, ONLY: section_vals_type,&
19  USE kinds, ONLY: dp
20  USE pint_types, ONLY: staging_env_type
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 
34 CONTAINS
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 
300 END 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....
Definition: grid_common.h:117
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.
Definition: pint_staging.F:16
elemental subroutine, public staging_release(staging_env)
releases the staging environment, kept for symmetry reasons with staging_env_create
Definition: pint_staging.F:69
pure subroutine, public staging_calc_uf_h(staging_env, mass_beads, ux, uf_h, e_h)
calculates the harmonic force in the staging basis
Definition: pint_staging.F:260
pure subroutine, public staging_x2u(staging_env, ux, x)
Transforms from the x into the u variables using a staging transformation for the positions.
Definition: pint_staging.F:143
pure subroutine, public staging_f2uf(staging_env, uf, f)
staging transformation for the forces
Definition: pint_staging.F:211
pure subroutine, public staging_u2x(staging_env, ux, x)
transform from the u variable to the x (back staging transformation for the positions)
Definition: pint_staging.F:169
subroutine, public staging_env_create(staging_env, staging_section, p, kT)
creates the data needed for a staging transformation
Definition: pint_staging.F:45
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
Definition: pint_staging.F:88