Branch data Line data Source code
1 : : !!****m* ABINIT/m_epjdos
2 : : !! NAME
3 : : !! m_epjdos
4 : : !!
5 : : !! FUNCTION
6 : : !! Tools for the computiation of electronic PJDOSes
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (MVer, XG, SM, MT, BAmadon, MG, MB)
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_epjdos
23 : :
24 : : use defs_basis
25 : : use m_abicore
26 : : use m_xmpi
27 : : use m_errors
28 : : use m_htetra
29 : : use m_splines
30 : : use m_cgtools
31 : : use m_atomdata
32 : : use m_crystal
33 : : use m_ebands
34 : : use m_nctk
35 : : use netcdf
36 : : use m_hdr
37 : : use m_mpinfo
38 : : use m_sort
39 : : use m_dtset
40 : :
41 : : use defs_abitypes, only : MPI_type
42 : : use defs_datatypes, only : pseudopotential_type
43 : : use m_occ, only : dos_hdr_write
44 : : use m_time, only : cwtime, timab
45 : : use m_io_tools, only : open_file
46 : : use m_numeric_tools, only : simpson, simpson_int
47 : : use m_fstrings, only : int2char4, strcat
48 : : use m_special_funcs, only : jlspline_t
49 : : use m_kpts, only : tetra_from_kptrlatt
50 : : use m_kg, only : ph1d3d, getph
51 : : use m_gsphere, only : getkpgnorm
52 : : use m_fftcore, only : sphereboundary
53 : : use m_fft, only : fftpac, fourwf, fourdp
54 : : use m_pawrad, only : pawrad_type, simp_gen
55 : : use m_pawtab, only : pawtab_type
56 : : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_get, pawcprj_free
57 : : use m_initylmg, only : initylmg
58 : :
59 : : implicit none
60 : :
61 : : private
62 : : !!***
63 : :
64 : : public :: recip_ylm ! Project input wavefunctions (real space) on to Ylm
65 : : public :: dens_in_sph ! Calculate integrated density in sphere around each atom
66 : : !!***
67 : :
68 : : !----------------------------------------------------------------------
69 : :
70 : : !!****t* m_epjdos/epjdos_t
71 : : !! NAME
72 : : !! epjdos_t
73 : : !!
74 : : !! FUNCTION
75 : : !! Stores different contributions to the electronic DOS.
76 : : !!
77 : : !! NOTES
78 : : !! Please contact gmatteo if you plan to change the internal implementation
79 : : !! or add new DOSes. These results are saved in a netcdf file (see fatbands_ncwrite)
80 : : !! so that one can read it with python and plot fatbands and PJDOSEs.
81 : : !! The python version is able to handle the different cases (L, LM, Spin ...) but
82 : : !! any change in the internal Abinit implementation is likely to break the python interface.
83 : : !!
84 : : !! SOURCE
85 : :
86 : : type,public :: epjdos_t
87 : :
88 : : integer :: mbesslang
89 : : ! Max L+1 used in LM-DOS (Bessel function expansion)
90 : :
91 : : integer :: ndosfraction
92 : : ! Defines the last dimension of the dos arrays.
93 : : ! Actual value depends on the other variables.
94 : :
95 : : integer :: prtdos
96 : : ! 2 --> Standard DOS with tetra.
97 : : ! 3 --> L-DOS with tetra (prtdosm>0 if LM is wanted in Ylm/Slm basis).
98 : : ! 4 --> L-DOS with gaussian (prtdosm if LM is wanted in Ylm/Slm basis).
99 : : ! 5 --> Spin-DOS
100 : :
101 : : integer :: prtdosm
102 : : ! Option for the m-contributions to the partial DOS
103 : : ! 1 if LM-projection is done onto complex Ylm
104 : : ! 2 if LM-projection is done onto real Slm
105 : :
106 : : integer :: partial_dos_flag
107 : :
108 : : integer :: paw_dos_flag
109 : : ! 1 if both PAW contributions are evaluated AND stored
110 : :
111 : : !integer :: pawfatbnd
112 : : integer :: fatbands_flag
113 : :
114 : : integer :: nkpt, mband, nsppol
115 : : ! Used to dimension arrays
116 : :
117 : : integer,allocatable :: mlang_type(:)
118 : : ! mlang_type(ntypat + natsph_extra)
119 : : ! Max L+1 used in LM-DOS for each atom type
120 : :
121 : : real(dp),allocatable :: fractions(:,:,:,:)
122 : : ! fractions(nkpt,mband,nsppol,ndosfraction))
123 : : ! TODO: replace nsppol with nspden = 1, 2 (nsppol==2) or 4 (nspinor==2)
124 : :
125 : : real(dp),allocatable :: fractions_m(:,:,:,:)
126 : : ! fractions_m(nkpt,mband,nsppol,ndosfraction*mbesslang)
127 : :
128 : : real(dp),allocatable :: fractions_paw1(:,:,:,:)
129 : : ! fractions_paw1(nkpt,mband,nsppol,ndosfraction)
130 : :
131 : : real(dp),allocatable :: fractions_pawt1(:,:,:,:)
132 : : ! fractions_pawt1(nkpt,mband,nsppol,ndosfraction))
133 : :
134 : : contains
135 : :
136 : : procedure :: init => epjdos_init
137 : : ! Create new object
138 : :
139 : : procedure :: calcnwrite => epjdos_calcnwrite
140 : : ! Calculate DOS and write results to file(s).
141 : :
142 : : procedure :: partial_dos_fractions => partial_dos_fractions
143 : : ! Calculate partial DOS fractions to feed to the tetrahedron method (PW part)
144 : :
145 : : procedure :: partial_dos_fractions_paw => partial_dos_fractions_paw
146 : : ! Calculate PAW contributions to the partial DOS fractions.
147 : :
148 : : procedure :: prtfatbands => epjdos_prtfatbands
149 : : ! Print PJDOS contributions in xmgrace format.
150 : :
151 : : procedure :: ncwrite => epjdos_ncwrite
152 : : ! Write PJDOS contributions to netcdf file.
153 : :
154 : : procedure :: free => epjdos_free
155 : : ! Free dynamic memory
156 : :
157 : : end type epjdos_t
158 : :
159 : : !----------------------------------------------------------------------
160 : :
161 : : contains !============================================================
162 : : !!***
163 : :
164 : : !!****f* m_epjdos/epjdos_init
165 : : !! NAME
166 : : !! epjdos_init
167 : : !!
168 : : !! FUNCTION
169 : : !! Create new object from dataset input variables.
170 : : !!
171 : : !! INPUTS
172 : : !! dtset <type(dataset_type)>=all input variables for this dataset
173 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
174 : : !! pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
175 : : !!
176 : : !! SOURCE
177 : :
178 : 49 : subroutine epjdos_init(new, dtset, psps, pawtab)
179 : :
180 : : !Arguments ------------------------------------
181 : : class(epjdos_t),intent(inout) :: new
182 : : type(dataset_type),intent(in) :: dtset
183 : : type(pseudopotential_type),intent(in) :: psps
184 : : type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
185 : :
186 : : !Local variables-------------------------------
187 : : !scalars
188 : : integer :: ierr,itypat,iat
189 : : ! *********************************************************************
190 : :
191 : : !write(std_out,*)' m_epjdos%epjdos_new, enter '
192 : :
193 : 49 : new%nkpt = dtset%nkpt; new%mband = dtset%mband; new%nsppol = dtset%nsppol
194 : :
195 : 49 : new%prtdos = dtset%prtdos
196 : 49 : new%partial_dos_flag = 0
197 : : if (new%prtdos==2) new%partial_dos_flag = 0 ! Standard DOS with tetra.
198 [ + + ]: 49 : if (new%prtdos==3) new%partial_dos_flag = 1 ! L-DOS with tetra (prtdosm>0 if LM is wanted in Ylm/Slm basis).
199 [ + + ]: 49 : if (new%prtdos==4) new%partial_dos_flag = 1 ! L-DOS with gaussian (prtdosm if LM is wanted in Ylm/Slm basis).
200 [ + + ]: 49 : if (new%prtdos==5) new%partial_dos_flag = 2 ! Spin DOS
201 : :
202 : 49 : new%prtdosm=0
203 [ + + ]: 49 : if (new%partial_dos_flag==1) new%prtdosm=dtset%prtdosm
204 : : ! paw_dos_flag= 1 if both PAW contributions are evaluated AND stored
205 : 49 : new%paw_dos_flag=0
206 [ + + + + : 49 : if (dtset%usepaw==1 .and. new%partial_dos_flag==1 .and. dtset%pawprtdos==1) new%paw_dos_flag=1
- + ]
207 : :
208 : 49 : new%fatbands_flag=0
209 [ + + + - ]: 49 : if (dtset%pawfatbnd>0 .and. new%prtdosm==0) new%fatbands_flag=1
210 [ + + - + ]: 49 : if (new%prtdosm==1.and.dtset%pawfatbnd>0)then
211 : : ! because they compute quantities in real and complex harmonics respectively
212 : 0 : ABI_ERROR('pawfatbnd>0 and prtdosm=1 are not compatible')
213 : : end if
214 : :
215 : : ! mjv : initialization is needed as mbesslang is used for allocation below
216 : : ! NOTE: 10/5/2010 the whole of this could be looped over ndosfraction,
217 : : ! to store much less in memory. The DOS is accumulated in an array
218 : : ! and then printed to file at the end.
219 : 49 : new%mbesslang = 1
220 [ + + + + ]: 49 : if (new%partial_dos_flag==1 .or. new%fatbands_flag==1) then
221 : :
222 [ - + + - : 132 : ABI_MALLOC(new%mlang_type, (dtset%ntypat + dtset%natsph_extra))
+ - + - -
+ - + -
+ ]
223 [ + + ]: 110 : new%mlang_type = 0
224 : :
225 : : ! TODO: Could use mbesslang = 4 or compute it from psps/pawtab
226 : : ! Increment by one (could underestimate if vloc = vlmax)
227 [ + + ]: 44 : if (dtset%usepaw == 0) then
228 [ + + ]: 52 : do iat=1,dtset%natsph
229 : 32 : itypat = dtset%typat(dtset%iatsph(iat))
230 [ + + ]: 173 : new%mlang_type(itypat) = 1 + maxval(psps%indlmn(1, :, itypat))
231 : : end do
232 : : else
233 [ + + ]: 62 : do iat=1,dtset%natsph
234 : 38 : itypat= dtset%typat(dtset%iatsph(iat))
235 : 62 : new%mlang_type(itypat) = 1 + (pawtab(itypat)%l_size - 1) / 2
236 : : end do
237 : : end if
238 : :
239 : : ! Up to l=g if we have natsph_extra.
240 [ + + + + ]: 56 : if (dtset%natsph_extra > 0) new%mlang_type(dtset%ntypat+1:) = 5
241 : :
242 [ + + ]: 110 : new%mlang_type = 5 ! This is to preserve the old implementation
243 [ + + ]: 110 : new%mbesslang = maxval(new%mlang_type)
244 : 44 : new%ndosfraction = (dtset%natsph + dtset%natsph_extra) * new%mbesslang
245 : :
246 [ + + ]: 5 : else if (new%partial_dos_flag == 2) then
247 : 1 : new%ndosfraction = 7
248 : :
249 : : else
250 : 4 : new%ndosfraction = 1
251 : 4 : new%mbesslang = 0
252 : : end if
253 : :
254 : : ! Check allocations status as these arrays are not distributed and the wavefunctions are still in memory.
255 [ - + + - : 294 : ABI_MALLOC_OR_DIE(new%fractions, (dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction), ierr)
- + + - -
+ + - - +
+ - + - +
- + - + -
- + + - -
+ ]
256 [ + + + + : 66018 : new%fractions = zero
+ + + + ]
257 : :
258 [ + + + + ]: 49 : if (new%prtdosm>=1 .or. new%fatbands_flag==1) then
259 [ - + + - : 18 : ABI_MALLOC_OR_DIE(new%fractions_m,(dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction*new%mbesslang), ierr)
- + + - -
+ + - - +
+ - + - +
- + - + -
- + + - -
+ ]
260 [ + + + + : 57874 : new%fractions_m = zero
+ + + + ]
261 : : end if
262 : :
263 [ + + + + ]: 49 : if (dtset%usepaw==1 .and. new%partial_dos_flag==1) then
264 [ - + + - : 138 : ABI_MALLOC_OR_DIE(new%fractions_paw1,(dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction), ierr)
- + + - -
+ + - - +
+ - + - +
- + - + -
- + + - -
+ ]
265 [ - + + - : 138 : ABI_MALLOC_OR_DIE(new%fractions_pawt1,(dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction), ierr)
- + + - -
+ + - - +
+ - + - +
- + - + -
- + + - -
+ ]
266 [ + + + + : 66663 : new%fractions_paw1 = zero; new%fractions_pawt1 = zero
+ + + + +
+ + + + +
+ + ]
267 : : end if
268 : :
269 : : !write(std_out,*)' m_epjdos%epjdos_new, exit '
270 : :
271 : 49 : end subroutine epjdos_init
272 : : !!***
273 : :
274 : : !!****f* m_epjdos/epjdos_free
275 : : !! NAME
276 : : !! epjdos_free
277 : : !!
278 : : !! FUNCTION
279 : : !! Deallocate memory
280 : : !!
281 : : !! SOURCE
282 : :
283 : 1774 : subroutine epjdos_free(self)
284 : :
285 : : !Arguments ------------------------------------
286 : : class(epjdos_t),intent(inout) :: self
287 : : ! *********************************************************************
288 : :
289 : : ! integer
290 [ + + ]: 1774 : ABI_SFREE(self%mlang_type)
291 : :
292 : : ! real
293 [ + + ]: 1774 : ABI_SFREE(self%fractions)
294 [ + + ]: 1774 : ABI_SFREE(self%fractions_m)
295 [ + + ]: 1774 : ABI_SFREE(self%fractions_paw1)
296 [ + + ]: 1774 : ABI_SFREE(self%fractions_pawt1)
297 : :
298 : 1774 : end subroutine epjdos_free
299 : : !!***
300 : :
301 : : !!****f* m_epjdos/epjdos_calcnwrite
302 : : !! NAME
303 : : !! epjdos_calcnwrite
304 : : !!
305 : : !! FUNCTION
306 : : !! calculate DOS and write results to file(s)
307 : : !!
308 : : !! INPUTS
309 : : !! dos_fractions= projections of wavefunctions on each angular momentum Ylm
310 : : !! which is the weight going into the DOS for an l-decomposed dos
311 : : !! dos_fractions_m= same as dos_fractions, but m-decomposed not just l-
312 : : !! dos_fractions_paw1= contribution to dos fractions from the PAW partial waves (phi)
313 : : !! dos_fractions_pawt1= contribution to dos fractions from the PAW pseudo partial waves (phi_tild)
314 : : !! dtset structured datatype, in particular one uses :
315 : : !! kptrlatt(3,3)=lattice vectors for full kpoint grid
316 : : !! nshiftk =number of kpoint grid shifts
317 : : !! pawprtdos =option to output the individual contributions to the partial DOS (0, 1 or 2)
318 : : !! shiftk(3,nshiftk)=kpoint shifts
319 : : !! usepaw =option for PAW
320 : : !! crystal<crystal_t>=Object defining the unit cell and its symmetries.
321 : : !! ebands<ebands_t>=Band structure data.
322 : : !! fermie=Fermi energy
323 : : !! fildata=name of the DOS output file
324 : : !! mbesslang=maximum angular momentum for Bessel function expansion
325 : : !! prtdosm=option for the m-contributions to the partial DOS
326 : : !! ndosfraction= number of types of DOS we are calculating, e.g. the number
327 : : !! of l channels. Could be much more general, for other types of partial DOS
328 : : !! paw_dos_flag= option for partial dos in PAW
329 : : !! comm=MPI communicator.
330 : : !!
331 : : !! OUTPUT
332 : : !! (no explicit output)
333 : : !!
334 : : !! SOURCE
335 : :
336 : 46 : subroutine epjdos_calcnwrite(dos,dtset,crystal,ebands,fildata,comm)
337 : :
338 : : !Arguments ------------------------------------
339 : : !scalars
340 : : class(epjdos_t),intent(in) :: dos
341 : : integer,intent(in) :: comm
342 : : character(len=*),intent(in) :: fildata
343 : : type(dataset_type),intent(in) :: dtset
344 : : type(crystal_t),intent(in) :: crystal
345 : : type(ebands_t),intent(in) :: ebands
346 : :
347 : : !Local variables-------------------------------
348 : : !scalars
349 : : integer,parameter :: bcorr0=0,master=0
350 : : integer :: iat,iband,iene,ikpt,isppol,natsph,natsph_extra,nkpt,nsppol,i1,i2
351 : : integer :: nene,prtdos,unitdos,ierr,prtdosm,paw_dos_flag,mbesslang,ndosfraction
352 : : integer :: my_rank,nprocs,cnt,ifrac,ii
353 : : real(dp),parameter :: dos_max=9999.9999_dp
354 : : real(dp) :: buffer,deltaene,enemax,enemin,integral_DOS,max_occ
355 : : real(dp) :: cpu,wall,gflops
356 : : logical :: bigDOS,iam_master
357 : : character(len=10) :: tag
358 : : character(len=500) :: frmt,frmt_extra,msg
359 : 46 : type(htetra_t) :: tetra
360 : : !arrays
361 : 46 : integer,allocatable :: unt_atsph(:)
362 : : real(dp) :: list_dp(3)
363 : 46 : real(dp),allocatable :: tmp_eigen(:),total_dos(:,:,:),eig_dos(:,:)
364 : 46 : real(dp),allocatable :: dos_m(:,:,:),dos_paw1(:,:,:),dos_pawt1(:,:,:), wdt(:,:)
365 : : ! *********************************************************************
366 : :
367 : : !write(std_out,*)' m_epjdos%dos_calcncwrite, enter '
368 : :
369 : 46 : my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm); iam_master = (my_rank == master)
370 : :
371 : 46 : prtdosm = dos%prtdosm; paw_dos_flag = dos%paw_dos_flag
372 : 46 : mbesslang = dos%mbesslang; ndosfraction = dos%ndosfraction
373 : :
374 : 46 : nkpt = dtset%nkpt; nsppol = dtset%nsppol
375 : :
376 : : !m-decomposed DOS not compatible with PAW-decomposed DOS
377 [ + + - + ]: 46 : if (prtdosm>=1.and.paw_dos_flag==1) then
378 : 0 : msg = 'm-decomposed DOS (prtdosm>=1) not compatible with PAW-decomposed DOS (pawprtdos=1) !'
379 : 0 : ABI_ERROR(msg)
380 : : end if
381 : :
382 : : !Refuse nband different for different kpoints
383 : : !Note: This means we can pass ebands%eig(:,:,:) instead of eigen(mband*nkpt*nsppol) in packed form
384 [ + + ]: 98 : do isppol=1,nsppol
385 [ + + ]: 486 : do ikpt=1,nkpt
386 [ - + ]: 440 : if ( dtset%nband(nkpt*(isppol-1) + ikpt) /= dtset%nband(1) ) then
387 : 0 : write(std_out,*) 'tetrahedron: skip subroutine.'
388 : 0 : write(std_out,*) 'nband must be the same for all kpoints'
389 : 0 : write(std_out,*) 'nband=', dtset%nband
390 : 0 : ABI_WARNING('tetrahedron: skip subroutine. See message above')
391 : 0 : return
392 : : end if
393 : : end do
394 : : end do
395 : :
396 : 46 : call cwtime(cpu, wall, gflops, "start")
397 : :
398 : : tetra = tetra_from_kptrlatt(crystal, dtset%kptopt, dtset%kptrlatt, dtset%nshiftk, &
399 : 46 : dtset%shiftk, dtset%nkpt, dtset%kpt, comm, msg, ierr)
400 [ - + ]: 46 : if (ierr /= 0) then
401 : 0 : call tetra%free()
402 : 0 : ABI_WARNING(msg)
403 : 0 : return
404 : : end if
405 : :
406 : 46 : natsph=dtset%natsph; natsph_extra=dtset%natsph_extra
407 : :
408 : : ! Master opens the DOS files.
409 [ + + ]: 46 : if (iam_master) then
410 [ + + ]: 25 : if (any(dtset%prtdos == [2, 5])) then
411 [ - + ]: 5 : if (open_file(fildata, msg, newunit=unitdos, status='unknown', form='formatted', action="write") /= 0) then
412 : 0 : ABI_ERROR(msg)
413 : : end if
414 : :
415 [ + - ]: 20 : else if (dtset%prtdos == 3) then
416 : : ! unt_atsph(0) is used for the total DOS.
417 [ - + + - : 60 : ABI_MALLOC(unt_atsph,(0:natsph+natsph_extra))
+ - + - -
+ - + -
+ ]
418 : :
419 : : ! Open file for total DOS as well.
420 [ - + ]: 20 : if (open_file(strcat(fildata, '_TOTAL'), msg, newunit=unt_atsph(0), &
421 : : status='unknown', form='formatted', action="write") /= 0) then
422 : 20 : ABI_ERROR(msg)
423 : : end if
424 : :
425 [ + + ]: 50 : do iat=1,natsph
426 : 30 : call int2char4(dtset%iatsph(iat),tag)
427 [ - + ]: 30 : ABI_CHECK((tag(1:1)/='#'),'Bug: string length too short!')
428 [ - + ]: 30 : if (open_file(strcat(fildata, '_AT', tag), msg, newunit=unt_atsph(iat), &
429 : 20 : status='unknown', form='formatted', action="write") /= 0) then
430 : 30 : ABI_ERROR(msg)
431 : : end if
432 : : end do
433 : : ! do extra spheres in vacuum too. Use _ATEXTRA[NUM] suffix
434 [ + + ]: 32 : do iat=1,natsph_extra
435 : 12 : call int2char4(iat,tag)
436 [ - + ]: 12 : ABI_CHECK((tag(1:1)/='#'),'Bug: string length too short!')
437 [ - + ]: 12 : if (open_file(strcat(fildata, '_ATEXTRA', tag), msg, newunit=unt_atsph(natsph+iat), &
438 : 20 : status='unknown', form='formatted', action="write") /= 0) then
439 : 12 : ABI_ERROR(msg)
440 : : end if
441 : : end do
442 : : end if
443 : : end if
444 : :
445 : : ! Write the header of the DOS file, and determine the energy range and spacing
446 : 46 : prtdos=dtset%prtdos
447 : 46 : buffer=0.01_dp ! Size of the buffer around the min and max ranges
448 : :
449 : : ! A Similar section is present is getnel. Should move all DOS stuff to m_ebands
450 : : ! Choose the lower and upper energies
451 [ + + + + : 6323 : enemax = maxval(ebands%eig) + buffer
+ + + + +
- - + -
- ]
452 [ + + + + : 6323 : enemin = minval(ebands%eig) - buffer
+ + + + +
- - + -
- ]
453 : :
454 : : ! Extend the range to a nicer value
455 [ + + ]: 46 : enemax=0.1_dp*ceiling(enemax*10._dp)
456 [ + - ]: 46 : enemin=0.1_dp*floor(enemin*10._dp)
457 : :
458 : : ! Choose the energy increment
459 [ + + ]: 46 : if(abs(dtset%dosdeltae)<tol10)then
460 : 44 : deltaene=0.001_dp
461 [ + - ]: 44 : if(dtset%prtdos>=2)deltaene=0.0005_dp ! Higher resolution possible (and wanted) for tetrahedron
462 : : else
463 : 2 : deltaene=dtset%dosdeltae
464 : : end if
465 : 46 : nene=nint((enemax-enemin)/deltaene)+1
466 : :
467 : 46 : call xmpi_bcast(nene, master, comm, ierr)
468 [ + + + + ]: 121 : if (iam_master) list_dp(1:3) = [deltaene, enemin, enemax]
469 : 46 : call xmpi_bcast(list_dp, master, comm, ierr)
470 : 46 : deltaene = list_dp(1); enemin = list_dp(2); enemax = list_dp(3)
471 : :
472 [ + + ]: 46 : if (iam_master) then
473 [ + + ]: 25 : if (any(dtset%prtdos == [2, 5])) then
474 : : call dos_hdr_write(deltaene,ebands%eig,enemax,enemin,ebands%fermie,ebands%fermih,&
475 : : dtset%mband,dtset%nband,nene,nkpt,nsppol,dtset%occopt,prtdos,&
476 : 5 : dtset%tphysel,dtset%tsmear,unitdos)
477 [ + - ]: 20 : else if (dtset%prtdos == 3) then
478 [ + + ]: 82 : do iat=0,natsph+natsph_extra
479 : : call dos_hdr_write(deltaene,ebands%eig,enemax,enemin,ebands%fermie,ebands%fermih,&
480 : : dtset%mband,dtset%nband,nene,nkpt,nsppol,dtset%occopt,prtdos,&
481 : 82 : dtset%tphysel,dtset%tsmear,unt_atsph(iat))
482 : : end do
483 : : end if
484 : : end if
485 : :
486 : : ! Tetra weights
487 [ - + + - : 138 : ABI_MALLOC(wdt, (nene, 2))
+ - + - -
+ - + ]
488 : :
489 : : ! Allocate arrays to store DOSes and fill with zeros.
490 : : ! 1--> DOS , 2--> IDOS
491 [ - + + - : 230 : ABI_MALLOC(total_dos,(nene,ndosfraction,2))
- + + - +
- + - + -
- + - + ]
492 [ - + + - : 92 : ABI_MALLOC(eig_dos, (nene, 2))
- + - + ]
493 : :
494 [ - + ]: 46 : if (paw_dos_flag==1) then
495 [ # # # # : 0 : ABI_MALLOC(dos_paw1,(nene,ndosfraction,2))
# # # # #
# # # ]
496 [ # # # # : 0 : ABI_MALLOC(dos_pawt1,(nene,ndosfraction,2))
# # # # #
# # # ]
497 : : end if
498 [ + + ]: 46 : if (prtdosm>=1) then
499 [ - + + - : 10 : ABI_MALLOC(dos_m, (nene,ndosfraction*mbesslang,2))
- + + - +
- + - + -
- + - + ]
500 : : end if
501 : :
502 : : !Get maximum occupation value (2 or 1)
503 [ + + + + ]: 46 : max_occ = one; if (dtset%nspinor == 1 .and. nsppol == 1) max_occ = two
504 : :
505 : : !-------------------------------------------------------------------
506 : : !For each spin polarisation and band, interpolate band over kpoints
507 : : !calculate integration weights and DOS contib from
508 : : !-------------------------------------------------------------------
509 : :
510 : : ! Workspace arrays.
511 [ - + + - : 138 : ABI_MALLOC(tmp_eigen,(nkpt))
+ - + - -
+ - + ]
512 : :
513 : 46 : cnt = 0
514 [ + + ]: 98 : do isppol=1,nsppol
515 : :
516 [ + + + + : 7702572 : total_dos = zero; eig_dos = zero
+ + + + +
+ ]
517 [ + + + + : 900458 : if (prtdosm>=1) dos_m = zero
+ + + + ]
518 [ - + ]: 52 : if (paw_dos_flag==1) then
519 [ # # # # : 0 : dos_paw1 = zero; dos_pawt1 = zero
# # # # #
# # # ]
520 : : end if
521 : :
522 [ + + ]: 440 : do ikpt=1,nkpt
523 [ + + ]: 6277 : do iband=1,ebands%nband(ikpt+(isppol-1)*ebands%nkpt)
524 [ + + ]: 5837 : cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! Mpi parallelism.
525 : :
526 : : ! Accumulate total DOS from eigenvalues (this is the **exact** total DOS)
527 [ + + ]: 24672 : tmp_eigen(:) = ebands%eig(iband, :, isppol)
528 : 2837 : call tetra%get_onewk(ikpt,bcorr0,nene,nkpt,tmp_eigen,enemin,enemax,max_occ,wdt)
529 [ + + + + ]: 48586585 : wdt = wdt*ebands%wtk(ikpt)
530 [ - + + + : 48589422 : eig_dos = eig_dos + wdt
+ + ]
531 : :
532 : : ! Accumulate L-DOS.
533 [ + + ]: 8511 : do ii=1,2
534 [ + + ]: 46713 : do ifrac=1,ndosfraction
535 [ + + ]: 383816878 : total_dos(:,ifrac,ii) = total_dos(:,ifrac,ii) + wdt(:,ii) * dos%fractions(ikpt,iband,isppol,ifrac)
536 : : end do
537 : : end do
538 : :
539 [ - + ]: 2837 : if (paw_dos_flag==1) then
540 : : ! Accumulate L-DOS (on-site terms).
541 [ # # ]: 0 : do ii=1,2
542 [ # # ]: 0 : do ifrac=1,ndosfraction
543 [ # # ]: 0 : dos_paw1(:,ifrac,ii) = dos_paw1(:,ifrac,ii) + wdt(:,ii) * dos%fractions_paw1(ikpt,iband,isppol,ifrac)
544 [ # # ]: 0 : dos_pawt1(:,ifrac,ii) = dos_pawt1(:,ifrac,ii) + wdt(:,ii) * dos%fractions_pawt1(ikpt,iband,isppol,ifrac)
545 : : end do
546 : : end do
547 : : end if
548 : :
549 [ + + ]: 3225 : if (prtdosm>=1) then
550 : : ! Accumulate LM-DOS.
551 [ + + ]: 609 : do ii=1,2
552 [ + + ]: 10909 : do ifrac=1,ndosfraction*mbesslang
553 [ + + ]: 86141006 : dos_m(:,ifrac,ii) = dos_m(:,ifrac,ii) + wdt(:,ii) * dos%fractions_m(ikpt, iband, isppol, ifrac)
554 : : end do
555 : : end do
556 : : end if
557 : :
558 : : end do ! ikpt
559 : : end do ! iband
560 : :
561 : : ! Collect results on master
562 : 52 : call xmpi_sum_master(eig_dos, master, comm, ierr)
563 : 52 : call xmpi_sum_master(total_dos, master, comm, ierr)
564 [ + + + + : 3446676 : bigDOS=(maxval(total_dos(:,:,1))>999._dp)
+ + + - -
+ - - ]
565 : :
566 [ - + ]: 52 : if (paw_dos_flag == 1) then
567 : 0 : call xmpi_sum_master(dos_paw1, master, comm, ierr)
568 : 0 : call xmpi_sum_master(dos_pawt1, master, comm, ierr)
569 : : end if
570 [ + + ]: 52 : if (prtdosm >= 1) call xmpi_sum_master(dos_m, master, comm, ierr)
571 : :
572 : : ! Write the DOS value in the DOS file
573 : : ! Print the data for this energy. Note the upper limit (dos_max), to be consistent with the format.
574 : : ! The use of "E" format is not adequate, for portability of the self-testing procedure.
575 : : ! header lines depend on the type of DOS (projected etc...) which is output
576 : :
577 [ + + ]: 52 : if (.not. iam_master) goto 10
578 : 31 : call write_extra_headers()
579 : :
580 [ + + ]: 31 : if (prtdos==2) then
581 : : ! E, DOS, IDOS
582 [ + + ]: 23610 : do iene=1,nene
583 : : write(unitdos, '(f11.5,1x,2(f10.4,1x))') &
584 [ + + ]: 47215 : enemin + (iene-1)*deltaene, min(total_dos(iene,:,1), dos_max), total_dos(iene,:,2)
585 : : end do
586 : :
587 [ + + ]: 26 : else if (prtdos==3) then
588 : :
589 : : ! Write E, DOS, IDOS
590 [ + + ]: 142330 : do iene=1,nene
591 : : write(unt_atsph(0), '(f11.5,1x,2(f10.4,1x))') &
592 : 142330 : enemin + (iene-1)*deltaene, min(eig_dos(iene,1), dos_max), eig_dos(iene,2)
593 : : end do
594 : :
595 : : ! E, DOS(L=1,LMAX), IDOS(L=1,LMAX)
596 : : ! Here we assume mpsang = 5 in the format.
597 [ - + - - ]: 25 : if (paw_dos_flag/=1.or.dtset%pawprtdos==2) then
598 : 25 : frmt = '(f11.5,1x,5(f9.4,1x),10x,5(f8.2,1x),10x,25(f8.2,1x))'
599 [ + + ]: 25 : if (bigDOS) frmt = '(f11.5,1x,5(f10.4,1x),10x,5(f8.2,1x),10x,25(f8.2,1x))'
600 : : ! for extra atoms in vacuum need more precision
601 : 25 : frmt_extra = '(f11.5,1x,5(f20.16,1x),10x,5(f20.16,1x),10x,25(f20.16,1x))'
602 : :
603 [ + + ]: 60 : do iat=1,natsph
604 : 35 : i1 = (iat-1)*mbesslang+1; i2 = iat*mbesslang
605 [ + + ]: 60 : if (prtdosm==0) then
606 [ + + ]: 216542 : do iene=1,nene
607 : 216511 : write(unt_atsph(iat), fmt=frmt) enemin + (iene-1)*deltaene, &
608 [ + + ]: 1515608 : min(total_dos(iene, i1:i2, 1), dos_max), total_dos(iene, i1:i2,2)
609 : : end do
610 : : else
611 [ + + ]: 18008 : do iene=1,nene
612 : 18004 : write(unt_atsph(iat), fmt=frmt) enemin + (iene-1)*deltaene, &
613 [ + + ]: 108024 : min(total_dos(iene, i1:i2, 1), dos_max),&
614 : 18004 : total_dos(iene, i1:i2, 2),&
615 [ + + ]: 486112 : min(dos_m(iene,(iat-1)*mbesslang**2+1:iat*mbesslang**2,1), dos_max)
616 : : end do
617 : : end if
618 : : end do
619 : :
620 : : ! Extra spheres.
621 [ + + ]: 37 : do iat=natsph+1,natsph+natsph_extra
622 : 12 : i1 = (iat-1)*mbesslang+1; i2 = iat*mbesslang
623 [ + - ]: 37 : if (prtdosm==0) then
624 [ + + ]: 14424 : do iene=1,nene
625 : 14412 : write(unt_atsph(iat), fmt=frmt_extra) enemin + (iene-1)*deltaene, &
626 : 14412 : total_dos(iene, i1:i2, 1), &
627 : 28836 : total_dos(iene, i1:i2, 2)
628 : : end do
629 : : else
630 [ # # ]: 0 : do iene=1,nene
631 : 0 : write(unt_atsph(iat), fmt=frmt_extra) enemin + (iene-1)*deltaene, &
632 : 0 : total_dos(iene, i1:i2, 1),&
633 : 0 : total_dos(iene, i1:i2, 2),&
634 : 0 : dos_m(iene,(iat-1)*mbesslang**2+1:iat*mbesslang**2, 1)
635 : : end do
636 : : end if
637 : : end do
638 : :
639 : : else
640 : 0 : frmt = '(f11.5,1x,5(f9.4,1x),3(6x,5f9.4))'
641 [ # # ]: 0 : if (bigDOS) frmt = '(f11.5,1x,5(f10.4,1x),3(6x,5f10.4))'
642 : : ! for extra atom spheres in vacuum need more precision
643 : 0 : frmt_extra = '(f11.5,1x,5(f20.16,1x),3(6x,5f20.16))'
644 : :
645 [ # # ]: 0 : do iat=1,natsph
646 : 0 : i1 = iat*5-4; i2 = iat*5
647 [ # # ]: 0 : do iene=1,nene
648 : 0 : write(unt_atsph(iat), fmt=frmt) enemin + (iene-1)*deltaene, &
649 [ # # ]: 0 : min(total_dos(iene,i1:i2,1), dos_max),&
650 [ # # ]: 0 : min(total_dos(iene,i1:i2,1) - dos_paw1(iene,i1:i2,1) + dos_pawt1(iene,i1:i2,1), dos_max),&
651 [ # # ]: 0 : min(dos_paw1(iene,i1:i2,1), dos_max),&
652 [ # # ]: 0 : min(dos_pawt1(iene,i1:i2,1), dos_max)
653 : : end do
654 : : end do
655 : :
656 : : ! Extra spheres.
657 [ # # ]: 0 : do iat=natsph+1,natsph+natsph_extra
658 : 0 : i1 = iat*5-4; i2 = iat*5
659 [ # # ]: 0 : do iene=1,nene
660 : 0 : write(unt_atsph(iat), fmt=frmt_extra) enemin + (iene-1)*deltaene, &
661 [ # # ]: 0 : min(total_dos(iene,i1:i2,1), dos_max),&
662 [ # # ]: 0 : min(total_dos(iene,i1:i2,1) - dos_paw1(iene,i1:i2,1) + dos_pawt1(iene,i1:i2,1), dos_max),&
663 [ # # ]: 0 : min(dos_paw1(iene,i1:i2,1), dos_max),&
664 [ # # ]: 0 : min(dos_pawt1(iene,i1:i2,1), dos_max)
665 : : end do
666 : : end do
667 : : end if
668 : :
669 [ + - ]: 1 : else if (prtdos==5)then
670 : : ! E, SPIN-DOS
671 : 1 : frmt = '(f11.5,1x,7(f9.4,1x),10x,7(f8.2,1x))'
672 [ - + ]: 1 : if (bigDOS) frmt = '(f11.5,1x,7(f10.4,1x),10x,7(f8.2,1x))'
673 [ + + ]: 9402 : do iene=1,nene
674 [ + + ]: 75209 : write(unitdos, fmt=frmt) enemin + (iene-1)*deltaene, min(total_dos(iene,1:7,1), dos_max), total_dos(iene,1:7,2)
675 : : end do
676 : : end if
677 : :
678 : : 10 continue
679 [ + + ]: 464 : integral_DOS=sum(total_dos(nene,:,2))
680 : 52 : write(msg, '(a,es16.8)' ) ' tetrahedron : integrate to',integral_DOS
681 : 98 : call wrtout(std_out,msg)
682 : : end do ! isppol
683 : :
684 : : ! Close files.
685 [ + + ]: 46 : if (iam_master) then
686 [ + + ]: 25 : if (any(prtdos == [2, 5])) then
687 : 5 : close(unitdos)
688 [ + - ]: 20 : else if (prtdos == 3) then
689 [ + + ]: 82 : do iat=0,natsph+natsph_extra
690 : 82 : close(unt_atsph(iat))
691 : : end do
692 [ - + ]: 20 : ABI_FREE(unt_atsph)
693 : : end if
694 : : end if
695 : :
696 [ - + ]: 46 : ABI_FREE(tmp_eigen)
697 [ - + ]: 46 : ABI_FREE(total_dos)
698 [ - + ]: 46 : ABI_FREE(wdt)
699 [ - + ]: 46 : ABI_FREE(eig_dos)
700 : :
701 [ + + ]: 46 : if (prtdosm>=1) then
702 [ - + ]: 2 : ABI_FREE(dos_m)
703 : : end if
704 : :
705 [ - + ]: 46 : if (paw_dos_flag==1) then
706 [ # # ]: 0 : ABI_FREE(dos_paw1)
707 [ # # ]: 0 : ABI_FREE(dos_pawt1)
708 : : end if
709 : :
710 : 46 : call tetra%free()
711 : :
712 : 46 : call cwtime(cpu,wall,gflops,"stop")
713 : 46 : write(msg,'(2(a,f8.2),a)')" tetrahedron: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
714 [ - + - + : 138 : call wrtout(std_out,msg,"PERS")
- + - + -
+ - - - -
- + - - -
- - + - +
- + - + -
+ ]
715 : :
716 : : !write(std_out,*)' m_epjdos%dos_calcncwrite, exit '
717 : :
718 : : contains
719 : :
720 : 31 : subroutine write_extra_headers()
721 : :
722 [ + + ]: 31 : if (nsppol==2) then
723 [ + + ]: 12 : if(isppol==1) write(msg,'(a,16x,a)') '#','Spin-up DOS'
724 [ + + ]: 12 : if(isppol==2) write(msg,'(2a,16x,a)') ch10,'#','Spin-dn DOS'
725 : : ! NB: dtset%prtdos == 5 should not happen for nsppol==2
726 : :
727 [ + + ]: 12 : if (any(dtset%prtdos == [2, 5])) then
728 : 2 : write(unitdos, "(a)")trim(msg)
729 : :
730 [ + - ]: 10 : else if (dtset%prtdos == 3) then
731 [ + + ]: 30 : do iat=0,natsph+natsph_extra
732 : 30 : write(unt_atsph(iat), "(a)")trim(msg)
733 : : end do
734 : : end if
735 : :
736 : : end if
737 : :
738 [ + + ]: 31 : if (prtdos==2) then
739 : 5 : write(unitdos, '(a)' )'# energy(Ha) DOS integrated DOS'
740 : :
741 [ + + ]: 26 : else if (prtdos==3) then
742 : :
743 : 25 : write(unt_atsph(0), '(a)' )'# energy(Ha) DOS integrated DOS'
744 : :
745 [ - + - - ]: 25 : if (paw_dos_flag/=1.or.dtset%pawprtdos==2) then
746 [ + + ]: 60 : do iat=1,natsph
747 : : write(unt_atsph(iat), '(3a,i5,a,i5,a,a,es16.6,3a)' ) &
748 : 35 : '# Local DOS (columns 2-6) and integrated local DOS (columns 7-11),',ch10,&
749 : 35 : '# for atom number iat=',iat,' iatom=',dtset%iatsph(iat),ch10,&
750 : 70 : '# inside sphere of radius ratsph=',dtset%ratsph(dtset%typat(dtset%iatsph(iat))),' Bohr.',ch10,"#"
751 : :
752 [ + + + + ]: 35 : if (dtset%usepaw==1.and.dtset%pawprtdos==2) then
753 : : write(unt_atsph(iat), '(3a)' ) &
754 : 6 : '# PAW: note that only all-electron on-site part has been used to compute DOS !',ch10,"#"
755 : : end if
756 [ + + ]: 35 : if (bigDOS) then
757 : : write(msg, '(a,a)' ) &
758 : 14 : '# energy(Ha) l=0 l=1 l=2 l=3 l=4',&
759 : 28 : ' (integral=>) l=0 l=1 l=2 l=3 l=4'
760 : : else
761 : : write(msg, '(a,a)' ) &
762 : 21 : '# energy(Ha) l=0 l=1 l=2 l=3 l=4',&
763 : 42 : ' (integral=>) l=0 l=1 l=2 l=3 l=4'
764 : : end if
765 [ + + ]: 35 : if (prtdosm>=1) then
766 : 4 : write(msg, '(7a)' ) trim(msg),' ',&
767 : 4 : ' lm=0 0',&
768 : 4 : ' lm=1-1 lm=1 0 lm=1 1',&
769 : 4 : ' lm=2-2 lm=2-1 lm=2 0 lm=2 1 lm=2 2',&
770 : 4 : ' lm=3-3 lm=3-2 lm=3-1 lm=3 0 lm=3 1 lm=3 2 lm=3 3',&
771 : 8 : ' lm=4-4 lm=4-3 lm=4-2 lm=4-1 lm=4 0 lm=4 1 lm=4 2 lm=4 3 lm=4 4'
772 : : end if
773 : 60 : write(unt_atsph(iat), "(a)")trim(msg)
774 : : end do
775 : : else
776 [ # # ]: 0 : do iat=1,natsph
777 : : write(unt_atsph(iat), '(9a,i5,a,i5,a,a,es16.6,3a)' ) &
778 : 0 : '# Local DOS (columns 2-6),',ch10,&
779 : 0 : '# plane-waves contrib. to DOS (columns 7-11),',ch10,&
780 : 0 : '# AE on-site contrib. to DOS (columns 12-16),',ch10,&
781 : 0 : '# -PS on-site contrib. to DOS (columns 17-21),',ch10,&
782 : 0 : '# for atom number iat=',iat,' iatom=',dtset%iatsph(iat),ch10,&
783 : 0 : '# inside sphere of radius ratsph=',dtset%ratsph(dtset%typat(dtset%iatsph(iat))),' Bohr.',ch10,"#"
784 [ # # ]: 0 : if (bigDOS) then
785 : : write(msg, '(4a)' ) &
786 : 0 : '#energy(Ha) l=0 l=1 l=2 l=3 l=4',&
787 : 0 : ' (PW) l=0 l=1 l=2 l=3 l=4',&
788 : 0 : ' (Phi) l=0 l=1 l=2 l=3 l=4',&
789 : 0 : ' (tPhi) l=0 l=1 l=2 l=3 l=4'
790 : : else
791 : : write(msg, '(4a)' ) &
792 : 0 : '#energy(Ha) l=0 l=1 l=2 l=3 l=4',&
793 : 0 : ' (PW) l=0 l=1 l=2 l=3 l=4',&
794 : 0 : ' (Phi) l=0 l=1 l=2 l=3 l=4',&
795 : 0 : ' (tPhi) l=0 l=1 l=2 l=3 l=4'
796 : : end if
797 : 0 : write(unt_atsph(iat), "(a)")trim(msg)
798 : : end do
799 : : end if
800 [ + + ]: 37 : do iat=1,natsph_extra
801 : : write(unt_atsph(natsph+iat), '(3a,i5,2a,es16.6,3a)' ) &
802 : 12 : '# Local DOS (columns 2-6) and integrated local DOS (columns 7-11),',ch10,&
803 : 12 : '# for non-atomic sphere number iat=',iat,ch10,&
804 : 24 : '# of radius ratsph=',dtset%ratsph_extra,' Bohr.',ch10,"#"
805 [ - + ]: 12 : if (bigDOS) then
806 : : write(msg, '(a,a)' ) &
807 : 0 : '# energy(Ha) l=0 l=1 l=2 l=3 l=4',&
808 : 0 : ' (integral=>) l=0 l=1 l=2 l=3 l=4'
809 : : else
810 : : write(msg, '(a,a)' ) &
811 : 12 : '# energy(Ha) l=0 l=1 l=2 l=3 l=4',&
812 : 24 : ' (integral=>) l=0 l=1 l=2 l=3 l=4'
813 : : end if
814 [ - + ]: 12 : if (prtdosm>=1) then
815 : 0 : write(msg, '(7a)' ) trim(msg),' ',&
816 : 0 : ' lm=0 0',&
817 : 0 : ' lm=1-1 lm=1 0 lm=1 1',&
818 : 0 : ' lm=2-2 lm=2-1 lm=2 0 lm=2 1 lm=2 2',&
819 : 0 : ' lm=3-3 lm=3-2 lm=3-1 lm=3 0 lm=3 1 lm=3 2 lm=3 3',&
820 : 0 : ' lm=4-4 lm=4-3 lm=4-2 lm=4-1 lm=4 0 lm=4 1 lm=4 2 lm=4 3 lm=4 4'
821 : : end if
822 : 37 : write(unt_atsph(natsph+iat), "(a)")trim(msg)
823 : : end do
824 : :
825 [ + - ]: 1 : else if (prtdos==5) then
826 : : write(unitdos, '(a)' )&
827 : 1 : '# energy(Ha) DOS up,up up,dn dn,up dn,dn sigma_x sigma_y sigma_z and integrated DOS components'
828 : : end if ! prtdos value
829 : :
830 : 31 : end subroutine write_extra_headers
831 : :
832 : : end subroutine epjdos_calcnwrite
833 : : !!***
834 : :
835 : : !!****f* m_epjdos/recip_ylm
836 : : !! NAME
837 : : !! recip_ylm
838 : : !!
839 : : !! FUNCTION
840 : : !! Project input wavefunctions in reciprocal space on to Ylm
841 : : !! (real or complex harmonics depending on rc_ylm).
842 : : !!
843 : : !! INPUTS
844 : : !! bess_fit(mpw,nradintmax,ll) = Bessel functions for L, splined
845 : : !! with arguments $2 \pi |k+G| \Delta r$, for all G vectors in sphere
846 : : !! and all points on radial grid.
847 : : !! cg_1band(2,npw_k)=wavefunction in recip space (note that nspinor is missing, see Notes).
848 : : !! istwfk= storage mode of cg_1band
849 : : !! nradint(natsph)=number of points on radial real-space grid for a given atom.
850 : : !! nradintmax=dimension of rint array.
851 : : !! me_g0=1 if this processor has G=0, 0 otherwise
852 : : !! mlang=maximum angular momentum in Bessel functions.
853 : : !! mpw=Maximum number of planewaves. Used to dimension bess_fit
854 : : !! natsph=number of atoms around which ang mom projection has to be done
855 : : !! typat_extra(natsph)=Type of each atom. ntypat + 1 if empty sphere
856 : : !! mlang_type(ntypat + natsph_extra)=Max L+1 for each atom type
857 : : !! npw_k=number of plane waves for this kpt
858 : : !! nspinor=number of spinor components
859 : : !! ph3d(2,npw_k,natsph)=3-dim structure factors, for each atom and plane wave.
860 : : !! prtsphere= if 1, print a complete analysis of the angular momenta in atomic spheres
861 : : !! rint(nradintmax) = points on radial real-space grid for integration
862 : : !! rmax(natsph)=maximum radius for real space integration sphere
863 : : !! rc_ylm= 1 for real spherical harmonics. 2 for complex spherical harmonics,
864 : : !! ucvol=unit cell volume in bohr**3.
865 : : !! ylm_k(npw_k,mlang**2)=real spherical harmonics for each G and LM.
866 : : !! znucl_sph(natsph)=gives the nuclear number for each type of atom
867 : : !!
868 : : !! OUTPUT
869 : : !! sum_1ll_1atom(mlang,natsph)= projected scalars for each atom and ang. mom.
870 : : !! sum_1lm_1atom(mlang*mlang,natsph)= projected scalars for each atom and LM component.
871 : : !! cplx_1lm_1atom(2,dtset%nspinor**2,dos%mbesslang**2,natsph_tot) = complex projection of wave function on atomic like orbital
872 : : !!
873 : : !! NOTES
874 : : !! * ph3d atoms are ordered with natsph and must be provided by the caller in the correct order!
875 : : !!
876 : : !! * spinor components are not treated here. This facilitates the implementation of spinor parallelism
877 : : !! because the caller can easily call the routine inside a loop over spinors and then sum the
878 : : !! different contributions outside the loop thus reducing the number of MPI calls.
879 : : !!
880 : : !! SOURCE
881 : :
882 : 12852 : subroutine recip_ylm (bess_fit, cg_1band, istwfk, mpi_enreg, nradint, nradintmax, mlang,&
883 [ - + ]: 4284 : & mpw, natsph, typat_extra, mlang_type, npw_k, nspinor, ph3d, prtsphere, rint, rmax,&
884 [ - + ]: 4284 : & rc_ylm, sum_1ll_1atom, sum_1lm_1atom, cplx_1lm_1atom, ucvol, ylm_k, znucl_sph)
885 : :
886 : : !Arguments ------------------------------------
887 : : !scalars
888 : : integer,intent(in) :: istwfk,mlang,mpw,natsph,npw_k,nradintmax
889 : : integer,intent(in) :: nspinor
890 : : integer,intent(in) :: prtsphere,rc_ylm
891 : : real(dp),intent(in) :: ucvol
892 : : !arrays
893 : : integer,intent(in) :: nradint(natsph),typat_extra(natsph),mlang_type(:)
894 : : real(dp),intent(in) :: bess_fit(mpw,nradintmax,mlang),cg_1band(:,:) !(2,my_nspinor*npw_k)
895 : : real(dp),intent(in) :: ph3d(2,npw_k,natsph),rint(nradintmax)
896 : : real(dp),intent(in) :: rmax(natsph),ylm_k(npw_k,mlang*mlang)
897 : : real(dp),intent(in) :: znucl_sph(natsph)
898 : : type(MPI_type),intent(in) :: mpi_enreg
899 : : real(dp),intent(out) :: sum_1ll_1atom(nspinor**2, mlang, natsph)
900 : : real(dp),intent(out) :: sum_1lm_1atom(nspinor**2, mlang*mlang,natsph)
901 : : real(dp),intent(out) :: cplx_1lm_1atom(2,nspinor, mlang*mlang,natsph)
902 : :
903 : : !Local variables-------------------------------
904 : : !scalars
905 : : integer :: ilm,iat,ipw,ixint,ll,mm,il,jlm,ierr,lm_size,itypat, ispinor,ipauli, is, isp, my_nspinor
906 : : real(dp),parameter :: invsqrt2=one/sqrt2
907 : : real(dp) :: sum_all, dr, fact
908 : : type(atomdata_t) :: atom
909 : : character(len=500) :: msg
910 : : !arrays
911 : 8568 : integer :: ilang(mlang**2)
912 : 4284 : integer, allocatable :: ispinors(:)
913 : 8568 : real(dp) :: c1(2),c2(2), sum_1atom(natsph),sum_1ll(mlang),sum_1lm(mlang**2)
914 : 8568 : real(dp) :: func(nradintmax), func_cplx(nradintmax,2)
915 : 8568 : complex(dp) :: vect(npw_k)
916 : 4284 : complex(dp),allocatable :: tmppsia(:,:),tmppsim(:,:),dotc(:), values(:,:,:,:)
917 : : ! *************************************************************************
918 : :
919 : : ! Workspace array (used to reduce the number of MPI communications)
920 : : ! One could reduce a bit the memory requirement by using non-blocking operations ...
921 [ - + + - : 25704 : ABI_MALLOC_OR_DIE(values, (nradintmax, nspinor, mlang**2, natsph), ierr)
- + + - -
+ + - - +
+ - + - +
- + - - +
- + ]
922 [ + + + + : 81628070 : values = czero
+ + + + ]
923 : :
924 : 4284 : my_nspinor = max(1,nspinor/mpi_enreg%nproc_spinor)
925 [ - + + - : 17136 : ABI_MALLOC(tmppsia, (npw_k,my_nspinor))
- + + - +
- + - - +
- + ]
926 [ - + + - : 12852 : ABI_MALLOC(tmppsim, (npw_k,my_nspinor))
- + + - -
+ - + ]
927 [ - + + - : 12852 : ABI_MALLOC(dotc, (my_nspinor))
+ - - + -
+ ]
928 [ - + + - : 12852 : ABI_MALLOC(ispinors, (my_nspinor))
+ - - + -
+ ]
929 [ + + ]: 4284 : if (my_nspinor == 2) then
930 : 496 : ispinors(1) = 1
931 : 496 : ispinors(2) = 2
932 : : else
933 : 3788 : ispinors(1) = mpi_enreg%me_spinor+1
934 : : end if
935 : :
936 [ + + + + : 519720 : sum_1lm_1atom = zero
+ + ]
937 [ + + + + : 841520 : cplx_1lm_1atom = zero
+ + + + ]
938 : :
939 [ + + ]: 25704 : do ll=0,mlang-1
940 [ + + ]: 132804 : do mm=-ll,ll
941 : 107100 : ilm = (ll+1)**2-ll+mm
942 : 128520 : ilang(ilm) = ll+1
943 : : end do
944 : : end do
945 : :
946 : : ! Big loop on all atoms
947 [ + + ]: 10720 : do iat=1,natsph
948 : 6436 : itypat = typat_extra(iat)
949 : 6436 : lm_size = mlang_type(itypat) ** 2
950 : 6436 : dr = rmax(iat) / (nradint(iat)-1)
951 : :
952 : : ! u(G) e^{i(k+G).Ra}
953 : : ! tmppsia = Temporary array for part which depends only on iat
954 [ + + ]: 13768 : do ispinor=1,my_nspinor
955 [ + + ]: 1293880 : do ipw=1,npw_k
956 : : tmppsia(ipw,ispinor) = dcmplx(cg_1band(1,ipw+(ispinor-1)*npw_k),cg_1band(2,ipw+(ispinor-1)*npw_k)) &
957 : 1287444 : & * dcmplx(ph3d(1,ipw,iat), ph3d(2,ipw,iat))
958 : : end do
959 : : end do
960 : :
961 : : ! tmppsim = temporary arrays for part of psi which does not depend on ixint = tmppsia * ylm.
962 : : ! could remove this intermediate array to save memory...
963 : : ! u(G) Y_LM^*(k+G) e^{i(k+G).Ra}
964 : : ! Take into account the fact that ylm_k are REAL spherical harmonics, see initylmg.f
965 : : ! For time-reversal states, detailed treatment show that only the real or imaginary
966 : : ! part of tmppsia is needed here, depending on l being even or odd: only one of the coef is 1, the other 0
967 [ + + ]: 171620 : do ilm=1,lm_size
968 : 160900 : il = ilang(ilm)
969 : 160900 : ll = ilang(ilm) - 1
970 : 160900 : mm = ilm - (ll+1)**2 + ll
971 : :
972 : 160900 : select case (rc_ylm)
973 : : case (1)
974 : : ! to get PDOS for real spherical harmonics, simply multiply here by ylm_k
975 [ + + ]: 2750 : do ispinor=1,my_nspinor
976 [ + + ]: 497025 : do ipw=1,npw_k
977 : 495650 : tmppsim(ipw,ispinor) = tmppsia(ipw,ispinor) * ylm_k(ipw,ilm)
978 : : end do
979 : : end do
980 : :
981 : : ! Handle time-reversal
982 : : ! TODO: check if time reversal with spinors is special and may need some treatment.
983 : : ! normally SOC will simply impose istwfk 1 in appropriate cases (kptopt 4).
984 [ + + ]: 1375 : if (istwfk /= 1) then
985 [ + + ]: 400 : if (mod(ll, 2) == 0) then
986 [ + + + + ]: 64485 : tmppsim(:,:) = dcmplx(real(tmppsim(:,:)),zero)
987 : : else
988 [ + + + + ]: 42990 : tmppsim(:,:) = dcmplx(aimag(tmppsim(:,:)),zero)
989 : : end if
990 : : ! f2008 version:
991 : : ! if (mod(ll, 2) == 0) then
992 : : ! tmppsim(:,:)%im = zero
993 : : ! else
994 : : ! tmppsim(:,:)%re = tmppsim(:,:)%im
995 : : ! tmppsim(:,:)%im = zero
996 : : ! end if
997 : : end if
998 : :
999 : : case (2)
1000 : : ! to get PDOS for complex spherical harmonics, build linear combination of real ylm_k
1001 : 159525 : jlm = (ll+1)**2-ll-mm ! index of (l, -m)
1002 [ + + ]: 159525 : if (mm == 0) then
1003 [ + + ]: 5975930 : vect(:) = dcmplx(ylm_k(1:npw_k,ilm),zero)
1004 [ + + ]: 127620 : else if (mm > 0) then
1005 : : !vect(1,:) = invsqrt2 * ylm_k(1:npw_k,ilm) * (-1)**mm
1006 : : !vect(2,:) = +invsqrt2 * ylm_k(1:npw_k,jlm) * (-1)**mm
1007 : 63810 : c1 = sy(ll, mm, mm)
1008 : 63810 : c2 = sy(ll,-mm, mm)
1009 : : vect(:) = dcmplx(c1(1) * ylm_k(1:npw_k,ilm) + c2(1) * ylm_k(1:npw_k,jlm), &
1010 [ + + ]: 11951860 : c1(2) * ylm_k(1:npw_k,ilm) + c2(2) * ylm_k(1:npw_k,jlm))
1011 : :
1012 : : else if (mm < 0) then
1013 : : !vect(1,:) = invsqrt2 * ylm_k(1:npw_k,jlm) !* (-1)**mm
1014 : : !vect(2,:) = -invsqrt2 * ylm_k(1:npw_k,ilm) !* (-1)**mm
1015 : 63810 : c1 = sy(ll, mm, mm)
1016 : 63810 : c2 = sy(ll,-mm, mm)
1017 : : vect(:) = dcmplx(c1(1) * ylm_k(1:npw_k,ilm) + c2(1) * ylm_k(1:npw_k,jlm),&
1018 [ + + ]: 11951860 : c1(2) * ylm_k(1:npw_k,ilm) + c2(2) * ylm_k(1:npw_k,jlm))
1019 : : end if
1020 [ + + ]: 29879650 : vect(:) = dcmplx(real(vect(:)), -aimag(vect(:)))
1021 : : !vect(:)%im = -vect(:)%im
1022 : :
1023 [ + + ]: 159525 : if (istwfk == 1) then
1024 [ + + ]: 334700 : do ispinor=1,my_nspinor
1025 [ + + ]: 31602950 : do ipw=1,npw_k
1026 : 31446800 : tmppsim(ipw,ispinor) = tmppsia(ipw,ispinor) * vect(ipw)
1027 : : end do
1028 : : end do
1029 : : else
1030 : : ! Handle time-reversal
1031 [ + + ]: 3375 : if (mod(ll, 2) == 0) then
1032 [ + + ]: 4050 : do ispinor=1,my_nspinor
1033 [ + + ]: 148215 : do ipw=1,npw_k
1034 : 146190 : tmppsim(ipw,ispinor) = real(tmppsia(ipw,ispinor)) * vect(ipw)
1035 : : end do
1036 : : end do
1037 : : else
1038 [ + + ]: 2700 : do ispinor=1,my_nspinor
1039 [ + + ]: 98810 : do ipw=1,npw_k
1040 : 97460 : tmppsim(ipw,ispinor) = aimag(tmppsia(ipw,ispinor)) * vect(ipw)
1041 : : end do
1042 : : end do
1043 : : end if
1044 : : end if
1045 : :
1046 : : case default
1047 [ + + - ]: 160900 : ABI_ERROR("Wrong value for rc_ylm")
1048 : : end select
1049 : :
1050 : : ! Compute integral $ \int_0^{rc} dr r**2 ||\sum_G u(G) Y_LM^*(k+G) e^{i(k+G).Ra} j_L(|k+G| r)||**2 $
1051 : : ! or more general spinor case integral
1052 : : ! $ \int_0^{rc} dr r**2 dotc^*_s \sigma^x_{ss'} dotc_{s'}
1053 : : ! where dotc_s = \sum_G u_s (G) Y_LM^*(k+G) e^{i(k+G).Ra} j_L(|k+G| r)
1054 [ + + ]: 64389286 : do ixint=1,nradint(iat)
1055 [ + + ]: 134103100 : dotc = czero
1056 [ + + ]: 134103100 : do ispinor=1, my_nspinor
1057 [ + + ]: 16359986925 : do ipw=1,npw_k
1058 : 16295764975 : dotc(ispinor) = dotc(ispinor) + bess_fit(ipw, ixint, il) * tmppsim(ipw, ispinor)
1059 : : end do
1060 : : end do
1061 [ + + ]: 64221950 : if (istwfk /= 1) then
1062 [ + + ]: 2813950 : dotc = two * dotc
1063 [ + + - + ]: 1406975 : if (istwfk == 2 .and. mpi_enreg%me_g0 == 1) then
1064 [ + + ]: 876700 : dotc(:) = dotc(:) - bess_fit(1, ixint, il) * tmppsim(1, :)
1065 : : end if
1066 : : end if
1067 : :
1068 : : ! Store results to reduce number of xmpi_sum calls if MPI
1069 [ + + ]: 134264000 : do ispinor=1, my_nspinor
1070 : 134103100 : values(ixint, ispinors(ispinor), ilm, iat) = dotc(ispinor)
1071 : : end do
1072 : : end do ! ixint
1073 : :
1074 : : end do ! ilm
1075 : : end do ! iat
1076 : :
1077 [ - + ]: 4284 : ABI_FREE(tmppsia)
1078 [ - + ]: 4284 : ABI_FREE(tmppsim)
1079 [ - + ]: 4284 : ABI_FREE(dotc)
1080 [ - + ]: 4284 : ABI_FREE(ispinors)
1081 : :
1082 : : ! Collect results in comm_pw (data are distributed over plane waves)
1083 : 4284 : call xmpi_sum(values, mpi_enreg%comm_bandfft, ierr)
1084 : : ! ! Collect results in mpi_enreg%comm_spinor (data are distributed over spinor components)
1085 : 4284 : call xmpi_sum(values, mpi_enreg%comm_spinor, ierr)
1086 : :
1087 : : ! Multiply by r**2 and take norm, integrate
1088 [ + + ]: 10720 : do iat=1,natsph
1089 : 6436 : itypat = typat_extra(iat)
1090 : 6436 : lm_size = mlang_type(itypat) ** 2
1091 [ + + ]: 171620 : do ilm=1,lm_size
1092 : :
1093 [ + + ]: 509000 : do ipauli=0,nspinor**2-1
1094 [ + + ]: 111067650 : do ixint=1,nradint(iat)
1095 : 110719550 : func(ixint) = zero
1096 [ + + ]: 283435900 : do is=1,nspinor
1097 [ + + ]: 580145850 : do isp=1,nspinor
1098 : : func(ixint) = func(ixint) + real(conjg(values(ixint, is, ilm, iat)) * pauli_mat(is,isp,ipauli)*&
1099 : 469426300 : & values(ixint, isp, ilm, iat))
1100 : : end do
1101 : : end do
1102 : 111067650 : func(ixint) = rint(ixint)**2 * func(ixint)
1103 : : end do
1104 : : ! Here I should treat the case in which the last point /= rcut
1105 : : ! NB: indexing is from 1 not 0 for spin matrix components
1106 : 509000 : sum_1lm_1atom (ipauli+1, ilm, iat) = simpson(dr, func(1:nradint(iat)))
1107 : : end do ! ipauli
1108 : :
1109 [ + + ]: 390636 : do is = 1, nspinor
1110 [ + + ]: 81456450 : func_cplx(:,1) = real(values(:, is, ilm, iat))
1111 [ + + ]: 81456450 : func_cplx(:,2) = aimag(values(:, is, ilm, iat))
1112 [ + + ]: 79944450 : do ixint=1,nradint(iat)
1113 [ + + ]: 239386750 : func_cplx(ixint,:) = rint(ixint)**2 * func_cplx(ixint,:)
1114 : : end do
1115 : 223300 : cplx_1lm_1atom(1, is, ilm, iat) = simpson(dr, func_cplx(1:nradint(iat),1))
1116 : 384200 : cplx_1lm_1atom(2, is, ilm, iat) = simpson(dr, func_cplx(1:nradint(iat),2))
1117 : : end do
1118 : :
1119 : : end do ! ilm
1120 : : end do ! iat
1121 : :
1122 : : ! Normalize with unit cell volume and include 4pi term coming from Rayleigh expansion.
1123 : 4284 : fact = four_pi**2 / ucvol
1124 [ + + + + : 519720 : sum_1lm_1atom = fact * sum_1lm_1atom
+ + ]
1125 [ + + + + : 841520 : cplx_1lm_1atom = fact * cplx_1lm_1atom
+ + + + ]
1126 : :
1127 : : ! sum up the m-independent fractions
1128 [ + + + + : 112520 : sum_1ll_1atom = zero
+ + ]
1129 [ + + ]: 10720 : do iat=1,natsph
1130 : 6436 : itypat = typat_extra(iat)
1131 : 6436 : lm_size = mlang_type(itypat) ** 2
1132 [ + + ]: 171620 : do ilm=1,lm_size
1133 : 160900 : il = ilang(ilm)
1134 [ + + ]: 515436 : sum_1ll_1atom(:,il, iat) = sum_1ll_1atom(:,il, iat) + sum_1lm_1atom(:,ilm, iat)
1135 : : end do
1136 : : end do
1137 : :
1138 [ - + ]: 4284 : ABI_FREE(values)
1139 : :
1140 : : ! Output
1141 [ + + ]: 8568 : if (prtsphere == 1) then
1142 [ + + ]: 240 : sum_1ll = zero
1143 [ + + ]: 1040 : sum_1lm = zero
1144 [ + + ]: 95 : sum_1atom = zero
1145 [ + + ]: 95 : do iat=1,natsph
1146 [ + + ]: 1430 : sum_1atom(iat) = sum(sum_1lm_1atom(1,:,iat))
1147 [ + + ]: 330 : sum_1ll(:)=sum_1ll(:)+sum_1ll_1atom(1,:,iat)
1148 [ + + ]: 1470 : sum_1lm(:)=sum_1lm(:)+sum_1lm_1atom(1,:,iat)
1149 : : end do
1150 [ + + ]: 95 : sum_all = sum(sum_1atom)
1151 : :
1152 [ + - ]: 40 : if (rc_ylm == 1) msg = " Angular analysis (real spherical harmonics)"
1153 [ - + ]: 40 : if (rc_ylm == 2) msg = " Angular analysis (complex spherical harmonics)"
1154 : 40 : call wrtout(std_out, msg)
1155 [ + + ]: 95 : do iat=1,natsph
1156 : 55 : call atomdata_from_znucl(atom, znucl_sph(iat))
1157 : 55 : call wrtout(std_out, " ")
1158 : 55 : write(msg,'(a,i3,a,a,a,f10.6)' )' Atom # ',iat, ' is ', atom%symbol,', in-sphere charge =',sum_1atom(iat)
1159 : 55 : call wrtout(std_out, msg)
1160 [ + + ]: 425 : do ll=0,mlang-1
1161 : : write(msg,'(a,i1,a,f9.6,a,9f6.3)' )&
1162 : 275 : ' l=',ll,', charge=',sum_1ll_1atom(1,ll+1,iat),&
1163 : 550 : ', m=-l,l splitting:',sum_1lm_1atom(1,1+ll**2:(ll+1)**2,iat)
1164 : 330 : call wrtout(std_out, msg)
1165 : : end do ! ll
1166 : : end do ! iat
1167 : 40 : write(msg,'(a,a)') ch10,' Sum of angular contributions for all atomic spheres '
1168 : 40 : call wrtout(std_out, msg)
1169 [ + + ]: 240 : do ll=0,mlang-1
1170 : : write(msg,'(a,i1,a,f9.6,a,f9.6)' )&
1171 : 200 : ' l=',ll,', charge =',sum_1ll(ll+1),' proportion =',sum_1ll(ll+1)/sum_all
1172 : 240 : call wrtout(std_out, msg)
1173 : : end do
1174 : 40 : write(msg,'(a,a,f10.6)' ) ch10,' Total over all atoms and l=0 to 4 :',sum_all
1175 : 40 : call wrtout(std_out, msg)
1176 : 40 : call wrtout(std_out, " ")
1177 : : end if
1178 : :
1179 : : contains
1180 : :
1181 [ - + ]: 255240 : function sy(ll, mm, mp)
1182 : : use m_paw_sphharm, only : ys
1183 : : ! Computes the matrix element <Slm|Ylm'>
1184 : : integer,intent(in) :: ll,mm, mp
1185 : :
1186 : : real(dp) :: sy(2)
1187 : : complex(dp) :: ys_val
1188 : :
1189 : : ! Computes the matrix element <Yl'm'|Slm>
1190 : 255240 : call ys(ll,mp,ll,mm,ys_val)
1191 : : !call ys(ll,mm,ll,mp,ys_val)
1192 : 255240 : sy(1) = real(ys_val)
1193 : 255240 : sy(2) = -aimag(ys_val)
1194 : :
1195 : : end function sy
1196 : :
1197 : : end subroutine recip_ylm
1198 : : !!***
1199 : :
1200 : : !!****f* m_epjdos/dens_in_sph
1201 : : !! NAME
1202 : : !! dens_in_sph
1203 : : !!
1204 : : !! FUNCTION
1205 : : !! Calculate integrated density in sphere around each atom
1206 : : !!
1207 : : !! INPUTS
1208 : : !! cg = wavefunction coefficitents in recip space
1209 : : !! gmet = metric in recip space
1210 : : !! istwfk = storage mode for cg coefficients
1211 : : !! kg_k = G vector indices
1212 : : !! natom = number of atoms
1213 : : !! mpi_enreg=information about MPI parallelization
1214 : : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
1215 : : !! npw_k = number of plane waves for this kpoint
1216 : : !! ph1d = phase factors for different atoms for all G vectors
1217 : : !! rmax(natom) = max radius to integrate to (in bohr)
1218 : : !!
1219 : : !! OUTPUT
1220 : : !! cmax = integrated density for each atom for a rmax-radius sphere
1221 : : !!
1222 : : !! WARNING
1223 : : !! cg should not be modified by fourwf.
1224 : : !!
1225 : : !! SOURCE
1226 : :
1227 : 40 : subroutine dens_in_sph(cmax,cg,gmet,istwfk,kg_k,natom,ngfft,mpi_enreg,npw_k,&
1228 : 40 : & ph1d,rmax,ucvol)
1229 : :
1230 : : !Arguments ------------------------------------
1231 : : !scalars
1232 : : integer,intent(in) :: istwfk,natom,npw_k
1233 : : real(dp),intent(in) :: ucvol
1234 : : type(MPI_type),intent(in) :: mpi_enreg
1235 : : !arrays
1236 : : integer,intent(in) :: kg_k(3,npw_k),ngfft(18)
1237 : : real(dp),intent(in) :: gmet(3,3)
1238 : : real(dp),intent(in) :: ph1d(2,(2*ngfft(1)+1+2*ngfft(2)+1+2*ngfft(3)+1)*natom)
1239 : : real(dp),intent(in) :: rmax(natom)
1240 : : real(dp),intent(inout) :: cg(2,npw_k)
1241 : : real(dp),intent(out) :: cmax(natom)
1242 : :
1243 : : !Local variables -------------------------
1244 : : !scalars
1245 : : integer,parameter :: tim_fourwf=0
1246 : : integer :: cplex,i1,i2,i3,iatom,id1,id2,id3,ifft,mgfft,n1,n2,n3,n4,n5,n6,nfft,nfftot
1247 : : real(dp) :: cmaxr,g1,g2,g3,norm,weight
1248 : : !arrays
1249 : : integer :: ngfft_here(18)
1250 : 40 : integer,allocatable :: garr(:,:),gbound(:,:)
1251 : 40 : real(dp),allocatable :: denpot(:,:,:),fofgout(:,:),fofr(:,:,:,:),gnorm(:)
1252 : 40 : real(dp),allocatable :: ph3d(:,:,:),phkxred(:,:),rhog(:,:),rhor(:), sphrhog(:,:)
1253 : : ! *********************************************************************
1254 : :
1255 : 40 : n1=ngfft(1)
1256 : 40 : n2=ngfft(2)
1257 : 40 : n3=ngfft(3)
1258 : 40 : n4=ngfft(4)
1259 : 40 : n5=ngfft(5)
1260 : 40 : n6=ngfft(6)
1261 : 40 : nfftot = n1*n2*n3
1262 : 40 : nfft=n1*n2*n3
1263 : 40 : ngfft_here(:) = ngfft(:)
1264 : : !fourwf doesnt work with other options for mode 0 (fft G -> r)
1265 : 40 : ngfft_here(7)=111
1266 : 40 : ngfft_here(8)=256
1267 [ + + ]: 160 : mgfft=maxval(ngfft_here(1:3))
1268 : :
1269 : 40 : call sqnorm_g(norm,istwfk,npw_k,cg,mpi_enreg%me_g0,mpi_enreg%comm_fft)
1270 : :
1271 [ - + ]: 40 : if (abs(one-norm) > tol6) then
1272 : 0 : write(std_out,'(a,f8.5)' ) ' dens_in_sph : this state is not normalized : norm=',norm
1273 : : end if
1274 : :
1275 : : !-----------------------------------------------------------------
1276 : : !inverse FFT of wavefunction to real space => density in real space
1277 : : !-----------------------------------------------------------------
1278 [ + - - + : 160 : ABI_MALLOC(gbound,(2*mgfft+8,2))
+ - + - +
- + - - +
- + ]
1279 : 40 : call sphereboundary(gbound,istwfk,kg_k,mgfft,npw_k)
1280 : :
1281 : 40 : weight = one
1282 : 40 : cplex=1
1283 [ - + + - : 200 : ABI_MALLOC(denpot,(cplex*n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
1284 [ + + + + : 500360 : denpot(:,:,:)=zero
+ + ]
1285 [ - + + - : 120 : ABI_MALLOC(fofgout,(2,npw_k))
+ - + - -
+ - + ]
1286 [ - + + - : 200 : ABI_MALLOC(fofr,(2,n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
1287 : :
1288 : : call fourwf(cplex,denpot,cg,fofgout,fofr,gbound,gbound, &
1289 : : istwfk,kg_k,kg_k,mgfft,mpi_enreg,1,ngfft_here,npw_k,&
1290 : 40 : npw_k,n4,n5,n6,1,tim_fourwf,weight,weight)
1291 : :
1292 [ - + ]: 40 : ABI_FREE(fofgout)
1293 [ - + ]: 40 : ABI_FREE(fofr)
1294 [ - + ]: 40 : ABI_FREE(gbound)
1295 : :
1296 [ + + + + : 500360 : norm = sum(denpot(:,:,:))/nfftot
+ + ]
1297 [ - + ]: 40 : if (abs(one-norm) > tol6) then
1298 : 0 : write(std_out,'(a,f8.5)') ' dens_in_sph : this state is not normalized in real space : norm=',norm
1299 : : end if
1300 : :
1301 : : !-----------------------------------------------------------------
1302 : : !FFT of new density: we obtain n(G) in rhog(1,:)
1303 : : !-----------------------------------------------------------------
1304 : :
1305 : : !Change the packing of the reciprocal space density
1306 [ - + + - : 120 : ABI_MALLOC(rhor,(nfft))
+ - + - -
+ - + ]
1307 : 40 : call fftpac(1,mpi_enreg,1,n1,n2,n3,n4,n5,n6,ngfft,rhor,denpot,1)
1308 : :
1309 [ - + + - : 120 : ABI_MALLOC(rhog,(2,nfft))
+ - + - -
+ - + ]
1310 : 40 : call fourdp(1,rhog,rhor,-1,mpi_enreg,nfft,1,ngfft,0)
1311 : :
1312 [ - + ]: 40 : ABI_FREE(rhor)
1313 [ - + ]: 40 : ABI_FREE(denpot)
1314 : :
1315 [ + + ]: 439208 : do ifft=1,nfft
1316 [ + + ]: 1317544 : rhog(:,ifft) = rhog(:,ifft) / ucvol
1317 : : end do
1318 : :
1319 : : !-----------------------------------------------------------------
1320 : : !calculate norms of G vectors
1321 : : !-----------------------------------------------------------------
1322 : :
1323 [ - + + - : 120 : ABI_MALLOC(garr,(3,nfft))
+ - + - -
+ - + ]
1324 [ - + + - : 80 : ABI_MALLOC(gnorm,(nfft))
- + - + ]
1325 : 40 : id3=ngfft(3)/2+2 ; id2=ngfft(2)/2+2 ; id1=ngfft(1)/2+2
1326 [ + + ]: 920 : do i3=1,n3
1327 : 880 : g3=i3-(i3/(id3))*ngfft(3)-one
1328 [ + + ]: 20472 : do i2=1,n2
1329 : 19552 : g2=i2-(i2/(id2))*ngfft(2)-one
1330 [ + + ]: 459600 : do i1=1,n1
1331 : 439168 : g1=i1-(i1/(id1))*ngfft(1)-one
1332 : 439168 : ifft=i1+(i2-1)*n1+(i3-1)*n1*n2
1333 : 439168 : garr(1,ifft)=nint(g1)
1334 : 439168 : garr(2,ifft)=nint(g2)
1335 : 439168 : garr(3,ifft)=nint(g3)
1336 : : gnorm(ifft)=sqrt(gmet(1,1)*g1*g1 + &
1337 : : & two*gmet(2,1)*g2*g1 + &
1338 : : & two*gmet(3,1)*g3*g1 + &
1339 : : & gmet(2,2)*g2*g2 + &
1340 : : & gmet(3,2)*g3*g2 + &
1341 : 458720 : & gmet(3,3)*g3*g3)
1342 : : end do
1343 : : end do
1344 : : end do
1345 : :
1346 : : !-----------------------------------------------------------------
1347 : : !For each atom call sphericaldens to calculate
1348 : : !n(G) * 1/|G|^3 * int_0^2*\pi*r_{max}*|G| 4 \pi y^2 j_0 (y) dy
1349 : : !for all G vectors put into array sphrhog
1350 : : !scalar product of phase factors with spherically convoluted density
1351 : : !-----------------------------------------------------------------
1352 : :
1353 : : !largest mem occupation = nfft * (2(sphrog) +2*1(ph3d) +3(garr) +2(rhog) +1(gnorm)) = nfft * 10
1354 [ - + + - : 80 : ABI_MALLOC(sphrhog,(2,nfft))
- + - + ]
1355 [ - + + - : 120 : ABI_MALLOC(phkxred,(2,natom))
+ - + - -
+ - + ]
1356 [ + + ]: 95 : phkxred(1,:)=one
1357 [ + + ]: 95 : phkxred(2,:)=zero
1358 [ - + + - : 80 : ABI_MALLOC(ph3d,(2,nfft,1))
- + - + ]
1359 : :
1360 [ + + ]: 95 : do iatom=1,natom
1361 : :
1362 : 55 : call sphericaldens(rhog,gnorm,nfft,rmax(iatom),sphrhog)
1363 : : ! -----------------------------------------------------------------
1364 : : ! Compute the phases for the whole set of fft vectors
1365 : : ! -----------------------------------------------------------------
1366 : :
1367 : 55 : call ph1d3d(iatom,iatom,garr,natom,natom,nfft,ngfft(1),ngfft(2),ngfft(3),phkxred,ph1d,ph3d)
1368 : :
1369 : : ! For the phase factors, take the compex conjugate, before evaluating the scalar product
1370 [ + + ]: 542519 : do ifft=1,nfft
1371 : 542519 : ph3d(2,ifft,1)=-ph3d(2,ifft,1)
1372 : : end do
1373 : 55 : cplex=2
1374 : 55 : call dotprod_v(cplex,cmaxr,nfft,1,0,ph3d,sphrhog,mpi_enreg%comm_fft)
1375 : 95 : cmax(iatom) = cmaxr
1376 : : ! write(std_out,'(a,i4,a,es14.6,a,es12.6)' )' dens_in_sph : At ', iatom, ' has ',cmaxr, ' el.s in a sphere of rad ', rmax
1377 : : end do
1378 : :
1379 [ - + ]: 40 : ABI_FREE(rhog)
1380 [ - + ]: 40 : ABI_FREE(gnorm)
1381 [ - + ]: 40 : ABI_FREE(garr)
1382 [ - + ]: 40 : ABI_FREE(sphrhog)
1383 [ - + ]: 40 : ABI_FREE(ph3d)
1384 [ - + ]: 40 : ABI_FREE(phkxred)
1385 : :
1386 : 40 : end subroutine dens_in_sph
1387 : : !!***
1388 : :
1389 : : !!****f* m_epjdos/sphericaldens
1390 : : !! NAME
1391 : : !! sphericaldens
1392 : : !!
1393 : : !! FUNCTION
1394 : : !! Compute the convolution of a function with
1395 : : !! the unity constant function over a sphere of radius rmax .
1396 : : !! The function is to be given in reciprocal space,
1397 : : !! the resulting function is also given in reciprocal space.
1398 : : !! The routine needs the norm of the reciprocal space vectors.
1399 : : !!
1400 : : !! The resulting function in reciprocal space can give the
1401 : : !! integral of the density in any sphere of that radius, centered
1402 : : !! on any point, by a simple scalar product.
1403 : : !!
1404 : : !! INPUTS
1405 : : !! fofg(2,nfft)=initial function, in reciprocal space
1406 : : !! gnorm(nfft)=norm of the reciprocal space vectors
1407 : : !! nfft=(effective) number of FFT grid points (for this processor)
1408 : : !! rmax=radius of the sphere
1409 : : !!
1410 : : !! OUTPUT
1411 : : !! sphfofg(2,nfft)=convoluted function, in reciprocal space
1412 : : !!
1413 : : !! SOURCE
1414 : :
1415 : 55 : subroutine sphericaldens(fofg,gnorm,nfft,rmax,sphfofg)
1416 : :
1417 : : !Arguments ------------------------------------
1418 : : !scalars
1419 : : integer,intent(in) :: nfft
1420 : : real(dp),intent(in) :: rmax
1421 : : !arrays
1422 : : real(dp),intent(in) :: fofg(2,nfft),gnorm(nfft)
1423 : : real(dp),intent(out) :: sphfofg(2,nfft)
1424 : :
1425 : : !Local variables-------------------------------
1426 : : !scalars
1427 : : integer :: ifft
1428 : : real(dp) :: factor,int0yy,rmax_2pi,yy
1429 : : ! *************************************************************************
1430 : :
1431 : 55 : rmax_2pi=two_pi*rmax
1432 : 55 : factor=four_pi/(two_pi)**3
1433 : :
1434 [ + + ]: 542519 : do ifft=1,nfft
1435 [ + + ]: 542519 : if(abs(gnorm(ifft)) < tol12)then
1436 : 55 : sphfofg(1,ifft)=fofg(1,ifft)*four_pi*third*rmax**3
1437 : 55 : sphfofg(2,ifft)=fofg(2,ifft)*four_pi*third*rmax**3
1438 : : else
1439 : 542409 : yy=gnorm(ifft)*rmax_2pi
1440 : 542409 : int0yy=factor*(sin(yy)-yy*cos(yy))/(gnorm(ifft)**3)
1441 : 542409 : sphfofg(1,ifft)=fofg(1,ifft)*int0yy
1442 : 542409 : sphfofg(2,ifft)=fofg(2,ifft)*int0yy
1443 : : end if
1444 : : end do
1445 : :
1446 : 55 : end subroutine sphericaldens
1447 : : !!***
1448 : :
1449 : : !!****f* m_epjdos/epjdos_prtfatbands
1450 : : !! NAME
1451 : : !! epjdos_prtfatbands
1452 : : !!
1453 : : !! FUNCTION
1454 : : !! Print dos_fractions_m in order to plot easily fatbands
1455 : : !! if pawfatbnd=1 1 : fatbands are resolved in L.
1456 : : !! if pawfatbnd=1 2 : fatbands are resolved in L and M.
1457 : : !!
1458 : : !! INPUTS
1459 : : !! dos_fractions_m(nkpt,mband,nsppol,ndosfraction*mbesslang*m_dos_flag)
1460 : : !! = m-resolved projected dos inside PAW sphere.
1461 : : !! dtset = Input variables
1462 : : !! ebands<ebands_t>=Band structure data.
1463 : : !! pawfatbnd = keyword for fatbands
1464 : : !! mbesslang =maximum angular momentum for Bessel function expansion
1465 : : !! m_dos_flag =option for the m-contributions to the partial DOS
1466 : : !! ndosfraction =natsph*mbesslang
1467 : : !!
1468 : : !! OUTPUT
1469 : : !! (only writing)
1470 : : !!
1471 : : !! NOTES
1472 : : !! This routine should be called by master only
1473 : : !!
1474 : : !! SOURCE
1475 : :
1476 : 1 : subroutine epjdos_prtfatbands(dos,dtset,ebands,fildata,pawfatbnd,pawtab)
1477 : :
1478 : : !Arguments ------------------------------------
1479 : : !scalars
1480 : : class(epjdos_t),intent(in) :: dos
1481 : : integer,intent(in) :: pawfatbnd
1482 : : type(ebands_t),intent(in) :: ebands
1483 : : type(dataset_type),intent(in) :: dtset
1484 : : character(len=fnlen),intent(in) :: fildata
1485 : : !arrays
1486 : : type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
1487 : :
1488 : : !Local variables-------------------------------
1489 : : !scalars
1490 : : integer :: iall,il,iat,natsph,inbfatbands,iband,mband,ixfat,isppol,nkpt,lmax,ll,mm
1491 : : integer :: ikpt,nband_k,ndosfraction,mbesslang
1492 : : real(dp) :: xfatband,cpu,wall,gflops
1493 : : character(len=1) :: tag_l,tag_1m,tag_is
1494 : : character(len=2) :: tag_2m
1495 : : character(len=10) :: tag_il,tag_at,tag_grace
1496 : : character(len=1500) :: msg
1497 : : character(len=fnlen) :: tmpfil
1498 : : type(atomdata_t) :: atom
1499 : : !arrays
1500 : : integer :: units(2)
1501 : 1 : integer,allocatable :: unitfatbands_arr(:,:)
1502 : 1 : real(dp),allocatable :: eigenvalues(:,:,:)
1503 : : character(len=2) :: symbol
1504 : : !*************************************************************************
1505 : :
1506 : : DBG_ENTER("COLL")
1507 : :
1508 [ + + ]: 3 : units = [std_out, ab_out]
1509 : 1 : ndosfraction = dos%ndosfraction; mbesslang = dos%mbesslang
1510 : :
1511 [ - + ]: 1 : if(dos%prtdosm.ne.0) then
1512 : : write(msg,'(3a)')&
1513 : 0 : 'm decomposed dos is activated',ch10, &
1514 : 0 : 'Action: deactivate it with prtdosm=0 !'
1515 : 0 : ABI_ERROR(msg)
1516 : : end if
1517 : :
1518 [ - + ]: 1 : if(dtset%nspinor==2) then
1519 : 0 : ABI_WARNING("Fatbands are not yet available in the case nspinor==2!")
1520 : : end if
1521 : :
1522 [ - + ]: 1 : ABI_CHECK(allocated(dos%fractions_m), "dos%fractions_m is not allocated!")
1523 : :
1524 : 1 : natsph=dtset%natsph
1525 : 1 : nkpt=dtset%nkpt
1526 : 1 : mband=dtset%mband
1527 : :
1528 [ - + ]: 1 : if(natsph>1000) then
1529 : : write(msg,'(3a)')&
1530 : 0 : 'Too big number of fat bands!',ch10, &
1531 : 0 : 'Action: decrease natsph in input file !'
1532 : 0 : ABI_ERROR(msg)
1533 : : end if
1534 : :
1535 : : !-------------- PRINTING IN LOG
1536 : 1 : call cwtime(cpu, wall, gflops, "start")
1537 : 1 : write(msg,'(a,a,a,a,i5,a,a,1000i5)') ch10," ***** Print of fatbands activated ****** ",ch10,&
1538 : 1 : " Number of atom: natsph = ",natsph,ch10, &
1539 [ + - + + ]: 6 : " atoms are = ",(dtset%iatsph(iat),iat=1,natsph)
1540 : 1 : call wrtout(units, msg)
1541 : 1 : iall=0;inbfatbands=0
1542 : :
1543 [ - + ]: 1 : if(pawfatbnd==1) then
1544 : 0 : inbfatbands=mbesslang-1
1545 : 0 : write(msg,'(3a)')" (fatbands are in eV and are given for each value of L)",ch10
1546 [ + - ]: 1 : else if(pawfatbnd==2) then
1547 : 1 : write(msg,'(3a)')" (fatbands are in eV and are given for each value of L and M)",ch10
1548 : 1 : inbfatbands=(mbesslang-1)**2
1549 : : end if
1550 : 1 : call wrtout(units, msg)
1551 : :
1552 : 1 : write(msg,'(a,e12.5,a,e12.5,a)') " Fermi energy is ",ebands%fermie*Ha_eV," eV = ",ebands%fermie," Ha"
1553 : 1 : call wrtout(std_out,msg)
1554 : :
1555 : : !-------------- OPEN AND NAME FILES FOR FATBANDS
1556 [ - + + - : 4 : ABI_MALLOC(unitfatbands_arr,(natsph*inbfatbands,dtset%nsppol))
- + + - +
- + - - +
- + ]
1557 [ + + + + ]: 66 : unitfatbands_arr = -3
1558 : :
1559 [ + + ]: 5 : do iat=1,natsph
1560 : 4 : lmax=(pawtab(dtset%typat(dtset%iatsph(iat)))%l_size-1)/2
1561 : 4 : call int2char4(dtset%iatsph(iat),tag_at)
1562 [ - + ]: 4 : ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
1563 : 4 : call atomdata_from_znucl(atom,dtset%znucl(dtset%typat(dtset%iatsph(iat))))
1564 : 4 : symbol = atom%symbol
1565 [ + + ]: 69 : do il=1,inbfatbands
1566 : 64 : iall=iall+1
1567 : 64 : ll=int(sqrt(float(il-1))) ! compute l
1568 [ + + ]: 68 : if(ll.le.lmax) then ! print only angular momentum included in the PAW data
1569 [ + + ]: 72 : do isppol=1,dtset%nsppol
1570 : 36 : write(tag_is,'(i1)')isppol
1571 [ - + ]: 36 : if(pawfatbnd==1) then
1572 : 0 : call int2char4(il-1,tag_il)
1573 [ # # ]: 0 : ABI_CHECK((tag_il(1:1)/='#'),'Bug: string length too short!')
1574 [ # # # # ]: 0 : tmpfil = trim(fildata)//'_at'//trim(tag_at)//'_'//trim(adjustl(symbol))//'_is'//tag_is//'_l'//trim(tag_il)
1575 [ + - ]: 36 : else if (pawfatbnd==2) then
1576 : 36 : write(tag_l,'(i1)') ll
1577 : 36 : mm=il-(ll**2+ll+1) ! compute m
1578 [ + + ]: 36 : if(mm<0) write(tag_2m,'(i2)') mm
1579 [ + + ]: 36 : if(mm>=0) write(tag_1m,'(i1)') mm
1580 [ + + ]: 36 : if(mm<0) tmpfil = trim(fildata)// &
1581 [ + - + - ]: 12 : & '_at'//trim(tag_at)//'_'//trim(adjustl(symbol))//'_is'//tag_is//'_l'//tag_l//'_m'//tag_2m
1582 [ + + ]: 36 : if(mm>=0) tmpfil = trim(fildata)// &
1583 [ + - + - ]: 24 : & '_at'//trim(tag_at)//'_'//trim(adjustl(symbol))//'_is'//tag_is//'_l'//tag_l//'_m+'//tag_1m
1584 : : end if
1585 : : !unitfatbands_arr(iall,isppol)=tmp_unit+100+iall-1+(natsph*inbfatbands)*(isppol-1)
1586 : : !open (unit=unitfatbands_arr(iall,isppol),file=trim(tmpfil),status='unknown',form='formatted')
1587 [ - + ]: 36 : if (open_file(tmpfil, msg, newunit=unitfatbands_arr(iall,isppol), status='unknown',form='formatted') /= 0) then
1588 : 0 : ABI_ERROR(msg)
1589 : : end if
1590 : :
1591 : 36 : write(msg,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitfatbands_arr(iall,isppol)
1592 : 36 : call wrtout(std_out,msg)
1593 : 36 : write(msg,'(9a)') "# ",ch10,"# ABINIT package : FATBAND file ", ch10,&
1594 : 36 : "# It contains, for each band: the eigenvalues in eV (and the character of the band) as a function of the k-point",&
1595 : 72 : ch10,"# This file can be read with xmgrace (http://plasma-gate.weizmann.ac.il/Grace/) ",ch10,"# "
1596 : 36 : write(unitfatbands_arr(iall,isppol), "(a)")trim(msg)
1597 [ + + ]: 1116 : do iband=1,mband
1598 : 1080 : call int2char4(iband-1,tag_grace)
1599 [ - + ]: 1080 : ABI_CHECK((tag_grace(1:1)/='#'),'Bug: string length too short!')
1600 : 1080 : write(msg,'(16a)') ch10,"@ s",trim(tag_grace)," line color 1",&
1601 : 1080 : ch10,"@ s",trim(tag_grace)," errorbar color 2",&
1602 : 1080 : ch10,"@ s",trim(tag_grace)," errorbar riser linewidth 5.0", &
1603 : 2160 : ch10,"@ s",trim(tag_grace)," errorbar linestyle 0"
1604 : 1116 : write(unitfatbands_arr(iall,isppol), "(a)")trim(msg)
1605 : : end do !iband
1606 : 72 : write(unitfatbands_arr(iall,isppol), '(a,a)') ch10,'@type xydy'
1607 : : end do ! isppol
1608 : : end if ! ll=<lmax
1609 : : end do ! il
1610 : : end do ! iat
1611 : :
1612 [ - + ]: 1 : if(iall.ne.(natsph*inbfatbands)) then
1613 : 0 : ABI_ERROR("error1 ")
1614 : : end if
1615 : :
1616 : : !-------------- WRITE FATBANDS IN FILES
1617 [ + - ]: 1 : if (pawfatbnd>0) then
1618 : : ! Store eigenvalues with nkpt as first dimension for efficiency reasons
1619 [ - + + - : 5 : ABI_MALLOC(eigenvalues,(nkpt,mband,dtset%nsppol))
- + + - -
+ + - + -
+ - - + -
+ ]
1620 [ + + ]: 2 : do isppol=1,dtset%nsppol
1621 [ + + ]: 18 : do ikpt=1,nkpt
1622 : 16 : nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
1623 [ + + ]: 497 : do iband=1,mband
1624 : 496 : eigenvalues(ikpt,iband,isppol)= ebands%eig(iband, ikpt, isppol) - ebands%fermie
1625 : : end do
1626 : : end do
1627 : : end do
1628 : 1 : iall=0
1629 [ + + ]: 5 : do iat=1,natsph
1630 : 4 : lmax=(pawtab(dtset%typat(dtset%iatsph(iat)))%l_size-1)/2
1631 [ + + ]: 69 : do il=1,inbfatbands
1632 : 64 : iall=iall+1
1633 : 64 : ll=int(sqrt(float(il-1)))
1634 [ + + ]: 68 : if(ll.le.lmax) then
1635 [ + + ]: 72 : do isppol=1,dtset%nsppol
1636 [ + + ]: 1116 : do iband=1,mband
1637 : 1080 : write(unitfatbands_arr(iall,isppol),'(a,a,i8)') ch10,"# BAND number :",iband
1638 [ + + ]: 18396 : do ikpt=1,nkpt
1639 [ - + ]: 17280 : if(pawfatbnd==1) then
1640 : 0 : xfatband=0.d0
1641 [ # # ]: 0 : do ixfat=(il-1)**2+1,il**2
1642 : 0 : xfatband=xfatband+dos%fractions_m(ikpt,iband,isppol,(iat-1)*mbesslang**2+ixfat)
1643 : : end do ! ixfat
1644 [ + - ]: 17280 : else if (pawfatbnd==2) then
1645 : 17280 : xfatband=dos%fractions_m(ikpt,iband,isppol,(iat-1)*mbesslang**2+il)
1646 : : end if
1647 : : write(unitfatbands_arr(iall,isppol),'(i5,e20.5,e20.5)')&
1648 : 18360 : ikpt-1,eigenvalues(ikpt,iband,isppol)*Ha_eV,xfatband
1649 : : end do ! ikpt
1650 : : end do !iband
1651 : 72 : write(unitfatbands_arr(iall,isppol),'(a)') '&'
1652 : : !close(unitfatbands_arr(iall,isppol))
1653 : : end do !isppol
1654 : : end if
1655 : : end do ! il
1656 : : end do ! iat
1657 [ - + ]: 1 : ABI_FREE(eigenvalues)
1658 : : end if
1659 : :
1660 [ + + ]: 2 : do isppol=1,size(unitfatbands_arr, dim=2)
1661 [ + + ]: 66 : do iat=1,size(unitfatbands_arr, dim=1)
1662 [ + + ]: 65 : if (unitfatbands_arr(iat, isppol) /= -3) close (unitfatbands_arr(iat, isppol))
1663 : : end do
1664 : : end do
1665 : :
1666 [ - + ]: 1 : ABI_FREE(unitfatbands_arr)
1667 : :
1668 : 1 : call cwtime(cpu,wall,gflops,"stop")
1669 : 1 : write(msg,'(2(a,f8.2),a)')" epjdos_prtfatbands: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
1670 : 1 : call wrtout(std_out,msg,"PERS")
1671 : :
1672 : : DBG_EXIT("COLL")
1673 : :
1674 : 2 : end subroutine epjdos_prtfatbands
1675 : : !!***
1676 : :
1677 : : !----------------------------------------------------------------------
1678 : :
1679 : : !!****f* m_epjdos/epjdos_ncwrite
1680 : : !! NAME
1681 : : !! epjdos_ncwrite
1682 : : !!
1683 : : !! FUNCTION
1684 : : !! Write PJDOS contributions to netcdf file.
1685 : : !!
1686 : : !! INPUTS
1687 : : !! crystal<crystal_t>=Object defining the unit cell and its symmetries.
1688 : : !! ebands<ebands_t>=Band structure data.
1689 : : !! hdr<hdr_t>=Abinit header
1690 : : !! dtset<dtset_type>=Dataset type
1691 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
1692 : : !! pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
1693 : : !! ncid=NC file handle.
1694 : : !!
1695 : : !! OUTPUT
1696 : : !! Only writing
1697 : : !!
1698 : : !! SOURCE
1699 : :
1700 : 28 : subroutine epjdos_ncwrite(dos, crystal, ebands, hdr, dtset, psps, pawtab, ncid)
1701 : :
1702 : : !Arguments ------------------------------------
1703 : : !scalars
1704 : : class(epjdos_t),intent(in) :: dos
1705 : : integer,intent(in) :: ncid
1706 : : type(crystal_t),intent(in) :: crystal
1707 : : type(ebands_t),intent(in) :: ebands
1708 : : type(hdr_type),intent(in) :: hdr
1709 : : type(dataset_type),intent(in) :: dtset
1710 : : type(pseudopotential_type),intent(in) :: psps
1711 : : !arrays
1712 : : type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*dtset%usepaw)
1713 : :
1714 : : !Local variables-------------------------------
1715 : : !scalars
1716 : : integer :: itype,ncerr,fform
1717 : : real(dp) :: cpu,wall,gflops
1718 : : character(len=500) :: msg
1719 : : !arrays
1720 : 56 : integer :: lmax_type(crystal%ntypat)
1721 : : !*************************************************************************
1722 : :
1723 [ - + ]: 28 : ABI_CHECK(dtset%natsph > 0, "natsph <=0")
1724 : 28 : call cwtime(cpu, wall, gflops, "start")
1725 : :
1726 : 28 : fform = fform_from_ext("FATBANDS.nc")
1727 [ - + ]: 28 : ABI_CHECK(fform /= 0, "Cannot find fform associated to FATBANDS.nc")
1728 : :
1729 : : ! Write header, crystal structure and band energies.
1730 [ - + ]: 28 : NCF_CHECK(hdr%ncwrite(ncid, fform, nc_define=.True.))
1731 [ - + ]: 28 : NCF_CHECK(crystal%ncwrite(ncid))
1732 [ - + ]: 28 : NCF_CHECK(ebands%ncwrite(ncid))
1733 : :
1734 : : ! Add fatband-specific quantities
1735 : : ncerr = nctk_def_dims(ncid, [ &
1736 : : nctkdim_t("natsph", dtset%natsph), &
1737 [ + + ]: 84 : nctkdim_t("ndosfraction", dos%ndosfraction)], defmode=.True.)
1738 [ - + ]: 28 : NCF_CHECK(ncerr)
1739 : :
1740 [ + + ]: 28 : if (dos%ndosfraction*dos%mbesslang > 0) then
1741 : : ncerr = nctk_def_dims(ncid, [ &
1742 : : nctkdim_t("mbesslang", dos%mbesslang), &
1743 [ + + ]: 72 : nctkdim_t("dos_fractions_m_lastsize", dos%ndosfraction*dos%mbesslang)])
1744 [ - + ]: 24 : NCF_CHECK(ncerr)
1745 : : end if
1746 [ + + ]: 28 : if (dtset%natsph_extra /= 0) then
1747 [ + + - + : 2 : NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("natsph_extra", dtset%natsph_extra)]))
- - ]
1748 : : end if
1749 : :
1750 [ + + ]: 112 : ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "prtdos", "pawprtdos", "prtdosm"])
1751 [ - + ]: 28 : NCF_CHECK(ncerr)
1752 [ + + ]: 56 : ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "ratsph_extra"])
1753 [ - + ]: 28 : NCF_CHECK(ncerr)
1754 : :
1755 : : ncerr = nctk_def_arrays(ncid, [&
1756 : : nctkarr_t("lmax_type", "int", "number_of_atom_species"), &
1757 : : nctkarr_t("iatsph", "int", "natsph"), &
1758 : : nctkarr_t("ratsph", "dp", "number_of_atom_species"), &
1759 : : nctkarr_t("dos_fractions", "dp", "number_of_kpoints, max_number_of_states, number_of_spins, ndosfraction") &
1760 [ + + ]: 140 : ])
1761 [ - + ]: 28 : NCF_CHECK(ncerr)
1762 : :
1763 [ + + ]: 28 : if (allocated(dos%fractions_m)) then
1764 : : ncerr = nctk_def_arrays(ncid, &
1765 : : nctkarr_t("dos_fractions_m", "dp", &
1766 : 3 : "number_of_kpoints, max_number_of_states, number_of_spins, dos_fractions_m_lastsize"))
1767 [ - + ]: 3 : NCF_CHECK(ncerr)
1768 : : end if
1769 : :
1770 [ + + ]: 28 : if (allocated(dos%fractions_paw1)) then
1771 : : ncerr = nctk_def_arrays(ncid, [&
1772 : : nctkarr_t("dos_fractions_paw1", "dp", "number_of_kpoints, max_number_of_states, number_of_spins, ndosfraction"), &
1773 : : nctkarr_t("dos_fractions_pawt1", "dp", "number_of_kpoints, max_number_of_states, number_of_spins, ndosfraction") &
1774 [ + + ]: 24 : ])
1775 [ - + ]: 8 : NCF_CHECK(ncerr)
1776 : : end if
1777 : :
1778 [ + + ]: 28 : if (dtset%natsph_extra /= 0) then
1779 : : ncerr = nctk_def_arrays(ncid, [&
1780 : : nctkarr_t("xredsph_extra", "dp", "number_of_reduced_dimensions, natsph_extra") &
1781 [ + + ]: 2 : ])
1782 [ - + ]: 1 : NCF_CHECK(ncerr)
1783 : : end if
1784 : :
1785 : : ! Write variables
1786 [ - + ]: 28 : NCF_CHECK(nctk_set_datamode(ncid))
1787 : :
1788 : : ! scalars
1789 [ - + ]: 28 : NCF_CHECK(nf90_put_var(ncid, vid("pawprtdos"), dtset%pawprtdos))
1790 [ - + ]: 28 : NCF_CHECK(nf90_put_var(ncid, vid("prtdos"), dos%prtdos))
1791 [ - + ]: 28 : NCF_CHECK(nf90_put_var(ncid, vid("prtdosm"), dos%prtdosm))
1792 : :
1793 : : ! arrays
1794 [ + + ]: 28 : if (dtset%usepaw == 1) then
1795 [ + + ]: 22 : lmax_type = (pawtab(:)%l_size - 1) / 2
1796 : : else
1797 [ + + ]: 38 : do itype=1,crystal%ntypat
1798 [ + + ]: 121 : lmax_type(itype) = maxval(psps%indlmn(1, :, itype))
1799 : : end do
1800 : : end if
1801 [ - + ]: 28 : NCF_CHECK(nf90_put_var(ncid, vid("lmax_type"), lmax_type))
1802 [ - + ]: 28 : NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions"), dos%fractions))
1803 : :
1804 [ + + ]: 28 : if (dos%prtdos == 3) then
1805 [ - + ]: 20 : NCF_CHECK(nf90_put_var(ncid, vid("iatsph"), dtset%iatsph(1:dtset%natsph)))
1806 [ - + ]: 20 : NCF_CHECK(nf90_put_var(ncid, vid("ratsph"), dtset%ratsph(1:dtset%ntypat)))
1807 [ - + ]: 20 : NCF_CHECK(nf90_put_var(ncid, vid("ratsph_extra"), dtset%ratsph_extra))
1808 [ + + ]: 20 : if (dtset%natsph_extra /= 0) then
1809 [ - + ]: 1 : NCF_CHECK(nf90_put_var(ncid, vid("xredsph_extra"), dtset%xredsph_extra(:, 1:dtset%natsph_extra)))
1810 : : end if
1811 : : end if
1812 : :
1813 [ + + ]: 28 : if (allocated(dos%fractions_m)) then
1814 [ - + ]: 3 : NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions_m"), dos%fractions_m))
1815 : : end if
1816 [ + + ]: 28 : if (allocated(dos%fractions_paw1)) then
1817 [ - + ]: 8 : NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions_paw1"), dos%fractions_paw1))
1818 [ - + ]: 8 : NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions_pawt1"), dos%fractions_pawt1))
1819 : : end if
1820 : :
1821 : 28 : call cwtime(cpu,wall,gflops,"stop")
1822 : 28 : write(msg,'(2(a,f8.2),a)')" epjdos_ncwrite: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
1823 : 28 : call wrtout(std_out,msg,"PERS")
1824 : :
1825 : : contains
1826 : 220 : integer function vid(vname)
1827 : : character(len=*),intent(in) :: vname
1828 : 220 : vid = nctk_idname(ncid, vname)
1829 : : end function vid
1830 : :
1831 : : end subroutine epjdos_ncwrite
1832 : : !!***
1833 : :
1834 : : !!****f* m_epjdos/partial_dos_fractions
1835 : : !! NAME
1836 : : !! partial_dos_fractions
1837 : : !!
1838 : : !! FUNCTION
1839 : : !! calculate partial DOS fractions to feed to the tetrahedron method
1840 : : !! 1: project states on angular momenta
1841 : : !! 2: should be able to choose certain atoms or atom types, slabs of space...
1842 : : !!
1843 : : !! INPUTS
1844 : : !! crystal<crystal_t>= data type gathering info on symmetries and unit cell
1845 : : !! dtset<type(dataset_type)>=all input variables for this dataset
1846 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
1847 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates.
1848 : : !! cg(2,mcg)=planewave coefficients of wavefunctions
1849 : : !! mcg=size of wave-functions array (cg) =mpw*my_nspinor*mband*mkmem*nsppol
1850 : : !! collect=1 if fractions should be MPI collected at the end, 0 otherwise.
1851 : : !! mpi_enreg=information about MPI parallelization
1852 : : !!
1853 : : !! SIDE EFFECTS
1854 : : !! dos%fractions(ikpt,iband,isppol,ndosfraction) = percentage of s, p, d..
1855 : : !! character on each atom for the wavefunction # ikpt,iband, isppol
1856 : : !! == if prtdosm /= 0
1857 : : !! dos%fractions_m(ikpt,iband,isppol,ndosfraction*mbesslang) = percentage of s, p, d..
1858 : : !! character on each atom for the wavefunction # ikpt,iband, isppol (m-resolved)
1859 : : !!
1860 : : !! NOTES
1861 : : !!
1862 : : !! psi(r) = (4pi/sqrt(ucvol)) \sum_{LMG} i**l u(G) e^{i(k+G).Ra} x Y_{LM}^*(k+G) Y_{LM}(r-Ra) j_L(|k+G||r-Ra|)
1863 : : !!
1864 : : !! int_(ratsph) |psi(r)|**2 = \sum_LM rho(LM)
1865 : : !!
1866 : : !! where
1867 : : !!
1868 : : !! rho_{LM} = 4pi \int_o^{rc} dr r**2 ||\sum_G u(G) Y_LM^*(k+G) e^{i(k+G).Ra} j_L(|k+G| r)||**2
1869 : : !!
1870 : : !! where S is a RSH. The final expression is:
1871 : : !!
1872 : : !! When k = G0/2, we have u_{G0/2}(G) = u_{G0/2}(-G-G0)^* and P can be rewritten as
1873 : : !!
1874 : : !! P = (4pi i^L}/sqrt(ucvol) \sum^'_G w(G) S_{LM}(k+G) \int_0^ratsph dr r^2 j_L(|k+G|r) x
1875 : : !! 2 Re[u_k(G) e^{i(k+G).R_atom}] if L = 2n
1876 : : !! 2 Im[u_k(G) e^{i(k+G).R_atom}] if L = 2n + 1
1877 : : !!
1878 : : !! where the sum over G is done on the reduced G-sphere and w(G) = 1/2 if G=G0 else 1.
1879 : : !!
1880 : : !! SOURCE
1881 : :
1882 : 42 : subroutine partial_dos_fractions(dos,crystal,dtset,eigen,occ,npwarr,kg,cg,mcg,collect,mpi_enreg)
1883 : :
1884 : : !Arguments ------------------------------------
1885 : : !scalars
1886 : : class(epjdos_t),intent(inout) :: dos
1887 : : integer,intent(in) :: mcg,collect
1888 : : type(MPI_type),intent(inout) :: mpi_enreg
1889 : : type(dataset_type),intent(in) :: dtset
1890 : : type(crystal_t),intent(in) :: crystal
1891 : : !arrays
1892 : : integer,intent(in) :: kg(3,dtset%mpw*dtset%mkmem),npwarr(dtset%nkpt)
1893 : : real(dp),intent(in) :: cg(2,mcg)
1894 : : real(dp),intent(in) :: eigen(dtset%mband*dtset%nkpt*dtset%nsppol)
1895 : : real(dp),intent(in) :: occ(dtset%mband*dtset%nkpt*dtset%nsppol)
1896 : :
1897 : : !Local variables-------------------------------
1898 : : !scalars
1899 : : integer,parameter :: prtsphere0=0 ! do not output all the band by band details for projections.
1900 : : integer :: shift_b,shift_sk,iat,iatom,iband,ierr,ikpt,ilang,ioffkg,is1, is2, isoff
1901 : : integer :: ipw,isppol,ixint,mbess,mcg_disk,me_kpt,shift_cg
1902 : : integer :: mgfft,my_nspinor,n1,n2,n3,natsph_tot,npw_k,nradintmax
1903 : : integer :: rc_ylm,itypat,nband_k, abs_shift_b, unit_procar, ipauli
1904 : : real(dp),parameter :: bessint_delta = 0.1_dp
1905 : : real(dp) :: arg,bessarg,bessargmax,kpgmax,rmax, cpu,wall,gflops
1906 : : character(len=500) :: msg
1907 : : character(len=4) :: ikproc_str
1908 : : character(len=fnlen) :: filename
1909 : 42 : type(jlspline_t) :: jlspl
1910 : 42 : type(MPI_type) :: mpi_enreg_seq
1911 : : !arrays
1912 [ + - ]: 42 : integer :: iindex(dtset%mpw),nband_tmp(1),npwarr_tmp(1)
1913 : 42 : integer,allocatable :: iatsph(:),nradint(:),atindx(:),typat_extra(:),kg_k(:,:)
1914 : : real(dp) :: kpoint(3),spin(3),ylmgr_dum(1)
1915 : 84 : real(dp) :: xfit(dtset%mpw),yfit(dtset%mpw)
1916 : 42 : real(dp),allocatable :: ylm_k(:,:), bess_fit(:,:,:)
1917 : 42 : real(dp),allocatable :: cg_1band(:,:),cg_1kpt(:,:),kpgnorm(:),ph1d(:,:)
1918 : 42 : real(dp),allocatable :: ph3d(:,:,:),ratsph(:),rint(:),sum_1ll_1atom(:,:,:)
1919 : 42 : real(dp),allocatable :: sum_1lm_1atom(:,:,:), cplx_1lm_1atom(:,:,:,:)
1920 : 42 : real(dp),allocatable :: xred_sph(:,:),znucl_sph(:),phkxred(:,:)
1921 : : complex(dp) :: cgcmat(2,2)
1922 : : !*************************************************************************
1923 : :
1924 : : ! write(std_out, '(a)') ' m_epjdos%partial_dos_fractions : enter '
1925 : :
1926 [ + + ]: 42 : if(dtset%natsph==dtset%natom)then
1927 : 26 : write(msg, '(a)') ' Compute the partial DOS fractions. This can be time-consuming. Think using natsph and iatsph.'
1928 : : else
1929 : 16 : write(msg, '(a)') ' Compute the partial DOS fractions.'
1930 : : endif
1931 : 42 : call wrtout(std_out,msg)
1932 : :
1933 : : ! for the moment, only support projection on angular momenta
1934 [ - + ]: 42 : if (dos%partial_dos_flag /= 1 .and. dos%partial_dos_flag /= 2) then
1935 : 0 : write(std_out,*) 'Error: partial_dos_fractions only supports angular '
1936 : 0 : write(std_out,*) ' momentum projection and spinor components for the moment. return to outscfcv'
1937 : 0 : write(std_out,*) ' partial_dos = ', dos%partial_dos_flag
1938 : 0 : return
1939 : : end if
1940 : :
1941 : : ! impose all kpoints have same number of bands
1942 [ + + ]: 89 : do isppol=1,dtset%nsppol
1943 [ + + ]: 443 : do ikpt=1,dtset%nkpt
1944 [ - + ]: 401 : if (dtset%nband((isppol-1)*dtset%nkpt + ikpt) /= dtset%mband) then
1945 : 0 : write(std_out,*) 'Error: partial_dos_fractions wants same number of bands at each kpoint'
1946 : 0 : write(std_out,*) ' isppol, ikpt = ', isppol,ikpt, dtset%nband((isppol-1)*dtset%nkpt + ikpt), dtset%mband
1947 : 0 : write(std_out,*) ' all nband = ', dtset%nband
1948 : 0 : return
1949 : : end if
1950 : : end do
1951 : : end do
1952 : :
1953 : : ! Real or complex spherical harmonics?
1954 [ - + ]: 42 : rc_ylm = 2; if (dos%prtdosm == 2) rc_ylm = 1
1955 : :
1956 : 42 : me_kpt = mpi_enreg%me_kpt
1957 : 42 : my_nspinor = max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
1958 : :
1959 : 42 : n1 = dtset%ngfft(1); n2 = dtset%ngfft(2); n3 = dtset%ngfft(3)
1960 : : mgfft = maxval(dtset%ngfft(1:3))
1961 : :
1962 : 42 : call cwtime(cpu, wall, gflops, "start")
1963 : :
1964 [ + + ]: 42 : if (dtset%prtprocar /= 0) then
1965 : : ! open file for each proc, and print header for master node
1966 : 1 : call int2char4(me_kpt, ikproc_str)
1967 : 1 : filename = 'PROCAR_'//ikproc_str
1968 [ - + ]: 1 : if (open_file(filename, msg, newunit=unit_procar, form="formatted", action="write") /= 0) then
1969 : 0 : ABI_ERROR(msg)
1970 : : end if
1971 [ + - ]: 1 : if(mpi_enreg%me==0) then
1972 : 1 : write (unit_procar,'(a)') 'PROCAR lm decomposed - need to merge files yourself in parallel case!!! Or use pyprocar package'
1973 [ + - ]: 1 : if (dtset%prtprocar == 2) then
1974 : 1 : write (unit_procar,'(a)') ' Requested complex output of PROCAR file (prtprocar 2)'
1975 : : end if
1976 : 1 : write (unit_procar,'(a,I10,a,I10,a,I10,a)') '# of k-points: ', dtset%nkpt, &
1977 : 2 : ' # of bands:', dtset%mband, ' # of ions:', dtset%natom, ch10
1978 : : end if
1979 : : end if
1980 : :
1981 : : !##############################################################
1982 : : !FIRST CASE: project on angular momenta to get dos parts
1983 : : !##############################################################
1984 : :
1985 [ + + ]: 42 : if (dos%partial_dos_flag == 1) then
1986 : 41 : natsph_tot = dtset%natsph + dtset%natsph_extra
1987 : :
1988 [ - + + - : 123 : ABI_MALLOC(iatsph, (natsph_tot))
+ - + - -
+ - + ]
1989 [ - + + - : 82 : ABI_MALLOC(typat_extra, (natsph_tot))
- + - + ]
1990 [ - + + - : 123 : ABI_MALLOC(ratsph, (natsph_tot))
+ - + - -
+ - + ]
1991 [ - + + - : 82 : ABI_MALLOC(znucl_sph, (natsph_tot))
- + - + ]
1992 [ - + + - : 82 : ABI_MALLOC(nradint, (natsph_tot))
- + - + ]
1993 [ - + + - : 82 : ABI_MALLOC(atindx, (natsph_tot))
- + - + ]
1994 [ - + + - : 123 : ABI_MALLOC(phkxred, (2,natsph_tot))
+ - + - -
+ - + ]
1995 : :
1996 : : ! initialize atindx
1997 [ + + ]: 114 : do iatom=1,natsph_tot
1998 : 114 : atindx(iatom) = iatom
1999 : : end do
2000 : :
2001 [ + + ]: 102 : iatsph(1:dtset%natsph) = dtset%iatsph(1:dtset%natsph)
2002 [ + + ]: 102 : do iatom=1,dtset%natsph
2003 : 61 : itypat = dtset%typat(iatsph(iatom))
2004 : 61 : typat_extra(iatom) = itypat
2005 : 61 : ratsph(iatom) = dtset%ratsph(itypat)
2006 : 102 : znucl_sph(iatom) = dtset%znucl(itypat)
2007 : : end do
2008 : :
2009 : : ! fictitious atoms are declared with
2010 : : ! %natsph_extra, %ratsph_extra and %xredsph_extra(3, dtset%natsph_extra)
2011 : : ! they have atom index (natom + ii) and itype = ntypat + 1
2012 [ + + ]: 53 : do iatom=1,dtset%natsph_extra
2013 : 12 : typat_extra(iatom+dtset%natsph) = dtset%ntypat + 1
2014 : 12 : ratsph(iatom+dtset%natsph) = dtset%ratsph_extra
2015 : 12 : znucl_sph(iatom+dtset%natsph) = zero
2016 : 53 : iatsph(iatom+dtset%natsph) = dtset%natom + iatom
2017 : : end do
2018 : :
2019 : : ! init bessel function integral for recip_ylm max ang mom + 1
2020 [ - + + - : 205 : ABI_MALLOC(sum_1ll_1atom,(dtset%nspinor**2,dos%mbesslang,natsph_tot))
- + + - -
+ + - + -
+ - - + -
+ ]
2021 [ - + + - : 205 : ABI_MALLOC(sum_1lm_1atom,(dtset%nspinor**2,dos%mbesslang**2,natsph_tot))
- + + - -
+ + - + -
+ - - + -
+ ]
2022 [ - + + - : 205 : ABI_MALLOC(cplx_1lm_1atom,(2,dtset%nspinor,dos%mbesslang**2,natsph_tot))
- + + - -
+ + - + -
+ - - + -
+ ]
2023 : :
2024 : : ! Note ecuteff instead of ecut.
2025 : 41 : kpgmax = sqrt(dtset%ecut * dtset%dilatmx**2)
2026 : 41 : rmax = zero; bessargmax = zero; nradintmax = 0
2027 [ + + ]: 114 : do iatom=1,natsph_tot
2028 : 73 : rmax = max(rmax, ratsph(iatom))
2029 : 73 : bessarg = ratsph(iatom)*two_pi*kpgmax
2030 : 73 : bessargmax = max(bessargmax, bessarg)
2031 : 73 : nradint(iatom) = int (bessarg / bessint_delta) + 1
2032 : 114 : nradintmax = max(nradintmax,nradint(iatom))
2033 : : end do
2034 : : !write(std_out,*)' partial_dos_fractions: rmax=', rmax,' nradintmax: ", nradintmax
2035 : : ! use same number of grid points to calculate Bessel function and to do the integration later on r
2036 : : ! and make sure bessargmax is a multiple of bessint_delta
2037 : 41 : mbess = nradintmax
2038 : 41 : bessargmax = bessint_delta*mbess
2039 : :
2040 [ - + + - : 123 : ABI_MALLOC(rint,(nradintmax))
+ - + - -
+ - + ]
2041 [ - + + - : 205 : ABI_MALLOC(bess_fit,(dtset%mpw,nradintmax,dos%mbesslang))
- + + - -
+ + - + -
+ - - + -
+ ]
2042 : :
2043 : : ! initialize general Bessel function array on uniform grid xx, from 0 to (2 \pi |k+G|_{max} |r_{max}|)
2044 : 41 : call jlspl%init(mbess, bessint_delta, dos%mbesslang)
2045 : :
2046 [ - + + - : 123 : ABI_MALLOC(xred_sph, (3, natsph_tot))
+ - + - -
+ - + ]
2047 [ + + ]: 102 : do iatom=1,dtset%natsph
2048 [ + + ]: 285 : xred_sph(:,iatom) = crystal%xred(:,iatsph(iatom))
2049 : : end do
2050 [ + + ]: 53 : do iatom=1,dtset%natsph_extra
2051 [ + + ]: 89 : xred_sph(:,dtset%natsph+iatom) = dtset%xredsph_extra(:, iatom)
2052 : : end do
2053 : :
2054 [ - + + - : 123 : ABI_MALLOC(ph1d,(2,(2*n1+1 + 2*n2+1 + 2*n3+1)*natsph_tot))
+ - + - -
+ - + ]
2055 : 41 : call getph(atindx,natsph_tot,n1,n2,n3,ph1d,xred_sph)
2056 : :
2057 : : ! Fake MPI data to be used for sequential call to initylmg.
2058 : 41 : call initmpi_seq(mpi_enreg_seq)
2059 : 41 : mpi_enreg_seq%my_natom = dtset%natom
2060 : :
2061 : 41 : shift_sk = 0
2062 : 41 : abs_shift_b = 0 ! offset to allow for automatic update with +1 below
2063 [ + + ]: 87 : do isppol=1,dtset%nsppol
2064 : 46 : ioffkg = 0
2065 : :
2066 [ + + ]: 431 : do ikpt=1,dtset%nkpt
2067 : 344 : nband_k = dtset%nband((isppol-1)*dtset%nkpt + ikpt)
2068 [ + + ]: 344 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) then
2069 : 78 : abs_shift_b = abs_shift_b + nband_k ! jump the whole kpt in the eig and occ arrays
2070 : 78 : cycle
2071 : : end if
2072 : 266 : npw_k = npwarr(ikpt)
2073 [ + + ]: 1064 : kpoint(:) = dtset%kpt(:,ikpt)
2074 : :
2075 [ + + ]: 266 : if (dtset%prtprocar /= 0) then
2076 : : write (unit_procar,'(a,I7,a,3F12.6,a,F12.6,a)') &
2077 : 8 : ' k-point ', ikpt, ' : ', kpoint(:), ' weight = ', dtset%wtk(ikpt), ch10
2078 : : end if
2079 : :
2080 : : ! make phkred for all atoms
2081 [ + + ]: 677 : do iat=1,natsph_tot
2082 : 411 : arg=two_pi*( kpoint(1)*xred_sph(1,iat) + kpoint(2)*xred_sph(2,iat) + kpoint(3)*xred_sph(3,iat) )
2083 : 411 : phkxred(1,iat)=cos(arg)
2084 : 677 : phkxred(2,iat)=sin(arg)
2085 : : end do
2086 : :
2087 [ - + + - : 798 : ABI_MALLOC(kg_k, (3, npw_k))
+ - + - -
+ - + ]
2088 [ - + + + : 210416 : kg_k = kg(:,ioffkg+1:ioffkg+npw_k)
+ + ]
2089 : :
2090 : : ! kpgnorm contains norms only for kpoints used by this processor
2091 [ - + + - : 798 : ABI_MALLOC(kpgnorm, (npw_k))
+ - + - -
+ - + ]
2092 : 266 : call getkpgnorm(crystal%gprimd, kpoint, kg_k, kpgnorm, npw_k)
2093 : :
2094 : : ! Now get Ylm(k, G) factors: returns "real Ylms", which are real (+m) and
2095 : : ! imaginary (-m) parts of actual complex Ylm. Yl-m = Ylm*
2096 : : ! Call initylmg for a single k-point (mind mpi_enreg_seq).
2097 [ - + + - : 1064 : ABI_MALLOC(ylm_k, (npw_k, dos%mbesslang**2))
- + + - +
- + - - +
- + ]
2098 : 266 : npwarr_tmp(1) = npw_k; nband_tmp(1) = nband_k
2099 : : call initylmg(crystal%gprimd,kg_k,kpoint,1,mpi_enreg_seq,dos%mbesslang,&
2100 : 266 : npw_k,nband_tmp,1,npwarr_tmp,1,0,crystal%rprimd,ylm_k,ylmgr_dum)
2101 : :
2102 : : ! get phases exp (2 pi i (k+G).x_tau) in ph3d
2103 [ - + + - : 1064 : ABI_MALLOC(ph3d,(2,npw_k,natsph_tot))
- + + - +
- + - - +
- + ]
2104 : 266 : call ph1d3d(1,natsph_tot,kg_k,natsph_tot,natsph_tot,npw_k,n1,n2,n3,phkxred,ph1d,ph3d)
2105 : :
2106 : : ! get Bessel function factors on array of |k+G|*r distances
2107 : : ! since we need many r distances and have a large number of different
2108 : : ! |k+G|, get j_l on uniform grid (above, in array gen_besj),
2109 : : ! and spline it for each kpt Gvector set.
2110 : : ! Note that we use the same step based on rmax, this can lead to (hopefully small)
2111 : : ! inaccuracies when we integrate from 0 up to rmax(iatom)
2112 [ + + ]: 113667 : do ixint=1,nradintmax
2113 : 113401 : rint(ixint) = (ixint-1)*rmax / (nradintmax-1)
2114 [ + + ]: 28972190 : do ipw=1,npw_k
2115 : 28858789 : xfit(ipw) = two_pi * kpgnorm(ipw) * rint(ixint)
2116 : 28972190 : iindex(ipw) = ipw
2117 : : end do
2118 : :
2119 : 113401 : call sort_dp(npw_k,xfit,iindex,tol14)
2120 [ + + ]: 680672 : do ilang=1,dos%mbesslang
2121 : 567005 : call splint(mbess, jlspl%xx, jlspl%bess_spl(:,ilang), jlspl%bess_spl_der(:,ilang), npw_k, xfit, yfit)
2122 : : ! re-order results for different G vectors
2123 [ + + ]: 144974351 : do ipw=1,npw_k
2124 : 144860950 : bess_fit(iindex(ipw),ixint,ilang) = yfit(ipw)
2125 : : end do
2126 : : end do
2127 : : end do ! ixint
2128 : :
2129 : 266 : shift_b = 0
2130 [ + + ]: 4510 : do iband=1,nband_k
2131 : 4244 : abs_shift_b = abs_shift_b + 1
2132 [ + - ]: 4244 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,isppol,me_kpt)) cycle
2133 : : !write(std_out,*)"in band:",iband
2134 : : ! TODO: eventually import eig and occ down to here - a pain, but printing outside would imply saving a huge array in memory
2135 [ + + ]: 4244 : if (dtset%prtprocar /= 0) then
2136 : 200 : write (unit_procar,'(a,I7,a,F12.6,a,F12.6,a)') 'band ', iband, ' # energy ', &
2137 : 400 : eigen(abs_shift_b), ' # occ. ', occ(abs_shift_b), ch10
2138 : : end if
2139 : :
2140 : : ! Select wavefunction in cg array
2141 : 4244 : shift_cg = shift_sk + shift_b
2142 : :
2143 : : call recip_ylm(bess_fit, cg(:,shift_cg+1:shift_cg+my_nspinor*npw_k), dtset%istwfk(ikpt),&
2144 : : & mpi_enreg, nradint, nradintmax, dos%mbesslang , dtset%mpw, natsph_tot, typat_extra, dos%mlang_type,&
2145 : : & npw_k, dtset%nspinor, ph3d, prtsphere0, rint, ratsph, rc_ylm, sum_1ll_1atom, sum_1lm_1atom, cplx_1lm_1atom,&
2146 : 4244 : & crystal%ucvol, ylm_k, znucl_sph)
2147 : : ! on exit the sum_1atom_* have both spinors counted
2148 : :
2149 : : ! Accumulate
2150 [ + + ]: 10625 : do iatom=1,natsph_tot
2151 [ + + ]: 42530 : do ilang=1,dos%mbesslang
2152 : : dos%fractions(ikpt,iband,isppol,dos%mbesslang*(iatom-1) + ilang) &
2153 : : & = dos%fractions(ikpt,iband,isppol,dos%mbesslang*(iatom-1) + ilang) &
2154 : 38286 : & + sum_1ll_1atom(1,ilang,iatom)
2155 : : end do
2156 : : end do
2157 : :
2158 [ + + ]: 4244 : if (dos%prtdosm /= 0) then
2159 [ + + ]: 409 : do iatom=1,natsph_tot
2160 [ + + ]: 5559 : do ilang=1,dos%mbesslang**2
2161 : : dos%fractions_m(ikpt,iband,isppol,dos%mbesslang**2*(iatom-1) + ilang) &
2162 : : & = dos%fractions_m(ikpt,iband,isppol,dos%mbesslang**2*(iatom-1) + ilang) &
2163 : 5356 : & + sum_1lm_1atom(1,ilang,iatom)
2164 : : end do
2165 : : end do
2166 : : end if
2167 : :
2168 : : ! Increment band, spinor shift
2169 : : !shift_b = shift_b + npw_k
2170 : 4244 : shift_b = shift_b + my_nspinor*npw_k
2171 : :
2172 : : ! now we have both spinor components. The first option is for real values projections, eventually decomposed by Pauli spinor components
2173 [ + + ]: 4510 : if (dtset%prtprocar /= 0) then
2174 : 200 : write (unit_procar,'(a)') 'ion s py pz px dxy dyz dz2 dxz dx2 tot'
2175 [ + + ]: 400 : do ipauli= 1,dtset%nspinor**2
2176 : : ! Contract with Pauli matrices to get projections for this k and band, all atoms and ilang
2177 [ + + ]: 400 : do iatom = 1, natsph_tot
2178 : 200 : write (unit_procar, '(1x,I5)', advance='no') iatom
2179 [ + + ]: 2000 : do ilang=1,min(dos%mbesslang**2,9)
2180 : 2000 : write (unit_procar, '(F7.3)',advance='no') sum_1lm_1atom(ipauli,ilang,iatom)
2181 : : end do
2182 [ + + ]: 5400 : write (unit_procar, '(F7.3)',advance='yes') sum(sum_1lm_1atom(ipauli,:,iatom))
2183 : : end do
2184 : : ! final line with sum over atoms
2185 : 200 : write (unit_procar, '(a)', advance='no') 'tot '
2186 [ + + ]: 2000 : do ilang=1,min(dos%mbesslang**2,9)
2187 [ + + ]: 3800 : write (unit_procar, '(F7.3)',advance='no') sum(sum_1lm_1atom(ipauli,ilang,:))
2188 : : end do
2189 [ + + + + ]: 5600 : write (unit_procar, '(F7.3)',advance='yes') sum(sum_1lm_1atom(ipauli,:,:))
2190 : : end do
2191 : :
2192 : : ! second option is to also print the complex projection on the atomic like orbital: <psi_nk | Y_lm> in a sphere
2193 : : ! Two blocks are printed, first real then imaginary part
2194 [ - + ]: 200 : if (dtset%prtprocar == 2) then
2195 : 200 : write (unit_procar,'(2a)') 'ion s py pz px',&
2196 : 400 : & ' dxy dyz dz2 dxz dx2 tot'
2197 [ + + ]: 400 : do is1= 1,dtset%nspinor
2198 : : ! Contracted with Pauli matrices to get projections for this k and band, all atoms and ilang
2199 [ + + ]: 400 : do iatom = 1, natsph_tot
2200 : 200 : write (unit_procar, '(1x,I5)', advance='no') iatom
2201 [ + + ]: 2000 : do ilang=1,min(dos%mbesslang**2,9)
2202 : 2000 : write (unit_procar, '(2(F7.3,1x))',advance='no') cplx_1lm_1atom(:,is1,ilang,iatom)
2203 : : end do
2204 [ + + ]: 5200 : write (unit_procar, '(2(F7.3,1x))',advance='yes') sum(cplx_1lm_1atom(1,is1,:,iatom)), &
2205 [ + + ]: 5600 : & sum(cplx_1lm_1atom(2,is1,:,iatom))
2206 : : end do
2207 : : ! final line with sum over atoms
2208 : 200 : write (unit_procar, '(a)', advance='no') 'charge'
2209 [ + + ]: 2000 : do ilang=1,min(dos%mbesslang**2,9)
2210 [ + + + + ]: 7400 : write (unit_procar, '(F7.3,9x)',advance='no') sum(cplx_1lm_1atom(:,is1,ilang,:)**2)
2211 : : end do
2212 [ + + + + : 15600 : write (unit_procar, '(F7.3,9x)',advance='yes') sum(cplx_1lm_1atom(:,is1,:,:)**2)
+ + ]
2213 : : end do
2214 : 200 : write (unit_procar,*)
2215 : : end if
2216 : : end if
2217 : :
2218 : : end do ! band
2219 : :
2220 : : ! Increment kpt and (spin, kpt) shifts
2221 : 266 : ioffkg = ioffkg + npw_k
2222 : 266 : shift_sk = shift_sk + nband_k*my_nspinor*npw_k
2223 : :
2224 [ - + ]: 266 : ABI_FREE(kg_k)
2225 [ - + ]: 266 : ABI_FREE(kpgnorm)
2226 [ - + ]: 266 : ABI_FREE(ylm_k)
2227 [ - + ]: 312 : ABI_FREE(ph3d)
2228 : : end do ! ikpt
2229 : : end do ! isppol
2230 : :
2231 : : ! collect = 1 ==> gather all contributions from different processors
2232 [ + - ]: 41 : if (collect == 1) then
2233 : 41 : call xmpi_sum(dos%fractions,mpi_enreg%comm_kpt,ierr)
2234 [ + + ]: 41 : if (dos%prtdosm /= 0) call xmpi_sum(dos%fractions_m,mpi_enreg%comm_kpt,ierr)
2235 : :
2236 : : ! this is now done inside recip_ylm
2237 : : ! if (mpi_enreg%paral_spinor == 1)then
2238 : : ! call xmpi_sum(dos%fractions,mpi_enreg%comm_spinor,ierr)
2239 : : ! if (dos%prtdosm /= 0) call xmpi_sum(dos%fractions_m,mpi_enreg%comm_spinor,ierr)
2240 : : ! end if
2241 : : end if
2242 : :
2243 [ - + ]: 41 : ABI_FREE(atindx)
2244 [ - + ]: 41 : ABI_FREE(bess_fit)
2245 [ - + ]: 41 : ABI_FREE(iatsph)
2246 [ - + ]: 41 : ABI_FREE(typat_extra)
2247 [ - + ]: 41 : ABI_FREE(nradint)
2248 [ - + ]: 41 : ABI_FREE(ph1d)
2249 [ - + ]: 41 : ABI_FREE(phkxred)
2250 [ - + ]: 41 : ABI_FREE(ratsph)
2251 [ - + ]: 41 : ABI_FREE(rint)
2252 [ - + ]: 41 : ABI_FREE(sum_1ll_1atom)
2253 [ - + ]: 41 : ABI_FREE(sum_1lm_1atom)
2254 [ - + ]: 41 : ABI_FREE(cplx_1lm_1atom)
2255 [ - + ]: 41 : ABI_FREE(xred_sph)
2256 [ - + ]: 41 : ABI_FREE(znucl_sph)
2257 : :
2258 : 41 : call jlspl%free()
2259 : 41 : call destroy_mpi_enreg(mpi_enreg_seq)
2260 : :
2261 : : !##############################################################
2262 : : !2ND CASE: project on spinors
2263 : : !##############################################################
2264 : :
2265 [ + - ]: 1 : else if (dos%partial_dos_flag == 2) then
2266 : :
2267 [ + - - + ]: 1 : if (dtset%nsppol /= 1 .or. dtset%nspinor /= 2) then
2268 : 0 : ABI_WARNING("spinor projection is meaningless if nsppol==2 or nspinor/=2. Not calculating projections.")
2269 : 0 : return
2270 : : end if
2271 [ - + ]: 1 : if (my_nspinor /= 2) then
2272 : 0 : ABI_WARNING("spinor projection with spinor parallelization is not coded. Not calculating projections.")
2273 : 0 : return
2274 : : end if
2275 [ - + ]: 1 : ABI_CHECK(mpi_enreg%paral_spinor == 0, "prtdos 5 does not support spinor parallelism")
2276 : :
2277 : : ! FIXME: We should not allocate such a large chunk of memory!
2278 : 1 : mcg_disk = dtset%mpw*my_nspinor*dtset%mband
2279 [ - + + - : 3 : ABI_MALLOC(cg_1kpt,(2,mcg_disk))
+ - + - -
+ - + ]
2280 : 1 : shift_sk = 0
2281 : 1 : isppol = 1
2282 : :
2283 [ + + ]: 11 : do ikpt=1,dtset%nkpt
2284 : 10 : nband_k = dtset%nband((isppol-1)*dtset%nkpt + ikpt)
2285 [ - + ]: 10 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) cycle
2286 : 10 : npw_k = npwarr(ikpt)
2287 : :
2288 [ + + + + ]: 793810 : cg_1kpt(:,:) = cg(:,shift_sk+1:shift_sk+mcg_disk)
2289 [ + - - + : 30 : ABI_MALLOC(cg_1band,(2,2*npw_k))
+ - + - +
- - + -
+ ]
2290 : 10 : shift_b=0
2291 [ + + ]: 310 : do iband=1,nband_k
2292 [ - + ]: 300 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,isppol,me_kpt)) cycle
2293 : :
2294 : : ! Select wavefunction in cg array
2295 : : !shift_cg = shift_sk + shift_b
2296 [ + + + + ]: 780960 : cg_1band(:,:) = cg_1kpt(:,shift_b+1:shift_b+2*npw_k)
2297 : 300 : call cg_getspin(cg_1band, npw_k, spin, cgcmat=cgcmat)
2298 : :
2299 : : ! MG: TODO: imag part of off-diagonal terms is missing.
2300 : : ! I will add them later on.
2301 [ + + ]: 900 : do is1=1,2
2302 [ + + ]: 2100 : do is2=1,2
2303 : 1200 : isoff = is2 + (is1-1)*2
2304 : : dos%fractions(ikpt,iband,isppol,isoff) = dos%fractions(ikpt,iband,isppol,isoff) &
2305 : 1800 : & + real(cgcmat(is1,is2))
2306 : : end do
2307 : : end do
2308 : :
2309 : 300 : dos%fractions(ikpt,iband,isppol,5) = dos%fractions(ikpt,iband,isppol,5) + spin(1)
2310 : 300 : dos%fractions(ikpt,iband,isppol,6) = dos%fractions(ikpt,iband,isppol,6) + spin(2)
2311 : 300 : dos%fractions(ikpt,iband,isppol,7) = dos%fractions(ikpt,iband,isppol,7) + spin(3)
2312 : :
2313 : 310 : shift_b = shift_b + 2*npw_k
2314 : : end do
2315 [ - + ]: 10 : ABI_FREE(cg_1band)
2316 : 11 : shift_sk = shift_sk + nband_k*2*npw_k
2317 : : end do
2318 [ - + ]: 1 : ABI_FREE(cg_1kpt)
2319 : :
2320 : : ! Gather all contributions from different processors
2321 [ + - ]: 1 : if (collect == 1) then
2322 : 1 : call xmpi_sum(dos%fractions,mpi_enreg%comm_kpt,ierr)
2323 : 1 : call xmpi_sum(dos%fractions,mpi_enreg%comm_bandfft,ierr)
2324 : : !below for future use - spinors should not be parallelized for the moment
2325 : : !if (mpi_enreg%paral_spinor == 1)then
2326 : : ! call xmpi_sum(dos%fractions,mpi_enreg%comm_spinor,ierr)
2327 : : !end if
2328 : : end if
2329 : :
2330 : : else
2331 : 0 : ABI_WARNING('only partial_dos==1 or 2 is coded')
2332 : : end if
2333 : :
2334 [ + + ]: 42 : if (dtset%prtprocar /= 0) close(unit_procar)
2335 : :
2336 : 42 : call cwtime(cpu,wall,gflops,"stop")
2337 : 42 : write(msg,'(2(a,f8.2),a)')" partial_dos_fractions: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
2338 : 42 : call wrtout(std_out,msg,"PERS")
2339 : : !write(std_out,*) ' m_epjdos%partial_dos_fractions : exit '
2340 : :
2341 [ - + - + : 42 : end subroutine partial_dos_fractions
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ ]
2342 : : !!***
2343 : :
2344 : : !!****f* m_epjdos/partial_dos_fractions_paw
2345 : : !! NAME
2346 : : !! partial_dos_fractions_paw
2347 : : !!
2348 : : !! FUNCTION
2349 : : !! Calculate PAW contributions to the partial DOS fractions (tetrahedron method)
2350 : : !!
2351 : : !! INPUTS
2352 : : !! cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk> and each |p_lmn> non-local projector
2353 : : !! dimcprj(natom)=array of dimensions of array cprj (not ordered)
2354 : : !! dtset structured datatype, from which one uses :
2355 : : !! iatsph(nasph)=number of atoms used to project dos
2356 : : !! kpt(3,nkpt) =irreducible kpoints
2357 : : !! mband =max number of bands per k-point
2358 : : !! mkmem =number of kpoints in memory
2359 : : !! natom =number of atoms in total
2360 : : !! natsph =number of atoms ofor which the spherical decomposition must be done
2361 : : !! nband =number of electronic bands for each kpoint
2362 : : !! nkpt =number of irreducible kpoints
2363 : : !! nspinor =number of spinor components
2364 : : !! nsppol =1 or 2 spin polarization channels
2365 : : !! fatbands_flag =1 if pawfatbnd=1 or 2
2366 : : !! mbesslang=maximum angular momentum for Bessel function expansion
2367 : : !! mpi_enreg=information about MPI parallelization
2368 : : !! prtdosm=option for the m-contributions to the partial DOS
2369 : : !! ndosfraction=natsph*mbesslang
2370 : : !! paw_dos_flag=option for the PAW contributions to the partial DOS
2371 : : !! pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data:
2372 : : !! pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
2373 : : !!
2374 : : !! OUTPUT
2375 : : !! === If paw_dos_flag==1:
2376 : : !! dos%fractions_paw1(ikpt,iband,isppol,natom*mbesslang) = contribution to
2377 : : !! dos fractions from the PAW partial waves (phi)
2378 : : !! dos%fractions_pawt1(ikpt,iband,isppol,natom*mbesslang) = contribution to
2379 : : !! dos fractions from the PAW pseudo partial waves (phi_tild)
2380 : : !!
2381 : : !! SIDE EFFECTS
2382 : : !! dos%fractions(ikpt,iband,isppol,ndosfraction) = percentage of s, p, d..
2383 : : !! character on each atom for the wavefunction # ikpt,iband, isppol
2384 : : !! As input: contains only the pseudo contribution
2385 : : !! As output: contains pseudo contribution + PAW corrections
2386 : : !! == if prtdosm==1
2387 : : !! dos%fractions_m(ikpt,iband,isppol,ndosfraction*mbesslang*prtdosm) =
2388 : : !! m discretization of partial DOS fractions
2389 : : !!
2390 : : !! SOURCE
2391 : :
2392 : 24 : subroutine partial_dos_fractions_paw(dos,cprj,dimcprj,dtset,mcprj,mkmem,mpi_enreg,pawrad,pawtab)
2393 : :
2394 : : !Arguments ------------------------------------
2395 : : !scalars
2396 : : class(epjdos_t),intent(inout) :: dos
2397 : : integer,intent(in) :: mcprj,mkmem
2398 : : type(MPI_type),intent(in) :: mpi_enreg
2399 : : type(dataset_type),intent(in) :: dtset
2400 : : !arrays
2401 : : integer,intent(in) :: dimcprj(dtset%natom)
2402 : : type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj)
2403 : : type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
2404 : : type(pawtab_type),target,intent(in) :: pawtab(dtset%ntypat)
2405 : :
2406 : : !Local variables-------------------------------
2407 : : !scalars
2408 : : integer :: bandpp,basis_size,comm_kptband,cplex,fatbands_flag,iat,iatom,iband,ibg,ibsp
2409 : : integer :: ierr,ikpt,il,ilang,ilmn,iln,im,iorder_cprj,ispinor,isppol,itypat,j0lmn,j0ln
2410 : : integer :: jl,jlmn,jln,jm,klmn,kln,lmn_size,mbesslang,me_band,me_kpt,my_nspinor
2411 : : integer :: nband_cprj_k,nband_k,ndosfraction,nprocband,nproc_spkptband,paw_dos_flag,prtdosm
2412 : : real(dp) :: cpij,one_over_nproc
2413 : : !character(len=500) :: msg
2414 : : !arrays
2415 : 24 : integer ,allocatable :: dimcprj_atsph(:)
2416 : 24 : integer,contiguous, pointer :: indlmn(:,:)
2417 : : real(dp) :: tsec(2)
2418 : 24 : real(dp),allocatable :: int1(:,:),int2(:,:),int1m2(:,:)
2419 : 24 : type(pawcprj_type),allocatable :: cprj_k(:,:)
2420 : : !******************************************************************************************
2421 : :
2422 : : DBG_ENTER("COLL")
2423 : :
2424 : 0 : ABI_CHECK(mkmem/=0,"mkmem==0 not supported anymore!")
2425 : :
2426 : 24 : fatbands_flag = dos%fatbands_flag
2427 : 24 : mbesslang = dos%mbesslang
2428 : 24 : prtdosm = dos%prtdosm
2429 : 24 : ndosfraction = dos%ndosfraction
2430 : 24 : paw_dos_flag = dos%paw_dos_flag
2431 : :
2432 : : !m-decomposed DOS not compatible with PAW-decomposed DOS
2433 [ - + ]: 24 : if(prtdosm>=1.and.paw_dos_flag==1) then
2434 : 0 : ABI_ERROR('m-decomposed DOS not compatible with PAW-decomposed DOS!')
2435 : : end if
2436 : :
2437 : : !Prepare some useful integrals
2438 : 24 : basis_size=pawtab(1)%basis_size
2439 [ + + ]: 24 : if (dtset%ntypat>1) then
2440 [ + + ]: 30 : do itypat=1,dtset%ntypat
2441 : 30 : basis_size=max(basis_size,pawtab(itypat)%basis_size)
2442 : : end do
2443 : : end if
2444 [ + - - + : 96 : ABI_MALLOC(int1 ,(basis_size*(basis_size+1)/2,dtset%natsph))
+ - - + +
- + - + -
- + - + ]
2445 [ - + + - : 72 : ABI_MALLOC(int2,(basis_size*(basis_size+1)/2,dtset%natsph))
- + + - -
+ - + ]
2446 [ - + + - : 72 : ABI_MALLOC(int1m2,(basis_size*(basis_size+1)/2,dtset%natsph))
- + + - -
+ - + ]
2447 [ + + + + : 2181 : int1=zero;int2=zero;int1m2=zero
+ + + + +
+ + + ]
2448 [ + + ]: 62 : do iat=1,dtset%natsph
2449 : 38 : iatom=dtset%iatsph(iat)
2450 : 38 : itypat= dtset%typat(iatom)
2451 [ + + ]: 264 : do jln=1,pawtab(itypat)%basis_size
2452 : 202 : j0ln=jln*(jln-1)/2
2453 [ + + ]: 897 : do iln=1,jln
2454 : 657 : kln=j0ln+iln
2455 : 657 : call simp_gen(int1(kln,iat),pawtab(itypat)%phiphj(:,kln),pawrad(itypat))
2456 [ + + ]: 859 : if (dtset%pawprtdos<2) then
2457 : 549 : call simp_gen(int2(kln,iat),pawtab(itypat)%tphitphj(:,kln),pawrad(itypat))
2458 : 549 : int1m2(kln,iat)=int1(kln,iat)-int2(kln,iat)
2459 : : else
2460 : 108 : int2(kln,iat)=zero;int1m2(kln,iat)=int1(kln,iat)
2461 : : end if
2462 : : end do !iln
2463 : : end do !jln
2464 : : end do
2465 : :
2466 : : !Antiferro case
2467 [ + + + + : 24 : if (dtset%nspden==2.and.dtset%nsppol==1.and.dtset%nspinor==1) then
+ - ]
2468 [ + + + + ]: 178 : int1m2(:,:)=half*int1m2(:,:)
2469 [ + + - + ]: 2 : if (paw_dos_flag==1.or.fatbands_flag==1.or.prtdosm==2) then
2470 [ + + + + : 178 : int1(:,:)=half*int1(:,:);int2(:,:)=half*int2(:,:)
+ + + + ]
2471 : : end if
2472 : : end if
2473 : :
2474 : : !Init parallelism
2475 : 24 : comm_kptband=mpi_enreg%comm_kptband
2476 : 24 : nproc_spkptband=xmpi_comm_size(comm_kptband)*mpi_enreg%nproc_spinor
2477 : 24 : me_kpt=mpi_enreg%me_kpt ; me_band=mpi_enreg%me_band
2478 : 24 : my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
2479 [ + + ]: 24 : bandpp=1;if (mpi_enreg%paral_kgb==1) bandpp=mpi_enreg%bandpp
2480 : : !Check if cprj is distributed over bands
2481 : 24 : nprocband=my_nspinor*dtset%mband*dtset%mkmem*dtset%nsppol/mcprj
2482 [ - + ]: 24 : if (nprocband/=mpi_enreg%nproc_band) then
2483 : 0 : ABI_BUG('wrong mcprj/nproc_band!')
2484 : : end if
2485 : :
2486 : : !Quick hack: in case of parallelism, dos_fractions have already
2487 : : ! been reduced over MPI processes; they have to be prepared before
2488 : : ! the next reduction (at the end of the following loop).
2489 [ + + ]: 24 : if (nproc_spkptband>1) then
2490 : 16 : one_over_nproc=one/real(nproc_spkptband,kind=dp)
2491 : : !$OMP PARALLEL DO COLLAPSE(4) DEFAULT(SHARED) PRIVATE(ilang,isppol,iband,ikpt)
2492 [ + + ]: 136 : do ilang=1,ndosfraction
2493 [ + + ]: 256 : do isppol=1,dtset%nsppol
2494 [ + + ]: 4720 : do iband=1,dtset%mband
2495 [ + + ]: 25400 : do ikpt=1,dtset%nkpt
2496 : : dos%fractions(ikpt,iband,isppol,ilang)= &
2497 : 25280 : & one_over_nproc*dos%fractions(ikpt,iband,isppol,ilang)
2498 : : end do
2499 : : end do
2500 : : end do
2501 : : end do
2502 : : !$OMP END PARALLEL DO
2503 : :
2504 [ + - - + ]: 16 : if (fatbands_flag==1.or.prtdosm==1.or.prtdosm==2) then
2505 : : !$OMP PARALLEL DO COLLAPSE(4) DEFAULT(SHARED) PRIVATE(ilang,isppol,iband,ikpt)
2506 [ # # ]: 0 : do ilang=1,ndosfraction*mbesslang
2507 [ - - ]: 16 : do isppol=1,dtset%nsppol
2508 [ # # ]: 0 : do iband=1,dtset%mband
2509 [ # # ]: 0 : do ikpt=1,dtset%nkpt
2510 : : dos%fractions_m(ikpt,iband,isppol,ilang)= &
2511 : 0 : & one_over_nproc*dos%fractions_m(ikpt,iband,isppol,ilang)
2512 : : end do
2513 : : end do
2514 : : end do
2515 : : end do
2516 : : !$OMP END PARALLEL DO
2517 : : end if
2518 : : end if
2519 : :
2520 : 24 : iorder_cprj=0
2521 : :
2522 : : !LOOPS OVER SPINS,KPTS
2523 : 24 : ibg=0
2524 [ + + ]: 50 : do isppol =1,dtset%nsppol
2525 [ + + ]: 241 : do ikpt=1,dtset%nkpt
2526 : :
2527 : 191 : nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
2528 [ + + ]: 191 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) cycle
2529 : :
2530 [ + + ]: 133 : cplex=2;if (dtset%istwfk(ikpt)>1) cplex=1
2531 : 133 : nband_cprj_k=nband_k/nprocband
2532 [ - + + - : 10742 : ABI_MALLOC(cprj_k,(dtset%natsph,my_nspinor*nband_cprj_k))
- + + - +
- + - - +
- + - + +
+ + + ]
2533 [ - + + - : 399 : ABI_MALLOC(dimcprj_atsph,(dtset%natsph))
+ - + - -
+ - + -
+ ]
2534 [ + + ]: 347 : do iat=1,dtset%natsph
2535 : 347 : dimcprj_atsph(iat)=dimcprj(dtset%iatsph(iat))
2536 : : end do
2537 : 133 : call pawcprj_alloc(cprj_k,0,dimcprj_atsph)
2538 [ - + ]: 133 : ABI_FREE(dimcprj_atsph)
2539 : :
2540 : : ! Extract cprj for this k-point.
2541 : 133 : ibsp=0
2542 [ + + ]: 3183 : do iband=1,nband_cprj_k
2543 [ + + ]: 6633 : do ispinor=1,my_nspinor
2544 : 3450 : ibsp=ibsp+1
2545 [ + + ]: 13260 : do iat=1,dtset%natsph
2546 : 6760 : iatom=dtset%iatsph(iat)
2547 [ + + + + ]: 343030 : cprj_k(iat,ibsp)%cp(:,:)=cprj(iatom,ibsp+ibg)%cp(:,:)
2548 : : end do
2549 : : end do
2550 : : end do
2551 : :
2552 : : ! LOOP OVER ATOMS (natsph_extra is not included on purpose)
2553 [ + + ]: 347 : do iat=1,dtset%natsph
2554 : 214 : iatom=dtset%iatsph(iat)
2555 : 214 : itypat= dtset%typat(iatom)
2556 : 214 : lmn_size=pawtab(itypat)%lmn_size
2557 : 214 : indlmn => pawtab(itypat)%indlmn
2558 : :
2559 : : ! LOOP OVER BANDS
2560 : 214 : ibsp=0
2561 [ + + ]: 6307 : do iband=1,nband_k
2562 : :
2563 [ + - ]: 5960 : if (mod((iband-1)/bandpp,nprocband)/=me_band) cycle
2564 [ - + ]: 5960 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,isppol,me_kpt)) then
2565 : 0 : ibsp=ibsp+my_nspinor;cycle
2566 : : end if
2567 : :
2568 [ + + ]: 12934 : do ispinor=1,my_nspinor
2569 : 6760 : ibsp=ibsp+1
2570 : :
2571 [ + + ]: 46520 : do ilang=1,mbesslang
2572 : :
2573 [ + + ]: 595260 : do jlmn=1,lmn_size
2574 : 554700 : jl=indlmn(1,jlmn)
2575 : 554700 : jm=indlmn(2,jlmn)
2576 : 554700 : j0lmn=jlmn*(jlmn-1)/2
2577 [ + + ]: 5773700 : do ilmn=1,jlmn
2578 : 5185200 : il=indlmn(1,ilmn)
2579 : 5185200 : im=indlmn(2,ilmn)
2580 : 5185200 : klmn=j0lmn+ilmn
2581 : 5185200 : kln=pawtab(itypat)%indklmn(2,klmn)
2582 : :
2583 [ + + + + : 5739900 : if (il==ilang-1.and.jl==ilang-1.and.im==jm) then
+ + ]
2584 : :
2585 : 163560 : cpij=cprj_k(iat,ibsp)%cp(1,ilmn)*cprj_k(iat,ibsp)%cp(1,jlmn)
2586 [ + + ]: 163560 : if (cplex==2) cpij=cpij+cprj_k(iat,ibsp)%cp(2,ilmn)*cprj_k(iat,ibsp)%cp(2,jlmn)
2587 : 163560 : cpij=pawtab(itypat)%dltij(klmn)*cpij
2588 : :
2589 : : dos%fractions(ikpt,iband,isppol,mbesslang*(iat-1)+ilang)= &
2590 : : & dos%fractions(ikpt,iband,isppol,mbesslang*(iat-1)+ilang) + &
2591 : 163560 : & cpij*int1m2(kln,iat)
2592 [ + + ]: 163560 : if (prtdosm==1) then
2593 : : dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im)= &
2594 : : & dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im) + &
2595 : 5400 : & cpij*int1m2(kln,iat)
2596 : : end if
2597 [ + + ]: 163560 : if (fatbands_flag==1.or.prtdosm==2) then
2598 : : dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im)= &
2599 : : & dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im) + &
2600 : 42240 : & cpij*int1(kln,iat)
2601 : : end if
2602 [ - + ]: 163560 : if (paw_dos_flag==1) then
2603 : : dos%fractions_paw1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang)= &
2604 : : & dos%fractions_paw1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang) + &
2605 : 0 : & cpij*int1(kln,iat)
2606 : : dos%fractions_pawt1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang)= &
2607 : : & dos%fractions_pawt1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang) + &
2608 : 0 : & cpij*int2(kln,iat)
2609 : : end if
2610 : :
2611 : : end if
2612 : :
2613 : : end do !ilmn
2614 : : end do !jlmn
2615 : :
2616 : : end do ! ilang
2617 : : end do ! ispinor
2618 : : end do ! iband
2619 : :
2620 : : end do !iatom
2621 : :
2622 [ + - ]: 133 : if (mkmem/=0) ibg = ibg + my_nspinor*nband_cprj_k
2623 : 133 : call pawcprj_free(cprj_k)
2624 [ + - + + : 6977 : ABI_FREE(cprj_k)
- + - + -
+ ]
2625 : : end do ! ikpt
2626 : : end do ! isppol
2627 : :
2628 [ - + ]: 24 : ABI_FREE(int1)
2629 [ - + ]: 24 : ABI_FREE(int2)
2630 [ - + ]: 24 : ABI_FREE(int1m2)
2631 : :
2632 : : !Reduce data in case of parallelism
2633 : 24 : call timab(48,1,tsec)
2634 : 24 : call xmpi_sum(dos%fractions,comm_kptband,ierr)
2635 [ + + ]: 24 : if (prtdosm>=1.or.fatbands_flag==1) then
2636 : 2 : call xmpi_sum(dos%fractions_m,comm_kptband,ierr)
2637 : : end if
2638 [ - + ]: 24 : if (paw_dos_flag==1) then
2639 : 0 : call xmpi_sum(dos%fractions_paw1,comm_kptband,ierr)
2640 : 0 : call xmpi_sum(dos%fractions_pawt1,comm_kptband,ierr)
2641 : : end if
2642 : 24 : call timab(48,2,tsec)
2643 [ + + ]: 24 : if (mpi_enreg%paral_spinor==1) then
2644 : 4 : call xmpi_sum(dos%fractions,mpi_enreg%comm_spinor,ierr)
2645 [ - + ]: 4 : if (prtdosm>=1.or.fatbands_flag==1) then
2646 : 0 : call xmpi_sum(dos%fractions_m,mpi_enreg%comm_spinor,ierr)
2647 : : end if
2648 [ - + ]: 4 : if (paw_dos_flag==1) then
2649 : 0 : call xmpi_sum(dos%fractions_paw1, mpi_enreg%comm_spinor,ierr)
2650 : 0 : call xmpi_sum(dos%fractions_pawt1, mpi_enreg%comm_spinor,ierr)
2651 : : end if
2652 : : end if
2653 : :
2654 : : !Averaging: A quick hack for m-decomposed LDOS:
2655 : : !BA: not valid in presence of spin-orbit coupling !
2656 [ + + ]: 24 : if (prtdosm==1.and.fatbands_flag==0) then
2657 : : ! if pawfatbnd is activated, one think in the cubic harmonics basis
2658 : : ! whereas prtdosm=1 is in the spherical harmonics basis.
2659 : : ! the following trick is done in order to have everything
2660 : : ! in the complex spherical basis (not useful for pawfatbnd if we want to
2661 : : ! have e.g t2g and eg d-orbitals).
2662 [ + + ]: 2 : do iat=1,dtset%natsph
2663 [ + + ]: 7 : do il = 0, mbesslang-1
2664 [ + + ]: 16 : do im = 1, il
2665 : : dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1+im) = &
2666 : : (dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1+im) + &
2667 [ + + + + : 2530 : dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1-im))/2
+ + ]
2668 : : dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1-im) = &
2669 [ + + + + : 2535 : dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1+im)
+ + ]
2670 : : end do
2671 : : end do
2672 : : end do !iatom
2673 : : end if
2674 : :
2675 : : DBG_EXIT("COLL")
2676 : :
2677 [ - + - + : 72 : end subroutine partial_dos_fractions_paw
- + - - -
- - - ]
2678 : : !!***
2679 : :
2680 [ # # # # : 0 : end module m_epjdos
# # # # #
# # # # #
# # # # #
# # # ]
2681 : : !!***
|