atomes 1.3.1
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
sq.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-2026 by CNRS and University of Strasbourg
15!
16!>
17!! @file sq.F90
18!! @short S(q) analysis: Fourier transform calculation
19!! @author Sébastien Le Roux <sebastien.leroux@ipcms.unistra.fr>
20
21INTEGER (KIND=c_int) FUNCTION s_of_q (QMAX, QMIN, NQ) bind (C,NAME='s_of_q_')
22
23! Total structure factor
24! Partials structure factors
25
26! Total structure factor:
27
28!
29! 00 sin (q*r)
30! S(q)= 1 + 4*PI*rho* / dr r² ------------ (g(r) - 1)
31! 0 (q*r)
32!
33
34! or:
35
36! 1 Rmax sin (q*r) sin (PI*r/Rmax)
37! S(q)= 1 + 4*PI*rho* / dr r² (g(r) -1) ----------- * ---------------
38! 0 (q*r) PI*r/Rmax
39!
40
41! Partials structure factors:
42
43!
44! Rmax
45! S (q)= delta(a,b) + sqrt(x * x ) *4*PI*rho* / dr r² (g (r) - 1)
46! ab a b 0 ab
47!
48!
49
50! or:
51
52! Rmax sin (q*r) sin (PI*r/Rmax)
53! S (q)= delta(a,b) + sqrt(x * x ) *4*PI*rho* / dr r² (g (r) - go ) ----------- * ---------------
54! ab a b 0 ab ab (q*r) PI*r/Rmax
55!
56
57! with x = Nbre(a)/Nbre(tot)
58! a
59
60
61USE parameters
62
63IMPLICIT NONE
64
65INTEGER (KIND=c_int), INTENT(IN) :: nq
66real(kind=c_double), INTENT(IN) :: qmax , qmin
67DOUBLE PRECISION :: dq
68DOUBLE PRECISION, DIMENSION (:), ALLOCATABLE :: sqtab
69
70INTERFACE
71 INTEGER FUNCTION recup_data (i, j)
72 INTEGER, INTENT(IN) :: i, j
73 END FUNCTION
74 LOGICAL FUNCTION fzbt (NDQ, SQIJ)
75 USE parameters
76 INTEGER, INTENT(IN) :: ndq
77 DOUBLE PRECISION, DIMENSION(NDQ,NSP,NSP), INTENT(IN) :: sqij
78 END FUNCTION
79END INTERFACE
80
81number_of_qmod = nq
82total_density = dble(na)/meanvol
83
84if (allocated(q_point)) deallocate(q_point)
85allocate(q_point(nq), stat=err)
86if (err .ne. 0) then
87 call show_error ("Impossible to allocate memory"//char(0), &
88 "Function: s_of_q"//char(0), "Table: Q_POINT"//char(0))
89 s_of_q = 0
90 goto 001
91endif
92if (allocated(s)) deallocate(s)
93allocate(s(nq), stat=err)
94if (err .ne. 0) then
95 call show_error ("Impossible to allocate memory"//char(0), &
96 "Function: s_of_q"//char(0), "Table: S"//char(0))
97 s_of_q = 0
98 goto 001
99endif
100if (allocated(xs)) deallocate(xs)
101allocate(xs(nq), stat=err)
102if (err .ne. 0) then
103 call show_error ("Impossible to allocate memory"//char(0), &
104 "Function: s_of_q"//char(0), "Table: XS"//char(0))
105 s_of_q = 0
106 goto 001
107endif
108if (allocated(sij)) deallocate(sij)
109allocate(sij(nq,nsp,nsp), stat=err)
110if (err .ne. 0) then
111 call show_error ("Impossible to allocate memory"//char(0), &
112 "Function: s_of_q"//char(0), "Table: Sij"//char(0))
113 s_of_q = 0
114 goto 001
115endif
116
117! 'QMIN' is minimum q modulus accessible considering the analysed
118! lattice ie. the minimum modulus of the reciprocal cell vectors,
119dq=((qmax-qmin)/dble(nq))
120
121s(:)=0.0d0
122xs(:)=0.0d0
123q_point(:)=0.0d0
124do i=1, nq
125 q_point(i)= dble(i-1)*dq+qmin
126enddo
127
128sij(:,:,:)=0.0d0
129
130j=0
131if (recup_data(j, idgr) .ne. 1) then
132 s_of_q = 0
133 goto 001
134endif
135
136j=j+8
137if (recup_data(j, idgr) .ne. 1) then
138 s_of_q = 0
139 goto 001
140endif
141
142j=j+8
143do o=1, nsp
144do p=1, nsp
145 if (recup_data(j, idgr) .ne. 1) then
146 s_of_q = 0
147 goto 001
148 endif
149 j=j+5
150enddo
151enddo
152
153if (.not. fzbt(nq, sij)) then
154 s_of_q = 0
155 goto 001
156endif
157
158if (allocated(sqtab)) deallocate(sqtab)
159allocate(sqtab(nq), stat=err)
160if (err .ne. 0) then
161 call show_error ("Impossible to allocate memory"//char(0), &
162 "Function: s_of_q"//char(0), "Table: SQTAB"//char(0))
163 s_of_q = 0
164 goto 001
165endif
166
167l=0
168do k=1, nq
169 sqtab(k)= s(k)
170enddo
171call save_curve (nq, sqtab, l, idsq)
172l=l+2
173
174do k=1, nq
175 sqtab(k)= (s(k)-1.0)*q_point(k)
176enddo
177call save_curve (nq, sqtab, l, idsq)
178l=l+2
179
180do k=1, nq
181 sqtab(k)= xs(k)
182enddo
183call save_curve (nq, sqtab, l, idsq)
184l=l+2
185
186do k=1, nq
187 sqtab(k)= (xs(k)-1.0)*q_point(k)
188enddo
189call save_curve (nq, sqtab, l, idsq)
190l=l+2
191
192do i=1, nsp
193do j=1, nsp
194 do k=1, nq
195 sqtab(k)= sij(k,i,j)
196 enddo
197 call save_curve (nq, sqtab, l, idsq)
198 l=l+2
199enddo
200enddo
201do i=1, nsp
202do j=1, nsp
203 do k=1, nq
204 sqtab(k)= fzsij(k,i,j)
205 enddo
206 call save_curve (nq, sqtab, l, idsq)
207 l=l+2
208enddo
209enddo
210if (nsp .eq. 2) then
211 do i=1, 4
212 do j=1, nq
213 sqtab(j)= btij(j,i)
214 enddo
215 call save_curve (nq, sqtab, l, idsq)
216 l=l+2
217 enddo
218endif
219
220s_of_q = 1
221
222001 continue
223
224if (allocated(sqtab)) deallocate(sqtab)
225if (allocated(q_point)) deallocate(q_point)
226if (allocated(sij)) deallocate(sij)
227if (allocated(s)) deallocate(s)
228if (allocated(xs)) deallocate(xs)
229if (allocated(fzsij)) deallocate(fzsij)
230if (allocated(btij)) deallocate(btij)
231
232END FUNCTION
233
234INTEGER (KIND=c_int) FUNCTION send_gr (IC, VAL, DR, RDATA, GDATA) bind (C,NAME='send_gr_')
235
236USE parameters
237
238INTEGER (KIND=c_int), INTENT(IN) :: ic, val
239real(kind=c_double), INTENT(IN) :: dr
240real(kind=c_double), DIMENSION(VAL), INTENT(IN) :: rdata, gdata
241DOUBLE PRECISION :: hcap1, hcap2, vcap
242INTEGER :: rinit
243
244if (allocated(shell_vol)) deallocate(shell_vol)
245allocate(shell_vol(val+1), stat=err)
246if (err .ne. 0) then
247 call show_error ("Impossible to allocate memory"//char(0), &
248 "Function: send_gr"//char(0), "Table: SHELL_VOL"//char(0))
249 send_gr = 0
250 goto 001
251endif
252
253do i=1, val
254 shell_vol(i) = 0.0d0
255 shell_vol(i) = 4.0d0*pi*((rdata(i)+dr)**3 - (rdata(i)**3))/3
256! To take into account the atoms between a/2 and a srqt(3)/2
257! We need the small volume they can be found in.
258 if (overall_cubic .and. rdata(i)+dr.gt.mbox) then
259 hcap1=rdata(i)+dr-mbox
260 if (rdata(i) .le. mbox) then
261 hcap2=0.0d0
262 else
263 hcap2=rdata(i)-mbox
264 endif
265 vcap=hcap1**2*(3*rdata(i) - hcap1) - hcap2**2*(3*rdata(i) - hcap2)
266 vcap=vcap*pi*2
267 shell_vol(i)=shell_vol(i)-vcap
268 endif
269enddo
270
271j=ic
272if (j > 8) then
273 m=j-16
274 m=m/5
275 k=m/nsp+1
276 l=m-(k-1)*nsp+1
277endif
278
279rinit = 1
280if (rdata(1) .eq. 0.0) rinit = 2
281
282rmax = rdata(val)
283do i=1, number_of_qmod
284 do n=rinit, val
285 phi = q_point(i)*rdata(n)
286 fact_rmax = pi*rdata(n)/rmax
287! Sinus_Fact_Rmax = sin(Fact_Rmax)/Fact_Rmax
288 sinus_phi = sin(phi)/phi
289 if (j .eq. 0) then
290 s(i) = s(i) + shell_vol(n)*(gdata(n) - 1)*sinus_phi!*Sinus_Fact_Rmax
291 else if (j .eq. 8) then
292 xs(i) = xs(i) + shell_vol(n)*(gdata(n) - 1)*sinus_phi
293 else
294 sij(i,k,l) = sij(i,k,l) + shell_vol(n)*(gdata(n) - 1)*sinus_phi!*Sinus_Fact_Rmax
295 endif
296 enddo
297 if (j .eq. 0) then
298 s(i) = 1.0d0 + s(i)*total_density
299 else if (j .eq. 8) then
300 xs(i) = 1.0d0 + xs(i)*total_density
301 else
302 if (l .eq. k) then
303 sij(i,k,l) = 1.0d0 + xi(l)*sij(i,k,l)*total_density
304 else
305 sij(i,k,l) = sqrt(xi(k)*xi(l))*sij(i,k,l)*total_density
306 endif
307 endif
308enddo
309
310send_gr = 1
311
312001 continue
313
314if (allocated(shell_vol)) deallocate(shell_vol)
315
316END FUNCTION
logical function fzbt(ndq, sqij)
Definition fzbt.F90:22
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:299
double precision total_density
double precision rmax
double precision fact_rmax
integer number_of_qmod
double precision, dimension(:), allocatable q_point
double precision, dimension(:), allocatable xi
double precision phi
double precision, dimension(:), allocatable s
double precision, dimension(:), allocatable xs
integer err
double precision, dimension(:), allocatable shell_vol
double precision mbox
logical overall_cubic
double precision sinus_phi
integer nsp
double precision, dimension(:,:,:), allocatable sij
double precision, parameter pi
integer(kind=c_int) function s_of_q(qmax, qmin, nq)
Definition sq.F90:22
integer(kind=c_int) function send_gr(ic, val, dr, rdata, gdata)
Definition sq.F90:235