atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
gr.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 g_of_r (NDR, DTR, FCR) bind (C,NAME='g_of_r_')
22
23! Radial Pair Distribution function
24
25!
26! -2 V
27! g(r)= rho < Sum Sum d(ri)d(rj-r) > = -- < Sum Sum d(r-rij) >
28! i j!i N² i j!i
29!
30!
31!
32!
33! 1 rho(b) rho(b)
34! g (r)= ------------ Sum Sum ---------- = Sum Sum ------------------
35! ab 4*PI*Delat(r) a b!a d(ab)²*N(a) a b!a Vshell(d(ab))*N(a)
36!
37
38USE parameters
39
40#ifdef OPENMP
41!$ USE OMP_LIB
42#endif
43IMPLICIT NONE
44
45INTEGER (KIND=c_int), INTENT(IN) :: ndr, fcr
46real(kind=c_double), INTENT(IN) :: dtr
47DOUBLE PRECISION :: hcap1, hcap2, vcap, dgr
48DOUBLE PRECISION :: norm_fact, grlim
49DOUBLE PRECISION :: suml, xsuml
50LOGICAL :: is_crystal=.false.
51#ifdef OPENMP
52INTEGER :: numth
53LOGICAL :: doatoms
54#endif
55
56INTERFACE
57 LOGICAL FUNCTION allocgr(NDR)
58 INTEGER, INTENT(IN) :: ndr
59 END FUNCTION
60 LOGICAL FUNCTION grbt(GrToBT, NDTR)
61 USE parameters
62 INTEGER, INTENT(IN) :: ndtr
63 DOUBLE PRECISION, DIMENSION(NDTR,NSP,NSP), INTENT(IN) :: grtobt
64 END FUNCTION
65 DOUBLE PRECISION FUNCTION calcdij (R12, AT1, AT2, STEP_1, STEP_2, SID)
66 DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: r12
67 INTEGER, INTENT(IN) :: at1, at2, step_1, step_2, sid
68 END FUNCTION
69END INTERFACE
70
71if (.not. allocgr(ndr)) then
72 g_of_r = 0
73 goto 001
74endif
75
76do i=1, ndr+1
77 shell_vol(i) = 0.0d0
78 shell_vol(i) = 4.0d0*pi*(((i-1)*dtr+dtr)**3 - ((i-1)*dtr)**3)/3
79! To take into account the atoms between a/2 and a srqt(3)/2
80! We need the small volume they can be found in.
81 if (overall_cubic .and. i*dtr.gt.mbox) then
82 hcap1=i*dtr-mbox
83 if ((i-1)*dtr .le. mbox) then
84 hcap2=0.0d0
85 else
86 hcap2=(i-1)*dtr-mbox
87 endif
88 vcap=hcap1**2*(3*i*dtr - hcap1) - hcap2**2*(3*(i-1)*dtr - hcap2)
89 vcap=vcap*pi*2
90 shell_vol(i)=shell_vol(i)-vcap
91 endif
92enddo
93
94grlim = ndr*dtr
95grlim = grlim*grlim
96
97#ifdef OPENMP
98 numth = omp_get_max_threads()
99 doatoms=.false.
100 if (ns.lt.numth) then
101 if (numth .ge. 2*(ns-1)) then
102 doatoms=.true.
103 else
104 numth=ns
105 endif
106 endif
107
108 if (all_atoms) doatoms=.true.
109#endif
110
111if (is_crystal) then
112 ! To write the case of highly distoreded crystal
113else
114#ifdef OPENMP
115 if (doatoms) then
116 if (na.lt.numth) numth=na
117 ! OpemMP on atoms only
118 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
119 !$OMP& PRIVATE(Dgr, Dij, Rij, GR_INDEX, NORM_FACT, i, j, k, l, m, n) &
120 !$OMP& SHARED(NUMTH, NS, NA, NCELLS, LOT, NBSPBS, SHELL_VOL, DTR, MEANVOL, GRLIM, Gij, Dn, NSP, NDR)
121 !$OMP DO SCHEDULE(STATIC,NA-1/NUMTH)
122 do i=1, na-1
123 do k=1, ns
124 do j=i+1, na
125 if (ncells .gt. 1) then
126 dij = calcdij(rij,i,j,k,k,k)
127 else
128 dij = calcdij(rij,i,j,k,k,1)
129 endif
130 if (dij <= grlim) then
131 l=lot(i)
132 m=lot(j)
133 dgr = sqrt(dij)
134 if (l .eq. m) then
135 n = nbspbs(l)-1
136 else
137 n = nbspbs(l)
138 endif
139 gr_index = int(dgr/dtr)+1
140 norm_fact = 1.0d0/(shell_vol(gr_index)*dble(n))
141 !$OMP ATOMIC
142 gij(gr_index,l,m,k) = gij(gr_index,l,m,k) + norm_fact/(dble(nbspbs(m))/meanvol)
143 !$OMP ATOMIC
144 dn(gr_index,l,m,k) = dn(gr_index,l,m,k) + 1.0d0
145 endif
146 enddo
147 enddo
148 enddo
149 !$OMP END DO NOWAIT
150 !$OMP END PARALLEL
151 else
152 ! OpemMP on MD steps
153 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
154 !$OMP& PRIVATE(Dgr, Dij, Rij, GR_INDEX, NORM_FACT, i, j, k, l, m, n) &
155 !$OMP& SHARED(NUMTH, NS, NA, NCELLS, LOT, NBSPBS, SHELL_VOL, DTR, MEANVOL, GRLIM, Gij, Dn, NSP, NDR)
156 !$OMP DO SCHEDULE(STATIC,NS/NUMTH)
157#endif
158 do k=1, ns
159 do i=1, na-1
160 do j=i+1, na
161 if (ncells .gt. 1) then
162 dij = calcdij(rij,i,j,k,k,k)
163 else
164 dij = calcdij(rij,i,j,k,k,1)
165 endif
166 if (dij <= grlim) then
167 l=lot(i)
168 m=lot(j)
169 dgr = sqrt(dij)
170 if (l .eq. m) then
171 n = nbspbs(l)-1
172 else
173 n = nbspbs(l)
174 endif
175 gr_index = int(dgr/dtr)+1
176 norm_fact = 1.0d0/(shell_vol(gr_index)*dble(n))
177#ifdef OPENMP
178 !$OMP ATOMIC
179#endif
180 gij(gr_index,l,m,k) = gij(gr_index,l,m,k) + norm_fact/(dble(nbspbs(m))/meanvol)
181#ifdef OPENMP
182 !$OMP ATOMIC
183#endif
184 dn(gr_index,l,m,k) = dn(gr_index,l,m,k) + 1.0d0
185 endif
186 enddo
187 enddo
188 enddo
189#ifdef OPENMP
190 !$OMP END DO NOWAIT
191 !$OMP END PARALLEL
192 endif
193#endif
194endif
195
196do i=1, ndr
197 do l=1, ns
198 do j=1, nsp
199 dn(i,j,j,l) = 2.0d0*dn(i,j,j,l)/dble(nbspbs(j)-1)
200 enddo
201 do j=1, nsp-1
202 do k=j+1, nsp
203 dn(i,j,k,l) = dn(i,j,k,l)+dn(i,k,j,l)
204 dn(i,k,j,l) = dn(i,j,k,l)
205 dn(i,j,k,l) = dn(i,j,k,l)/dble(nbspbs(j))
206 dn(i,k,j,l) = dn(i,k,j,l)/dble(nbspbs(k))
207 enddo
208 enddo
209 enddo
210enddo
211
212do i=2, ndr
213 do l=1, ns
214 do j=1, nsp
215 do k=1, nsp
216 dn(i,j,k,l) = dn(i-1,j,k,l) + dn(i,j,k,l)
217 enddo
218 enddo
219 enddo
220enddo
221
222do i=1, nsp
223 do j=1, nsp
224 do k=1, ndr
225 do l=1, ns
226 dn_ij(k,i,j) = dn_ij(k,i,j) + dn(k,i,j,l)
227 gr_ij(k,i,j) = gr_ij(k,i,j) + gij(k,i,j,l)
228 enddo
229 gr_ij(k,i,j) = gr_ij(k,i,j)/dble(ns)
230 dn_ij(k,i,j) = dn_ij(k,i,j)/dble(ns)
231 enddo
232 enddo
233enddo
234
235do k=1, ndr
236 do l=1, nsp
237 gr_ij(k,l,l) = 2.0d0*gr_ij(k,l,l)
238 enddo
239 do j=1, nsp-1
240 do i=j+1, nsp
241 gr_ij(k,i,j) = gr_ij(k,i,j) + gr_ij(k,j,i)
242 gr_ij(k,j,i) = gr_ij(k,i,j)
243 enddo
244 enddo
245enddo
246
247if (allocated(dn)) deallocate(dn)
248if (allocated(gij)) deallocate(gij)
249
250l = 16
251do i=1, nsp
252 do j=1, nsp
253 do k=1, ndr
254 grtab(k)=gr_ij(k,i,j)
255 enddo
256 call save_curve (ndr, grtab, l, idgr)
257 l = l+2
258 do k=1, ndr
259 ggr_ij(k,i,j) = (gr_ij(k,i,j)-1.0)*4.0*pi*(na/meanvol)*(k-0.5)*dtr
260 grtab(k) = ggr_ij(k,i,j)
261 enddo
262 call save_curve (ndr, grtab, l, idgr)
263 l = l+2
264 do k=1, ndr
265 grtab(k)=dn_ij(k,i,j)
266 enddo
267 call save_curve (ndr, grtab, l, idgr)
268 l = l+1
269 enddo
270enddo
271
272if (nsp .eq. 2) then
273 if (grbt(gr_ij, ndr)) then
274 do k=1, ndr
275 grtab(k)=btij(k,1)
276 enddo
277 call save_curve (ndr, grtab, l, idgr)
278 l = l+2
279 do k=1, ndr
280 grtab(k)=btij(k,2)
281 enddo
282 call save_curve (ndr, grtab, l, idgr)
283 l = l+2
284 do k=1, ndr
285 grtab(k)=btij(k,3)
286 enddo
287 call save_curve (ndr, grtab, l, idgr)
288 endif
289 if (allocated(btij)) deallocate(btij)
290endif
291
292suml=0.0d0
293xsuml=0.0d0
294do k=1, nsp
295 suml=suml+nscattl(k)*xi(k)
296 xsuml=xsuml+xscattl(k)*xi(k)
297enddo
298suml=suml*suml
299xsuml=xsuml*xsuml
300
301! Attention bi(NSCATTL(i) dans le code) en fm et bi² en barn = fm*fm*1e-2 = 1e-24cm²
302do i=1, ndr
303 do j=1, nsp
304 do k=1, nsp
305 grtot(i) = grtot(i) + xi(j)*xi(k)*nscattl(j)*nscattl(k)*gr_ij(i,j,k)
306 ggrtot(i) = ggrtot(i) + xi(j)*xi(k)*nscattl(j)*nscattl(k)*ggr_ij(i,j,k)
307 xgrtot(i) = xgrtot(i) + xi(j)*xi(k)*xscattl(j)*xscattl(k)*gr_ij(i,j,k)
308 xggrtot(i) = xggrtot(i) + xi(j)*xi(k)*xscattl(j)*xscattl(k)*ggr_ij(i,j,k)
309 enddo
310 enddo
311 grtot(i) = grtot(i)/suml
312 drn(i) = ggrtot(i)
313 trn(i) = drn(i) + 4.0*pi*(na/meanvol)*(i-0.5)*dtr*suml
314 ggrtot(i) = ggrtot(i)/suml
315
316
317 xgrtot(i) = xgrtot(i)/xsuml
318 drx(i) = xggrtot(i)
319 trx(i) = drx(i) + 4.0*pi*(na/meanvol)*(i-0.5)*dtr*xsuml
320 xggrtot(i) = xggrtot(i)/xsuml
321enddo
322
323do i=1, ndr
324 grtab(i) = grtot(i)
325enddo
326call save_curve (ndr, grtab, 0, idgr)
327
328do i=1, ndr
329 grtab(i) = ggrtot(i)
330enddo
331call save_curve (ndr, grtab, 2, idgr)
332
333do i=1, ndr
334 grtab(i) = drn(i)
335enddo
336call save_curve (ndr, grtab, 4, idgr)
337
338do i=1, ndr
339 grtab(i) = trn(i)
340enddo
341call save_curve (ndr, grtab, 6, idgr)
342
343do i=1, ndr
344 grtab(i) = xgrtot(i)
345enddo
346call save_curve (ndr, grtab, 8, idgr)
347
348do i=1, ndr
349 grtab(i) = xggrtot(i)
350enddo
351call save_curve (ndr, grtab, 10, idgr)
352
353do i=1, ndr
354 grtab(i) = drx(i)
355enddo
356call save_curve (ndr, grtab, 12, idgr)
357
358do i=1, ndr
359 grtab(i) = trx(i)
360enddo
361call save_curve (ndr, grtab, 14, idgr)
362
363if (fcr .eq. 1) call fitcutoffs
364
365g_of_r=1
366
367001 continue
368
369if (allocated(dn)) deallocate (dn)
370if (allocated(gij)) deallocate (gij)
371if (allocated(dn_ij)) deallocate (dn_ij)
372if (allocated(grtab)) deallocate (grtab)
373if (allocated(ggrtot)) deallocate (ggrtot)
374if (allocated(xggrtot)) deallocate (xggrtot)
375if (allocated(trn)) deallocate (trn)
376if (allocated(trx)) deallocate (trx)
377if (allocated(drn)) deallocate (drn)
378if (allocated(drx)) deallocate (drx)
379if (allocated(ggr_ij)) deallocate (ggr_ij)
380if (allocated(gr_ij)) deallocate (gr_ij)
381if (allocated(shell_vol)) deallocate(shell_vol)
382
383CONTAINS
384
385SUBROUTINE fitcutoffs
386
387INTERFACE
388 INTEGER FUNCTION cutfit (TABTOFIT, NPOINTS)
389
390 INTEGER, INTENT(IN) :: npoints
391 DOUBLE PRECISION, DIMENSION(NPOINTS), INTENT(IN) :: tabtofit
392 END FUNCTION
393END INTERFACE
394
395if (allocated(gfft)) deallocate(gfft)
396allocate(gfft(ndr), stat=err)
397if (err .ne. 0) then
398 call show_error ("Impossible to allocate memory"//char(0), &
399 "Subroutine: FITCUTOFFS"//char(0), "Table: GFFT"//char(0))
400endif
401
402do l=1, nsp
403 do j=1, nsp
404 do k=1, ndr
405 gfft(k)=gr_ij(k,l,j)
406 enddo
407 gr_cut(l,j) = (cutfit(gfft, ndr) - 0.5) * dtr
408 enddo
409enddo
410gr_cutoff = (cutfit(grtot, ndr) - 0.5) * dtr
411
412call sendcutoffs(nsp, gr_cutoff, gr_cut)
413
414if (allocated(gfft)) deallocate(gfft)
415
416END SUBROUTINE
417
418END FUNCTION
419
420INTEGER FUNCTION cutfit (TABTOFIT, NPOINTS)
421
422USE parameters
423
424IMPLICIT NONE
425
426INTEGER, INTENT(IN) :: npoints
427DOUBLE PRECISION, DIMENSION(NPOINTS), INTENT(IN) :: tabtofit
428
429o = 1
430p = 0
431do while (p .eq. 0)
432 r=int(o+1+anint(5.0*dble(npoints)/dble(100*ns)))
433 if (o.eq.npoints .or. r.gt.npoints) exit
434 if (tabtofit(o) .le. tabtofit(o+1)) then
435 o=o+1
436 else if (tabtofit(o) .le. tabtofit(r)) then
437 o=o+1
438 else if (tabtofit(o) .le. 0.05) then
439 o=o+1
440 else
441 p=1
442 endif
443enddo
444p = 0
445do while (p .eq. 0)
446 r=int(o+1+anint(5.0*dble(npoints)/dble(100*ns)))
447 if (o.eq.npoints .or. r.gt.npoints) exit
448 if (tabtofit(o) .le. tabtofit(o+1)) then
449 o=o+1
450 else if (tabtofit(o) .le. tabtofit(r)) then
451 o=o+1
452 else
453 p=1
454 endif
455enddo
456
457cutfit = o
458
459END FUNCTION
460
461LOGICAL FUNCTION allocgr (NDR)
462
463USE parameters
464
465IMPLICIT NONE
466
467INTEGER, INTENT(IN) :: ndr
468
469allocgr=.true.
470
471if (allocated(shell_vol)) deallocate(shell_vol)
472allocate(shell_vol(ndr+1), stat=err)
473if (err .ne. 0) then
474 call show_error ("Impossible to allocate memory"//char(0), &
475 "Function: ALLOCGR"//char(0), "Table: SHELL_VOL"//char(0))
476 allocgr=.false.
477 goto 001
478endif
479if (allocated(gij)) deallocate(gij)
480allocate(gij(ndr+1,nsp,nsp,ns), stat=err)
481if (err .ne. 0) then
482 call show_error ("Impossible to allocate memory"//char(0), &
483 "Function: ALLOCGR"//char(0), "Table: Gij"//char(0))
484 allocgr=.false.
485 goto 001
486endif
487if (allocated(dn)) deallocate(dn)
488allocate(dn(ndr+1,nsp,nsp,ns), stat=err)
489if (err .ne. 0) then
490 call show_error ("Impossible to allocate memory"//char(0), &
491 "Function: ALLOCGR"//char(0), "Table: Dn"//char(0))
492 allocgr=.false.
493 goto 001
494endif
495
496gij(:,:,:,:)=0.0d0
497dn(:,:,:,:)=0.0d0
498
499if (allocated(xgrtot)) deallocate(xgrtot)
500allocate(xgrtot(ndr), stat=err)
501if (err .ne. 0) then
502 call show_error ("Impossible to allocate memory"//char(0), &
503 "Function: ALLOCGR"//char(0), "Table: XGrTOT"//char(0))
504 allocgr=.false.
505 goto 001
506endif
507if (allocated(grtot)) deallocate(grtot)
508allocate(grtot(ndr), stat=err)
509if (err .ne. 0) then
510 call show_error ("Impossible to allocate memory"//char(0), &
511 "Function: ALLOCGR"//char(0), "Table: GrTOT"//char(0))
512 allocgr=.false.
513 goto 001
514endif
515if (allocated(gr_ij)) deallocate(gr_ij)
516allocate(gr_ij(ndr,nsp,nsp), stat=err)
517if (err .ne. 0) then
518 call show_error ("Impossible to allocate memory"//char(0), &
519 "Function: ALLOCGR"//char(0), "Table: Gr_ij"//char(0))
520 allocgr=.false.
521 goto 001
522endif
523if (allocated(dn_ij)) deallocate(dn_ij)
524allocate(dn_ij(ndr,nsp,nsp), stat=err)
525if (err .ne. 0) then
526 call show_error ("Impossible to allocate memory"//char(0), &
527 "Function: ALLOCGR"//char(0), "Table: Dn_ij"//char(0))
528 allocgr=.false.
529 goto 001
530endif
531if (allocated(grtab)) deallocate(grtab)
532allocate(grtab(ndr), stat=err)
533if (err .ne. 0) then
534 call show_error ("Impossible to allocate memory"//char(0), &
535 "Function: ALLOCGR"//char(0), "Table: GRTAB"//char(0))
536 allocgr=.false.
537 goto 001
538endif
539if (allocated(ggr_ij)) deallocate(ggr_ij)
540allocate(ggr_ij(ndr,nsp,nsp), stat=err)
541if (err .ne. 0) then
542 call show_error ("Impossible to allocate memory"//char(0), &
543 "Function: ALLOCGR"//char(0), "Table: Ggr_ij"//char(0))
544 allocgr=.false.
545 goto 001
546endif
547if (allocated(ggrtot)) deallocate(grtot)
548allocate(ggrtot(ndr), stat=err)
549if (err .ne. 0) then
550 call show_error ("Impossible to allocate memory"//char(0), &
551 "Function: ALLOCGR"//char(0), "Table: GgrTOT"//char(0))
552 allocgr=.false.
553 goto 001
554endif
555if (allocated(xggrtot)) deallocate(xggrtot)
556allocate(xggrtot(ndr), stat=err)
557if (err .ne. 0) then
558 call show_error ("Impossible to allocate memory"//char(0), &
559 "Function: ALLOCGR"//char(0), "Table: XGgrTOT"//char(0))
560 allocgr=.false.
561 goto 001
562endif
563if (allocated(trn)) deallocate(trn)
564allocate(trn(ndr), stat=err)
565if (err .ne. 0) then
566 call show_error ("Impossible to allocate memory"//char(0), &
567 "Function: ALLOCGR"//char(0), "Table: Trn"//char(0))
568 allocgr=.false.
569 goto 001
570endif
571if (allocated(drn)) deallocate(drn)
572allocate(drn(ndr), stat=err)
573if (err .ne. 0) then
574 call show_error ("Impossible to allocate memory"//char(0), &
575 "Function: ALLOCGR"//char(0), "Table: Drn"//char(0))
576 allocgr=.false.
577 goto 001
578endif
579if (allocated(trx)) deallocate(trx)
580allocate(trx(ndr), stat=err)
581if (err .ne. 0) then
582 call show_error ("Impossible to allocate memory"//char(0), &
583 "Function: ALLOCGR"//char(0), "Table: Trx"//char(0))
584 allocgr=.false.
585 goto 001
586endif
587if (allocated(drx)) deallocate(drx)
588allocate(drx(ndr), stat=err)
589if (err .ne. 0) then
590 call show_error ("Impossible to allocate memory"//char(0), &
591 "Function: ALLOCGR"//char(0), "Table: Drx"//char(0))
592 allocgr=.false.
593 goto 001
594endif
595
596grtot(:)=0.0d0
597xgrtot(:)=0.0d0
598grtab(:)=0.0d0
599ggrtot(:)=0.0d0
600xggrtot(:)=0.0d0
601trn(:)=0.0d0
602trx(:)=0.0d0
603drn(:)=0.0d0
604drx(:)=0.0d0
605gr_ij(:,:,:)=0.0d0
606dn_ij(:,:,:)=0.0d0
607ggr_ij(:,:,:)=0.0d0
608
609001 continue
610
611END FUNCTION
logical function grbt(grtobt, ndtr)
Definition fzbt.F90:114
integer(kind=c_int) function g_of_r(ndr, dtr, fcr)
Definition gr.F90:22
logical function allocgr(ndr)
Definition gr.F90:462
integer function cutfit(tabtofit, npoints)
Definition gr.F90:421
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:293
double precision, dimension(:), allocatable drx
double precision, dimension(:), allocatable trx
double precision, dimension(:,:,:), allocatable dn_ij
double precision, dimension(:), allocatable ggrtot
double precision, dimension(:,:,:), allocatable ggr_ij
double precision, dimension(:), allocatable grtab
double precision, dimension(:,:,:,:), allocatable gij
double precision, dimension(:), allocatable grtot
integer err
double precision, dimension(:,:,:,:), allocatable dn
double precision, dimension(:,:,:), allocatable gr_ij
double precision, dimension(:), allocatable xggrtot
double precision, dimension(:), allocatable shell_vol
double precision, dimension(:), allocatable drn
double precision, dimension(:), allocatable trn
integer nsp
double precision, dimension(:), allocatable xgrtot
double precision function calcdij(r12, at1, at2, step_1, step_2, sid)
Definition utils.F90:185