atomes 1.1.15
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
msd.F90
Go to the documentation of this file.
1! This file is part of the 'atomes' software.
2!
3! 'atomes' is free software: you can redistribute it and/or modify it under the terms
4! of the GNU Affero General Public License as published by the Free Software Foundation,
5! either version 3 of the License, or (at your option) any later version.
6!
7! 'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8! without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9! See the GNU General Public License for more details.
10!
11! You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12! If not, see <https://www.gnu.org/licenses/>
13!
14! Copyright (C) 2022-2024 by CNRS and University of Strasbourg
15!
20
21INTEGER (KIND=c_int) FUNCTION msd (DLT, NDTS) bind (C,NAME='msd_')
22
23!
24! Mean Square Displacement
25!
26
27USE parameters
28
29#ifdef OPENMP
30!$ USE OMP_LIB
31#endif
32IMPLICIT NONE
33
34INTEGER (KIND=c_int), INTENT(IN) :: ndts
35real(kind=c_double), INTENT(IN) :: dlt
36DOUBLE PRECISION :: masstot
37DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: msdtab
38#ifdef OPENMP
39INTEGER :: numth
40#endif
41
42INTERFACE
43 LOGICAL FUNCTION allocmsd()
44 END FUNCTION
45END INTERFACE
46
47! Calcul du déplacement carré moyen
48if(.not.transpo()) then
49 msd=0
50 goto 001
51endif
52
53if (.not. allocmsd()) then
54 msd=0
55 goto 001
56endif
57
58masstot=0.0d0
59do j=1, nsp
60 masstot=masstot+nbspbs(j)*mass(j)
61enddo
62
63#ifdef OPENMP
64numth = omp_get_max_threads()
65if (ns.lt.numth) numth=ns
66
67! OpemMP on MD steps
68!$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
69!$OMP& PRIVATE(RCm, RCm2, R2Cor, Dij, Rij, i, j, k, l, m, n, o, p, Vij) &
70!$OMP& SHARED(NUMTH, NS, NA, D2i, D2dir, DRIFT, LOT, MASS, MASSTOT, NDTS, DLT, NFULLPOS)
71!$OMP DO SCHEDULE(STATIC,NS-1/NUMTH)
72#endif
73do j=1, ns-1
74
75 do m=1, 3
76 rcm(m)=0.0d0
77 enddo
78
79 do i=1, na
80
81 k=lot(i)
82 do m=1, 3
83 rcm(m)=rcm(m)+mass(k)*nfullpos(i,m,j)
84 enddo
85 enddo
86
87 do m=1, 3
88 rcm(m)=rcm(m)/masstot
89 enddo
90
91 do k=j+1, ns
92
93 do m=1, 3
94 rcm2(m)=0.0d0
95 enddo
96
97 do i=1, na
98 n=lot(i)
99 do m=1, 3
100 rcm2(m)=rcm2(m)+mass(n)*nfullpos(i,m,k)
101 enddo
102 enddo
103
104 do m=1, 3
105 rcm2(m)=rcm2(m)/masstot
106 enddo
107
108 do i=1, na
109
110 o=lot(i)
111 dij=0.0d0
112 do m=1,3
114 r2cor(m) = rcm2(m) - rcm(m)
115 vij = (rij(m)-r2cor(m))**2
116#ifdef OPENMP
117 !$OMP ATOMIC
118#endif
119 d2dir(o,m,k-j)=d2dir(o,m,k-j)+vij
120 dij=dij+vij
121 enddo
122#ifdef OPENMP
123 !$OMP ATOMIC
124#endif
125 d2i(o,k-j)=d2i(o,k-j)+dij
126
127#ifdef OPENMP
128 !$OMP CRITICAL
129#endif
130 p=4
131 do m=1, 2
132 do n=m+1, 3
133 d2dir(o,p,k-j)=d2dir(o,m,k-j)+d2dir(o,n,k-j)
134 p=p+1
135 enddo
136 enddo
137#ifdef OPENMP
138 !$OMP END CRITICAL
139#endif
140 enddo
141
142 if (k .eq. j+1) then
143
144 do i=1, na
145 o=lot(i)
146 do m=1,3
147 drift(m,k)=drift(m,k)+1e5*(nfullpos(i,m,k)-nfullpos(i,m,j))*mass(o)/(ndts*dlt)
148 enddo
149 enddo
150
151 do m=1,3
152 drift(m,k)=drift(m,k)/masstot
153 enddo
154
155 endif
156
157 enddo
158enddo
159#ifdef OPENMP
160!$OMP END DO NOWAIT
161!$OMP END PARALLEL
162#endif
163
164do k=1, ns-1
165
166 l=k+1
167 do m=1,3
168 rcm(m)=0.0d0
169 rcm2(m)=0.0d0
170 enddo
171
172 do i=1, na
173 o=lot(i)
174 do m=1, 3
175 rcm(m)=rcm(m)+ mass(o)*nfullpos(i,m,k)
176 rcm2(m)=rcm2(m)+ mass(o)*nfullpos(i,m,l)
177 enddo
178 enddo
179
180 do m=1, 3
181 rcm(m)=rcm(m)/masstot
182 rcm2(m)=rcm2(m)/masstot
183 enddo
184
185 do i=1, na
186
187 o=lot(i)
188 dij=0.0d0
189 do m=1,3
190 r2cor(m) = rcm2(m) - rcm(m)
192 d2dirnac(o,m,k)=(rij(m)-r2cor(m))**2
193 dij=dij+(rij(m)-r2cor(m))**2
194 cor(m,k)=cor(m,k)+r2cor(m)
195 enddo
196
197 p=4
198 do m=1, 2
199 do n=m+1, 3
201 p=p+1
202 enddo
203 enddo
204 d2inac(o,k)=d2inac(o,k)+dij
205
206 enddo
207enddo
208
209do k=1, ns-1
210 do i=1, 6
211 do l=1, nsp
212 d2dir(l,i,k)=d2dir(l,i,k)/(ns-k)/nbspbs(l)
214 enddo
215 enddo
216enddo
217
218do k=1, ns-1
219 do i=1, nsp
220 d2i(i,k)=d2i(i,k)/(ns-k)/nbspbs(i)
222 enddo
223enddo
224
225! Evaluation of the diffusion constant D
226! A minimum of dynamic time is needed for a 'physical' meaning of D
227! so if the simulation time is big enough we compute D
228! Here arbitrary we choose 30ps as time limit (30000 fs)
229! We also decide to evaluate only if there is more than 1000 MD steps
230if (ns*ndts*dlt .gt. 30000 .and. ns.gt.1000) then
231! then take car to cut the first 1 ps of the simulation
232! not to be anymore in the ballistic regime
233! afterwards take care to cut the last 1 ps of the calculation
234! usually the correlations are unclear in this zone of the MSD
235 z=ns*ndts*dlt
236 z=z-1.0
237 k=int(z/(ndts*dlt))
238 l=int(1.0/(ndts*dlt))
239 do i=1, nsp
240 dcte(i)=(d2i(i,k)-d2i(i,l))/((k-l)*ndts*dlt)
241 enddo
242
243else
244
245 do i=1, nsp
246 dcte(i)=0.d0
247 enddo
248
249endif
250
251allocate(msdtab(ns-1), stat=err)
252if (err .ne. 0) then
253 call show_error ("Impossible to allocate memory"//char(0), &
254 "Function: MSD"//char(0), "Table: MSDTAB"//char(0))
255 msd=0
256 goto 001
257endif
258
259k=0
260do i=1, nsp
261 do j=1, ns-1
262 msdtab(j)=d2i(i,j)
263 enddo
264 call save_curve (ns-1, msdtab, k, idmsd)
265 k=k+1
266 do j=1, ns-1
267 msdtab(j)=d2inac(i,j)
268 enddo
269 call save_curve (ns-1, msdtab, k, idmsd)
270 k=k+1
271enddo
272
273do i=1, nsp
274 do l=1, 6
275 do j=1, ns-1
276 msdtab(j)=d2dir(i,l,j)
277 enddo
278 call save_curve (ns-1, msdtab, k, idmsd)
279 k=k+1
280 enddo
281enddo
282
283do i=1, nsp
284 do l=1, 6
285 do j=1, ns-1
286 msdtab(j)=d2dirnac(i,l,j)
287 enddo
288 call save_curve (ns-1, msdtab, k, idmsd)
289 k=k+1
290 enddo
291enddo
292
293do i=1, 3
294 do j=1, ns-1
295 msdtab(j)=cor(i,j)
296 enddo
297 call save_curve (ns-1, msdtab, k, idmsd)
298 k=k+1
299enddo
300do i=1, 3
301 do j=1, ns-1
302 msdtab(j)=drift(i,j)
303 enddo
304 call save_curve (ns-1, msdtab, k, idmsd)
305 k=k+1
306enddo
307
308msd=1
309
310001 continue
311
312if (allocated(nfullpos)) deallocate(nfullpos)
313
314call deallocmsd
315
316CONTAINS
317
318LOGICAL FUNCTION transpo()
319
320USE parameters
321
322if (allocated(nfullpos)) deallocate(nfullpos)
323allocate(nfullpos(na,3,ns), stat=err)
324if (err .ne. 0) then
325 call show_error ("Impossible to allocate memory"//char(0), &
326 "Function: TRANSPO"//char(0), "Table: NFULLPOS"//char(0))
327 transpo=.false.
328 goto 001
329endif
330
331if (allocated(poa)) deallocate(poa)
332allocate(poa(na,3), stat=err)
333if (err .ne. 0) then
334 call show_error ("Impossible to allocate memory"//char(0), &
335 "Function: TRANSPO"//char(0), "Table: POA"//char(0))
336 transpo=.false.
337 goto 001
338endif
339
340if (allocated(pob)) deallocate(pob)
341allocate(pob(na,3), stat=err)
342if (err .ne. 0) then
343 call show_error ("Impossible to allocate memory"//char(0), &
344 "Function: TRANSPO"//char(0), "Table: POB"//char(0))
345 transpo=.false.
346 goto 001
347endif
348
349do noa=1, ns
350do nob=1, na
351do noc=1, 3
353enddo
354enddo
355enddo
356
357do noa=1, na
358 do nob=1, 3
360 enddo
361enddo
362
363do noc=2, ns
364 do noa=1, na
365 do nob=1, 3
367 enddo
368 if (ncells .gt. 1) then
369 call calcrij(noa, noa, -1, -1, noc-1)
370 else
371 call calcrij(noa, noa, -1, -1, 1)
372 endif
373 do nob=1, 3
376 enddo
377 enddo
378enddo
379
380transpo = .true.
381
382001 continue
383
384if (allocated(poa)) deallocate(poa)
385if (allocated(pob)) deallocate(pob)
386
387END FUNCTION
388
389END FUNCTION
logical function allocmsd()
Definition allocmsd.F90:22
subroutine deallocmsd
Definition allocmsd.F90:103
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:293
integer(kind=c_int) function msd(dlt, ndts)
Definition msd.F90:22
double precision, dimension(:,:,:), allocatable fullpos
integer ncells
double precision, dimension(:,:,:), allocatable nfullpos
double precision, dimension(3) rcm
integer idmsd
double precision, dimension(:,:), allocatable d2inac
double precision, dimension(:), allocatable mass
double precision, dimension(:,:), allocatable pob
double precision, dimension(:,:,:), allocatable d2dirnac
double precision, dimension(:,:), allocatable poa
double precision, dimension(:), allocatable dcte
integer nob
integer, dimension(:), allocatable nbspbs
double precision, dimension(:,:), allocatable d2i
integer noc
integer noa
double precision z
integer err
double precision, dimension(:,:), allocatable cor
double precision, dimension(3) rij
double precision, dimension(:,:,:), allocatable d2dir
double precision dij
double precision vij
double precision, dimension(:,:), allocatable drift
double precision, dimension(3) rcm2
integer, dimension(:), allocatable lot
integer nsp
double precision, dimension(3) r2cor
subroutine calcrij(at1, at2, step_1, step_2, sid)
Definition utils.F90:115