atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
angles.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 bond_angles(nda) bind (C,NAME='bond_angles_')
22
23USE parameters
24
25#ifdef OPENMP
26!$ USE OMP_LIB
27#endif
28IMPLICIT NONE
29
30INTEGER (KIND=c_int), INTENT(IN) :: nda
31INTEGER, DIMENSION(:,:,:,:), ALLOCATABLE :: anglea
32INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: sum_anga
33DOUBLE PRECISION :: ang
34DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: angtab
35#ifdef OPENMP
36INTEGER :: numth
37LOGICAL :: doatoms
38#endif
39INTERFACE
40 DOUBLE PRECISION FUNCTION angijk (ATG1, ATG2, ATG3, ASTEP)
41 INTEGER, INTENT(IN) :: atg1, atg2, atg3, astep
42 END FUNCTION
43END INTERFACE
44
45if (allocated(anglea)) deallocate(anglea)
46allocate(anglea(nsp,nsp,nsp,nda), stat=err)
47if (err .ne. 0) then
48 call show_error ("Impossible to allocate memory"//char(0), &
49 "Function: bond_angles"//char(0), "Table: ANGLEA"//char(0))
51 goto 001
52endif
53
54anglea(:,:,:,:)=0
55
56delta_ang=180.0/dble(nda)
57
58#ifdef OPENMP
59numth = omp_get_max_threads()
60doatoms=.false.
61if (ns.lt.numth) then
62 if (numth .ge. 2*(ns-1)) then
63 doatoms=.true.
64 else
65 numth=ns
66 endif
67endif
68
69if (all_atoms) doatoms=.true.
70
71if (doatoms) then
72 do i=1, ns
73 ! OpemMP on Atoms
74 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
75 !$OMP& PRIVATE(j, k, l, m, n, ANG, ANG_I) &
76 !$OMP& SHARED(NUMTH, NS, i, NA, NCELLS, LOT, CONTJ, VOISJ, ANGLEA, DELTA_ANG, nda)
77 !$OMP DO SCHEDULE(STATIC,NA/NUMTH)
78 do j=1, na
79
80 if (contj(j,i) .gt. 1) then
81
82 do k=1, contj(j,i)-1
83 do l=k+1, contj(j,i)
84 m=voisj(k,j,i)
85 n=voisj(l,j,i)
86 ang = angijk(m, j, n, i)
87
88 ang_i=anint(ang/delta_ang)
89 if (ang_i.le.0) ang_i=1
90 if (ang_i.gt.nda) ang_i=nda
91 !$OMP ATOMIC
92 anglea(lot(m),lot(j),lot(n),ang_i)=anglea(lot(m),lot(j),lot(n),ang_i)+1
93 if (lot(m) .ne. lot(n)) then
94 !$OMP ATOMIC
95 anglea(lot(n),lot(j),lot(m),ang_i)=anglea(lot(n),lot(j),lot(m),ang_i)+1
96 endif
97 enddo
98 enddo
99
100 endif
101
102 enddo
103 !$OMP END DO NOWAIT
104 !$OMP END PARALLEL
105 enddo
106
107else
108 ! OpemMP on MD steps
109 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
110 !$OMP& PRIVATE(i, j, k, l, m, n, ANG, ANG_I) &
111 !$OMP& SHARED(NUMTH, NS, NA, NCELLS, LOT, CONTJ, VOISJ, ANGLEA, DELTA_ANG, nda)
112 !$OMP DO SCHEDULE(STATIC,NS/NUMTH)
113#endif
114 do i=1, ns
115
116 do j=1, na
117
118 if (contj(j,i) .gt. 1) then
119
120 do k=1, contj(j,i)-1
121 do l=k+1, contj(j,i)
122 m=voisj(k,j,i)
123 n=voisj(l,j,i)
124 ang = angijk(m, j, n, i)
125
126 ang_i=anint(ang/delta_ang)
127 if (ang_i.le.0) ang_i=1
128 if (ang_i.gt.nda) ang_i=nda
129#ifdef OPENMP
130 !$OMP ATOMIC
131#endif
132 anglea(lot(m),lot(j),lot(n),ang_i)=anglea(lot(m),lot(j),lot(n),ang_i)+1
133 if (lot(m) .ne. lot(n)) then
134#ifdef OPENMP
135 !$OMP ATOMIC
136#endif
137 anglea(lot(n),lot(j),lot(m),ang_i)=anglea(lot(n),lot(j),lot(m),ang_i)+1
138 endif
139 enddo
140 enddo
141
142 endif
143
144 enddo
145 enddo
146#ifdef OPENMP
147 !$OMP END DO NOWAIT
148 !$OMP END PARALLEL
149endif
150#endif
151
152if (allocated(sum_anga)) deallocate(sum_anga)
153allocate (sum_anga(nsp,nsp,nsp), stat=err)
154if (err .ne. 0) then
155 call show_error ("Impossible to allocate memory"//char(0), &
156 "Function: bond_angles"//char(0), "Table: SUM_ANGA"//char(0))
158 goto 001
159endif
160
161do i=1, nsp
162 do j=1, nsp
163 do k=1, nsp
164 sum_anga(i,j,k) = 0
165 do l=1, nda
166 sum_anga(i,j,k) = sum_anga(i,j,k) + anglea(i,j,k,l)
167 enddo
168 enddo
169 enddo
170enddo
171
172if (allocated(angtab)) deallocate(angtab)
173allocate(angtab(nda), stat=err)
174if (err .ne. 0) then
175 call show_error ("Impossible to allocate memory"//char(0), &
176 "Function: bond_angles"//char(0), "Table: ANGTAB"//char(0))
178 goto 001
179endif
180angtab(:)=0.0
181
182m=0
183do i=1, nsp
184 do j=1, nsp
185 do k=1, nsp
186 if (sum_anga(i,j,k) .ne. 0) then
187 do l=1, nda
188 angtab(l)=100.0*dble(anglea(i,j,k,l))/dble(sum_anga(i,j,k))
189 enddo
190 call save_curve (nda, angtab, m, idan)
191 else
192 call save_curve (0, angtab, m, idan)
193 endif
194 m=m+1
195 enddo
196 enddo
197enddo
198
200
201001 continue
202
203if (allocated(anglea)) deallocate(anglea)
204if (allocated(sum_anga)) deallocate(sum_anga)
205if (allocated(angtab)) deallocate(angtab)
206
207END FUNCTION bond_angles
208
209INTEGER (KIND=c_int) FUNCTION bond_diedrals(nda) bind (C,NAME='bond_diedrals_')
210
211USE parameters
212
213#ifdef OPENMP
214!$ USE OMP_LIB
215#endif
216IMPLICIT NONE
217
218INTEGER (KIND=c_int), INTENT(IN) :: nda
219INTEGER, DIMENSION(:,:,:,:,:), ALLOCATABLE :: angled
220INTEGER, DIMENSION(:,:,:,:), ALLOCATABLE :: sum_angd
221DOUBLE PRECISION :: ang
222DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: angtab
223#ifdef OPENMP
224INTEGER :: numth
225LOGICAL :: doatoms
226#endif
227INTERFACE
228 DOUBLE PRECISION FUNCTION diedre (DG1, DG2, DG3, DG4, DSTEP)
229 INTEGER, INTENT(IN) :: dg1, dg2, dg3, dg4, dstep
230 END FUNCTION
231END INTERFACE
232
233if (allocated(angled)) deallocate(angled)
234allocate(angled(nsp,nsp,nsp,nsp,nda), stat=err)
235if (err .ne. 0) then
236 call show_error ("Impossible to allocate memory"//char(0), &
237 "Function: bond_angles"//char(0), "Table: ANGLED"//char(0))
239 goto 001
240endif
241
242angled(:,:,:,:,:)=0
243
244delta_ang=180.0/dble(nda)
245
246#ifdef OPENMP
247numth = omp_get_max_threads()
248doatoms=.false.
249if (ns.lt.numth) then
250 if (numth .ge. 2*(ns-1)) then
251 doatoms=.true.
252 else
253 numth=ns
254 endif
255endif
256
257if (all_atoms) doatoms=.true.
258
259if (doatoms) then
260 if (na.lt.numth) numth=na
261 do i=1, ns
262 ! OpemMP on Atoms
263 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
264 !$OMP& PRIVATE(j, k, l, m, n, o, p, ANG, ANG_I) &
265 !$OMP& SHARED(NUMTH, NS, i, NA, NCELLS, LOT, CONTJ, VOISJ, ANGLED, DELTA_ANG, nda)
266 !$OMP DO SCHEDULE(STATIC,NA/NUMTH)
267 do j=1, na
268 do k=1, contj(j,i)
269 m=voisj(k,j,i)
270 if (contj(m,i) .ge. 2) then
271 do l=1, contj(m,i)
272 n=voisj(l,m,i)
273 if (n .ne. j) then
274 if (contj(n,i) .ge. 2) then
275 do o=1, contj(n,i)
276 p = voisj(o,n,i)
277 if (p.ne.j .and. p.ne.m) then
278 ang=diedre(j, m, n, p, i)
279 ang_i=anint(ang/delta_ang)+1
280 if (ang_i.le.0) ang_i=1
281 if (ang_i.gt.nda) ang_i=nda
282 !$OMP ATOMIC
283 angled(lot(j),lot(m),lot(n),lot(p),ang_i)=angled(lot(j),lot(m),lot(n),lot(p),ang_i)+1
284 if (lot(j).ne.lot(m) .or. lot(j).ne.lot(n) .or. lot(j).ne.lot(p)) then
285 !$OMP ATOMIC
286 angled(lot(p),lot(n),lot(m),lot(j),ang_i)=angled(lot(p),lot(n),lot(m),lot(j),ang_i)+1
287 endif
288 endif
289 enddo
290 endif
291 endif
292 enddo
293 endif
294 enddo
295 enddo
296 !$OMP END DO NOWAIT
297 !$OMP END PARALLEL
298 enddo
299
300else
301 ! OpemMP on MD steps
302 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
303 !$OMP& PRIVATE(i, j, k, l, m, n, o, p, ANG, ANG_I) &
304 !$OMP& SHARED(NUMTH, NS, NA, NCELLS, LOT, CONTJ, VOISJ, ANGLED, DELTA_ANG, nda)
305 !$OMP DO SCHEDULE(STATIC,NS/NUMTH)
306#endif
307 do i=1, ns
308 do j=1, na
309 do k=1, contj(j,i)
310 m=voisj(k,j,i)
311 if (contj(m,i) .ge. 2) then
312 do l=1, contj(m,i)
313 n=voisj(l,m,i)
314 if (n .ne. j) then
315 if (contj(n,i) .ge. 2) then
316 do o=1, contj(n,i)
317 p = voisj(o,n,i)
318 if (p.ne.j .and. p.ne.m) then
319 ang=diedre(j, m, n, p, i)
320 ang_i=anint(ang/delta_ang)+1
321 if (ang_i.le.0) ang_i=1
322 if (ang_i.gt.nda) ang_i=nda
323#ifdef OPENMP
324 !$OMP ATOMIC
325#endif
326 angled(lot(j),lot(m),lot(n),lot(p),ang_i)=angled(lot(j),lot(m),lot(n),lot(p),ang_i)+1
327 if (lot(j).ne.lot(m) .or. lot(j).ne.lot(n) .or. lot(j).ne.lot(p)) then
328#ifdef OPENMP
329 !$OMP ATOMIC
330#endif
331 angled(lot(p),lot(n),lot(m),lot(j),ang_i)=angled(lot(p),lot(n),lot(m),lot(j),ang_i)+1
332 endif
333 endif
334 enddo
335 endif
336 endif
337 enddo
338 endif
339 enddo
340 enddo
341 enddo
342#ifdef OPENMP
343 !$OMP END DO NOWAIT
344 !$OMP END PARALLEL
345endif
346#endif
347if (allocated(sum_angd)) deallocate(sum_angd)
348allocate (sum_angd(nsp,nsp,nsp,nsp), stat=err)
349if (err .ne. 0) then
350 call show_error ("Impossible to allocate memory"//char(0), &
351 "Function: bond_angles"//char(0), "Table: SUM_ANGD"//char(0))
353 goto 001
354endif
355sum_angd(:,:,:,:) = 0
356do i=1, nsp
357 do j=1, nsp
358 do k=1, nsp
359 do l=1, nsp
360 do m=1, nda
361 sum_angd(i,j,k,l) = sum_angd(i,j,k,l) + angled(i,j,k,l,m)
362 enddo
363 enddo
364 enddo
365 enddo
366enddo
367
368if (allocated(angtab)) deallocate(angtab)
369allocate(angtab(nda), stat=err)
370if (err .ne. 0) then
371 call show_error ("Impossible to allocate memory"//char(0), &
372 "Function: bond_angles"//char(0), "Table: ANGTAB"//char(0))
374 goto 001
375endif
376angtab(:)=0.0
377
378n=nsp*nsp*nsp
379do i=1, nsp
380 do j=1, nsp
381 do k=1, nsp
382 do l=1, nsp
383 if (sum_angd(i,j,k,l) .ne. 0) then
384 o=1
385 do m=1, nda
386 angtab(m)=100.0*dble(angled(i,j,k,l,m))/dble(sum_angd(i,j,k,l))
387 enddo
388 call save_curve (nda, angtab, n, idan)
389 else
390 call save_curve (0, angtab, n, idan)
391 endif
392 n=n+1
393 enddo
394 enddo
395 enddo
396enddo
397
399
400001 continue
401
402if (allocated(angled)) deallocate(angled)
403if (allocated(sum_angd)) deallocate(sum_angd)
404if (allocated(angtab)) deallocate(angtab)
405
406END FUNCTION bond_diedrals
integer(kind=c_int) function bond_diedrals(nda)
Definition angles.F90:210
integer(kind=c_int) function bond_angles(nda)
Definition angles.F90:22
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:293
integer idan
integer, dimension(:,:), allocatable contj
integer err
double precision delta_ang
integer, dimension(:,:,:), allocatable voisj
integer ang_i
integer, dimension(:), allocatable lot
integer nsp
double precision function angijk(atg1, atg2, atg3, astep)
Definition utils.F90:285
double precision function diedre(dg1, dg2, dg3, dg4, dstep)
Definition utils.F90:331