Branch data Line data Source code
1 : : !!****m* ABINIT/m_eprenorms
2 : : !! NAME
3 : : !! m_eprenorms
4 : : !!
5 : : !! FUNCTION
6 : : !! This module contains datatypes to compute the renormalization of electronic states due to
7 : : !! eph coupling and temperature effects
8 : : !!
9 : : !! NOTES
10 : : !! This code is still under development and the API will change in the next versions.
11 : : !! Contact gmatteo
12 : : !!
13 : : !! COPYRIGHT
14 : : !! Copyright (C) 2001-2026 ABINIT group (YG)
15 : : !! This file is distributed under the terms of the
16 : : !! GNU General Public License, see ~abinit/COPYING
17 : : !! or http://www.gnu.org/copyleft/gpl.txt .
18 : : !!
19 : : !! SOURCE
20 : :
21 : : #if defined HAVE_CONFIG_H
22 : : #include "config.h"
23 : : #endif
24 : :
25 : : #include "abi_common.h"
26 : :
27 : : module m_eprenorms
28 : :
29 : : use defs_basis
30 : : use m_abicore
31 : : use m_errors
32 : : use m_xmpi
33 : : use netcdf
34 : : use m_nctk
35 : : use m_ebands
36 : :
37 : : use m_crystal, only : crystal_t
38 : : use m_kpts, only : listkk
39 : :
40 : : implicit none
41 : :
42 : : private
43 : : !!***
44 : :
45 : : !!****t* m_eprenorms/eprenorms_t
46 : : !! NAME
47 : : !! eprenorms_t
48 : : !!
49 : : !! FUNCTION
50 : : !! Datatype gathering data for electron-phonon renormalization of the band structure
51 : : !!
52 : : !! SOURCE
53 : :
54 : : type,public :: eprenorms_t
55 : :
56 : : !scalars
57 : : integer :: nkpt
58 : : ! Number of kpoints
59 : :
60 : : integer :: nsppol
61 : : ! Number of spin channels
62 : :
63 : : integer :: mband
64 : : ! Maximum number of bands
65 : :
66 : : integer :: ntemp
67 : : ! Number of temperatures
68 : :
69 : : !arrays
70 : : real(dp), allocatable :: kpts(:,:)
71 : : ! kpt(3,nkpt)
72 : : ! Kpoints
73 : :
74 : : real(dp), allocatable :: temps(:)
75 : : ! temps(ntemp)
76 : : ! Temperatures
77 : :
78 : : real(dp), allocatable :: eigens(:,:,:)
79 : : ! eigens(mband,nkpt,nsppol)
80 : : ! Kohn-Sham eigenvalues
81 : :
82 : : real(dp), allocatable :: occs(:,:,:)
83 : : ! occ(mband,nkpt,nsppol)
84 : : ! Occupation numbers
85 : :
86 : : real(dp), allocatable :: renorms(:,:,:,:,:)
87 : : ! renorms(2,mband,nkpt,nsppol,ntemp)
88 : : ! Renormalization of the eigenvalues for each temperature
89 : :
90 : : real(dp), allocatable :: linewidth(:,:,:,:,:)
91 : : ! linewidth(2,mband,nkpt,nsppol,ntemp)
92 : : ! Electron-phonon induced linewidth of the eigens
93 : :
94 : : end type eprenorms_t
95 : :
96 : : public :: eprenorms_init
97 : : public :: eprenorms_free
98 : : public :: eprenorms_from_epnc
99 : : public :: eprenorms_bcast
100 : :
101 : : public :: renorm_bst
102 : : !!***
103 : :
104 : : CONTAINS !============================================================================
105 : : !!***
106 : :
107 : : !!****f* m_eprenorms/eprenorms_init
108 : : !! NAME
109 : : !! eprenorms_init
110 : : !!
111 : : !! FUNCTION
112 : : !! Initializes an eprenorms_t datatype
113 : : !!
114 : : !! INPUTS
115 : : !!
116 : : !! OUTPUT
117 : : !! Epren<eprenorms_t>=Datatype gathering electron-phonon renormalizations
118 : : !!
119 : : !! SOURCE
120 : :
121 : 3 : subroutine eprenorms_init(Epren,nkpt,nsppol,mband,ntemp)
122 : :
123 : : !Arugments -----------------------------------
124 : : !scalars
125 : : integer,intent(in) :: nkpt, nsppol, mband, ntemp
126 : : type(eprenorms_t) :: Epren
127 : : !arrays
128 : :
129 : : !*************************************************************************
130 : :
131 : : DBG_ENTER("COLL")
132 : :
133 : 3 : Epren%nkpt = nkpt
134 : 3 : Epren%nsppol = nsppol
135 : 3 : Epren%mband = mband
136 : 3 : Epren%ntemp = ntemp
137 : :
138 [ - + + - : 9 : ABI_MALLOC(Epren%temps,(Epren%ntemp))
+ - + - -
+ - + -
+ ]
139 [ - + + - : 9 : ABI_MALLOC(Epren%kpts,(3,Epren%nkpt))
+ - + - -
+ - + -
+ ]
140 [ - + + - : 15 : ABI_MALLOC(Epren%eigens,(Epren%mband,Epren%nkpt,Epren%nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
141 [ - + + - : 12 : ABI_MALLOC(Epren%occs,(Epren%mband,Epren%nkpt,Epren%nsppol))
- + + - -
+ + - - +
- + - + ]
142 [ - + + - : 18 : ABI_MALLOC(Epren%renorms,(2,Epren%mband,Epren%nkpt,Epren%nsppol,Epren%ntemp))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
143 [ - + + - : 15 : ABI_MALLOC(Epren%linewidth,(2,Epren%mband,Epren%nkpt,Epren%nsppol,Epren%ntemp))
- + + - -
+ + - - +
+ - - + -
+ - + ]
144 : :
145 : : DBG_EXIT("COLL")
146 : :
147 : 3 : end subroutine eprenorms_init
148 : : !!***
149 : :
150 : : !---------------------------------------------------------------------
151 : :
152 : : !!****f* m_eprenorms/eprenorms_free
153 : : !! NAME
154 : : !! eprenorms_free
155 : : !!
156 : : !! FUNCTION
157 : : !! Deallocate all memory associated with eprenorms
158 : : !!
159 : : !! INPUTS
160 : : !! Epren<eprenorms_t>=The datatype to be freed
161 : : !!
162 : : !! SOURCE
163 : :
164 : 30 : subroutine eprenorms_free(Epren)
165 : :
166 : : !Arguments -----------------------------------
167 : : !scalars
168 : : type(eprenorms_t),intent(inout) :: Epren
169 : :
170 : : !*********************************************************************
171 : :
172 [ + + ]: 30 : ABI_SFREE(Epren%temps)
173 [ + + ]: 30 : ABI_SFREE(Epren%kpts)
174 [ + + ]: 30 : ABI_SFREE(Epren%eigens)
175 [ + + ]: 30 : ABI_SFREE(Epren%occs)
176 [ + + ]: 30 : ABI_SFREE(Epren%renorms)
177 [ + + ]: 30 : ABI_SFREE(Epren%linewidth)
178 : :
179 : 30 : end subroutine eprenorms_free
180 : : !!***
181 : :
182 : : !---------------------------------------------------------------------
183 : :
184 : : !!****f* m_eprenorms/eprenorms_from_epnc
185 : : !! NAME
186 : : !! eprenorms_from_epnc
187 : : !!
188 : : !! FUNCTION
189 : : !! Allocates and initializes the datatype from a _EP.nc file
190 : : !!
191 : : !! INPUTS
192 : : !! filename = name of the file to be read
193 : : !!
194 : : !! SIDE EFFECTS
195 : : !! Epren<eprenorms_t> = fields are initialized and filled with data from filename
196 : : !!
197 : : !! SOURCE
198 : :
199 : 3 : subroutine eprenorms_from_epnc(Epren,filename)
200 : :
201 : : !Arguments -----------------------------------
202 : : !scalars
203 : : character(len=fnlen),intent(in) :: filename
204 : : type(eprenorms_t),intent(inout) :: Epren
205 : :
206 : : !Local variables------------------------------
207 : : integer :: nkpt, mband, nsppol, ntemp
208 : : integer :: ncid
209 : : ! ************************************************************************
210 : :
211 [ - + ]: 3 : NCF_CHECK(nctk_open_read(ncid, filename, xmpi_comm_self))
212 [ - + ]: 3 : NCF_CHECK(nctk_set_datamode(ncid))
213 : :
214 [ - + ]: 3 : NCF_CHECK(nctk_get_dim(ncid, "number_of_kpoints", nkpt))
215 [ - + ]: 3 : NCF_CHECK(nctk_get_dim(ncid, "number_of_spins",nsppol))
216 [ - + ]: 3 : NCF_CHECK(nctk_get_dim(ncid, "max_number_of_states",mband))
217 [ - + ]: 3 : NCF_CHECK(nctk_get_dim(ncid, "number_of_temperature",ntemp))
218 : :
219 : 3 : call eprenorms_init(Epren, nkpt, nsppol, mband, ntemp)
220 : :
221 [ - + ]: 3 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"reduced_coordinates_of_kpoints"), Epren%kpts))
222 [ - + ]: 3 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"temperature"), Epren%temps))
223 [ - + ]: 3 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"eigenvalues"), Epren%eigens))
224 [ - + ]: 3 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"occupations"), Epren%occs))
225 [ - + ]: 3 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"zero_point_motion"), Epren%renorms))
226 : : ! TODO: This should be changed. What is stored is a linewidth, not a lifetime,
227 : : ! we postone the change so as to not break compatibility
228 [ - + ]: 3 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"lifetime"), Epren%linewidth))
229 : :
230 : 3 : end subroutine eprenorms_from_epnc
231 : : !!***
232 : :
233 : : !---------------------------------------------------------------------
234 : :
235 : : !!****f* m_eprenorms/eprenorms_bcast
236 : : !! NAME
237 : : !! eprenorms_bcast
238 : : !!
239 : : !! FUNCTION
240 : : !! MPI broadcast all the content of eprenorms_t
241 : : !!
242 : : !! INPUTS
243 : : !! master = Rank of master
244 : : !! comm = MPI communicator
245 : : !!
246 : : !! SIDE EFFECTS
247 : : !! Epren<eprenorms_t> = Data broadcasted on every node from master
248 : : !!
249 : : !! SOURCE
250 : :
251 : 3 : subroutine eprenorms_bcast(Epren,master,comm)
252 : :
253 : : !Arguments -----------------------------------
254 : : !scalars
255 : : integer,intent(in) :: master, comm
256 : : type(eprenorms_t),intent(inout) :: Epren
257 : :
258 : : !Local variables------------------------------
259 : : !scalars
260 : : integer :: ierr
261 : :
262 : : ! ************************************************************************
263 : :
264 [ + - ]: 3 : if (xmpi_comm_size(comm) == 1) return
265 : :
266 : 0 : call xmpi_bcast(Epren%nkpt, master, comm, ierr)
267 : 0 : call xmpi_bcast(Epren%nsppol, master, comm, ierr)
268 : 0 : call xmpi_bcast(Epren%mband, master, comm, ierr)
269 : 0 : call xmpi_bcast(Epren%ntemp, master, comm, ierr)
270 : :
271 [ # # ]: 0 : if (xmpi_comm_rank(comm) /= master) then
272 : 0 : call eprenorms_init(Epren, Epren%nkpt, Epren%nsppol, Epren%mband, Epren%ntemp)
273 : : end if
274 : :
275 : 0 : call xmpi_bcast(Epren%kpts, master, comm, ierr)
276 : 0 : call xmpi_bcast(Epren%temps, master, comm, ierr)
277 : 0 : call xmpi_bcast(Epren%eigens, master, comm, ierr)
278 : 0 : call xmpi_bcast(Epren%occs, master, comm, ierr)
279 : 0 : call xmpi_bcast(Epren%renorms, master, comm, ierr)
280 : 0 : call xmpi_bcast(Epren%linewidth, master, comm, ierr)
281 : :
282 : : end subroutine eprenorms_bcast
283 : : !!***
284 : :
285 : : !---------------------------------------------------------------------
286 : :
287 : : !!****f* m_eprenorms/renorm_bst
288 : : !! NAME
289 : : !! renorm_bst
290 : : !!
291 : : !! FUNCTION
292 : : !! Renormalize the band structure Bst from data contained Epren
293 : : !!
294 : : !! INPUTS
295 : : !! Epren<eprenorms_t> = datatype containing the elphon renormalization
296 : : !! itemp = index of the temperature you want to use
297 : : !! do_lifetime = .true. if we want to use imaginary eigenvalues (lifetime field)
298 : : !!
299 : : !! SIDE EFFECTS
300 : : !! Bst<bands_t> : eigens are changed according to epren
301 : : !! linewidth is allocated and filled with data if do_linewidth
302 : : !!
303 : : !! SOURCE
304 : :
305 : 50 : subroutine renorm_bst(Epren,Bst,Cryst,itemp,do_lifetime,do_check)
306 : :
307 : : !Arguments -----------------------------------
308 : : !scalars
309 : : integer :: itemp
310 : : logical,intent(in) :: do_lifetime
311 : : logical,optional,intent(in) :: do_check
312 : : type(eprenorms_t),intent(in) :: Epren
313 : : type(ebands_t),intent(inout) :: Bst
314 : : type(crystal_t),intent(in) :: Cryst
315 : :
316 : : !Local variables------------------------------
317 : : !scalars
318 : : integer :: isppol,ikpt,comm
319 : : integer :: nband1, nband_tmp
320 : : integer :: timrev, sppoldbl
321 : : integer :: ik_eph
322 : : real(dp) :: dksqmax
323 : : logical :: check
324 : : !arrays
325 : 50 : integer,allocatable :: bs2eph(:,:)
326 : :
327 : : ! ************************************************************************
328 : :
329 [ - + ]: 50 : ABI_CHECK(Bst%nsppol == Epren%nsppol, "Nsppol should be the same")
330 : :
331 : 50 : comm = xmpi_comm_self
332 : :
333 [ + - ]: 50 : if(do_lifetime) then
334 [ - + + - : 250 : ABI_MALLOC(Bst%linewidth,(1,Bst%mband,Bst%nkpt,Bst%nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
335 : : end if
336 : :
337 : 50 : check = .TRUE.
338 [ + - ]: 50 : if(present(do_check)) then
339 : 50 : check = do_check
340 : : end if
341 : :
342 : 50 : sppoldbl = 1 !; if (any(Cryst%symafm == -1) .and. Epren%nsppol == 1) nsppoldbl=2
343 [ - + + - : 150 : ABI_MALLOC(bs2eph, (BSt%nkpt*sppoldbl, 6))
+ - + - -
+ - + ]
344 : 50 : timrev = 1
345 : : call listkk(dksqmax, Cryst%gmet, bs2eph, Epren%kpts, BSt%kptns, Epren%nkpt, Bst%nkpt, Cryst%nsym, &
346 : 50 : & sppoldbl, Cryst%symafm, Cryst%symrel, timrev, comm, use_symrec=.False.)
347 : :
348 [ + + ]: 100 : do isppol=1,Bst%nsppol
349 [ + + ]: 300 : do ikpt=1,Bst%nkpt
350 : 200 : nband1 = Bst%nband(ikpt+(isppol-1)*Bst%nkpt)
351 : 200 : nband_tmp=MIN(nband1,Epren%mband)
352 : :
353 : 200 : ik_eph = bs2eph(ikpt,1)
354 : :
355 : : !FIXME change check
356 [ + + ]: 200 : if (check) then
357 [ + + + - : 1420 : if (ANY(ABS(Bst%eig(1:MIN(10,nband_tmp),ikpt,isppol) - Epren%eigens(1:MIN(10,nband_tmp),ik_eph,isppol)) > tol3)) then
- + ]
358 : : !write(stdout,*) "eig : ",BSt%eig(1:MIN(10,nband_tmp),ikpt,isppol)
359 : : !write(stdout,*) "eigens : ",Epren%eigens(1:MIN(10,nband_tmp),ikpt,isppol)
360 : 0 : ABI_ERROR("Error in eigenvalues, check the _EP.nc file with respect to your input file !")
361 : : end if
362 [ + + + - : 1420 : if (ANY(ABS(Bst%occ(1:MIN(10,nband_tmp),ikpt,isppol) - Epren%occs(1:MIN(10,nband_tmp),ik_eph,isppol)) > tol3)) then
- + ]
363 : 0 : ABI_ERROR("Error in occupations, check the _EP.nc file with respect to your input file !")
364 : : end if
365 : : end if
366 : :
367 : : ! Upgrade energies
368 [ + + ]: 2280 : Bst%eig(1:nband_tmp,ikpt,isppol) = BSt%eig(1:nband_tmp,ikpt,isppol) + Epren%renorms(1,1:nband_tmp,ik_eph,isppol,itemp)
369 : :
370 [ + - ]: 250 : if (do_lifetime) then
371 [ + + ]: 2280 : Bst%linewidth(1,1:nband_tmp,ikpt,isppol) = Epren%linewidth(1,1:nband_tmp,ik_eph,isppol,itemp)
372 : : end if
373 : : end do
374 : : end do
375 : :
376 [ - + ]: 50 : ABI_FREE(bs2eph)
377 : :
378 : 50 : end subroutine renorm_bst
379 : : !!***
380 : :
381 : : !---------------------------------------------------------------------
382 : :
383 [ # # # # : 0 : end module m_eprenorms
# # # # #
# # # # #
# # # # #
# # # #
# ]
384 : : !!***
|