atomes 1.3.1
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
cqvf.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 cqvf.F90
18!! @short q vectors selection for the reciprocal calculation of the S(k)
19!! @author Sébastien Le Roux <sebastien.leroux@ipcms.unistra.fr>
20
21INTEGER (KIND=c_int) FUNCTION cqvf (QMAX, QMIN, NQ, PROBA, LIMQ) bind (C,NAME='cqvf_')
22
23!
24! Determines the q-vectors for which the q-dependent
25! correlation functions are computed - general cell
26!
27
28 USE parameters
29
30 IMPLICIT NONE
31
32 INTEGER (KIND=c_int), INTENT(IN) :: nq
33 REAL (kind=c_double), INTENT(IN) :: proba, limq
34 REAL (kind=c_double), INTENT(IN) :: qmax, qmin
35
36 LOGICAL :: kpts, keepkpts
37 INTEGER :: hkl, q_index, seed
38 INTEGER :: klow, llow
39 INTEGER, DIMENSION(3) :: nkpts
40 DOUBLE PRECISION, DIMENSION(3) :: qmrecip
41 DOUBLE PRECISION :: qmax2, qmin2, limq2
42 DOUBLE PRECISION :: kpx, kpy, kpz, keep
43
44 INTERFACE
45 DOUBLE PRECISION FUNCTION ran3 (idnum)
46 INTEGER, INTENT(IN) :: idnum
47 END FUNCTION
48 END INTERFACE
49
50 qmrecip(:) = 0.0d0
51 do i=1, ncells
52 do j=1, 3
53 qmrecip(j) = qmrecip(j)+the_box(i)%modr(j)
54 enddo
55 enddo
56 qmrecip(:) = qmrecip(:)/ncells
57 do i=1, 3
58 nkpts(i) = anint(qmax/qmrecip(i))+1
59 enddo
60 hkl=0
61! To simplify the case of the calculation in the case of a simple cubic box
62 if (overall_cubic) then
63 qmax2=(qmax/qmin)**2
64 qmin2=1.0d0
65 limq2=(limq/qmin)**2
66 else
67 qmax2=qmax**2 ! mod(q_max)**2
68 limq2=limq**2
69 qmin2=qmin**2 ! min module of the reciprocal lattice vectors - lattice.f90
70 endif
71 q_index=0
72 qvmax=0.0d0
73 qvmin=50.0d0
74
75do i=1, 2
76
77! The first iteration to evaluate the number of k-points
78! to be saved for the analysis, and the second to store them.
79
80 if (i .eq. 2) then
81
82 number_of_qmod=q_index
83 if (allocated(qvectx)) deallocate(qvectx)
84 allocate(qvectx(number_of_qmod), stat=err)
85 if (err .ne. 0) then
86 call show_error ("Impossible to allocate memory"//char(0), &
87 "Function: COMP_Q_VAL_FULL"//char(0), "Table: qvectx"//char(0))
88 cqvf=0
89 goto 001
90 endif
91 if (allocated(qvecty)) deallocate(qvecty)
92 allocate(qvecty(number_of_qmod), stat=err)
93 if (err .ne. 0) then
94 call show_error ("Impossible to allocate memory"//char(0), &
95 "Function: COMP_Q_VAL_FULL"//char(0), "Table: qvecty"//char(0))
96 cqvf=0
97 goto 001
98 endif
99 if (allocated(qvectz)) deallocate(qvectz)
100 allocate(qvectz(number_of_qmod), stat=err)
101 if (err .ne. 0) then
102 call show_error ("Impossible to allocate memory"//char(0), &
103 "Function: COMP_Q_VAL_FULL"//char(0), "Table: qvectz"//char(0))
104 cqvf=0
105 goto 001
106 endif
107 if (allocated(modq)) deallocate(modq)
108 allocate(modq(number_of_qmod), stat=err)
109 if (err .ne. 0) then
110 call show_error ("Impossible to allocate memory"//char(0), &
111 "Function: COMP_Q_VAL_FULL"//char(0), "Table: modq"//char(0))
112 cqvf=0
113 goto 001
114 endif
115 q_index=0
116
117 endif
118
119 do h=0, nkpts(1)
120
121 if (h .eq. 0) then
122 klow=0
123 else
124 klow=-nkpts(2)
125 endif
126
127 do k=klow, nkpts(2)
128
129 if (k.eq.0 .and. h.eq.0) then
130 llow=0
131 else
132 llow=-nkpts(3)
133 endif
134
135 do l=llow, nkpts(3)
136
137 if (overall_cubic) then
138 kpx= h
139 kpy= k
140 kpz= l
141 else
142 ! Note : because we only consider the first step this is an approximation in the case of NPT trajectory
143 kpx= 2.0d0*pi*(h*the_box(1)%lrecp(1,1) + k*the_box(1)%lrecp(2,1) + l*the_box(1)%lrecp(3,1))
144 kpy= 2.0d0*pi*(h*the_box(1)%lrecp(1,2) + k*the_box(1)%lrecp(2,2) + l*the_box(1)%lrecp(3,2))
145 kpz= 2.0d0*pi*(h*the_box(1)%lrecp(1,3) + k*the_box(1)%lrecp(2,3) + l*the_box(1)%lrecp(3,3))
146 endif
147 qvmod= kpx**2 + kpy**2 + kpz**2
148
149! we want the maximum number of k-points in the FSDP part of the spectra
150! therefore we choose to keep all qvectors with qmod in:
151! minr < qmod < limq
152! where 'minr' is minimum q modulus accessible considering the analyzed
153! lattice ie. the minimum modulus of the reciprocal cell vectors,
154! 'limq' is the limit to be fixed for the FSDP part of the spectra
155! Thereafter: QMIN=minr**2 and LIMQ2=limq**2.
156! The qvectors with a 'qmod > limq' are accepted with a probability of 'PROBA'
157
158 if (qvmod .le. qmax2 .and. qvmod .ge. qmin2) then
159 kpts=.true.
160 else
161 kpts=.false.
162 endif
163 if (i .eq. 1 .and. kpts) then
164 q_index=q_index+2
165 elseif (i .eq. 2 .and. kpts) then
166 if (qvmod .le. limq2) then
167 keepkpts=.true.
168 else
169 seed=173932
170 keep = ran3(seed+h**3+k**2+l**5)
171 if (keep .le. proba) then
172 keepkpts=.true.
173 else
174 keepkpts=.false.
175 endif
176 endif
177 if (keepkpts) then
178 q_index=q_index+1
179 qvectx(q_index)=kpx
180 qvecty(q_index)=kpy
181 qvectz(q_index)=kpz
182 modq(q_index)=sqrt(qvmod)
183 qvmax=max(qvmax,modq(q_index))
184 qvmin=min(qvmin,modq(q_index))
185 if (h.ne.0 .or. k.ne.0 .or. l.ne.0) then
186 q_index=q_index+1
187 qvectx(q_index)=-kpx
188 qvecty(q_index)=-kpy
189 qvectz(q_index)=-kpz
190 modq(q_index)=sqrt(qvmod)
191 endif
192 endif
193 endif
194
195 enddo ! l
196
197 enddo ! k
198
199 enddo ! h
200
201enddo
202
203number_of_qvect=q_index
204
205! NQ is given in input
206! the value of each K_POINT is found in the
207! interval |qvmax - qvmin| and then we compute
208! the degeneracy of each K_POINT in q modulus.
209
210if (allocated(degeneracy)) deallocate(degeneracy)
211allocate(degeneracy(nq+1), stat=err)
212if (err .ne. 0) then
213 call show_error ("Impossible to allocate memory"//char(0), &
214 "Function: COMP_Q_VAL_FULL"//char(0), "Table: degeneracy"//char(0))
215 cqvf=0
216 goto 001
217endif
218degeneracy(:)=0
220
221do i=1, number_of_qvect
222 hkl=anint((modq(i)-qvmin)/delta_q)+1
223 degeneracy(hkl)=degeneracy(hkl)+1
224enddo
225
226if (allocated(k_point)) deallocate(k_point)
227allocate(k_point(nq), stat=err)
228if (err .ne. 0) then
229 call show_error ("Impossible to allocate memory"//char(0), &
230 "Function: COMP_Q_VAL_FULL"//char(0), "Table: K_POINT"//char(0))
231 cqvf=0
232 goto 001
233endif
234
235do i=1, nq
236 k_point(i)=(i-1.0)*delta_q+qvmin
237enddo
238
239if (overall_cubic) then
240 do i=1, number_of_qvect
241 qvectx(i)=qvectx(i)*qmin
242 qvecty(i)=qvecty(i)*qmin
243 qvectz(i)=qvectz(i)*qmin
244 enddo
245 do i=1, nq
246 k_point(i)=k_point(i)*qmin
247 enddo
248endif
249
250!do i=1, NQ
251! write (6, *) "i= ",i,", K_POINT(i)= ",K_POINT(i)
252!enddo
253
254cqvf=1
255
256001 continue
257
258END FUNCTION
integer(kind=c_int) function cqvf(qmax, qmin, nq, proba, limq)
Definition cqvf.F90:22
#define min(a, b)
Definition global.h:93
#define max(a, b)
Definition global.h:92
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:299
double precision qvmin
integer ncells
double precision qvmod
double precision, dimension(:), allocatable qvectx
integer number_of_qmod
integer number_of_qvect
double precision, dimension(:), allocatable qvecty
double precision delta_q
double precision, dimension(:), allocatable k_point
integer, dimension(:), allocatable degeneracy
integer err
double precision, dimension(:), allocatable modq
type(lattice), dimension(:), allocatable, target the_box
double precision, dimension(:), allocatable qvectz
logical overall_cubic
double precision qvmax
double precision, parameter pi
double precision function ran3(idnum)
Definition utils.F90:421