Branch data Line data Source code
1 : : !!****m* ABINIT/m_fold2block
2 : : !! NAME
3 : : !! m_fold2block
4 : : !!
5 : : !! FUNCTION
6 : : !! This module contains basic tools to operate on vectors expressed in reduced coordinates.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (AB)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : MODULE m_fold2block
23 : :
24 : : use defs_basis
25 : : use m_abicore
26 : : use m_errors
27 : :
28 : : implicit none
29 : :
30 : : public
31 : : !private
32 : :
33 : : CONTAINS !===========================================================
34 : : !!***
35 : :
36 : : !----------------------------------------------------------------------
37 : :
38 : : !!****f* m_fold2block/SortC
39 : : !! NAME
40 : : !! SortC
41 : : !!
42 : : !! FUNCTION
43 : : !! Part of fold2Bloch that unfolds the wavefunction and calculates
44 : : !! the weight of each band.
45 : : !!
46 : : !! INPUTS
47 : : !! FX, FY, FZ= Number of folds in each dimention
48 : : !! vector= Array of energy coefficient position vectors
49 : : !! coefc= Array of energy coefficients of in a certain band
50 : : !! NV= Number of vectors/coefficients
51 : : !!
52 : : !! OUTPUT
53 : : !! wegihts= Calculated weights of a band in an unfolded state.
54 : : !! Depends on the number of folds the WFK file was structured with.
55 : : !!
56 : : !! SOURCE
57 : :
58 : :
59 : 168 : subroutine SortC(FX, FY, FZ, Vector, CoefC, NV, Weights)
60 : :
61 : : !Arguments ------------------------------------
62 : : !scalars
63 : : integer, intent(in) :: FX, FY, FZ, NV
64 : : !arrays
65 : : integer, intent(in) :: Vector(3,NV)
66 : : real(dp), intent(in) :: CoefC(2,NV)
67 : : real(dp), intent(inout) :: Weights(FX*FY*FZ)
68 : :
69 : : !Local variables-------------------------------
70 : : !scalars
71 : : real :: sumtot
72 : : integer :: remainder_x, remainder_y, remainder_z, jj, kk, ll, pp, el
73 : : !arrays
74 : 168 : real(dp), allocatable :: Sums(:)
75 : 168 : real(dp), allocatable :: coefsqr(:),TGroupC(:,:,:,:)
76 : 168 : integer, allocatable :: counter(:,:,:)
77 : :
78 : : ! *************************************************************************
79 : :
80 [ - + + - : 1008 : ABI_MALLOC(TGroupC,(FX, FY, FZ, NV))
- + + - -
+ + - - +
+ - + - +
- - + -
+ ]
81 [ - + + - : 504 : ABI_MALLOC(Sums,(FX*FY*FZ))
+ - + - -
+ - + ]
82 [ - + + - : 840 : ABI_MALLOC(counter,(FX,FY,FZ))
- + + - -
+ + - + -
+ - - + -
+ ]
83 [ - + + - : 504 : ABI_MALLOC(coefsqr,(NV))
+ - + - -
+ + - ]
84 : :
85 : : !Convert to sum of squares
86 [ + + ]: 108100 : do jj=1, NV
87 : 108100 : coefsqr(jj)=coefc(1,jj)*coefc(1,jj)+coefc(2,jj)*coefc(2,jj)
88 : : end do
89 : :
90 : : !Initiates the counter and TGroupC elements at 0
91 [ + + ]: 336 : do jj=1,FX
92 [ + + ]: 672 : do kk=1,FY
93 [ + + ]: 1512 : do ll=1,FZ
94 : 1008 : counter(jj,kk,ll)=0
95 [ + + ]: 648936 : do pp=1,NV
96 : 648600 : TGroupC(jj,kk,ll,pp)=0.0
97 : : end do
98 : : end do
99 : : end do
100 : : end do
101 : :
102 : : !Sorts the energy coeeficients
103 [ + + ]: 108100 : do jj=1, (NV)
104 : 107932 : remainder_x=MODULO(Vector(1,jj), FX)
105 : 107932 : remainder_y=MODULO(Vector(2,jj), FY)
106 : 107932 : remainder_z=MODULO(Vector(3,jj), FZ)
107 : 107932 : counter(remainder_x+1, remainder_y+1, remainder_z+1)=counter(remainder_x+1, remainder_y+1, remainder_z+1)+1
108 : 108100 : TGroupC(remainder_x+1, remainder_y+1, remainder_z+1, counter(remainder_x+1, remainder_y+1, remainder_z+1))=Coefsqr(jj)
109 : : end do
110 : :
111 : : !Sums the squares of all coefficients per group
112 : : el=1
113 [ + + ]: 336 : do jj=1, FX
114 [ + + ]: 672 : do kk=1, FY
115 [ + + ]: 1512 : do ll=1, FZ
116 [ + - ]: 1344 : if (counter(jj, kk, ll)>0) then
117 [ + + ]: 108940 : Sums(el)=SUM(TGroupC(jj, kk, ll,1:counter(jj, kk, ll)))
118 : 1008 : el=el+1
119 : : else
120 : 0 : Sums(el)=0.0
121 : 0 : el=el+1
122 : : end if
123 : : end do
124 : : end do
125 : : end do
126 : :
127 : : !Assign weights to an array
128 [ + + ]: 1176 : sumtot=SUM(Sums)
129 [ + + ]: 1176 : do jj=1, (FX*FY*FZ)
130 : 1176 : Weights(jj)=Sums(jj)/sumtot
131 : : end do
132 [ - + ]: 168 : ABI_FREE(TGroupC)
133 [ - + ]: 168 : ABI_FREE(Sums)
134 [ - + ]: 168 : ABI_FREE(counter)
135 [ - + ]: 168 : ABI_FREE(coefsqr)
136 : :
137 : 168 : end subroutine SortC
138 : : !!***
139 : :
140 : : !!****f* m_fold2block/NewK
141 : : !! NAME
142 : : !! NewK
143 : : !!
144 : : !! FUNCTION
145 : : !! Part of fold2Bloch that determines the unfolded
146 : : !! positions of each K point.
147 : : !!
148 : : !! INPUTS
149 : : !! FX, FY, FZ= Number of folds in each dimention
150 : : !! XX, YY, ZZ= Original K point coordinates
151 : : !!
152 : : !! OUTPUT
153 : : !! nkval= Array of determined coordinates of unfolded K point locaations.
154 : : !! Depends on the number of folds the WFK file was structured with.
155 : : !!
156 : : !! SOURCE
157 : :
158 : 42 : subroutine NewK(XX, YY, ZZ, FX, FY, FZ, NKVal)
159 : :
160 : : !Arguments ------------------------------------
161 : : !scalars
162 : : integer, intent(in) :: FX, FY, FZ
163 : : real(dp), intent(in) :: XX, YY, ZZ
164 : : real(dp), intent(inout) :: NKVal (3,FX*FY*FZ)
165 : : !arrays
166 : :
167 : : !Local variables-------------------------------
168 : : !scalars
169 : : real(dp) :: field_x, field_y, field_z
170 : : real(dp) :: TX, TY, TZ
171 : : integer :: loop, ii, jj, kk, size
172 : : !arrays
173 : :
174 : : ! *************************************************************************
175 : :
176 : 42 : size=FX*FY*FZ
177 : :
178 : : !Brillouin zone range
179 : 42 : field_x=0.5*FX
180 : 42 : field_y=0.5*FY
181 : 42 : field_z=0.5*FZ
182 : 42 : loop=1
183 : :
184 : : !Determine new K point states
185 [ + + ]: 84 : do ii=0, (FX-1)
186 [ - + ]: 42 : if ((XX+ii)>(field_x)) then !if falls outside of field, loop it around
187 : 0 : TX=XX-(field_x*2)+ii
188 : : else
189 : : TX=XX+ii
190 : : end if
191 [ + + ]: 168 : do jj=0, (FY-1)
192 [ + + ]: 84 : if ((YY+jj)>(field_y)) then
193 : 10 : TY=YY-(field_y*2)+jj
194 : : else
195 : : TY=YY+jj
196 : : end if
197 [ + + ]: 378 : do kk=0,(FZ-1)
198 [ + + ]: 252 : if ((ZZ+kk)>(field_z)) then
199 : 82 : TZ=ZZ-(field_z*2)+kk
200 : : else
201 : : TZ=ZZ+kk
202 : : end if
203 : 252 : NKVal(1,loop)=TX !Assign to an output array
204 : 252 : NKVal(2,loop)=TY
205 : 252 : NKVal(3,loop)=TZ
206 : 336 : loop=loop+1
207 : : end do
208 : : end do
209 : : end do
210 : :
211 : : !reduce the values to fit in Brillouin zone
212 [ + + ]: 294 : do ii=1, FX*FY*FZ
213 : 252 : nkval(1,ii)=nkval(1,ii)/FX
214 : 252 : nkval(2,ii)=nkval(2,ii)/FY
215 : 294 : nkval(3,ii)=nkval(3,ii)/FZ
216 : : end do
217 : :
218 : 42 : END SUBROUTINE NewK
219 : : !!***
220 : :
221 : : !!****f* m_fold2block/getargs
222 : : !! NAME
223 : : !! getargs
224 : : !!
225 : : !! FUNCTION
226 : : !! Part of fold2Bloch that interprets the command line
227 : : !! arguments and checks for their corectness.
228 : : !!
229 : : !! INPUTS
230 : : !! fname: Name of input file
231 : : !! folds: Number of folds in x, y, and z directions.
232 : : !!
233 : : !! OUTPUT
234 : : !! folds: Number of folds in x, y, and z directions.
235 : : !! Returns the folds array filled with each element.
236 : : !!
237 : : !! SOURCE
238 : :
239 : 0 : subroutine getargs(folds, fname)
240 : :
241 : : !Arguments ------------------------------------
242 : : !scalars
243 : : character(len=fnlen), intent(inout) :: fname
244 : : !arrays
245 : : integer, intent(inout) :: folds(3)
246 : :
247 : : !Local variables-------------------------------
248 : : !scalars
249 : : integer :: num_args, argcount, ii, ios
250 : : character(len=fnlen) :: argfolds
251 : : logical :: dir
252 : : !arrays
253 : 0 : character(len=fnlen), allocatable :: args(:)
254 : :
255 : : ! *************************************************************************
256 : :
257 : : !get number of args
258 : 0 : num_args=command_argument_count()
259 [ # # # # : 0 : ABI_MALLOC(args,(num_args))
# # # # #
# # # ]
260 : :
261 : : !Check for errors in arguments
262 [ # # ]: 0 : if (num_args>2) then
263 : 0 : write(std_out,*) " Too many arguments."
264 : 0 : write(std_out,*) " Usage: $fold2Bloch file_WFK x:y:z (folds)"
265 : 0 : ABI_ERROR("Aborting now")
266 [ # # ]: 0 : elseif (num_args<2) then
267 [ # # ]: 0 : if (num_args==1) then
268 : 0 : call get_command_argument(1,args(1))
269 [ # # # # ]: 0 : if ((args(1)=="-h").or.(args(1)=="--help")) then
270 : 0 : write(std_out,*) " Usage: fold2Bloch file_WFK x:y:z (folds)"
271 : 0 : write(std_out,*) " file_WFK is the WFK file name (ex. Ex_WFK)"
272 : 0 : write(std_out,*) " x:y:z integers, greater than 0 that represent a multiplicity"
273 : 0 : write(std_out,*) " in the corresponding directions used when constructing the supercell."
274 : 0 : ABI_ERROR("Aborting now")
275 : : else
276 : 0 : write(std_out,*) " Not all arguments are present."
277 : 0 : write(std_out,*) " Make sure that file name and number of folds are indicated."
278 : 0 : write(std_out,*) " Usage: $fold2Bloch file_WFK x:y:z (folds)"
279 : 0 : ABI_ERROR("Aborting now")
280 : : end if
281 : : else
282 : 0 : write(std_out,*) " Not all arguments are present."
283 : 0 : write(std_out,*) " Make sure that file name and number of folds are indicated."
284 : 0 : write(std_out,*) " Usage: $fold2Bloch file_WFK x:y:z (folds)"
285 : 0 : ABI_ERROR("Aborting now")
286 : : end if
287 : : else
288 [ # # ]: 0 : do argcount=1, num_args
289 : 0 : call get_command_argument(argcount,args(argcount))
290 [ # # ]: 0 : if (argcount==1) then
291 : 0 : read(args(argcount), "(a)") fname !read first argument
292 : : else
293 : 0 : read(args(argcount), "(a)") argfolds !read second argument
294 : : end if
295 : : end do
296 : : end if
297 : :
298 : : ! Does intput file exist?
299 : 0 : inquire(file=fname, exist=dir)
300 [ # # ]: 0 : if (.not.(dir)) then
301 : 0 : write(std_out,*) " Case file not found: ", trim(fname)
302 : 0 : write(std_out,*) " Usage: $fold2Bloch file_WFK x:y:z (folds)"
303 : 0 : ABI_ERROR("Aborting now")
304 : : end if
305 : :
306 : : !Was the number of folds entered in correct format?
307 : 0 : ii=0
308 : 0 : ii=INDEX(argfolds, ':') !look for first ":" to differentiate between axis
309 [ # # ]: 0 : if (ii==0) then
310 : 0 : write(std_out,*) " Unknown number of folds. See below or type:"
311 : 0 : write(std_out,*) " fold2Bloch <-h> or fold2Bloch <--help> for more information."
312 : 0 : write(std_out,*) ' Usage: $fold2Bloch file_WFK x:y:z (folds)'
313 : 0 : ABI_ERROR("Aborting now")
314 : : end if
315 : 0 : read (argfolds(1:ii-1), *, iostat=ios) folds(1) !read X folds
316 [ # # # # ]: 0 : if ((ios/=0).or.(folds(1)<=0)) then
317 : 0 : ABI_ERROR('Number of folds has to be a positive integer greater than 0')
318 : : end if
319 [ # # ]: 0 : argfolds=argfolds(ii+1:) !Start argfolds from the first ":"
320 : 0 : ii=0
321 : 0 : ii=INDEX(argfolds, ':') !look for second ":"
322 [ # # ]: 0 : if (ii==0) then
323 : 0 : write(std_out,*) ' Unknown number of folds. See below or type:'
324 : 0 : write(std_out,*) " fold2Bloch <-h> or fold2Bloch <--help> for more information."
325 : 0 : write(std_out,*) ' Usage: $fold2Bloch file_WFK x:y:z (folds)'
326 : 0 : ABI_ERROR("Aborting now")
327 : : end if
328 : 0 : read (argfolds(1:ii-1),*, iostat=ios) folds(2) !read Y folds
329 [ # # # # ]: 0 : if ((ios/=0).or.(folds(2)<=0)) then
330 : 0 : ABI_ERROR('Number of folds has to be a positive integer greater than 0')
331 : : end if
332 : 0 : read(argfolds(ii+1:),*, iostat=ios) Folds(3) !read Z folds
333 [ # # # # ]: 0 : if ((ios/=0).or.(folds(3)<=0)) then
334 : 0 : ABI_ERROR('Number of folds has to be a positive integer greater than 0')
335 : : end if
336 : :
337 [ # # ]: 0 : ABI_FREE(args)
338 : :
339 : 0 : end subroutine getargs
340 : : !!***
341 : :
342 : : !!****f* m_fold2block/progress
343 : : !! NAME
344 : : !! progress
345 : : !!
346 : : !! FUNCTION
347 : : !! Part of fold2Bloch that unfolds the wavefunction and calculates
348 : : !! the weight of each band.
349 : : !!
350 : : !! INPUTS
351 : : !! ikpt: K point index
352 : : !! nkpt: Total number of K points in the function
353 : : !! kpt: Current K point being procesed.
354 : : !!
355 : : !! OUTPUT
356 : : !! Write to screen K point being processed and percent complete.
357 : : !!
358 : : !! SOURCE
359 : :
360 : 42 : subroutine progress(ikpt, nkpt, kpt)
361 : :
362 : : !Arguments ------------------------------------
363 : : !scalars
364 : : integer, intent(in) :: ikpt, nkpt
365 : : !arrays
366 : : real(dp), intent(in) :: kpt(3)
367 : : ! *************************************************************************
368 : :
369 : 42 : write(std_out, '(a,i10, a1)', advance='no') ''//achar(27)//'[97m',100*ikpt/nkpt,'%'//achar(27)//'[0m'
370 : 42 : write(std_out, '(a25,3f12.6,a)') ''//achar(27)//'[32m Processing K point: ', kpt,''//achar(27)//'[0m'
371 : :
372 : 42 : end subroutine progress
373 : : !!***
374 : :
375 : : end module m_fold2block
|