atomes 1.3.1
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
sk.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 sk.F90
18!! @short S(k) analysis: direct reciprocal space calculation
19!! @author Sébastien Le Roux <sebastien.leroux@ipcms.unistra.fr>
20
21INTEGER (KIND=c_int) FUNCTION s_of_k (NQ, XA) bind (C,NAME='s_of_k_')
22
23! Total structure factor
24! Partial structure factors from k-points
25
26USE parameters
27
28#ifdef OPENMP
29!$ USE OMP_LIB
30#endif
31IMPLICIT NONE
32
33INTEGER (KIND=c_int), INTENT(IN) :: nq, xa
34DOUBLE PRECISION :: factor, xfactor
35
36INTERFACE
37 DOUBLE PRECISION FUNCTION fqx(TA, Q)
38 INTEGER, INTENT(IN) :: ta
39 DOUBLE PRECISION, INTENT(IN) :: q
40 END FUNCTION
41END INTERFACE
42
43if(allocated(sij)) deallocate(sij)
44allocate(sij(nq,nsp,nsp), stat=err)
45if (err .ne. 0) then
46 call show_error ("Impossible to allocate memory"//char(0), &
47 "Function: s_of_k"//char(0), "Table: Sij"//char(0))
48 s_of_k = 0
49 goto 001
50endif
51sij(:,:,:)=0.0d0
52
53if(allocated(cij)) deallocate(cij)
54allocate(cij(nsp), stat=err)
55if (err .ne. 0) then
56 call show_error ("Impossible to allocate memory"//char(0), &
57 "Function: s_of_k"//char(0), "Table: cij"//char(0))
58 s_of_k = 0
59 goto 001
60endif
61if(allocated(sik)) deallocate(sik)
62allocate(sik(nsp), stat=err)
63if (err .ne. 0) then
64 call show_error ("Impossible to allocate memory"//char(0), &
65 "Function: s_of_k"//char(0), "Table: sik"//char(0))
66 s_of_k = 0
67 goto 001
68endif
69
70#ifdef OPENMP
71 !t0 = OMP_GET_WTIME ()
72 call fourier_trans_qvect () ! Default Q-vector parallelization
73 !t1 = OMP_GET_WTIME ()
74 !write (*,*) "temps d’excecution QVT 2:", t1-t0
75#else
76 call fourier_trans_steps ()
77#endif
78
79if (allocated(cij)) deallocate(cij)
80if (allocated(sik)) deallocate(sik)
81if (allocated(qvectx)) deallocate(qvectx)
82if (allocated(qvecty))deallocate(qvecty)
83if (allocated(qvectz)) deallocate(qvectz)
84if (allocated(modq)) deallocate(modq)
85
86if(allocated(s)) deallocate(s)
87allocate(s(nq), stat=err)
88if (err .ne. 0) then
89 call show_error ("Impossible to allocate memory"//char(0), &
90 "Function: s_of_k"//char(0), "Table: S"//char(0))
91 s_of_k = 0
92 goto 001
93endif
94if(allocated(xs)) deallocate(xs)
95allocate(xs(nq), stat=err)
96if (err .ne. 0) then
97 call show_error ("Impossible to allocate memory"//char(0), &
98 "Function: s_of_k"//char(0), "Table: XS"//char(0))
99 s_of_k = 0
100 goto 001
101endif
102
103factor=0.0d0
104do i=1, nsp
105 factor=factor + nbspbs(i)*nscattl(i)**2
106enddo
107factor=factor*ns
108
109if (xa .eq. 1) then
110 xfactor=0.0d0
111 do i=1, nsp
112 xfactor=xfactor + nbspbs(i)*xscattl(i)**2
113 enddo
114 xfactor=xfactor*ns
115endif
116
117s(:)=0.0d0
118xs(:)=0.0d0
119
120do i=1, nq
121 if (degeneracy(i) .gt. 0) then
122 do k=1, nsp
123 do j=1, nsp
124 s(i)=s(i)+sij(i,k,j)*nscattl(k)*nscattl(j)
125 if (xa .eq. 1) then
126 xs(i)=xs(i)+sij(i,k,j)*xscattl(k)*xscattl(j)
127 else
128 xs(i)=xs(i)+sij(i,k,j)*fqx(int(xscattl(k)),k_point(i))*fqx(int(xscattl(j)),k_point(i))
129 endif
130 enddo
131 enddo
132 s(i)=s(i)/(factor*degeneracy(i))
133 if (xa .eq. 1) then
134 xs(i)=xs(i)/(xfactor*degeneracy(i))
135 else
136 xfactor=0.0d0
137 do k=1, nsp
138 xfactor=xfactor + nbspbs(k)*fqx(int(xscattl(k)),k_point(i))**2
139 enddo
140 xs(i)=xs(i)/(xfactor*degeneracy(i)*ns)
141 endif
142 do j=1, nsp
143 do k=1, nsp
144 sij(i,j,k)=sij(i,j,k)/(degeneracy(i)*sqrt(dble(nbspbs(k)*nbspbs(j)))*ns)
145 enddo
146 enddo
147 endif
148enddo
149
150s_of_k = sk_save()
151
152001 continue
153
154if (allocated(degeneracy)) deallocate(degeneracy)
155if (allocated(k_point)) deallocate(k_point)
156if (allocated(sij)) deallocate(sij)
157if (allocated(s)) deallocate(s)
158if (allocated(xs)) deallocate(xs)
159
160CONTAINS
161
162!************************************************************
163!
164! this subroutine computes the sine and cosine sums from the
165! configuration for all q-vectors needed
166!
167SUBROUTINE fourier_trans_steps ()
168
169 USE parameters
170
171 IMPLICIT NONE
172 DOUBLE PRECISION :: qx, qy, qz, qtr, sini, cosi
173 INTEGER :: sp
174
175 do k=1, ns
176 do j=1, number_of_qvect
177
178 l=anint((modq(j)-qvmin)/delta_q)+1
179
180 if (l .le. nq) then
181
182 qx=qvectx(j)
183 qy=qvecty(j)
184 qz=qvectz(j)
185
186 do i=1, nsp
187 cij(i)=0.d0
188 sik(i)=0.d0
189 enddo
190
191 do i=1, na
192 qtr = qx*fullpos(i,1,k)+qy*fullpos(i,2,k)+qz*fullpos(i,3,k)
193 sini = sin(qtr)
194 cosi = cos(qtr)
195 sp = lot(i)
196 sik(sp) = sik(sp) + sini
197 cij(sp) = cij(sp) + cosi
198 enddo
199
200 do i=1, nsp
201 do m=1, nsp
202 sij(l,i,m) = sij(l,i,m) + cij(i)*cij(m) + sik(i)*sik(m)
203 enddo
204 enddo
205
206 endif
207 enddo
208 enddo
209
210END SUBROUTINE
211
212#ifdef OPENMP
213!************************************************************
214!
215! This subroutine computes the sine and cosine sums from the
216! configuration for all q-vectors needed
217! OpenMP // on Qvect
218!
219SUBROUTINE fourier_trans_qvect ()
220
221 USE parameters
222
223 !$ USE OMP_LIB
224 IMPLICIT NONE
225
226 INTEGER :: numth, sp
227 DOUBLE PRECISION :: qx, qy, qz, qtr, sini, cosi
228
229 numth = omp_get_max_threads()
230 if (number_of_qvect.lt.numth) numth=number_of_qvect
231 ! OpemMP on Qvect
232 !$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
233 !$OMP& PRIVATE(qx, qy, qz, cij, sik, qtr, sini, cosi, i, j, k, l, m, sp) &
234 !$OMP& SHARED(NUMTH, qvectx, qvecty, qvectz, &
235 !$OMP& FULLPOS, NS, NSP, NA, LOT, DELTA_Q, NUMBER_OF_QVECT, NQ, modq, qvmin, Sij)
236 !$OMP DO SCHEDULE(STATIC,NUMBER_OF_QVECT/NUMTH)
237 do j=1, number_of_qvect
238
239 l=anint((modq(j)-qvmin)/delta_q)+1
240 if (l .le. nq) then
241
242 qx=qvectx(j)
243 qy=qvecty(j)
244 qz=qvectz(j)
245
246 do k=1, ns
247
248 do i=1, nsp
249 cij(i)=0.d0
250 sik(i)=0.d0
251 enddo
252
253 do i=1, na
254 qtr = qx*fullpos(i,1,k)+qy*fullpos(i,2,k)+qz*fullpos(i,3,k)
255 sini = sin(qtr)
256 cosi = cos(qtr)
257 sp = lot(i)
258 sik(sp) = sik(sp) + sini
259 cij(sp) = cij(sp) + cosi
260 enddo
261
262 do i=1, nsp
263 do m=1, nsp
264 !$OMP ATOMIC
265 sij(l,i,m) = sij(l,i,m) + cij(i)*cij(m) + sik(i)*sik(m)
266 enddo
267 enddo
268
269 enddo
270
271 endif
272
273 enddo
274
275 !$OMP END DO NOWAIT
276 !$OMP END PARALLEL
277
278END SUBROUTINE
279#endif
280
281INTEGER FUNCTION sk_save()
282
283USE parameters
284
285INTEGER :: nsq
286DOUBLE PRECISION, DIMENSION (:), ALLOCATABLE :: sqtab
287
288INTERFACE
289 LOGICAL FUNCTION fzbt (NDQ, SQIJ)
290 USE parameters
291 INTEGER, INTENT(IN) :: ndq
292 DOUBLE PRECISION, DIMENSION(NDQ,NSP,NSP), INTENT(IN) :: sqij
293 END FUNCTION
294END INTERFACE
295
296i=0
297do j=1, nq
298 if (degeneracy(j) .gt. 0) i=i+1
299enddo
300nsq=i
301
302if (nsq .gt. 0) then ! If wave vectors exist
303
304 if (allocated(sqtab)) deallocate(sqtab)
305 allocate(sqtab(nsq), stat=err)
306 if (err .ne. 0) then
307 call show_error ("Impossible to allocate memory"//char(0), &
308 "Function: SK_SAVE"//char(0), "Table: SQTAB"//char(0))
309 sk_save = 0
310 goto 001
311 endif
312
313 i = 0;
314 do k=1, nq
315 if (degeneracy(k).gt.0) then
316 i=i+1
317 sqtab(i)= k_point(k)
318 endif
319 enddo
320 call save_xsk (nsq, sqtab)
321
322 i=0
323 do k=1, nq
324 if (degeneracy(k).gt.0) then
325 i=i+1
326 sqtab(i)= s(k)
327 endif
328 enddo
329 call save_curve (nsq, sqtab, 0, idsk)
330
331 i=0
332 do k=1, nq
333 if (degeneracy(k).gt.0) then
334 i=i+1
335 sqtab(i)= (s(k)-1.0)*k_point(k)
336 endif
337 enddo
338 call save_curve (nsq, sqtab, 2, idsk)
339
340 i=0
341 do k=1, nq
342 if (degeneracy(k).gt.0) then
343 i=i+1
344 sqtab(i)= xs(k)
345 endif
346 enddo
347 call save_curve (nsq, sqtab, 4, idsk)
348
349 i=0
350 do k=1, nq
351 if (degeneracy(k).gt.0) then
352 i=i+1
353 sqtab(i)= (xs(k)-1.0)*k_point(k)
354 endif
355 enddo
356 call save_curve (nsq, sqtab, 6, idsk)
357
358 l = 8
359 do i=1, nsp
360 do j=1, nsp
361 m=0
362 do k=1, nq
363 if (degeneracy(k).gt.0) then
364 m=m+1
365 sqtab(m)=sij(k,i,j)
366 endif
367 enddo
368 call save_curve (nsq, sqtab, l, idsk)
369 l=l+2
370 enddo
371 enddo
372
373 ! To compute FZ and BT partials
374 if (.not.fzbt(nq, sij)) then
375 sk_save = 0
376 goto 001
377 endif
378
379 do i=1, nsp
380 do j=1, nsp
381 m=0
382 do k=1, nq
383 if (degeneracy(k).gt.0) then
384 m=m+1
385 sqtab(m)= fzsij(k,i,j)
386 endif
387 enddo
388 call save_curve (nsq, sqtab, l, idsk)
389 l=l+2
390 enddo
391 enddo
392 if (nsp .eq. 2) then
393 do i=1, 4
394 k=0
395 do j=1, nq
396 if (degeneracy(j).gt.0) then
397 k=k+1
398 sqtab(k)= btij(j,i)
399 endif
400 enddo
401 call save_curve (nsq, sqtab, l, idsk)
402 l=l+2
403 enddo
404 endif
405
406 sk_save=1
407
408endif ! If wave vectors exist
409
410001 continue
411
412if (allocated(fzsij)) deallocate(fzsij)
413if (nsp.eq.2 .and. allocated(btij)) deallocate(btij)
414if (allocated(sqtab)) deallocate(sqtab)
415
416END FUNCTION
417
418END FUNCTION s_of_k
419
420INTEGER (KIND=c_int) FUNCTION smooth_and_save (DPOINT, CTS, SFC, IDC, NQPTS, DATS) bind (C,NAME='smooth_and_save_')
421
422USE parameters
423
424IMPLICIT NONE
425
426INTEGER (KIND=c_int), INTENT(IN) :: idc, nqpts, dats
427real(kind=c_double), DIMENSION(NQPTS), INTENT(IN) :: dpoint, cts
428real(kind=c_double), INTENT(IN) :: sfc
429DOUBLE PRECISION, DIMENSION (:), ALLOCATABLE :: sqtab
430
431INTERFACE
432 LOGICAL FUNCTION smooth (TABTOLISS, GTOLISS, DIMTOLISS, SIGMALISS)
433 INTEGER, INTENT(IN) :: dimtoliss
434 DOUBLE PRECISION, INTENT(IN) :: sigmaliss
435 DOUBLE PRECISION, INTENT(IN), DIMENSION(DIMTOLISS) :: gtoliss
436 DOUBLE PRECISION, INTENT(INOUT), DIMENSION(DIMTOLISS) :: tabtoliss
437 END FUNCTION
438END INTERFACE
439
440if (allocated(sqtab)) deallocate(sqtab)
441
442allocate(sqtab(nqpts), stat=err)
443if (err .ne. 0) then
444 call show_error ("Impossible to allocate memory"//char(0), &
445 "Function: smooth_and_save"//char(0), "Table: SQTAB"//char(0))
447 goto 001
448endif
449
450do k=1, nqpts
451 sqtab(k)=cts(k)
452enddo
453
454if (.not.smooth(sqtab, dpoint, nqpts, sfc)) then
456 goto 001
457endif
458
459call save_curve (nqpts, sqtab, idc, dats)
460
462
463001 continue
464
465if (allocated(sqtab)) deallocate(sqtab)
466
467END FUNCTION
468
469DOUBLE PRECISION FUNCTION fqx(TA, Q)
470
471USE mendeleiev
472
473INTEGER, INTENT(IN) :: ta
474DOUBLE PRECISION, INTENT(IN) :: q
475DOUBLE PRECISION :: sinla
476DOUBLE PRECISION, PARAMETER :: pi=acos(-1.0)
477!
478! Acta Cryst. (1968). A24, 321
479!
480! SINLA = ((sin(THETA)/LAMBDA)**2
481! and 2 d Sin(THETA) = LAMBDA
482! so 2 d = LAMBDA / Sin(THETA)
483! with d = 2 PI / Q we get:
484! 4.0 PI / Q = LAMBDA / Sin(THETA)
485sinla=(q/(4.0*pi))**2
486
487fqx = a1(ta)*exp(-b1(ta)*sinla) &
488 + a2(ta)*exp(-b2(ta)*sinla) &
489 + a3(ta)*exp(-b3(ta)*sinla) &
490 + a4(ta)*exp(-b4(ta)*sinla) + c(ta)
491
492END 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, dimension(98), parameter a3
double precision, dimension(98), parameter c
double precision, dimension(98), parameter a2
double precision, dimension(98), parameter b1
double precision, dimension(98), parameter b3
double precision, dimension(98), parameter a1
double precision, dimension(98), parameter b4
double precision, dimension(98), parameter b2
double precision, dimension(98), parameter a4
double precision, dimension(:,:,:), allocatable fullpos
double precision qvmin
double precision, dimension(:), allocatable qvectx
double precision, dimension(:), allocatable nscattl
integer number_of_qvect
double precision, dimension(:), allocatable qvecty
double precision delta_q
double precision, dimension(:), allocatable cij
double precision, dimension(:), allocatable k_point
integer, dimension(:), allocatable nbspbs
double precision, dimension(:), allocatable s
integer, dimension(:), allocatable degeneracy
double precision, dimension(:), allocatable xs
integer err
double precision, dimension(:), allocatable modq
double precision, dimension(:), allocatable xscattl
double precision, dimension(:), allocatable qvectz
integer, dimension(:), allocatable lot
integer nsp
double precision, dimension(:,:,:), allocatable sij
double precision, dimension(:), allocatable sik
double precision function fqx(ta, q)
Definition sk.F90:470
integer(kind=c_int) function s_of_k(nq, xa)
Definition sk.F90:22
integer(kind=c_int) function smooth_and_save(dpoint, cts, sfc, idc, nqpts, dats)
Definition sk.F90:421
logical function smooth(tabtoliss, gtoliss, dimtoliss, sigmaliss)
Definition utils.F90:612