Branch data Line data Source code
1 : : !!****m* ABINIT/m_macroave
2 : : !! NAME
3 : : !! m_macroave
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 1997-2003 J.Soler, P. Ordejon, J. Junquera
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : module m_macroave
22 : :
23 : : implicit none
24 : :
25 : : ! private
26 : :
27 : : public :: POLINT
28 : : !!***
29 : :
30 : : contains
31 : : !!***
32 : :
33 : 0 : subroutine iorho( task, fname, cell, mesh, nsm, maxp, nspin, f, found )
34 : :
35 : : ! *********************************************************************
36 : : ! Saves/recovers the electron density at the mesh points.
37 : : ! This simplified version reads only files written in serial mode.
38 : :
39 : : ! Writen by J.Soler July 1997.
40 : : ! Copyright (C) 1997-2003 J.Soler, P. Ordejon, J. Junquera
41 : : ! This file is distributed under the terms of the
42 : : ! GNU General Public License, see ~abinit/COPYING
43 : : ! or http://www.gnu.org/copyleft/gpl.txt .
44 : :
45 : : ! *************************** INPUT **********************************
46 : : ! character*(*) task : 'read'/'READ' or 'write'/'WRITE'
47 : : ! character*(*) fname : File name for input or output
48 : : ! integer nsm : Number of sub-mesh points per mesh point
49 : : ! (not used in this version)
50 : : ! integer maxp : First dimension of array rho
51 : : ! integer nspin : Second dimension of array rho
52 : : ! ************************** OUTPUT **********************************
53 : : ! integer maxp : Required first dimension of array rho,
54 : : ! equal to mesh(1)*mesh(2)*mesh(3)
55 : : ! Set only when task='read' and required
56 : : ! value is larger than input value
57 : : ! integer nspin : Number of spin polarizations (1 or 2)
58 : : ! logical found : Were data found? (only when task='read')
59 : : ! ******************** INPUT or OUTPUT (depending on task) ***********
60 : : ! real*8 cell(3,3) : Lattice vectors
61 : : ! integer mesh(3) : Number of mesh divisions of each
62 : : ! lattice vector
63 : : ! real f(maxp,nspin) : Electron density
64 : : ! Notice single precision in this version
65 : : ! *************************** UNITS ***********************************
66 : : ! Units should be consistent between task='read' and 'write'
67 : : ! ******************** BEHAVIOUR **************************************
68 : : ! If task='read', and the values of maxp or nspin on input are less than
69 : : ! those required to copy the array f from the file, then the required
70 : : ! values of maxp and nspin are returned on output, but f is not read.
71 : : ! *********************************************************************
72 : :
73 : : ! Arguments
74 : : character*(*) fname, task
75 : : integer maxp, mesh(3), nspin, nsm
76 : : real f(maxp,nspin)
77 : : real(kind=kind(0.0d0)) cell(3,3)
78 : : logical found
79 : :
80 : : ! Internal variables and arrays
81 : : character(len=11) :: fform
82 : : integer i2, i3, ind, ip, is, np, ns
83 : :
84 : : if(.false.)write(11,*)nsm
85 : : if(.false.)write(11,*)task
86 : :
87 : : ! Fix whether formatted or unformatted files will be used
88 : 0 : fform = 'unformatted'
89 : :
90 : : ! Look for data file
91 : 0 : inquire( file=fname, exist=found )
92 [ # # ]: 0 : if (.not.found) return
93 : :
94 : : ! Read unit cell vectors, number of mesh points and spin components
95 : 0 : open( unit=1, file=fname, status='old', form=fform )
96 [ # # ]: 0 : if (fform == 'formatted') then
97 : 0 : read(1,*) cell
98 : 0 : read(1,*) mesh, ns
99 : : else
100 : 0 : read(1,*) cell
101 : 0 : read(1,*) mesh, ns
102 : : endif
103 : :
104 : : ! Read density (only if array f is large enough)
105 : 0 : np = mesh(1) * mesh(2) * mesh(3)
106 [ # # # # ]: 0 : if (ns>nspin .or. np>maxp) then
107 : 0 : maxp = np
108 : : else
109 [ # # ]: 0 : if (fform == 'formatted') then
110 : : ind = 0
111 [ # # ]: 0 : do is = 1,ns
112 [ # # ]: 0 : do i3 = 1,mesh(3)
113 [ # # ]: 0 : do i2 = 1,mesh(2)
114 [ # # # # ]: 0 : read(1,*) (f(ind+ip,is),ip=1,mesh(1))
115 : 0 : ind = ind + mesh(1)
116 : : enddo
117 : : enddo
118 : : enddo
119 : : else
120 : : ind = 0
121 [ # # ]: 0 : do is = 1,ns
122 [ # # ]: 0 : do i3 = 1,mesh(3)
123 [ # # ]: 0 : do i2 = 1,mesh(2)
124 [ # # # # ]: 0 : read(1) (f(ind+ip,is),ip=1,mesh(1))
125 : 0 : ind = ind + mesh(1)
126 : : enddo
127 : : enddo
128 : : enddo
129 : : endif
130 : : endif
131 : 0 : close(1)
132 : 0 : nspin = ns
133 : : end SUBROUTINE iorho
134 : : !!***
135 : :
136 : 4 : SUBROUTINE FOUR1(DATA,NN,ISIGN)
137 : : !**********************************************************************
138 : : ! Discrete Fourier transform.
139 : : !**********************************************************************
140 : : ! Input:
141 : : ! real*8 DATA(2*NN) : Function to be Fourier transformed
142 : : ! integer NN : Number of points. Must be a power of 2
143 : : ! integer ISIGN : ISIG=+1/-1 => Direct/inverse transform
144 : : ! Output:
145 : : ! real*8 DATA(2*NN) : Fourier transformed function
146 : : !**********************************************************************
147 : : INTEGER :: NN, ISIGN
148 : : real(kind=kind(0.0d0)) :: DATA(2*NN)
149 : :
150 : : INTEGER :: I, ISTEP, J, M, MMAX, N
151 : : real(kind=kind(0.0d0)) :: TEMPI, TEMPR, THETA, WI, WPI, WPR, WR, WTEMP
152 : : DOUBLE PRECISION, PARAMETER :: TWOPI=6.28318530717959D0,&
153 : : & HALF=0.5D0, ONE=1.D0, TWO=2.D0, ZERO=0.D0
154 : :
155 : 4 : N=2*NN
156 : 4 : J=1
157 : :
158 [ - + ]: 4 : DO I=1,N,2
159 [ + + ]: 16384 : IF(J>I)THEN
160 : 8064 : TEMPR=DATA(J)
161 : 8064 : TEMPI=DATA(J+1)
162 : 8064 : DATA(J)=DATA(I)
163 : 8064 : DATA(J+1)=DATA(I+1)
164 : 8064 : DATA(I)=TEMPR
165 : 8064 : DATA(I+1)=TEMPI
166 : : ENDIF
167 : 16384 : M=N/2
168 : 16380 : DO ! until following condition is met
169 [ + + ]: 32764 : IF ((M<2).OR.(J<=M)) EXIT
170 : 16380 : J=J-M
171 : 16380 : M=M/2
172 : : END DO
173 [ + + ]: 16384 : J=J+M
174 : : END DO ! I
175 : : MMAX=2
176 : : DO ! until following condition is met
177 [ + + ]: 52 : IF (N<=MMAX) EXIT
178 : 48 : ISTEP=2*MMAX
179 : 48 : THETA=TWOPI/(ISIGN*MMAX)
180 : 48 : WPR=(-TWO)*SIN(HALF*THETA)**2
181 : 48 : WPI=SIN(THETA)
182 : 48 : WR=ONE
183 : 48 : WI=ZERO
184 [ - + ]: 48 : DO M=1,MMAX,2
185 [ - + - - : 16380 : DO I=M,N,ISTEP
- + ]
186 : 98304 : J=I+MMAX
187 : 98304 : TEMPR=WR*DATA(J)-WI*DATA(J+1)
188 : 98304 : TEMPI=WR*DATA(J+1)+WI*DATA(J)
189 : 98304 : DATA(J)=DATA(I)-TEMPR
190 : 98304 : DATA(J+1)=DATA(I+1)-TEMPI
191 : 98304 : DATA(I)=DATA(I)+TEMPR
192 [ + + ]: 98304 : DATA(I+1)=DATA(I+1)+TEMPI
193 : : END DO ! I
194 : 16380 : WTEMP=WR
195 : 16380 : WR=WR*WPR-WI*WPI+WR
196 [ + + ]: 16380 : WI=WI*WPR+WTEMP*WPI+WI
197 : : END DO ! M
198 : 4 : MMAX=ISTEP
199 : : END DO ! until (N<=MMAX)
200 : :
201 : 4 : END SUBROUTINE FOUR1
202 : : !!***
203 : :
204 : 0 : SUBROUTINE POLINT(XA,YA,N,X,Y,DY)
205 : : !*****************************************************************
206 : : ! Polinomic interpolation.
207 : : ! D. Sanchez-Portal, Oct. 1996
208 : : !*****************************************************************
209 : : ! Input:
210 : : ! real*8 XA(N) : x values of the function y(x) to interpolate
211 : : ! real*8 YA(N) : y values of the function y(x) to interpolate
212 : : ! integer N : Number of data points
213 : : ! real*8 X : x value at which the interpolation is desired
214 : : ! Output:
215 : : ! real*8 Y : interpolated value of y(x) at X
216 : : ! real*8 DY : accuracy estimate
217 : : !*****************************************************************
218 : : INTEGER :: N
219 : : real(kind=kind(0.0d0)) :: XA(N),YA(N), X, Y, DY
220 : :
221 : : INTEGER :: I, M, NS
222 : 0 : real(kind=kind(0.0d0)) :: C(N), D(N), DEN, DIF, DIFT, HO, HP, W
223 : : DOUBLE PRECISION, PARAMETER :: ZERO=0.D0
224 : :
225 : 0 : NS=1
226 : 0 : DIF=ABS(X-XA(1))
227 [ # # ]: 0 : DO I=1,N
228 : 0 : DIFT=ABS(X-XA(I))
229 [ # # ]: 0 : IF (DIFT<DIF) THEN
230 : 0 : NS=I
231 : 0 : DIF=DIFT
232 : : ENDIF
233 : 0 : C(I)=YA(I)
234 : 0 : D(I)=YA(I)
235 : : END DO ! I
236 : 0 : Y=YA(NS)
237 : 0 : NS=NS-1
238 [ # # ]: 0 : DO M=1,N-1
239 [ # # ]: 0 : DO I=1,N-M
240 : 0 : HO=XA(I)-X
241 : 0 : HP=XA(I+M)-X
242 : 0 : W=C(I+1)-D(I)
243 : 0 : DEN=HO-HP
244 [ # # ]: 0 : IF (DEN==ZERO) STOP 'polint: ERROR. Two XAs are equal'
245 : 0 : DEN=W/DEN
246 : 0 : D(I)=HP*DEN
247 : 0 : C(I)=HO*DEN
248 : : END DO ! I
249 [ # # ]: 0 : IF (2*NS<N-M) THEN
250 : 0 : DY=C(NS+1)
251 : : ELSE
252 : 0 : DY=D(NS)
253 : 0 : NS=NS-1
254 : : ENDIF
255 : 0 : Y=Y+DY
256 : : END DO ! M
257 : :
258 : 0 : END SUBROUTINE POLINT
259 : :
260 : 3 : SUBROUTINE MACROAV_SPLINE(DX,Y,N,YP1,YPN,Y2)
261 : : !***********************************************************
262 : : ! Cubic Spline Interpolation.
263 : : ! D. Sanchez-Portal, Oct. 1996.
264 : : ! Input:
265 : : ! real*8 DX : x interval between data points
266 : : ! real*8 Y(N) : value of y(x) at data points
267 : : ! integer N : number of data points
268 : : ! real*8 YP1 : value of dy/dx at X1 (first point)
269 : : ! real*8 YPN : value of dy/dx at XN (last point)
270 : : ! Output:
271 : : ! real*8 Y2(N): array to be used by routine MACROAV_SPLINT
272 : : ! Behavior:
273 : : ! - If YP1 or YPN are larger than 1E30, the natural spline
274 : : ! condition (d2y/dx2=0) at the corresponding edge point.
275 : : !************************************************************
276 : : INTEGER :: N
277 : : real(kind=kind(0.0d0)) :: DX, Y(N), YP1, YPN, Y2(N)
278 : :
279 : : INTEGER :: I, K
280 : 6 : real(kind=kind(0.0d0)) :: QN, P, SIG, U(N), UN
281 : : DOUBLE PRECISION, PARAMETER :: YPMAX=0.99D30, &
282 : : & HALF=0.5D0, ONE=1.D0, THREE=3.D0, TWO=2.D0, ZERO=0.D0
283 : :
284 [ - + ]: 3 : IF (YP1>YPMAX) THEN
285 : 0 : Y2(1)=ZERO
286 : 0 : U(1)=ZERO
287 : : ELSE
288 : 3 : Y2(1)=-HALF
289 : 3 : U(1)=(THREE/DX)*((Y(2)-Y(1))/DX-YP1)
290 : : ENDIF
291 [ + + ]: 160 : DO I=2,N-1
292 : 157 : SIG=HALF
293 : 157 : P=SIG*Y2(I-1)+TWO
294 : 157 : Y2(I)=(SIG-ONE)/P
295 : : U(I)=(THREE*( Y(I+1)+Y(I-1)-TWO*Y(I) )/(DX*DX)&
296 : 160 : & -SIG*U(I-1))/P
297 : : END DO ! I
298 [ + - ]: 3 : IF (YPN>YPMAX) THEN
299 : : QN=ZERO
300 : : UN=ZERO
301 : : ELSE
302 : 3 : QN=HALF
303 : 3 : UN=(THREE/DX)*(YPN-(Y(N)-Y(N-1))/DX)
304 : : ENDIF
305 : 3 : Y2(N)=(UN-QN*U(N-1))/(QN*Y2(N-1)+ONE)
306 [ + + ]: 163 : DO K=N-1,1,-1
307 : 163 : Y2(K)=Y2(K)*Y2(K+1)+U(K)
308 : : END DO ! K
309 : :
310 : 3 : END SUBROUTINE MACROAV_SPLINE
311 : :
312 : :
313 : 12288 : SUBROUTINE MACROAV_SPLINT(DX,YA,Y2A,N,X,Y,DYDX)
314 : : !***************************************************************
315 : : ! Cubic Spline Interpolation.
316 : : ! D. Sanchez-Portal, Oct. 1996.
317 : : ! Input:
318 : : ! real*8 DX : x interval between data points
319 : : ! real*8 YA(N) : value of y(x) at data points
320 : : ! real*8 Y2A(N): array returned by routine MACROAV_SPLINE
321 : : ! integer N : number of data points
322 : : ! real*8 X : point at which interpolation is desired
323 : : ! real*8 Y : interpolated value of y(x) at point X
324 : : ! real*8 DYDX : interpolated value of dy/dx at point X
325 : : !***************************************************************
326 : : INTEGER :: N
327 : : real(kind=kind(0.0d0)) :: DX, YA(N), Y2A(N), X, Y, DYDX
328 : :
329 : : INTEGER :: NHI, NLO
330 : : real(kind=kind(0.0d0)) :: A, B
331 : : DOUBLE PRECISION, PARAMETER ::&
332 : : & ONE=1.D0, THREE=3.D0, SIX=6.D0, ZERO=0.D0
333 : :
334 [ - + ]: 12288 : IF (DX==ZERO) STOP 'splint: ERROR: DX=0'
335 : 12288 : NLO=INT(X/DX)+1
336 : 12288 : NHI=NLO+1
337 : 12288 : A=NHI-X/DX-1
338 : 12288 : B=ONE-A
339 : : Y=A*YA(NLO)+B*YA(NHI)+&
340 : 12288 : & ((A**3-A)*Y2A(NLO)+(B**3-B)*Y2A(NHI))*(DX**2)/SIX
341 : : DYDX=(YA(NHI)-YA(NLO))/DX+&
342 : : & (-((THREE*(A**2)-ONE)*Y2A(NLO))+&
343 : 12288 : & (THREE*(B**2)-ONE)*Y2A(NHI))*DX/SIX
344 : :
345 : 12288 : END SUBROUTINE MACROAV_SPLINT
346 : :
347 : : ! Copyright (C) 1999-2003 (P. Ordejon, J. Junquera)
348 : : ! This file is distributed under the terms of the
349 : : ! GNU General Public License, see ~abinit/COPYING
350 : : ! or http://www.gnu.org/copyleft/gpl.txt .
351 : :
352 : 4 : real(kind=kind(0.0d0)) FUNCTION SURPLA( C )
353 : :
354 : : ! CALCULATES THE SRFACE OF THE UNIT CELL NORMAL TO THE INTERFACE
355 : :
356 : : real(kind=kind(0.0d0)) C(3,3)
357 : : SURPLA = ( C(2,1)*C(3,2) - C(3,1)*C(2,2) ) **2 +&
358 : : & ( C(3,1)*C(1,2) - C(1,1)*C(3,2) ) **2 +&
359 : 4 : & ( C(1,1)*C(2,2) - C(2,1)*C(1,2) ) **2
360 : 4 : SURPLA = SQRT( ABS( SURPLA ) )
361 : 4 : END FUNCTION SURPLA
362 : :
363 : 5 : subroutine thetaft(n,L,lav,ft)
364 : :
365 : : ! Copyright (C) 1999-2003 (P. Ordejon, J. Junquera)
366 : : ! This file is distributed under the terms of the
367 : : ! GNU General Public License, see ~abinit/COPYING
368 : : ! or http://www.gnu.org/copyleft/gpl.txt .
369 : :
370 : : !
371 : : ! Calculates the Fourier coefficients of the convoluting function
372 : : ! w(x) = (1/lav) theta(lav/2 - abs(x))
373 : : ! asuming it is periodic with period L:
374 : : !
375 : : ! | |
376 : : ! 1/lav|__________ __________|
377 : : ! | | | |
378 : : ! |__________|_____________________|_________|___
379 : : ! 0 lav/2 L-lav/2 L
380 : : !
381 : : integer n,j
382 : : real(kind=kind(0.0d0)) :: L,lav
383 : : real(kind=kind(0.0d0)) :: ft(2*n)
384 : : real(kind=kind(0.0d0)) :: pi
385 : :
386 : 5 : pi=4.0d0*datan(1.0d0)
387 : :
388 : 5 : ft(1)=n/L
389 : 5 : ft(2)=0.0
390 : :
391 [ + + ]: 10245 : do j=2,n/2+1
392 : : ft(2*(j-1)+1) = (n/(pi*lav*(j-1)/2.))*&
393 : : & sin(pi*lav*(j-1)/2./L)*&
394 : : & cos(pi*(L-lav/2.)*(j-1)/L)*&
395 : 10240 : & cos(pi*L*(j-1)/L)
396 : : ft(2*(j-1)+2) = (n/(pi*lav*(j-1)/2.))*&
397 : : & sin(pi*lav*(j-1)/2./L)*&
398 : : & cos(pi*(L-lav/2.)*(j-1)/L)*&
399 : 10245 : & sin(pi*L*(j-1)/L)
400 : : enddo
401 : :
402 [ + + ]: 10240 : do j=n/2+2,n
403 : : ft(2*(j-1)+1) = (n/(pi*lav*(-n+j-1)/2.))*&
404 : : & sin(pi*lav*(-n+j-1)/2./L)*&
405 : : & cos(pi*(L-lav/2.)*(-n+j-1)/L)*&
406 : 10235 : & cos(pi*L*(-n+j-1)/L)
407 : : ft(2*(j-1)+2) = (n/(pi*lav*(-n+j-1)/2.))*&
408 : : & sin(pi*lav*(-n+j-1)/2./L)*&
409 : : & cos(pi*(L-lav/2.)*(-n+j-1)/L)*&
410 : 10240 : & sin(pi*L*(-n+j-1)/L)
411 : : enddo
412 : :
413 : :
414 : 5 : return
415 : : end subroutine thetaft
416 : :
417 : 4 : DOUBLE PRECISION FUNCTION VOLCEL( C )
418 : :
419 : : ! Copyright (C) 1999-2003 (P. Ordejon, J. Junquera)
420 : : ! This file is distributed under the terms of the
421 : : ! GNU General Public License, see ~abinit/COPYING
422 : : ! or http://www.gnu.org/copyleft/gpl.txt .
423 : :
424 : : ! CALCULATES THE VOLUME OF THE UNIT CELL
425 : : DOUBLE PRECISION C(3,3)
426 : : VOLCEL = ( C(2,1)*C(3,2) - C(3,1)*C(2,2) ) * C(1,3) +&
427 : : & ( C(3,1)*C(1,2) - C(1,1)*C(3,2) ) * C(2,3) +&
428 : 4 : & ( C(1,1)*C(2,2) - C(2,1)*C(1,2) ) * C(3,3)
429 : 4 : VOLCEL = ABS( VOLCEL )
430 : 4 : END FUNCTION VOLCEL
431 : :
432 : : end module m_macroave
433 : : !!***
|