Branch data Line data Source code
1 : : !!****p* ABINIT/macroave
2 : : !! NAME
3 : : !! macroave
4 : : !!
5 : : !! FUNCTION
6 : : !! **********************************************************************
7 : : !! The MACROAVE program implements the macroscopic average technique,
8 : : !! introduced by A. Baldereschi and coworkers
9 : : !! (A. Baldereschi, S. Baroni, and R. Resta, Phys. Rev. Lett. 61, 734 (1988) [[cite:Baldereschi1988]]).
10 : : !! This is an extremely powerful method that relates
11 : : !! microscopic quantities, typical outputs of first-principles codes,
12 : : !! with macroscopic magnitudes, needed to perform electrostatic analysis.
13 : : !! Within this methodology, we will be able to wash out all the
14 : : !! wiggles of the rapidly-varying functions of position (resembling
15 : : !! the underlying atomic structure) of the microscopic quantities,
16 : : !! blowing up only the macroscopic features.
17 : : !! It can be used to compute band offsets, work functions, effective
18 : : !! charges, and high frequency dielectric constants, among others
19 : : !! interesting physical properties.
20 : : !! Ref: L. Colombo, R. Resta and S. Baroni Phys Rev B 44, 5572 (1991) [[cite:Colombo1991]].
21 : : !! Coded by P. Ordejon and J. Junquera, April 1999.
22 : : !! Modified by J. Junquera, November 2001.
23 : : !! **********************************************************************
24 : : !!
25 : : !! COPYRIGHT
26 : : !! Copyright (C) 1999-2008 (P. Ordejon, J. Junquera, J. Soler, A. Garcia)
27 : : !! This file is distributed under the terms of the
28 : : !! GNU General Public License, see ~abinit/COPYING
29 : : !! or http://www.gnu.org/copyleft/gpl.txt .
30 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
31 : : !!
32 : : !! INPUTS
33 : : !! (main routine)
34 : : !!
35 : : !! OUTPUT
36 : : !! (main routine)
37 : : !!
38 : : !! SOURCE
39 : :
40 : : #if defined HAVE_CONFIG_H
41 : : #include "config.h"
42 : : #endif
43 : :
44 : : #include "abi_common.h"
45 : :
46 : 8 : program macroave
47 : :
48 : 8 : use defs_basis
49 : : use m_xmpi
50 : : use m_abicore
51 : : use m_errors
52 : : use m_nctk
53 : : use netcdf
54 : : use m_hdr
55 : : use m_macroave
56 : :
57 : : use m_fstrings, only : sjoin, strcat, endswith
58 : : use m_io_tools, only : file_exists, open_file
59 : :
60 : : implicit none
61 : :
62 : : !Arguments -----------------------------------
63 : :
64 : : !Local variables-------------------------------
65 : : !no_abirules
66 : : ! --------- PARAMETERS -------------------------------------------------
67 : : ! INTEGER NP : Parameter needed to define maximum number of points
68 : : ! for FFT grid.
69 : : ! Number of points = (2**NP)
70 : : ! INTEGER N : Maximum number of complex data point for FFT.
71 : : ! MUST be a power of 2
72 : : ! REAL*8 HARTREE: Conversion factor from Hartrees to Rydbergs
73 : : ! 1 hartree = 2 Ry
74 : : ! REAL*8 RYDBERG: Conversion factor from Rydbergs to eV
75 : : ! ----------------------------------------------------------------------
76 : : integer, parameter :: np=12
77 : : integer, parameter :: n=2**np
78 : : real(dp), parameter :: hartree=two
79 : : real(dp), parameter :: rydberg=Ha_eV *half
80 : : ! --------- VARIABLES --------------------------------------------------
81 : : integer :: i,ii,ij,ip,is,j,iomode
82 : : integer :: nconv,npoints,npt,nsm,nspin,nz,nspden
83 : : integer :: unit1,unit2,unit3,unit4,varid
84 : : integer :: mesh(3)
85 : : character(len=10) :: code,interp
86 : : character(len=15) :: SNAME,inpdata
87 : : character(len=fnlen) :: fnamerho,fnamedelv,fnameplave
88 : : character(len=500) :: msg
89 : : character(len=nctk_slen) :: varname
90 : : logical :: siesta,abinit,potential,charge,totalcharge
91 : : logical :: found,linear,splin
92 : 8 : real,allocatable :: rhos(:,:)
93 : 8 : real(dp),allocatable :: rho(:,:)
94 : : real(dp) :: cell(3,3),dcell(3,3)
95 : : real(dp) :: l,sur,ds,length,convfac,qren,qtot,lav1,lav2,vol
96 : 8 : real(dp),allocatable :: z(:),rhoz(:),d2rhoz(:),drhodz(:)
97 : : real(dp) :: data(2*n),th(2*n),re(n),im(n)!,v(2*n)
98 : : real(dp) :: x,delta,yp1,ypn,phi
99 : : complex(dp) :: a,b,c
100 : : ! ABINIT variables
101 : : integer :: fform
102 : : integer :: comm,nproc,my_rank
103 : 8 : type(hdr_type) :: hdr
104 : : ! end ABINIT variables
105 : :
106 : : !************************************************************************
107 : : !CHARACTER CODE : First principles-code used to generate the
108 : : !electrostatic potential at the points of a grid
109 : : !in real space. It is read from file 'macroave.in'
110 : : !CHARACTER SNAME : System Label
111 : : !(If code = ABINIT, then SNAME = FNAMERHO)
112 : : !CHARACTER INPDATA : Calculate the band offset from the charge
113 : : !density or from the electrostatic potential?
114 : : !CHARACTER FNAMERHO : Name of the file where the electrostatic
115 : : !potential at the mesh is stored
116 : : !CHARACTER FNAMEPLAVE : Name of the file where the planar average of the
117 : : !electronic potential will be stored
118 : : !CHARACTER FNAMEDELV : Name of the file where the profile
119 : : !of the electrostatic potential will be stored
120 : : !LOGICAL SIESTA : Have you used SIESTA to get the electrostatic potential
121 : : !or the charge density?
122 : : !LOGICAL ABINIT : Have you used ABINIT to get the electrostatic potential
123 : : !or the charge density?
124 : : !LOGICAL LINEAR : Linear interpolation to get the charge
125 : : !density/potential in the FFT grid.
126 : : !LOGICAL SPLIN : Cubic spline interpolation to get the charge
127 : : !density/potential in the FFT grid.
128 : : !LOGICAL POTENTIAL : We are going to compute the band offset from
129 : : !the electrostatic potential
130 : : !LOGICAL CHARGE : We are going to compute the band offset from
131 : : !the charge density
132 : : !LOGICAL FOUND : Were data found? (only when task in iorho ='read')
133 : : !INTEGER NATOMS : Number of atoms in unit cell
134 : : !INTEGER NSPIN : Number of spin polarizations (1 or 2)
135 : : !INTEGER MESH(3) : Number of mesh divisions of each lattice vectors,
136 : : !INCLUDING subgrid
137 : : !INTEGER NSM : Number of sub-mesh points per mesh point
138 : : !(not used in this version)
139 : : !INTEGER NPOINTS : Number of mesh subdivisions in the normal direction
140 : : !to the interface
141 : : !INTEGER NCONV : Number of convolutions required to calculate the
142 : : !macroscopic average
143 : : !INTEGER NPT : Total number of mesh points (included subpoints)
144 : : !REAL*8 CELL(3,3) : Unit cell lattice vectors (a.u.) CELL(IXYZ,IVECT)
145 : : !REAL*8 DS : Differential area per point of the mesh
146 : : !REAL*8 SUR : Area of a plane parallel to the interface
147 : : !REAL*8 LENGTH : Distance between two planes parallel to the interface
148 : : !REAL*8 L : Length of the cell in the direction nomal
149 : : !to the interface (a.u.)
150 : : !REAL*8 LAV1 : Linear period of the electrostatic potential
151 : : !in the bulklike region for the first material
152 : : !REAL*8 LAV2 : Linear period of the electrostatic potential
153 : : !in the bulklike region for the second material
154 : : !REAL*8 CONVFAC : Conversion factor for the output units
155 : : !REAL*8 QTOT : Total electronic charge in the unit cell
156 : : !REAL*8 QREN : Total electronic charge calculated from
157 : : !the input data file
158 : : !REAL*4 Z(MESH(3)) : Z-coordinate of the planes where the elec. density
159 : : !is averaged
160 : : !REAL*4 RHO : Electron density
161 : : !Notice single precision in this version
162 : : !REAL*8 RHOZ : Planar average of the electron density
163 : : !REAL*8 DATA(2*N) : Fourier coefficients of the planar average density
164 : : !REAL*8 TH(2*N) : Fourier coefficients of the step functions
165 : : !REAL*8 V(2*N) : Fourier coefficients of the potential
166 : : !REAL*4 VREEC(N) : Real part of the electronic potential in real space
167 : : !REAL*4 VIMEC(N) : Imag. part of the electronic potential in real space
168 : : !REAL*4 VRENC(N) : Real part of the nuclear potential in real space
169 : : !REAL*4 VIMNC(N) : Imag. part of the nuclear potential in real space
170 : : !*********************************************************************
171 : :
172 : : !Change communicator for I/O (mandatory!)
173 : 8 : call abi_io_redirect(new_io_comm=xmpi_world)
174 : :
175 : : !Initialize MPI
176 : 8 : call xmpi_init()
177 : 8 : comm = xmpi_world
178 : 8 : nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
179 : :
180 : : !Initialize memory profiling if it is activated
181 : : !if a full abimem.mocc report is desired, set the argument of abimem_init to "2" instead of "0"
182 : : !note that abimem.mocc files can easily be multiple GB in size so don't use this option normally
183 : : #ifdef HAVE_MEM_PROFILING
184 : : call abimem_init(0)
185 : : #endif
186 : :
187 : : !Reading input data from a file ---------------------------------------
188 [ - + ]: 8 : if (open_file('macroave.in', msg, newunit=UNIT1, STATUS='OLD') /= 0) then
189 : 0 : ABI_ERROR(msg)
190 : : end if
191 : :
192 : 8 : READ(UNIT1,'(A)')CODE
193 : 8 : READ(UNIT1,'(A)')INPDATA
194 : 8 : READ(UNIT1,'(A)')SNAME
195 : 8 : READ(UNIT1,*)NCONV
196 : 8 : READ(UNIT1,*)LAV1
197 : 8 : READ(UNIT1,*)LAV2
198 : 8 : READ(UNIT1,*)QTOT
199 : 8 : READ(UNIT1,*)INTERP
200 : 8 : close(UNIT1)
201 : :
202 : : !Which code has been used to get the electrostatic potential? ---------
203 [ - + ]: 8 : if ( CODE == 'siesta' .OR. CODE == 'SIESTA' .OR.&
204 : : & CODE == 'Siesta' ) then
205 : 0 : SIESTA = .TRUE.
206 : 0 : ABINIT = .FALSE.
207 : : else if ( CODE == 'abinit' .OR. CODE == 'ab-init' .OR.&
208 : : & CODE == 'ABINIT' .OR. CODE == 'AB-INIT' .OR.&
209 [ + - ]: 8 : & CODE == 'Abinit' .OR. CODE == 'Ab-init') then
210 : 8 : SIESTA = .FALSE.
211 : 8 : ABINIT = .TRUE.
212 : : else
213 : 0 : ABI_ERROR(sjoin('macroave: Unknown code: ', CODE))
214 : : end if
215 : :
216 : : !Are we going to compute the band offset from the charge density or
217 : : !from the electrostatic potential? ------------------------------------
218 [ + + ]: 8 : if ( INPDATA == 'potential' .OR. INPDATA == 'POTENTIAL' .OR.&
219 : : & INPDATA == 'Potential' ) then
220 : 4 : POTENTIAL = .TRUE.
221 : 4 : CHARGE = .FALSE.
222 : 4 : TOTALCHARGE = .FALSE.
223 [ + - ]: 4 : else if ( INPDATA == 'charge' .OR. INPDATA == 'CHARGE' .OR.&
224 : : & INPDATA == 'Charge' ) then
225 : 4 : POTENTIAL = .FALSE.
226 : 4 : CHARGE = .TRUE.
227 : 4 : TOTALCHARGE = .FALSE.
228 : : else if ( INPDATA == 'totalcharge' .OR. &
229 : : & INPDATA == 'Totalcharge' .OR.&
230 [ # # ]: 0 : & INPDATA == 'TotalCharge' .OR.&
231 : : & INPDATA == 'TOTALCHARGE' ) then
232 : 0 : POTENTIAL = .FALSE.
233 : 0 : CHARGE = .FALSE.
234 : 0 : TOTALCHARGE = .TRUE.
235 : : else
236 : 0 : ABI_ERROR(sjoin('macroave: Unknown input data ', INPDATA))
237 : : end if
238 : :
239 : : !What kind of interpolation will we use to get the charge density/
240 : : !potential in a FFT grid? ---------------------------------------------
241 [ + + ]: 8 : if ( INTERP == 'linear' .OR. INTERP == 'Linear' .OR.&
242 : : & INTERP == 'LINEAR' ) then
243 : 2 : LINEAR = .TRUE.
244 : 2 : SPLIN = .FALSE.
245 [ + - ]: 6 : else if ( INTERP == 'spline' .OR. INTERP == 'Spline' .OR.&
246 : : & INTERP == 'SPLINE' ) then
247 : 6 : LINEAR = .FALSE.
248 : 6 : SPLIN = .TRUE.
249 : : end if
250 : :
251 : : !Reading charge density from a file -----------------------------------
252 [ - + ]: 8 : if ( SIESTA ) then
253 [ # # ]: 0 : if (POTENTIAL) then
254 [ # # # # ]: 0 : FNAMERHO = strcat(trim(SNAME),'.VH')
255 [ # # ]: 0 : elseif (CHARGE) then
256 [ # # # # ]: 0 : FNAMERHO = strcat(trim(SNAME),'.RHO')
257 [ # # ]: 0 : elseif (TOTALCHARGE) then
258 [ # # # # ]: 0 : FNAMERHO = strcat(trim(SNAME),'.TOCH')
259 : : end if
260 [ + - ]: 8 : else if ( ABINIT ) then
261 [ + - + - ]: 8 : FNAMERHO = trim(SNAME)
262 : : end if
263 : :
264 [ - + ]: 8 : if (SIESTA) then
265 : 0 : NSM = 1
266 : 0 : NPT = 0
267 : 0 : NSPIN = 0
268 : : CALL IORHO( 'READ', trim(FNAMERHO), DCELL, MESH, NSM, NPT, NSPIN,&
269 [ # # ]: 0 : & RHOS, FOUND )
270 [ # # ]: 0 : if (FOUND) then
271 [ # # # # : 0 : ABI_MALLOC( RHOS,(NPT,NSPIN))
# # # # #
# # # # #
# # # # ]
272 [ # # # # : 0 : ABI_MALLOC( RHO,(NPT,NSPIN))
# # # # #
# # # # #
# # # # ]
273 : : CALL IORHO( 'READ', trim(FNAMERHO), DCELL, MESH, NSM, NPT, NSPIN,&
274 [ # # ]: 0 : & RHOS, FOUND )
275 [ # # ]: 0 : do I = 1, 3
276 [ # # ]: 0 : do J = 1, 3
277 : 0 : CELL(J,I) = DCELL(J,I)
278 : : end do
279 : : end do
280 : : ! Transform the density or the potential read from SIESTA
281 : : ! from a single precision variable to a double precision variable
282 [ # # ]: 0 : do IS = 1, NSPIN
283 [ # # ]: 0 : do IP = 1, NPT
284 : 0 : RHO(IP,IS) = RHOS(IP,IS) * 1.0D0
285 : : end do
286 : : end do
287 : :
288 : : else
289 : 0 : ABI_ERROR(sjoin('macroave: file not found: ', FNAMERHO))
290 : : end if
291 : :
292 [ + - ]: 8 : else if (ABINIT) then
293 : :
294 [ - + ]: 8 : if (nctk_try_fort_or_ncfile(FNAMERHO, msg) /= 0) then
295 : 0 : ABI_ERROR(msg)
296 : : end if
297 [ + - ]: 8 : iomode = IO_MODE_FORTRAN; if (endswith(FNAMERHO, ".nc")) iomode = IO_MODE_ETSF
298 : :
299 [ - + ]: 8 : if (iomode == IO_MODE_FORTRAN) then
300 [ # # ]: 0 : if (open_file(FNAMERHO, msg, newunit=unit2, form="unformatted", status="old") /= 0) then
301 : 0 : ABI_ERROR(msg)
302 : : end if
303 : 0 : call hdr%fort_read(unit2, fform)
304 [ # # ]: 0 : ABI_CHECK(FFORM /= 0, "fform == 0")
305 : : else
306 [ - + ]: 8 : NCF_CHECK(nctk_open_read(unit2, fnamerho, xmpi_comm_self))
307 : 8 : call hdr%ncread(unit2, fform)
308 : : end if
309 : :
310 : : ! For debugging
311 : : ! call hdr%echo(fform,4,std_out)
312 : :
313 [ + + ]: 32 : do I = 1, 3
314 : 24 : MESH(I) = HDR%NGFFT(I)
315 [ + + ]: 104 : do J = 1, 3
316 : 96 : CELL(J,I) = HDR%RPRIMD(J,I)
317 : : end do
318 : : end do
319 : 8 : NSPIN = HDR%NSPPOL
320 : 8 : nspden = hdr%nspden
321 [ - + ]: 8 : ABI_CHECK(hdr%nspinor == 1, "nspinor == 2 not coded")
322 : 8 : call hdr%free()
323 : :
324 : 8 : NPT = MESH(1) * MESH(2) * MESH(3)
325 [ + - - + : 8 : ABI_MALLOC( RHO,(NPT,NSPIN))
+ - - + -
+ - + - +
- + - + ]
326 : :
327 [ - + ]: 8 : if (iomode == IO_MODE_FORTRAN) then
328 [ # # ]: 0 : do IS = 1, NSPIN
329 [ # # # # ]: 0 : READ(UNIT2) (RHO(IP,IS),IP=1,NPT)
330 : : end do
331 : 0 : close(UNIT2)
332 : : else
333 : 8 : varname = varname_from_fname(fnamerho)
334 [ - + ]: 8 : NCF_CHECK(nf90_inq_varid(unit2, varname, varid))
335 : : ! [cplex, n1, n2, n3, nspden]
336 [ + + - + : 48 : NCF_CHECK(nf90_get_var(unit2, varid, rho, start=[1,1,1,1,1], count=[1, mesh(1), mesh(2), mesh(3), nspden]))
- - ]
337 : : end if
338 : :
339 : : ! Units for the potential in Ab-init are in Hartrees,
340 : : ! so we transform them into Ry. No transformation is
341 : : ! needed for the charge density
342 : : ! (it is directly read in electrons/bohr**3).
343 : :
344 [ + + ]: 8 : if (POTENTIAL) then
345 [ + + ]: 8 : do IS = 1, NSPIN
346 [ + + ]: 28808 : do IP = 1, NPT
347 : 28804 : RHO(IP,IS) = RHO(IP,IS) * HARTREE
348 : : end do
349 : : end do
350 : : end if
351 : : end if
352 : :
353 : : !Initialize some variables (we suppose cells with a c axis orthogonal to a and b) -------------
354 : :
355 : 8 : L = CELL(3,3)
356 : 8 : SUR = SURPLA( CELL ) ! surface of unit cell in xy plane, perpendicular to z
357 : 8 : VOL = VOLCEL( CELL )
358 : 8 : DS = SUR/( MESH(1) * MESH(2) ) ! this seems adapted to arbitrary in-plane cells
359 : 8 : LENGTH = L/DBLE(N)
360 : 8 : NPOINTS = MESH(3)
361 : :
362 [ + - + - : 8 : ABI_MALLOC(Z,(NPOINTS+1))
- + - + -
+ - + - +
- + ]
363 [ + - + - : 8 : ABI_MALLOC(RHOZ,(NPOINTS+1))
- + - + -
+ - + - +
- + ]
364 [ + - + - : 8 : ABI_MALLOC(D2RHOZ,(NPOINTS+1))
- + - + -
+ - + - +
- + ]
365 [ - + - + : 8 : ABI_MALLOC(DRHODZ,(N))
- + ]
366 : :
367 [ + + ]: 480 : RHOZ(1:NPOINTS+1) = 0.D0
368 [ + + ]: 480 : D2RHOZ(1:NPOINTS+1) = 0.D0
369 [ + + ]: 32776 : DRHODZ(1:N) = 0.D0
370 : :
371 [ + + ]: 8 : if (POTENTIAL) then
372 : 4 : CONVFAC = RYDBERG
373 [ + - ]: 4 : else if (CHARGE) then
374 : 4 : CONVFAC = 1.0D0
375 [ # # ]: 0 : else if (TOTALCHARGE) then
376 : 0 : CONVFAC = 1.0D0
377 : : end if
378 : :
379 : :
380 : : !Loop over all points and calculate the planar average ----------------
381 : : !Warning: The planar average is only done for the first component of
382 : : !RHO. Spin polarization is not implemented yet ---------------
383 [ + + ]: 51400 : do IP = 1, NPT
384 : 51392 : NZ = (IP-1) / (MESH(1)*MESH(2)) + 1
385 : 51400 : RHOZ(NZ) = RHOZ(NZ) + RHO(IP,1)*DS
386 : : end do
387 : :
388 [ + + ]: 472 : do IP = 1, NPOINTS
389 : 472 : RHOZ(IP) = RHOZ(IP) / SUR
390 : : end do
391 : :
392 [ + + ]: 472 : do IP = 1, NPOINTS
393 : 472 : Z(IP) = (IP-1)*CELL(3,3)/DBLE(NPOINTS)
394 : : end do
395 : :
396 : : !Calculate electrostatic potential or electronic charge density -------
397 : : !in fft grid, interpolating the planar average calculated before ------
398 [ + + ]: 8 : if (SPLIN) then
399 : 6 : Z(NPOINTS+1) = L
400 : 6 : RHOZ(NPOINTS+1) = RHOZ(1)
401 : 6 : DELTA = L/DBLE(NPOINTS)
402 : 6 : YP1 = ( RHOZ(2) - RHOZ(NPOINTS) ) / (2.0D0*DELTA)
403 : 6 : YPN = YP1
404 : 6 : CALL MACROAV_SPLINE(DELTA, RHOZ, NPOINTS+1, YP1, YPN, D2RHOZ)
405 : 6 : I = 0
406 : 6 : do II = 1, 2*N-1, 2
407 : 24576 : I = I + 1
408 : 24576 : X = (I-1)*L/DBLE(N)
409 : : CALL MACROAV_SPLINT( DELTA, RHOZ, D2RHOZ, NPOINTS+1, X, DATA(II), &
410 : 24576 : & DRHODZ(I) )
411 [ + + ]: 24576 : DATA(II+1) = 0.D0
412 : : end do
413 [ + - ]: 2 : else if (LINEAR) then
414 : 2 : I = 0
415 [ + + ]: 8194 : do II = 1,2*N-1,2
416 : 8192 : I = I + 1
417 : 8192 : X = (I-1)*L/DBLE(N)
418 [ + + ]: 307122 : do IJ = 1, NPOINTS
419 [ + + ]: 307010 : if (X == Z(IJ)) then
420 : 14 : DATA(II) = RHOZ(IJ)
421 : 14 : DATA(II+1) = 0.D0
422 : 14 : GOTO 20
423 : : end if
424 [ + + ]: 307108 : if (Z(IJ) > X) then
425 : : DATA(II) = RHOZ(IJ-1) +&
426 : : & (X-Z(IJ-1))*(RHOZ(IJ)-RHOZ(IJ-1))/&
427 : 8066 : & (Z(IJ)-Z(IJ-1))
428 : 8066 : DATA(II+1) = 0.D0
429 : 8066 : GOTO 20
430 : : end if
431 : : end do
432 : : DATA(II)=RHOZ(NPOINTS) +&
433 : : & (X-Z(NPOINTS))*(RHOZ(1)-RHOZ(NPOINTS))/&
434 : 112 : & (Z(NPOINTS)-Z(NPOINTS-1))
435 : 112 : DATA(II+1) = 0.D0
436 : 2 : 20 CONTINUE
437 : : end do
438 : : end if
439 : :
440 : : !Renormalize the charge density ---------------------------------------
441 [ + + ]: 8 : if (CHARGE .OR. TOTALCHARGE) then
442 : 4 : QREN = 0.D0
443 : 4 : do IP = 1, 2*N-1, 2
444 [ + + ]: 16384 : QREN = QREN + DATA(IP)*LENGTH*SUR
445 : : end do
446 [ + + ]: 16388 : do IP = 1, 2*N-1, 2
447 [ + - ]: 16388 : if (CHARGE) then
448 : 16384 : DATA(IP) = DATA(IP) * QTOT/QREN
449 [ # # ]: 0 : elseif(TOTALCHARGE) then
450 : 0 : DATA(IP) = DATA(IP) - QREN/VOL
451 : : end if
452 : : end do
453 : 4 : QREN = 0.D0
454 : 4 : do IP = 1, 2*N-1, 2
455 [ + + ]: 16384 : QREN = QREN + DATA(IP)*LENGTH*SUR
456 : : end do
457 : : ! For debugging
458 : : ! write(std_out,*)' QREN = ', QREN
459 : : end if
460 : : !...
461 : :
462 : : !Print planar average of the electrostatic potential or ---------------
463 : : !the electronic charge density ----------------------------------------
464 [ + - ]: 8 : FNAMEPLAVE = strcat(SNAME,'.PAV')
465 [ - + ]: 8 : if (open_file(FNAMEPLAVE,msg,newunit=UNIT3,STATUS='UNKNOWN') /= 0) then
466 : 0 : ABI_ERROR(msg)
467 : : end if
468 : 8 : I = 0
469 [ + + ]: 32776 : do II = 1, 2*N-1, 2
470 : 32768 : I = I+1
471 : 32768 : X=(I-1)*L/DBLE(N)
472 : : ! WRITE(UNIT3,'(3F20.12)')X,
473 : : ! . DATA(II)*CONVFAC,DATA(II+1)*CONVFAC
474 : 32768 : WRITE(UNIT3,'(2F20.12)')X,&
475 : 65544 : & DATA(II)*CONVFAC
476 : : end do
477 : 8 : close(UNIT3)
478 : : !...
479 : :
480 : :
481 : : !Calculate Fourier transform of the electrostatic potential or
482 : : !the electronic density -----------------------------------------------
483 : 8 : CALL FOUR1(DATA,N,1)
484 : : !...
485 : :
486 : : !Calculate macroscopic average of the electrostatic potential or the
487 : : !electronic charge density taking the convolution with two step functions.
488 : : !In Fourier space, it is a product of the Fourier transform components -
489 : : !The decompositions in the sum over II is due to the special way in which
490 : : !the data are stored in subroutine four1( see Fig. 12.2.2, in
491 : : !'Numerical Recipes, The Art of Scientific Computing'
492 : : !by W.H. Press, S.A. Teukolsky, W.T. Veterling and B.P. Flannery,
493 : : !Cambridge U.P. 1987 and 1992.
494 : :
495 : :
496 : 8 : CALL THETAFT(N,L,LAV1,TH)
497 : :
498 : 8 : do II = 1, N+1, 2
499 : 16392 : A = DATA(II)*(1.D0,0.D0) + DATA(II+1)*(0.D0,1.D0)
500 : 16392 : B = TH(II)*(1.D0,0.D0) + TH(II+1)*(0.D0,1.D0)
501 : 16392 : C = A*B
502 : 16392 : DATA(II) = REAL(C)*L/DBLE(N)
503 [ + + ]: 16392 : DATA(II+1) = AIMAG(C)*L/DBLE(N)
504 : : end do
505 : :
506 : 8 : do II = N+3, 2*N-1, 2
507 : 16376 : A = DATA(II)*(1.D0,0.D0) + DATA(II+1)*(0.D0,1.D0)
508 : 16376 : B = TH(II)*(1.D0,0.D0) + TH(II+1)*(0.D0,1.D0)
509 : 16376 : C = A*B
510 : 16376 : DATA(II) = REAL(C)*L/DBLE(N)
511 [ + + ]: 16376 : DATA(II+1) = AIMAG(C)*L/DBLE(N)
512 : : end do
513 : :
514 : :
515 [ + + ]: 8 : if (NCONV == 2) then
516 : 2 : CALL THETAFT(N,L,LAV2,TH)
517 : :
518 : 2 : do II = 1, N+1, 2
519 : 4098 : A = DATA(II)*(1.D0,0.D0) + DATA(II+1)*(0.D0,1.D0)
520 : 4098 : B = TH(II)*(1.D0,0.D0) + TH(II+1)*(0.D0,1.D0)
521 : 4098 : C = A*B
522 : 4098 : DATA(II) = REAL(C)*L/DBLE(N)
523 [ + + ]: 4098 : DATA(II+1) = AIMAG(C)*L/DBLE(N)
524 : : ! if ( POISON ) then
525 : : ! IG = (II-1) / 2
526 : : ! GSQ= (2.D0*PI*IG/L)**2
527 : : ! if(GSQ > 0.D0) then
528 : : ! V(II) = DATA(II) * (4.D0*PI/GSQ) * HARTREE * RYDBERG
529 : : ! V(II+1) = DATA(II+1) * (4.D0*PI/GSQ) * HARTREE * RYDBERG
530 : : ! else
531 : : ! V(II) = 0.D0
532 : : ! V(II+1) = 0.D0
533 : : ! endif
534 : : ! endif
535 : : end do
536 : :
537 : 2 : do II = N+3, 2*N-1, 2
538 : 4094 : A = DATA(II)*(1.D0,0.D0) + DATA(II+1)*(0.D0,1.D0)
539 : 4094 : B = TH(II)*(1.D0,0.D0) + TH(II+1)*(0.D0,1.D0)
540 : 4094 : C = A*B
541 : 4094 : DATA(II) = REAL(C)*L/DBLE(N)
542 [ + + ]: 4094 : DATA(II+1) = AIMAG(C)*L/DBLE(N)
543 : : ! if ( POISON ) then
544 : : ! IG = (-2*N+II-1) / 2
545 : : ! GSQ= (2.D0*PI*IG/L)**2
546 : : ! if(GSQ > 0.D0) then
547 : : ! V(II) = DATA(II) * (4.D0*PI/GSQ) * HARTREE * RYDBERG
548 : : ! V(II+1) = DATA(II+1) * (4.D0*PI/GSQ) * HARTREE * RYDBERG
549 : : ! else
550 : : ! V(II) = 0.D0
551 : : ! V(II+1) = 0.D0
552 : : ! endif
553 : : ! endif
554 : : end do
555 : :
556 : : end if
557 : : !...
558 : :
559 : : !Transform average electronic density and potential to real space -----
560 : : !The decompositions in the sum over J is due to the special way in which
561 : : !the data are stored in subroutine four1( see Fig. 12.2.2, in
562 : : !'Numerical Recipes, The Art of Scientific Computing'
563 : : !by W.H. Press, S.A. Teukolsky, W.T. Veterling and B.P. Flannery,
564 : : !Cambridge U.P. 1987 and 1992.
565 : :
566 [ + + ]: 32776 : do II = 1, N
567 : 32768 : RE(II) = 0.D0
568 : 32768 : IM(II) = 0.D0
569 : : ! if ( POISON ) then
570 : : ! VREEC(II) = 0.D0
571 : : ! VIMEC(II) = 0.D0
572 : : ! endif
573 : 32768 : do J = 1, N+1, 2
574 : 67141632 : PHI = -2.D0 * PI * (II-1) * ( (J-1)/2 ) / DBLE(N)
575 : : RE(II)=RE(II)+(1.D0/DBLE(N))*(DATA(J)*COS(PHI)&
576 : 67141632 : & -DATA(J+1)*SIN(PHI))
577 : : IM(II)=IM(II)+(1.D0/DBLE(N))*(DATA(J)*SIN(PHI)&
578 [ + + ]: 67141632 : & +DATA(J+1)*COS(PHI))
579 : : ! if ( POISON ) then
580 : : ! VREEC(II)=VREEC(II)+(1.D0/DBLE(N))*(V(J)*COS(PHI)
581 : : ! . -V(J+1)*SIN(PHI))
582 : : ! VIMEC(II)=VIMEC(II)+(1.D0/DBLE(N))*(V(J)*SIN(PHI)
583 : : ! . +V(J+1)*COS(PHI))
584 : : ! endif
585 : : end do
586 : :
587 : 32776 : do J = N+3, 2*N-1, 2
588 : 67076096 : PHI = -2.0D0 * PI * (II-1) * ((-2*N+J-1)/2) / DBLE(N)
589 : : RE(II)=RE(II)+(1.D0/DBLE(N))*(DATA(J)*COS(PHI)&
590 : 67076096 : & -DATA(J+1)*SIN(PHI))
591 : : IM(II)=IM(II)+(1.D0/DBLE(N))*(DATA(J)*SIN(PHI)&
592 [ + + ]: 67076096 : & +DATA(J+1)*COS(PHI))
593 : : ! if ( POISON ) then
594 : : ! VREEC(II)=VREEC(II)+(1.D0/DBLE(N))*(V(J)*COS(PHI)
595 : : ! . -V(J+1)*SIN(PHI))
596 : : ! VIMEC(II)=VIMEC(II)+(1.D0/DBLE(N))*(V(J)*SIN(PHI)
597 : : ! . +V(J+1)*COS(PHI))
598 : : ! endif
599 : : end do
600 : : end do
601 : : !...
602 : :
603 : : !Print averaged electronic charge density and potential ---------------
604 [ + - + - ]: 8 : FNAMEDELV = strcat( trim(SNAME),'.MAV')
605 [ - + ]: 8 : if (open_file(FNAMEDELV, msg, newunit=UNIT4, STATUS='UNKNOWN') /= 0) then
606 : 0 : ABI_ERROR(msg)
607 : : end if
608 [ + + ]: 32776 : do I = 1, N
609 : 32768 : X=(I-1)*L/DBLE(N)
610 : : ! WRITE(UNIT4,'(3F20.5)')X,
611 : : ! . RE(I)*CONVFAC ,IM(I)*CONVFAC
612 : 32768 : WRITE(UNIT4,'(2F20.12)')X,&
613 : 65544 : & RE(I)*CONVFAC
614 : : end do
615 : 8 : close(UNIT4)
616 : : !...
617 : :
618 : : !Print electrostatic potential ----------------------------------------
619 : : !if (POISON) then
620 : : !FNAMEVEC = strcat( SNAME,'.VEC')
621 : : !if (open_file(FNAMEVEC, msg newunit=UNIT5, STATUS='UNKNOWN') /= 0) then
622 : : ! ABI_ERROR(msg)
623 : : !end if
624 : : !do I = 1, N
625 : : !X=(I-1)*L/DBLE(N)
626 : : !WRITE(UNIT5,'(3F20.12)')X, VREEC(I), VIMEC(I)
627 : : !enddo
628 : : !close(unit5)
629 : : !endif
630 : : !...
631 : :
632 [ - + ]: 8 : ABI_FREE(Z)
633 [ - + ]: 8 : ABI_FREE(RHOZ)
634 [ - + ]: 8 : ABI_FREE(DRHODZ)
635 [ - + ]: 8 : ABI_FREE(D2RHOZ)
636 [ + - ]: 8 : if (allocated(rho)) then
637 [ - + ]: 8 : ABI_FREE(rho)
638 : : end if
639 : :
640 : : !Write information on file about the memory before ending mpi module, if memory profiling is enabled
641 : 8 : call abinit_doctor("__macroave")
642 : :
643 : 8 : call xmpi_end()
644 : :
645 : 0 : end program macroave
646 : : !!***
|