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