Branch data Line data Source code
1 : : !!****m* ABINIT/m_eig2d
2 : : !! NAME
3 : : !! m_eig2d
4 : : !!
5 : : !! FUNCTION
6 : : !! This module contains utilities to analyze and retrieve information
7 : : !! from the second order derivative of the eigen-energies wrt
8 : : !! displacements.
9 : : !!
10 : : !! COPYRIGHT
11 : : !! Copyright (C) 2014-2026 ABINIT group (SP, PB, XG)
12 : : !! This file is distributed under the terms of the
13 : : !! GNU General Public License, see ~abinit/COPYING
14 : : !! or http://www.gnu.org/copyleft/gpl.txt .
15 : : !!
16 : : !! SOURCE
17 : :
18 : : #if defined HAVE_CONFIG_H
19 : : #include "config.h"
20 : : #endif
21 : :
22 : : #include "abi_common.h"
23 : :
24 : : MODULE m_eig2d
25 : :
26 : : use defs_basis
27 : : use m_errors
28 : : use m_abicore
29 : : use m_nctk
30 : : use netcdf
31 : : use m_xmpi
32 : : !use m_ebands
33 : : use m_cgtools
34 : : use m_hdr
35 : : use m_dtset
36 : : use m_dtfil
37 : : use m_ddb_hdr
38 : : use m_ddb
39 : :
40 : : use defs_datatypes, only : pseudopotential_type
41 : : use defs_abitypes, only : MPI_type
42 : : use m_time, only : timab
43 : : use m_fstrings, only : strcat
44 : : use m_crystal, only : crystal_t
45 : : use m_pawtab, only : pawtab_type
46 : : use m_double_grid,only : kptfine_av
47 : : use m_mpinfo, only : distrb2, proc_distrb_cycle
48 : : use m_ebands, only : ebands_t
49 : :
50 : : implicit none
51 : :
52 : : private
53 : :
54 : : public :: eigr2d_init ! Main creation method of EIG2D.nc files.
55 : : public :: eigr2d_ncwrite ! Dump the object into NETCDF file.
56 : : public :: eigr2d_free ! Destruction method.
57 : : public :: fan_init ! Main creation method of Fan.nc files.
58 : : public :: fan_ncwrite ! Dump the object into NETCDF file.
59 : : public :: fan_free ! Destruction method.
60 : : public :: gkk_init ! Main creation method of GKK.nc files.
61 : : public :: gkk_ncwrite ! Dump the object into NETCDF file.
62 : : public :: gkk_free ! Destruction method.
63 : :
64 : : public :: eig2tot ! This routine calculates the second-order eigenvalues.
65 : : public :: outbsd ! output bsd file for one perturbation (used for elphon calculations in anaddb)
66 : : public :: eig2stern
67 : : public :: elph2_fanddw ! Calculates the zero-point motion corrections
68 : :
69 : : !!***
70 : :
71 : : !!****t* m_eig2d/eigr2d_t
72 : : !! NAME
73 : : !! eig2d_t
74 : : !!
75 : : !! FUNCTION
76 : : !! It contains information about the second-order derivative of the
77 : : !! eigenenergies wrt atomic displacement
78 : : !!
79 : : !! SOURCE
80 : :
81 : : type,public :: eigr2d_t
82 : :
83 : : ! WARNING : if you modify this datatype, please check whether there might be
84 : : ! creation/destruction/copy routines,
85 : : ! declared in another part of ABINIT, that might need to take into account your
86 : : ! modification.
87 : :
88 : : integer :: mband ! Max number of bands i.e MAXVAL(nband) (to dimension arrays)
89 : : integer :: nsppol ! number of spin-polarization
90 : : integer :: nkpt ! number of k points
91 : : integer :: natom ! number of atoms
92 : :
93 : : real(dp),allocatable :: eigr2d(:,:,:,:,:,:,:)
94 : : ! eigr2d(2,mband*nsppol,nkpt,3,natom,3,natom)
95 : : ! Second-order derivative of eigenergies (real,im) at each
96 : : ! spin,band,k-point,dir1,dir2,natom1,natom2 .
97 : :
98 : :
99 : : end type eigr2d_t
100 : : !!***
101 : :
102 : : !!****t* m_eig2d/fan_t
103 : : !! NAME
104 : : !! fan_t
105 : : !!
106 : : !! FUNCTION
107 : : !! It contains information about the second-order derivative of the
108 : : !! eigenenergies wrt atomic displacement
109 : : !!
110 : : !! SOURCE
111 : :
112 : : type,public :: fan_t
113 : :
114 : : ! WARNING : if you modify this datatype, please check whether there might be
115 : : ! creation/destruction/copy routines,
116 : : ! declared in another part of ABINIT, that might need to take into account your
117 : : ! modification.
118 : :
119 : : integer :: mband ! Max number of bands i.e MAXVAL(nband) (to dimension arrays)
120 : : integer :: nsppol ! number of spin-polarization
121 : : integer :: nkpt ! number of k points
122 : : integer :: natom ! number of atoms
123 : :
124 : : real(dp),allocatable :: fan2d(:,:,:,:,:,:,:)
125 : : ! fan2d(2*mband*nsppol,nkpt,3,natom,3,natom,mband)
126 : : ! Second-order derivative of the eigenergies (real,im) at each
127 : : ! ispin,iband(real,im),k-point,dir1,dir2,natom1,natom2,jband
128 : :
129 : : end type fan_t
130 : : !!***
131 : :
132 : : !!****t* m_eig2d/gkk_t
133 : : !! NAME
134 : : !! gkk_t
135 : : !!
136 : : !! FUNCTION
137 : : !! It contains information about the second-order derivative of the
138 : : !! eigenenergies wrt atomic displacement
139 : : !!
140 : : !! SOURCE
141 : :
142 : : type,public :: gkk_t
143 : :
144 : : ! WARNING : if you modify this datatype, please check whether there might be
145 : : ! creation/destruction/copy routines,
146 : : ! declared in another part of ABINIT, that might need to take into account your
147 : : ! modification.
148 : :
149 : : integer :: mband ! Max number of bands i.e MAXVAL(nband) (to dimension arrays)
150 : : integer :: nsppol ! number of spin-polarization
151 : : integer :: nkpt ! number of k points
152 : : integer :: natom ! number of atoms
153 : : integer :: ncart ! number of cartesian directions
154 : :
155 : : real(dp),allocatable :: gkk2d(:,:,:,:,:)
156 : : ! gkk2d(2*mband*nsppol,nkpt,ncart,natom,mband)
157 : : ! Second-order derivative of the eigenergies (real,im) at each
158 : : ! ispin,iband(real,im),k-point,dir1,natom1,jband
159 : :
160 : : end type gkk_t
161 : : !!***
162 : :
163 : : CONTAINS
164 : : !!***
165 : :
166 : : !----------------------------------------------------------------------
167 : :
168 : : !!****f* m_eig2d/eigr2d_init
169 : : !! NAME
170 : : !! eigr2d_init
171 : : !!
172 : : !! FUNCTION
173 : : !! This subroutine initializes the eigr2d_t structured datatype
174 : : !!
175 : : !! INPUTS
176 : : !! mbands=maximum number of bands
177 : : !! nkpt=number of k points
178 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
179 : : !! natom=number of atoms
180 : : !! eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom)=second-order derivative of the
181 : : !! eigenenergies wrt phononic displacements
182 : : !!
183 : : !! OUTPUT
184 : : !! eigr2d<eigr2d_t>=the eigr2d_t datatype
185 : : !!
186 : : !! SOURCE
187 : :
188 [ # # ]: 0 : subroutine eigr2d_init(eig2nkq,eigr2d,mband,nsppol,nkpt,natom)
189 : :
190 : : !Arguments ------------------------------------
191 : : !scalars
192 : : integer,intent(in) ::mband,nsppol,nkpt,natom
193 : : type(eigr2d_t),intent(out) :: eigr2d
194 : : !arrays
195 : : real(dp), intent(in) :: eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom)
196 : :
197 : : ! *************************************************************************
198 : :
199 : 0 : eigr2d%mband = mband
200 : 0 : eigr2d%nsppol = nsppol
201 : 0 : eigr2d%nkpt = nkpt
202 : 0 : eigr2d%natom = natom
203 : :
204 [ # # # # : 0 : ABI_MALLOC(eigr2d%eigr2d ,(2,mband*nsppol,nkpt,3,natom,3,natom))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
205 [ # # # # : 0 : eigr2d%eigr2d=eig2nkq
# # # # #
# # # # #
# # ]
206 : :
207 : 0 : end subroutine eigr2d_init
208 : : !!***
209 : :
210 : : !----------------------------------------------------------------------
211 : :
212 : : !!****f* m_eig2d/eigr2d_ncwrite
213 : : !! NAME
214 : : !! eigr2d_ncwrite
215 : : !!
216 : : !! FUNCTION
217 : : !! Writes the content of a eigr2d_t object to a NETCDF file
218 : : !! according to the ETSF-IO specifications.
219 : : !!
220 : : !! INPUTS
221 : : !! ncid =NC file handle
222 : : !!
223 : : !! OUTPUT
224 : : !!
225 : : !! SOURCE
226 : :
227 : 0 : subroutine eigr2d_ncwrite(eigr2d,iqpt,wtq,ncid)
228 : :
229 : : !Arguments ------------------------------------
230 : : !scalars
231 : : integer,intent(in) ::ncid
232 : : real(dp),intent(in) :: iqpt(3),wtq
233 : : type(eigr2d_t),intent(in) :: eigr2d
234 : :
235 : : !Local variables-------------------------------
236 : : integer :: ncerr
237 : : integer :: cplex,cart_dir,one_dim
238 : : character(len=200) :: temp
239 : : ! *************************************************************************
240 : :
241 : : ! ==============================================
242 : : ! === Write the dimensions specified by ETSF ===
243 : : ! ==============================================
244 : 0 : one_dim=1; cplex=2; cart_dir=3
245 : :
246 : : ncerr = nctk_def_dims(ncid, [&
247 : : nctkdim_t('max_number_of_states', eigr2d%mband),&
248 : : nctkdim_t('number_of_spins', eigr2d%nsppol),&
249 : : nctkdim_t('number_of_kpoints', eigr2d%nkpt),&
250 : : nctkdim_t('number_of_atoms', eigr2d%natom),&
251 : : nctkdim_t('number_of_cartesian_directions', cart_dir),&
252 : : nctkdim_t('current_one_dim', one_dim),&
253 : : nctkdim_t('cplex', cplex),&
254 [ # # ]: 0 : nctkdim_t('product_mband_nsppol', eigr2d%mband*eigr2d%nsppol)], defmode=.True.)
255 [ # # ]: 0 : NCF_CHECK(ncerr)
256 : :
257 : : temp='cplex,product_mband_nsppol,number_of_kpoints,number_of_cartesian_directions,number_of_atoms,' //&
258 : 0 : 'number_of_cartesian_directions , number_of_atoms'
259 : : ncerr = nctk_def_arrays(ncid, [&
260 : : nctkarr_t('current_q_point', "dp", 'number_of_cartesian_directions'), &
261 : : nctkarr_t('current_q_point_weight', "dp", 'current_one_dim'), &
262 [ # # ]: 0 : nctkarr_t('second_derivative_eigenenergies', "dp", temp )])
263 : : ! nctkarr_t('second_derivative_eigenenergies', "dp",&
264 : : ! &'cplex, product_mband_nsppol, number_of_kpoints, number_of_cartesian_directions, number_of_atoms,&
265 : : ! &number_of_cartesian_directions, number_of_atoms')])
266 [ # # ]: 0 : NCF_CHECK(ncerr)
267 : :
268 : : ! Write data
269 [ # # ]: 0 : NCF_CHECK(nctk_set_datamode(ncid))
270 [ # # ]: 0 : NCF_CHECK(nf90_put_var(ncid, vid('current_q_point'), iqpt))
271 [ # # ]: 0 : NCF_CHECK(nf90_put_var(ncid, vid('current_q_point_weight'), wtq))
272 [ # # ]: 0 : NCF_CHECK(nf90_put_var(ncid, vid('second_derivative_eigenenergies'), eigr2d%eigr2d))
273 : :
274 : : contains
275 : 0 : integer function vid(vname)
276 : : character(len=*),intent(in) :: vname
277 : 0 : vid = nctk_idname(ncid, vname)
278 : : end function vid
279 : :
280 : : end subroutine eigr2d_ncwrite
281 : : !!***
282 : :
283 : : !----------------------------------------------------------------------
284 : :
285 : : !!****f* m_eig2d/eigr2d_free
286 : : !! NAME
287 : : !! eigr2d_free
288 : : !!
289 : : !! FUNCTION
290 : : !! Deallocates the components of the eigr2d_t structured datatype
291 : : !!
292 : : !! INPUTS
293 : : !! eigr2d<eigr2d_t>=The data type to be deallocated.
294 : : !!
295 : : !! OUTPUT
296 : : !! Deallocate the dynamic arrays in the ebands_t type.
297 : : !! (only deallocate)
298 : : !!
299 : : !! SOURCE
300 : :
301 : 0 : subroutine eigr2d_free(eigr2d)
302 : :
303 : : !Arguments ------------------------------------
304 : : !scalars
305 : : type(eigr2d_t),intent(inout) :: eigr2d
306 : : ! *************************************************************************
307 : : DBG_ENTER("COLL")
308 : :
309 : : !Deallocate all components of bstruct
310 [ # # ]: 0 : ABI_SFREE(eigr2d%eigr2d)
311 : :
312 : : DBG_EXIT("COLL")
313 : :
314 : 0 : end subroutine eigr2d_free
315 : : !!***
316 : :
317 : : !!****f* m_eig2d/fan_init
318 : : !! NAME
319 : : !! fan_init
320 : : !!
321 : : !! FUNCTION
322 : : !! This subroutine initializes the fan_t structured datatype
323 : : !!
324 : : !! INPUTS
325 : : !! mbands=maximum number of bands
326 : : !! nkpt=number of k points
327 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
328 : : !! natom=number of atoms
329 : : !! fan2d(2*mband*nsppol,nkpt,3,natom,3,natom,mband*nsppol)=second-order derivative of the
330 : : !! eigenenergies wrt phononic displacements
331 : : !!
332 : : !! OUTPUT
333 : : !! fan2d<fan_t>=the fan_t datatype
334 : : !!
335 : : !! SIDE EFFECTS
336 : : !!
337 : : !! SOURCE
338 : :
339 [ - + ]: 25 : subroutine fan_init(fan,fan2d,mband,nsppol,nkpt,natom)
340 : :
341 : : !Arguments ------------------------------------
342 : : !scalars
343 : : integer,intent(in) ::mband,nsppol,nkpt,natom
344 : : type(fan_t),intent(out) :: fan2d
345 : : !arrays
346 : : real(dp), intent(in) :: fan(2*mband*nsppol,nkpt,3,natom,3,natom,mband)
347 : : ! *************************************************************************
348 : :
349 : 25 : fan2d%mband = mband
350 : 25 : fan2d%nsppol = nsppol
351 : 25 : fan2d%nkpt = nkpt
352 : 25 : fan2d%natom = natom
353 : :
354 [ + - - + : 250 : ABI_MALLOC(fan2d%fan2d,(2*mband*nsppol,nkpt,3,natom,3,natom,mband))
+ - - + +
- + - - +
+ - + - -
+ + - - +
+ - + - +
- - + -
+ ]
355 [ - + + + : 1604402 : fan2d%fan2d=fan
+ + + + +
+ + + + +
+ + ]
356 : :
357 : 25 : end subroutine fan_init
358 : : !!***
359 : :
360 : : !!****f* m_eig2d/gkk_init
361 : : !! NAME
362 : : !! gkk_init
363 : : !!
364 : : !! FUNCTION
365 : : !! This subroutine initializes the gkk_t structured datatype
366 : : !!
367 : : !! INPUTS
368 : : !! mbands=maximum number of bands
369 : : !! nkpt=number of k points
370 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
371 : : !! natom=number of atoms
372 : : !! gkk2d(2*mband*nsppol,nkpt,3,natom,mband*nsppol)=second-order derivative of the
373 : : !! eigenenergies wrt phononic displacements
374 : : !!
375 : : !! OUTPUT
376 : : !! gkk2d<gkk_t>=the gkk_t datatype
377 : : !!
378 : : !! SIDE EFFECTS
379 : : !!
380 : : !! SOURCE
381 : :
382 [ - + ]: 122 : subroutine gkk_init(gkk,gkk2d,mband,nsppol,nkpt,natom,ncart)
383 : :
384 : : !Arguments ------------------------------------
385 : : !scalars
386 : : integer,intent(in) ::mband,nsppol,nkpt,natom,ncart
387 : : type(gkk_t),intent(out) :: gkk2d
388 : : !arrays
389 : : real(dp), intent(in) :: gkk(2*mband*nsppol,nkpt,ncart,natom,mband)
390 : : ! *************************************************************************
391 : :
392 : 122 : gkk2d%mband = mband
393 : 122 : gkk2d%nsppol = nsppol
394 : 122 : gkk2d%nkpt = nkpt
395 : 122 : gkk2d%natom = natom
396 : 122 : gkk2d%ncart = ncart
397 : :
398 [ + - - + : 976 : ABI_MALLOC(gkk2d%gkk2d,(2*mband*nsppol,nkpt,ncart,natom,mband))
+ - - + +
- - + + -
- + + - -
+ + - + -
+ - - + -
+ ]
399 [ - + + + : 2740315 : gkk2d%gkk2d=gkk
+ + + + +
+ + + ]
400 : :
401 : 122 : end subroutine gkk_init
402 : : !!***
403 : :
404 : : !----------------------------------------------------------------------
405 : :
406 : : !!****f* m_eig2d/fan_ncwrite
407 : : !! NAME
408 : : !! fan_ncwrite
409 : : !!
410 : : !! FUNCTION
411 : : !! Writes the content of a fan_t object to a NETCDF file
412 : : !! according to the ETSF-IO specifications.
413 : : !!
414 : : !! INPUTS
415 : : !! ncid =NC file handle
416 : : !!
417 : : !! OUTPUT
418 : : !!
419 : : !! SOURCE
420 : :
421 : 25 : subroutine fan_ncwrite(fan2d,iqpt,wtq,ncid)
422 : :
423 : : !Arguments ------------------------------------
424 : : !scalars
425 : : integer,intent(in) ::ncid
426 : : real(dp),intent(in) :: iqpt(3),wtq
427 : : type(fan_t),intent(in) :: fan2d
428 : :
429 : : !Local variables-------------------------------
430 : : integer :: ncerr
431 : : integer :: cplex,cart_dir,one_dim
432 : : character(len=200) :: temp
433 : : ! *************************************************************************
434 : :
435 : : ! ==============================================
436 : : ! === Write the dimensions specified by ETSF ===
437 : : ! ==============================================
438 : 25 : one_dim=1; cplex=2; cart_dir=3
439 : :
440 : : ncerr = nctk_def_dims(ncid, [&
441 : : nctkdim_t('max_number_of_states',fan2d%mband),&
442 : : nctkdim_t('number_of_spins',fan2d%nsppol),&
443 : : nctkdim_t('number_of_kpoints',fan2d%nkpt),&
444 : : nctkdim_t('number_of_atoms',fan2d%natom),&
445 : : nctkdim_t('3_number_of_atoms',3*fan2d%natom),& ! TODO: not sure that variables can start with digits
446 : : nctkdim_t('number_of_cartesian_directions',cart_dir),&
447 : : nctkdim_t('current_one_dim',one_dim),&
448 : : nctkdim_t('cplex',cplex),&
449 : : nctkdim_t('product_mband_nsppol',fan2d%mband*fan2d%nsppol),&
450 : : nctkdim_t('product_mband_nsppol2',fan2d%mband*fan2d%nsppol*2) &
451 [ + + ]: 275 : ], defmode=.True.)
452 [ - + ]: 25 : NCF_CHECK(ncerr)
453 : :
454 : : temp= 'product_mband_nsppol2, number_of_kpoints, number_of_cartesian_directions,' //&
455 : 25 : 'number_of_atoms, number_of_cartesian_directions, number_of_atoms, max_number_of_states'
456 : : ncerr = nctk_def_arrays(ncid, [&
457 : : nctkarr_t('current_q_point', "dp", 'number_of_cartesian_directions'),&
458 : : nctkarr_t('current_q_point_weight', "dp", 'current_one_dim'),&
459 [ + + ]: 100 : nctkarr_t('second_derivative_eigenenergies_actif', "dp", temp )])
460 : : ! nctkarr_t('second_derivative_eigenenergies_actif', "dp",&
461 : : ! &'product_mband_nsppol2, number_of_kpoints, number_of_cartesian_directions,&
462 : : ! &number_of_atoms, number_of_cartesian_directions, number_of_atoms, max_number_of_states')])
463 [ - + ]: 25 : NCF_CHECK(ncerr)
464 : :
465 : : ! Write data
466 [ - + ]: 25 : NCF_CHECK(nctk_set_datamode(ncid))
467 [ - + ]: 25 : NCF_CHECK(nf90_put_var(ncid, vid('current_q_point'), iqpt))
468 [ - + ]: 25 : NCF_CHECK(nf90_put_var(ncid, vid('current_q_point_weight'), wtq))
469 [ - + ]: 25 : NCF_CHECK(nf90_put_var(ncid, vid('second_derivative_eigenenergies_actif'), fan2d%fan2d))
470 : :
471 : : contains
472 : 75 : integer function vid(vname)
473 : : character(len=*),intent(in) :: vname
474 : 75 : vid = nctk_idname(ncid, vname)
475 : : end function vid
476 : :
477 : : end subroutine fan_ncwrite
478 : : !!***
479 : :
480 : : !----------------------------------------------------------------------
481 : :
482 : : !!****f* m_eig2d/gkk_ncwrite
483 : : !! NAME
484 : : !! gkk_ncwrite
485 : : !!
486 : : !! FUNCTION
487 : : !! Writes the content of a gkk_t object to a NETCDF file
488 : : !! according to the ETSF-IO specifications.
489 : : !!
490 : : !! INPUTS
491 : : !! ncid =NC file handle
492 : : !!
493 : : !! OUTPUT
494 : : !!
495 : : !! SOURCE
496 : :
497 : 122 : subroutine gkk_ncwrite(gkk2d,iqpt,wtq,ncid)
498 : :
499 : : !Arguments ------------------------------------
500 : : !scalars
501 : : integer,intent(in) ::ncid
502 : : real(dp), intent(in) :: iqpt(3),wtq
503 : : type(gkk_t),intent(in) :: gkk2d
504 : :
505 : : !Local variables-------------------------------
506 : : integer :: cplex,one_dim,ncerr,vid_
507 : : ! *************************************************************************
508 : :
509 : : ! ==============================================
510 : : ! === Write the dimensions specified by ETSF ===
511 : : ! ==============================================
512 : 122 : one_dim=1; cplex=2
513 : :
514 : : ncerr = nctk_def_dims(ncid, [ &
515 : : & nctkdim_t('max_number_of_states', gkk2d%mband), &
516 : : & nctkdim_t('number_of_spins', gkk2d%nsppol), &
517 : : & nctkdim_t('number_of_kpoints', gkk2d%nkpt), &
518 : : & nctkdim_t('number_of_atoms_for_gkk', gkk2d%natom), &
519 : : & nctkdim_t('3_number_of_atoms', 3*gkk2d%natom), &
520 : : & nctkdim_t('number_of_cartesian_directions_for_gkk', gkk2d%ncart), &
521 : : & nctkdim_t('current_one_dim', one_dim), &
522 : : & nctkdim_t('cplex', cplex), &
523 : : & nctkdim_t('product_mband_nsppol', gkk2d%mband*gkk2d%nsppol), &
524 : : & nctkdim_t('product_mband_nsppol2', gkk2d%mband*gkk2d%nsppol*2) &
525 [ + + ]: 1342 : & ], defmode=.True.)
526 [ - + ]: 122 : NCF_CHECK(ncerr)
527 : :
528 : : !arrays
529 : : ncerr = nctk_def_arrays(ncid, [&
530 : : & nctkarr_t('current_q_point', "dp", "number_of_cartesian_directions"), &
531 : : & nctkarr_t('current_q_point_weight', "dp", 'current_one_dim'), &
532 : : & nctkarr_t('second_derivative_eigenenergies_actif', "dp", &
533 : : & 'product_mband_nsppol2, number_of_kpoints, number_of_cartesian_directions_for_gkk,'// &
534 : : & 'number_of_atoms_for_gkk, max_number_of_states') &
535 [ + + ]: 488 : & ])
536 [ - + ]: 122 : NCF_CHECK(ncerr)
537 : :
538 [ - + ]: 122 : NCF_CHECK(nctk_set_datamode(ncid))
539 : 122 : vid_=vid('current_q_point')
540 [ - + ]: 122 : NCF_CHECK(nf90_put_var(ncid, vid_, iqpt))
541 : 122 : vid_=vid('current_q_point_weight')
542 [ - + ]: 122 : NCF_CHECK(nf90_put_var(ncid, vid_, wtq))
543 : 122 : vid_=vid('second_derivative_eigenenergies_actif')
544 [ - + ]: 122 : NCF_CHECK(nf90_put_var(ncid, vid_, gkk2d%gkk2d))
545 : :
546 : : contains
547 : 366 : integer function vid(vname)
548 : : character(len=*),intent(in) :: vname
549 : 366 : vid = nctk_idname(ncid, vname)
550 : : end function vid
551 : :
552 : : end subroutine gkk_ncwrite
553 : : !!***
554 : :
555 : : !----------------------------------------------------------------------
556 : :
557 : : !!****f* m_eig2d/fan_free
558 : : !! NAME
559 : : !! fan_free
560 : : !!
561 : : !! FUNCTION
562 : : !! Deallocates the components of the fan_t structured datatype
563 : : !!
564 : : !! INPUTS
565 : : !! fan2d<fan_t>=The data type to be deallocated.
566 : : !!
567 : : !! OUTPUT
568 : : !! Deallocate the dynamic arrays in the fan_t type.
569 : : !! (only deallocate)
570 : : !!
571 : : !! SOURCE
572 : :
573 : 54 : subroutine fan_free(fan2d)
574 : :
575 : : !Arguments ------------------------------------
576 : : !scalars
577 : : type(fan_t),intent(inout) :: fan2d
578 : : ! *************************************************************************
579 : : DBG_ENTER("COLL")
580 : :
581 : : !Deallocate all components of bstruct
582 : :
583 [ - - + + ]: 54 : ABI_SFREE(fan2d%fan2d)
584 : :
585 : : DBG_EXIT("COLL")
586 : :
587 : 0 : end subroutine fan_free
588 : : !!***
589 : :
590 : : !----------------------------------------------------------------------
591 : :
592 : : !!****f* m_eig2d/gkk_free
593 : : !! NAME
594 : : !! gkk_free
595 : : !!
596 : : !! FUNCTION
597 : : !! Deallocates the components of the gkk_t structured datatype
598 : : !!
599 : : !! INPUTS
600 : : !! gkk2d<gkk_t>=The data type to be deallocated.
601 : : !!
602 : : !! OUTPUT
603 : : !! Deallocate the dynamic arrays in the gkk_t type.
604 : : !! (only deallocate)
605 : : !!
606 : : !! SOURCE
607 : :
608 : 147 : subroutine gkk_free(gkk2d)
609 : :
610 : : !Arguments ------------------------------------
611 : : !scalars
612 : : type(gkk_t),intent(inout) :: gkk2d
613 : : ! *************************************************************************
614 : : DBG_ENTER("COLL")
615 : :
616 : : !Deallocate all components of bstruct
617 : :
618 [ + - ]: 122 : ABI_SFREE(gkk2d%gkk2d)
619 : :
620 : : DBG_EXIT("COLL")
621 : :
622 : 93 : end subroutine gkk_free
623 : : !!***
624 : :
625 : : !!****f* ABINIT/eig2stern
626 : : !! NAME
627 : : !! eig2stern
628 : : !!
629 : : !! FUNCTION
630 : : !! This routine calculates the second-order eigenvalues.
631 : : !! The output eig2nkq is this quantity for the input k points.
632 : : !!
633 : : !! INPUTS
634 : : !! bdeigrf = number of bands for which to calculate the second-order eigenvalues.
635 : : !! clflg(3,mpert)= array on calculated perturbations for eig2rf.
636 : : !! dim_eig2nkq = 1 if eig2nkq is to be computed.
637 : : !! cg1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol,3,mpert) = first-order wf in G
638 : : !! space for each perturbation. The wavefunction is orthogonal to the
639 : : !! active space.
640 : : !! gh0c1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol,3,mpert) = matrix containing the
641 : : !! vector: <G|H(0)|psi(1)>, for each perturbation.
642 : : !! gh1c_pert(2,mpw1*nspinor*mband*mk1mem*nsppol,3,mpert)) = matrix containing the
643 : : !! vector: <G|H(1)|n,k>, for each perturbation. The wavefunction is
644 : : !! orthogonal to the active space.
645 : : !! eigbrd(2,mband*nsppol,nkpt,3,natom,3,natom) = broadening factors for the
646 : : !! electronic eigenvalues (optional).
647 : : !! eigen0(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all K-points:
648 : : !! <k,n'|H(0)|k,n'> (hartree).
649 : : !! eigenq(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all shifted K-points:
650 : : !! <k+Q,n'|H(0)|k+Q,n'> (hartree).
651 : : !! eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert) = matrix of first-order:
652 : : !! <k+Q,n'|H(1)|k,n> (hartree) (calculated in dfpt_cgwf).
653 : : !! eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq) = second derivatives of
654 : : !! the electronic eigenvalues.
655 : : !! elph2_imagden = imaginary part of the denominator of the sum-over-state expression
656 : : !! for the electronic eigenenergy shift due to second-order electron-phonon
657 : : !! interation.
658 : : !! ieig2rf = integer for calculation type.
659 : : !! indsym(4,nsym,natom) = indirect indexing array for atom labels
660 : : !! (not used yet, but will be used with symmetries).
661 : : !! istwfk_pert(nkpt_rbz,3,mpert) = integer for choice of storage of wavefunction at
662 : : !! each k point for each perturbation.
663 : : !! mband = maximum number of bands.
664 : : !! mk1mem = maximum number of k points which can fit in memory (RF data);
665 : : !! 0 if use disk.
666 : : !! mpert = maximum number of perturbations.
667 : : !! natom = number of atoms in the unit cell.
668 : : !! npert = number of phonon perturbations, without taking into account directions:
669 : : !! natom.
670 : : !! nsym = number of symmetries (not used yet).
671 : : !! mpi_enreg = information about MPI parallelization.
672 : : !! mpw1 = maximum number of planewaves used to represent first-order wavefunctions.
673 : : !! nkpt_rbz = number of k-points for each perturbation.
674 : : !! npwar1(nkpt_rbz,mpert) = number of planewaves at k-point for first-order.
675 : : !! nspinor = number of spinorial components of the wavefunctions.
676 : : !! nsppol = 1 for unpolarized, 2 for spin-polarized.
677 : : !! occ(mband*nkpt*nsppol)=occup number for each band (often 2) at each k point
678 : : !! smdelta = integer controling the calculation of electron lifetimes.
679 : : !! symq(4,2,nsym) = 1 if symmetry preserves present qpoint. From littlegroup_q (not used yet).
680 : : !! symrec(3,3,nsym) = 3x3 matrices of the group symmetries (reciprocal space)
681 : : !! (not used yet).
682 : : !! symrel(3,3,nsym) = array containing the symmetries in real space (not used yet).
683 : : !! timrev = 1 if time-reversal preserves the q wavevector; 0 otherwise
684 : : !! (not in use yet).
685 : : !! dtset = OPTIONAL, dataset structure containing the input variable of the
686 : : !! calculation. This is required to use the k-interpolation routine.
687 : : !! eigenq_fine(mband_fine,mkpt_fine,nsppol_fine) = OPTIONAL, 0-order eigenvalues
688 : : !! at all shifted K-points: <k+Q,n'|H(0)|k+Q,n'> (hartree) of the
689 : : !! fine grid. This information is read from the WF dense k-grid file.
690 : : !! hdr_fine = OPTIONAL, header of the WF file of the fine k-point grid. This
691 : : !! variable is required for the k-interpolation routine.
692 : : !! hdr0 = OPTIONAL, header of the GS WF file of the corse k-point grid. This
693 : : !! variable is required for the k-interpolation routine.
694 : : !!
695 : : !! OUTPUT
696 : : !! eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= diagonal part of the
697 : : !! second-order eigenvalues: E^{(2),diag}_{k,q,j}.
698 : : !! eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= OPTIONAL, array containing the
699 : : !! electron lifetimes.
700 : : !!
701 : : !! SOURCE
702 : :
703 : 168 : subroutine eig2stern(dtfil,occ,bdeigrf,clflg,cg1_pert,dim_eig2nkq,dim_eig2rf,eigen0,eigenq,&
704 : 168 : & eigen1,eig2nkq,elph2_imagden,esmear,gh0c1_pert,gh1c_pert,ieig2rf,istwfk_pert,&
705 : 84 : & mband,mk1mem,mpert,npert,mpi_enreg,mpw1,nkpt_rbz,npwar1,nspinor,nsppol,smdelta,&
706 : 82 : & dtset,xred,pawtab,psps,eigbrd,eigenq_fine,hdr_fine,hdr0)
707 : :
708 : : !Arguments ------------------------------------
709 : : type(datafiles_type), intent(in) :: dtfil
710 : : type(MPI_type), intent(inout) :: mpi_enreg
711 : : !scalars
712 : : integer,intent(in) :: bdeigrf,dim_eig2nkq,dim_eig2rf,ieig2rf,mband,mk1mem,mpert,mpw1,nkpt_rbz
713 : : integer,intent(in) :: npert,nspinor,nsppol,smdelta
714 : : integer,intent(in) :: clflg(3,mpert)
715 : : integer,intent(in) :: istwfk_pert(nkpt_rbz,3,mpert)
716 : : integer,intent(in) :: npwar1(nkpt_rbz,mpert)
717 : : !arrays
718 : : type(dataset_type), intent(in) :: dtset
719 : : real(dp),intent(in) :: elph2_imagden,esmear
720 : : real(dp),intent(in) :: cg1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol*dim_eig2rf,3,mpert)
721 : : real(dp),intent(in) :: gh0c1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol*dim_eig2rf,3,mpert)
722 : : real(dp),intent(in) :: gh1c_pert(2,mpw1*nspinor*mband*mk1mem*nsppol*dim_eig2rf,3,mpert)
723 : : real(dp),intent(inout) :: eigen0(nkpt_rbz*mband*nsppol)
724 : : real(dp),intent(inout) :: xred(3,dtset%natom)
725 : : real(dp),intent(in) :: eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert)
726 : : real(dp),intent(inout) :: eigenq(nkpt_rbz*mband*nsppol)
727 : : real(dp),intent(out) :: eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert*dim_eig2nkq)
728 : : real(dp),intent(out),optional :: eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)
729 : : real(dp),intent(in),pointer,optional :: eigenq_fine(:,:,:)
730 : : real(dp), intent(in) :: occ(mband*nkpt_rbz*nsppol)
731 : : type(pseudopotential_type), intent(inout) :: psps
732 : : type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
733 : : type(hdr_type),intent(in),optional :: hdr_fine,hdr0
734 : :
735 : : !Local variables-------------------------------
736 : : !tolerance for non degenerated levels
737 : : !scalars
738 : : integer :: band2tot_index,band_index,bandtot_index,iband,icg2,idir1,idir2
739 : : integer :: ikpt,ipert1,ipert2,isppol,istwf_k,jband,npw1_k,nkpt_sub,ikpt2
740 : : !integer :: ipw
741 : : integer :: master,me,spaceworld,ierr,mband_mem,mpert_
742 : : !real(dp),parameter :: etol=1.0d-3
743 : : real(dp),parameter :: etol=1.0d-6
744 : : !real(dp),parameter :: etol=zero
745 : : real(dp) :: ar,ai,deltae,den,dot2i,dot2r,dot3i,dot3r,doti,dotr,eig1_i1,eig1_i2
746 : : real(dp) :: eig1_r1,eig1_r2,eig2_diai,den_av
747 : : real(dp) :: wgt_int
748 : : real(dp) :: eig2_diar,eigbrd_i,eigbrd_r
749 : : character(len=500) :: message
750 : : character(len=500) :: msg
751 : : character(len=fnlen) :: dscrpt
752 : : !DBSP
753 : : ! character(len=300000) :: message2
754 : : !END
755 : : logical :: test_do_band
756 : : !arrays
757 : 84 : integer, allocatable :: nband_rbz(:),icg2_rbz(:,:)
758 : 84 : integer, allocatable :: blkflg_save(:,:,:,:)
759 : 84 : integer, allocatable :: flg(:,:,:,:)
760 : 84 : real(dp),allocatable :: eig2nkq_tmp(:,:,:,:,:,:,:)
761 : 84 : integer, pointer :: kpt_fine_sub(:)
762 : : real(dp) :: tsec(2)
763 : 168 : real(dp),allocatable :: cwavef(:,:),cwavef2(:,:),center(:),eigen0tmp(:),eigenqtmp(:)
764 : 252 : real(dp) :: eigen(mband*nsppol),eigen_prime(mband*nsppol)
765 : 84 : real(dp),allocatable :: gh(:,:),gh1(:,:),ghc(:,:)
766 : 84 : real(dp),allocatable :: smdfun(:,:)
767 : 84 : real(dp),pointer :: wgt_sub(:)
768 : 84 : type(ddb_type) :: ddb
769 [ + + + + : 5292 : type(ddb_hdr_type) :: ddb_hdr
+ + + + +
+ + + + +
+ + + + +
+ ]
770 : :
771 : : ! *********************************************************************
772 : :
773 : : !Init parallelism
774 : 84 : master =0
775 : 84 : spaceworld=mpi_enreg%comm_cell
776 : 84 : me=mpi_enreg%me_kpt
777 : :
778 : : !Init interpolation method
779 : 84 : if(present(eigenq_fine))then
780 [ - + ]: 3 : ABI_MALLOC(center,(3))
781 : : end if
782 : :
783 : 84 : call timab(148,1,tsec)
784 : :
785 [ + + ]: 84 : if(nsppol==2)then
786 : 1 : message = 'nsppol=2 is still under development. Be careful when using it ...'
787 : 1 : ABI_COMMENT(message)
788 : : end if
789 : :
790 : 84 : band2tot_index =0
791 : 84 : bandtot_index=0
792 : 84 : band_index=0
793 : :
794 : : !Add scissor shift to eigenenergies
795 [ - + ]: 84 : if (dtset%dfpt_sciss > tol6 ) then
796 : : write(msg,'(a,f7.3,2a)')&
797 : 0 : & ' A scissor operator of ',dtset%dfpt_sciss*Ha_eV,' [eV] has been applied to the eigenenergies',ch10
798 : 0 : call wrtout(std_out,msg,'COLL')
799 : 0 : call wrtout(ab_out,msg,'COLL')
800 [ # # # # : 0 : ABI_MALLOC(eigen0tmp,(nkpt_rbz*mband*nsppol))
# # # # #
# # # ]
801 [ # # # # : 0 : ABI_MALLOC(eigenqtmp,(nkpt_rbz*mband*nsppol))
# # # # ]
802 [ # # # # ]: 0 : eigen0tmp = eigen0(:)
803 [ # # # # ]: 0 : eigenqtmp = eigenq(:)
804 [ # # ]: 0 : eigen0 = zero
805 [ # # ]: 0 : eigenq = zero
806 : : end if
807 : :
808 [ + - ]: 84 : if(ieig2rf > 0) then
809 [ + + + + : 1723672 : eig2nkq(:,:,:,:,:,:,:) = zero
+ + + + +
+ + + +
+ ]
810 : : end if
811 [ + + ]: 84 : if(present(eigbrd))then
812 [ + + + + : 1686694 : eigbrd(:,:,:,:,:,:,:) = zero
+ + + + +
+ + + +
+ ]
813 : : end if
814 : :
815 : : if(xmpi_paral==1) then
816 [ - + + - : 420 : ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt_rbz,mband,nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
817 [ - + + - : 252 : ABI_MALLOC(nband_rbz,(nkpt_rbz*nsppol))
+ - + - -
+ - + ]
818 [ - + ]: 84 : ABI_SFREE(mpi_enreg%my_kpttab)
819 [ - + + - : 252 : ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt_rbz))
+ - + - -
+ - + -
+ ]
820 : : ! Assume the number of bands is the same for all k points.
821 [ + + ]: 1569 : nband_rbz(:)=mband
822 : 84 : call distrb2(mband,mband_mem,nband_rbz,nkpt_rbz,mpi_enreg%nproc_cell,nsppol,mpi_enreg)
823 : : end if
824 : :
825 : 84 : icg2=0
826 : 84 : ipert1=1 ! Suppose that the situation is the same for all perturbations
827 [ - + + - : 336 : ABI_MALLOC(icg2_rbz,(nkpt_rbz,nsppol))
- + + - +
- + - - +
- + ]
828 [ + + ]: 169 : do isppol=1,nsppol
829 [ + + ]: 1654 : do ikpt=1,nkpt_rbz
830 : 1485 : icg2_rbz(ikpt,isppol)=icg2
831 [ + + ]: 1485 : if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,me)) cycle
832 : 1570 : icg2 = icg2 + npwar1(ikpt,ipert1)*nspinor*mband
833 : : end do
834 : : end do
835 : :
836 [ + + ]: 169 : do isppol=1,nsppol
837 [ + + ]: 1570 : do ikpt =1,nkpt_rbz
838 : :
839 [ + + ]: 1485 : if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,me)) then
840 : 224 : band2tot_index = band2tot_index + 2*mband**2
841 : 224 : bandtot_index = bandtot_index + mband
842 : 224 : cycle
843 : : end if
844 : :
845 [ + + ]: 1261 : if(present(eigenq_fine))then
846 : 24 : write(std_out,*) 'Start of the energy denominator interpolation method.'
847 : 24 : nkpt_sub = 0
848 : : ! center is the k+q point around which we will average the kpt_fine
849 [ + - - + : 120 : center = hdr0%kptns(:,ikpt)+ dtset%qptn(:)
- - + + ]
850 : :
851 : 24 : call kptfine_av(center,dtset%qptrlatt,hdr_fine%kptns,hdr_fine%nkpt,kpt_fine_sub,nkpt_sub,wgt_sub)
852 : : write(std_out,'(a,3f8.4,a,i3)') 'Number of k-points of the fine grid &
853 : 24 : & around the k+Q point ',center,' is:',nkpt_sub
854 [ + + ]: 672 : write(std_out,'(a,f10.5)') 'The sum of the weights of the k-points is: ',SUM(wgt_sub)
855 : : end if
856 : :
857 : : ! Add scissor shift to eigenenergies
858 [ - + ]: 1261 : if (dtset%dfpt_sciss > tol6 ) then
859 [ # # ]: 0 : do iband=1,mband
860 [ # # ]: 0 : if (occ(iband+bandtot_index) < tol6) then
861 : 0 : eigen0(iband+bandtot_index) = eigen0tmp(iband+bandtot_index) + dtset%dfpt_sciss
862 : 0 : eigenq(iband+bandtot_index) = eigenqtmp(iband+bandtot_index) + dtset%dfpt_sciss
863 : : else
864 : 0 : eigen0(iband+bandtot_index) = eigen0tmp(iband+bandtot_index)
865 : 0 : eigenq(iband+bandtot_index) = eigenqtmp(iband+bandtot_index)
866 : : end if
867 : : end do
868 : : end if
869 : :
870 : :
871 [ + + ]: 1261 : if(smdelta >0) then !broadening
872 [ + + ]: 1197 : if(.not.allocated(smdfun)) then
873 [ - + + - : 1443 : ABI_MALLOC(smdfun,(mband,mband))
- + + - +
- + - - +
- + - + ]
874 : : end if
875 [ + + + + ]: 159073 : smdfun(:,:) = zero
876 [ + + ]: 14033 : do iband=1,mband
877 : 12836 : eigen(iband) = eigen0(iband+bandtot_index)
878 : 14033 : eigen_prime(iband) =eigenq(iband+bandtot_index)
879 : : end do
880 [ + - ]: 1197 : if(esmear>tol6) then
881 : 1197 : call smeared_delta(eigen,eigen_prime,esmear,mband,smdelta,smdfun)
882 : : end if
883 : : end if
884 : 1261 : icg2=icg2_rbz(ikpt,isppol)
885 : :
886 : 1261 : ipert1=1 ! Suppose all perturbations lead to the same number of planewaves
887 : 1261 : npw1_k = npwar1(ikpt,ipert1)
888 [ - + + - : 3783 : ABI_MALLOC(cwavef,(2,npw1_k*nspinor))
+ - + - -
+ - + ]
889 [ - + + - : 2522 : ABI_MALLOC(cwavef2,(2,npw1_k*nspinor))
- + - + ]
890 [ - + + - : 2522 : ABI_MALLOC(gh,(2,npw1_k*nspinor))
- + - + ]
891 [ - + + - : 2522 : ABI_MALLOC(gh1,(2,npw1_k*nspinor))
- + - + ]
892 [ - + + - : 2522 : ABI_MALLOC(ghc,(2,npw1_k*nspinor))
- + - + ]
893 : :
894 [ + + ]: 14397 : do iband=1,bdeigrf
895 : :
896 : : ! If the k point and band belong to me, compute the contribution
897 : 13136 : test_do_band=.true.
898 [ + - ]: 13136 : if(mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me)test_do_band=.false.
899 : :
900 : 1261 : if(test_do_band)then
901 : :
902 [ + + ]: 39344 : do ipert1=1,npert
903 : :
904 [ + + ]: 117968 : do idir1=1,3
905 [ + + ]: 78624 : if(clflg(idir1,ipert1)==0)cycle
906 : 78584 : istwf_k = istwfk_pert(ikpt,idir1,ipert1)
907 : :
908 [ + + ]: 265800 : do ipert2=1,npert
909 [ + + ]: 722656 : do idir2=1,3
910 [ + + ]: 483024 : if(clflg(idir2,ipert2)==0)cycle
911 : :
912 : : eig2_diar = zero ; eig2_diai = zero ; eigbrd_r = zero ; eigbrd_i = zero
913 : :
914 [ + + ]: 6256096 : do jband=1,mband
915 : 5773152 : eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
916 : 5773152 : eig1_r2 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir2,ipert2)
917 : 5773152 : eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
918 : 5773152 : eig1_i2 = - eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir2,ipert2) !the negative sign is from the CC
919 : : ! If no interpolation, fallback on to the previous
920 : : ! implementation
921 [ + + ]: 5773152 : if(.not. present(eigenq_fine))then
922 : 5717856 : deltae=eigenq(jband+bandtot_index)-eigen0(iband+bandtot_index)
923 : : end if
924 : 5773152 : ar=eig1_r1*eig1_r2-eig1_i1*eig1_i2
925 : 5773152 : ai=eig1_r1*eig1_i2+eig1_i1*eig1_r2
926 : :
927 : : ! Sum over all active space to retrieve the diagonal gauge
928 [ + + ]: 5773152 : if(ieig2rf == 1 .or. ieig2rf ==2 ) then
929 : : ! if(abs(deltae)>etol) then ! This is commented because
930 : : ! there is no problem with divergencies with elph2_imag != 0
931 [ + + ]: 1036992 : if( present(eigenq_fine))then
932 : 55296 : den_av = zero
933 : 55296 : wgt_int = zero
934 [ + + ]: 1548288 : do ikpt2=1,nkpt_sub
935 : : deltae=eigenq_fine(jband,kpt_fine_sub(ikpt2),1)&
936 : 1492992 : & -eigen0(iband+bandtot_index)
937 : 1492992 : den_av = den_av-(wgt_sub(ikpt2)*deltae)/(deltae**2+elph2_imagden**2)
938 : 1548288 : wgt_int = wgt_int+wgt_sub(ikpt2)
939 : : end do
940 : 55296 : den = den_av/wgt_int
941 : : else
942 [ + + ]: 981696 : if(abs(elph2_imagden) < etol) then
943 [ + + ]: 723648 : if(abs(deltae)>etol) then
944 : 548132 : den=-one/(deltae**2+elph2_imagden**2)
945 : : else
946 : : den= zero
947 : : end if
948 : : else
949 : 258048 : den=-one/(deltae**2+elph2_imagden**2)
950 : : end if
951 : : end if
952 : :
953 : : ! The following should be the most general implementation of the presence of elph2_imagden
954 : : ! eig2_diar=eig2_diar+(ar*deltae+ai*elph2_imagden)*den
955 : : ! eig2_diai=eig2_diai+(ai*deltae-ar*elph2_imagden)*den
956 : : ! This gives back the implementation without elph2_imagden
957 : : ! eig2_diar=eig2_diar+ar*deltae*den
958 : : ! eig2_diai=eig2_diai+ai*deltae*den
959 : : ! This is what Samuel had implemented
960 : : ! eig2_diar=eig2_diar+ar*deltae*den
961 : : ! eig2_diai=eig2_diai+ai*elph2_imagden*den
962 : : ! Other possibility : throw away the broadening part, that is actually treated separately.
963 [ + + ]: 1036992 : if( present(eigenq_fine))then
964 : 55296 : eig2_diar=eig2_diar+ar*den
965 : 55296 : eig2_diai=eig2_diai+ai*den
966 : : else
967 : 981696 : eig2_diar=eig2_diar+ar*deltae*den
968 : 981696 : eig2_diai=eig2_diai+ai*deltae*den
969 : : !DBSP
970 : : ! if (iband+band_index==2 .and. ikpt==1 .and. idir1==1 .and. ipert1==1 .and. idir2==1 .and. ipert2==1) then
971 : : ! write(message2,*) 'eig2_diar1=',eig2_diar,' ar=',ar,' deltae=',deltae,' den=',den
972 : : ! call wrtout(std_out,message2,'PERS')
973 : : ! endif
974 : : !END
975 : :
976 : : end if
977 : : end if ! ieig2rf==1 or 2
978 : :
979 [ + + ]: 6256096 : if(present(eigbrd))then
980 [ + - ]: 5715552 : if(smdelta >0) then !broadening
981 : 5715552 : eigbrd_r = eigbrd_r + ar*smdfun(iband,jband)
982 : 5715552 : eigbrd_i = eigbrd_i + ai*smdfun(iband,jband)
983 : : end if
984 : : end if
985 : :
986 : : end do !jband
987 : :
988 : : ! Add the contribution of non-active bands, if DFPT calculation (= Sternheimer)
989 [ + + + + : 482944 : if(ieig2rf == 1 .or. ieig2rf ==3 .or. ieig2rf ==4 .or. ieig2rf==5 ) then
+ + ]
990 : : ! if(ieig2rf == 1 ) then
991 : :
992 : 482904 : dotr=zero ; doti=zero
993 : 482904 : dot2r=zero ; dot2i=zero
994 : 482904 : dot3r=zero ; dot3i=zero
995 : :
996 : :
997 [ + + + + ]: 923921136 : cwavef(:,:) = cg1_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir2,ipert2)
998 [ + + + + ]: 923921136 : cwavef2(:,:)= cg1_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir1,ipert1)
999 [ + + + + ]: 923921136 : gh1(:,:) = gh1c_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir1,ipert1)
1000 [ + + + + ]: 923921136 : gh(:,:) = gh1c_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir2,ipert2)
1001 [ + + + + ]: 923921136 : ghc(:,:) = gh0c1_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir1,ipert1)
1002 : :
1003 : : ! The first two dotprod corresponds to: <Psi(1)nkq|H(1)k+q,k|Psi(0)nk> and <Psi(0)nk|H(1)k,k+q|Psi(1)nkq>
1004 : : ! They are calculated using wavefunctions <Psi(1)| that are orthogonal to the active space.
1005 : 482904 : call dotprod_g(dotr,doti,istwf_k,npw1_k*nspinor,2,cwavef,gh1,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
1006 : 482904 : call dotprod_g(dot2r,dot2i,istwf_k,npw1_k*nspinor,2,gh,cwavef2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
1007 : :
1008 : : ! This dotprod corresponds to : <Psi(1)nkq|H(0)k+q- E(0)nk|Psi(1)nkq>
1009 : : ! It is calculated using wavefunctions that are orthogonal to the active space.
1010 : : ! Should work for metals. (But adiabatic approximation is bad in this case...)
1011 : 482904 : call dotprod_g(dot3r,dot3i,istwf_k,npw1_k*nspinor,2,cwavef,ghc,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
1012 : :
1013 : 482904 : eig2_diar= eig2_diar + dotr + dot2r + dot3r
1014 : 482904 : eig2_diai= eig2_diai + doti + dot2i + dot3i
1015 : :
1016 : : end if
1017 : :
1018 : : ! Store the contribution
1019 [ + - ]: 482944 : if(ieig2rf > 0) then
1020 : 482944 : eig2nkq(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eig2_diar
1021 : 482944 : eig2nkq(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eig2_diai
1022 : : end if
1023 : :
1024 [ + + ]: 643952 : if(present(eigbrd))then
1025 [ - + ]: 471424 : if(smdelta >0) then !broadening
1026 : 471424 : eigbrd(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_r
1027 : 471424 : eigbrd(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_i
1028 : : end if
1029 : : end if
1030 : :
1031 : : end do !idir2
1032 : : end do !ipert2
1033 : : end do !idir1
1034 : : end do !ipert1
1035 : :
1036 : : end if ! Selection of processor
1037 : :
1038 : : end do !iband
1039 : :
1040 [ - + ]: 1261 : ABI_FREE(cwavef)
1041 [ - + ]: 1261 : ABI_FREE(cwavef2)
1042 [ - + ]: 1261 : ABI_FREE(gh)
1043 [ - + ]: 1261 : ABI_FREE(gh1)
1044 [ - + ]: 1261 : ABI_FREE(ghc)
1045 : 1261 : band2tot_index = band2tot_index + 2*mband**2
1046 : 1261 : bandtot_index = bandtot_index + mband
1047 : :
1048 [ + + ]: 1346 : if(present(eigenq_fine))then
1049 [ - + ]: 24 : ABI_FREE(kpt_fine_sub) ! Deallocate the variable
1050 [ - + ]: 24 : ABI_FREE(wgt_sub)
1051 : : end if
1052 : :
1053 : : end do !ikpt
1054 : 169 : band_index = band_index + mband
1055 : : end do !isppol
1056 : :
1057 : : !Accumulate eig2nkq and/or eigbrd
1058 : : if(xmpi_paral==1) then
1059 [ + + ]: 84 : if(ieig2rf == 1 .or. ieig2rf == 2) then
1060 : 30 : call xmpi_sum(eig2nkq,spaceworld,ierr)
1061 [ - + ]: 30 : if (dtset%dfpt_sciss > tol6 ) then
1062 : 0 : call xmpi_sum(eigen0,spaceworld,ierr)
1063 : 0 : call xmpi_sum(eigenq,spaceworld,ierr)
1064 : : end if
1065 : : end if
1066 [ + + + + ]: 84 : if(present(eigbrd) .and. (ieig2rf == 1 .or. ieig2rf == 2))then
1067 [ + - ]: 28 : if(smdelta >0) then
1068 : 28 : call xmpi_sum(eigbrd,spaceworld,ierr)
1069 : : end if
1070 : : end if
1071 [ - + ]: 84 : ABI_FREE(nband_rbz)
1072 [ - + ]: 84 : ABI_FREE(mpi_enreg%proc_distrb)
1073 [ - + ]: 84 : ABI_FREE(mpi_enreg%my_kpttab)
1074 : : end if
1075 : :
1076 [ + + ]: 84 : if(ieig2rf==1 .or. ieig2rf==2 ) then
1077 : 30 : write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGR2D, in Ha unit.'
1078 : 30 : write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1079 [ + + ]: 120 : do idir1=1,3
1080 [ + + ]: 390 : do idir2=1,3
1081 [ + + ]: 270 : ar=eig2nkq(1,1,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1082 [ + + ]: 270 : ai=eig2nkq(2,1,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1083 : 360 : write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1084 : : end do ! idir2
1085 : : end do ! idir1
1086 : : end if
1087 [ + + ]: 84 : if(ieig2rf > 2) then
1088 : 54 : write(ab_out,'(a)')' Components of the Sternheimer part only of the second-order derivatives of the electronic energy,'
1089 : 54 : write(ab_out,'(a)')' EIGR2D, in Ha unit.'
1090 : 54 : write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1091 [ + + ]: 216 : do idir1=1,3
1092 [ + + ]: 702 : do idir2=1,3
1093 [ + + ]: 486 : ar=eig2nkq(1,1,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1094 [ + + ]: 486 : ai=eig2nkq(2,1,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1095 : 648 : write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1096 : : end do ! idir2
1097 : : end do ! idir1
1098 : : end if
1099 [ + + ]: 84 : if(present(eigbrd))then
1100 [ + - ]: 82 : if(smdelta >0) then !broadening
1101 : 82 : write(ab_out,'(a)')' '
1102 : 82 : write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGI2D.'
1103 : 82 : write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1104 [ + + ]: 328 : do idir1=1,3
1105 [ + + ]: 1066 : do idir2=1,3
1106 [ + + ]: 738 : ar=eigbrd(1,1,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1107 [ + + ]: 738 : ai=eigbrd(2,1,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1108 : 984 : write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1109 : : end do
1110 : : end do !nband
1111 : : end if
1112 : : end if
1113 : :
1114 : : ! -------------------------
1115 : : ! Output d2eig data to file
1116 : : ! -------------------------
1117 : : ! Write the second-order derivatives in reduced coordinate of the electronic energy, EIG2D to file, in Hartree unit.
1118 : : ! When ieig2rf==1 or 2 --> EIG(R/I)2D contains the total second-order derivatives
1119 : : ! When ieig2rf > 2 --> EIG(R/I)2D contains the Sternheimer part only.
1120 : : !
1121 [ + + ]: 84 : if (dtset%ieig2rf==1 .or. dtset%ieig2rf==2) then
1122 : : ! SP: For this case, the eig2nkq contains the active space and Sternheimer part
1123 : : !
1124 : : ! GA: Here, mpert needs to be replaced by natom
1125 : : ! but why is mpert larger than natom in the first place?
1126 : 30 : mpert_ = dtset%natom
1127 : :
1128 : : ! Initialize perturbation flags
1129 : : ! GA: At the moment, they are all set to one
1130 : : ! Instead, they should be used to save individual perturbations
1131 : : ! to separate files and merge them after the loop.
1132 [ - + + - : 150 : ABI_MALLOC(blkflg_save,(3,mpert_,3,mpert_))
+ - - + +
- + - + -
- + - + ]
1133 [ + + + + : 2134 : blkflg_save = one
+ + + + ]
1134 : :
1135 : : ! Initialize ddb object
1136 : : call ddb%init(dtset, 1, mpert_, &
1137 : : mband=bdeigrf,&
1138 : : nkpt=nkpt_rbz,&
1139 : : kpt=dtset%kptns(1:3,1:nkpt_rbz),&
1140 : 30 : with_d2eig=.true.)
1141 : :
1142 : : ! Create the ddb header
1143 : 30 : dscrpt=' Note : temporary (transfer) database '
1144 : : call ddb_hdr%init(dtset,psps,pawtab,dscrpt,1,&
1145 : : mpert=mpert_,&
1146 : : xred=xred,occ=occ,&
1147 : : mband=bdeigrf / dtset%nsppol,&
1148 : : nkpt=nkpt_rbz,&
1149 : 30 : kpt=dtset%kptns(:,1:nkpt_rbz))
1150 : :
1151 : : ! Set d2eig data
1152 : 30 : call ddb%set_qpt(1, dtset%qptn)
1153 : 30 : call ddb%set_d2eig_reshape(1, eig2nkq, blkflg_save)
1154 : :
1155 : 30 : call ddb_hdr%set_typ(ddb%nblok, ddb%typ)
1156 : :
1157 : : ! Open the file and write header
1158 : 30 : call ddb_hdr%open_write(dtfil%fnameabo_eigr2d, with_psps=1, comm=mpi_enreg%comm_world)
1159 : :
1160 : : ! Write d2eig data block
1161 : 30 : call ddb%write_d2eig(ddb_hdr, 1, comm=mpi_enreg%comm_world)
1162 : :
1163 : : ! close and free memory
1164 : 30 : call ddb_hdr%close()
1165 : 30 : call ddb_hdr%free()
1166 : 30 : call ddb%free()
1167 : :
1168 [ + + ]: 30 : if (smdelta>0) then
1169 : : ! write out _EIGI2D file
1170 : :
1171 : : call ddb%init(dtset, 1, mpert_, &
1172 : : mband=bdeigrf,&
1173 : : nkpt=nkpt_rbz,&
1174 : : kpt=dtset%kptns(:,1:nkpt_rbz),&
1175 : 28 : with_d2eig=.true.)
1176 : :
1177 : : ! Create the ddb header
1178 : 28 : dscrpt=' Note : temporary (transfer) database '
1179 : : call ddb_hdr%init(dtset,psps,pawtab,dscrpt,1,&
1180 : : mpert=mpert_,&
1181 : : xred=xred,occ=occ,&
1182 : : mband=bdeigrf / dtset%nsppol,&
1183 : : nkpt=nkpt_rbz,&
1184 : 28 : kpt=dtset%kptns(:,1:nkpt_rbz))
1185 : :
1186 : 28 : call ddb%set_qpt(1, dtset%qptn)
1187 : 28 : call ddb%set_d2eig_reshape(1, eigbrd, blkflg_save, blktyp=BLKTYP_d2eig_im)
1188 : :
1189 : 28 : call ddb_hdr%set_typ(ddb%nblok, ddb%typ)
1190 : :
1191 : 28 : call ddb_hdr%open_write(dtfil%fnameabo_eigi2d, with_psps=1,comm=mpi_enreg%comm_world)
1192 : 28 : call ddb%write_d2eig(ddb_hdr, 1, comm=mpi_enreg%comm_world)
1193 : :
1194 : 28 : call ddb_hdr%close()
1195 : 28 : call ddb_hdr%free()
1196 : 28 : call ddb%free()
1197 : :
1198 : : end if !smdelta
1199 : :
1200 [ - + ]: 30 : ABI_FREE(blkflg_save)
1201 : :
1202 : : end if !ieig2rf==1.or.ieig2rf==2
1203 : : !
1204 [ + + ]: 84 : if (ieig2rf == 3 .or. ieig2rf == 4 .or. ieig2rf == 5) then
1205 : : ! SP: these cases are used for non-adiabatic quantities. In this routine we do not have access
1206 : : ! to the phonon frequency. Therefore eig2nkq only contains the Sternheimer part.
1207 : : !
1208 : :
1209 : 54 : mpert_ = dtset%natom
1210 : :
1211 : : ! Initialize perturbation flags
1212 [ - + + - : 270 : ABI_MALLOC(flg,(3,mpert_,3,mpert_))
+ - - + +
- + - + -
- + - + ]
1213 [ + + + + : 3078 : flg = one
+ + + + ]
1214 : :
1215 : : ! Initialize ddb object
1216 : : call ddb%init(dtset, 1, mpert_, &
1217 : : mband=bdeigrf,&
1218 : : nkpt=nkpt_rbz,&
1219 : : kpt=dtset%kptns(1:3,1:nkpt_rbz),&
1220 : 54 : with_d2eig=.true.)
1221 : :
1222 : : ! Create the ddb header
1223 : 54 : dscrpt=' Note : temporary (transfer) database '
1224 : : call ddb_hdr%init(dtset,psps,pawtab,dscrpt,1,&
1225 : : mpert=mpert_,&
1226 : : xred=xred,occ=occ,&
1227 : : mband=bdeigrf / dtset%nsppol,&
1228 : : nkpt=nkpt_rbz,&
1229 : 54 : kpt=dtset%kptns(:,1:nkpt_rbz))
1230 : :
1231 : : ! Set d2eig data
1232 : 54 : call ddb%set_qpt(1, dtset%qptn)
1233 : :
1234 : : ! Copy eig2nkq because it needs to be summed before writing the file,
1235 : : ! yet there are further processing on the eig2nkq array occuring
1236 : : ! after this function
1237 [ - + + - : 432 : ABI_MALLOC(eig2nkq_tmp,(2,mband*nsppol,nkpt_rbz,3,npert,3,npert*dim_eig2nkq))
- + + - +
- - + + -
+ - - + +
- + - + -
- + - + ]
1238 [ - + + + : 1347408 : eig2nkq_tmp = eig2nkq
+ + + + +
+ + + + +
+ + ]
1239 : : if(xmpi_paral==1) then
1240 : 54 : call xmpi_sum(eig2nkq_tmp,spaceworld,ierr)
1241 : : end if
1242 : :
1243 : 54 : call ddb%set_d2eig_reshape(1, eig2nkq_tmp, flg)
1244 : :
1245 [ - + ]: 54 : ABI_FREE(eig2nkq_tmp)
1246 : :
1247 : : ! Open the file and write header
1248 : 54 : call ddb_hdr%set_typ(ddb%nblok, ddb%typ)
1249 : :
1250 : : ! Write d2eig data block
1251 : 54 : call ddb_hdr%open_write(dtfil%fnameabo_eigr2d, with_psps=1, comm=mpi_enreg%comm_world)
1252 : 54 : call ddb%write_d2eig(ddb_hdr, 1, comm=mpi_enreg%comm_world)
1253 : :
1254 : : ! close and free memory
1255 : 54 : call ddb_hdr%close()
1256 : 54 : call ddb_hdr%free()
1257 : 54 : call ddb%free()
1258 : : !
1259 [ - + ]: 108 : ABI_FREE(flg)
1260 : : !
1261 : : end if
1262 : :
1263 [ + + ]: 84 : if(allocated(smdfun)) then
1264 : 82 : ABI_FREE(smdfun)
1265 : : end if
1266 [ - + ]: 84 : ABI_FREE(icg2_rbz)
1267 [ + + ]: 84 : if(present(eigenq_fine))then
1268 [ - + ]: 3 : ABI_FREE(center)
1269 : : end if
1270 [ - + ]: 84 : if (dtset%dfpt_sciss > tol6 ) then
1271 [ # # ]: 0 : ABI_FREE(eigen0tmp)
1272 [ # # ]: 0 : ABI_FREE(eigenqtmp)
1273 : : end if
1274 : :
1275 : 84 : call timab(148,2,tsec)
1276 : :
1277 [ + + + + : 252 : end subroutine eig2stern
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
- - - - -
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + ]
1278 : : !!***
1279 : :
1280 : : !!****f* m_eig2d/eig2tot
1281 : : !! NAME
1282 : : !! eig2tot
1283 : : !!
1284 : : !! FUNCTION
1285 : : !! This routine calculates the second-order eigenvalues.
1286 : : !! The output eig2nkq is this quantity for the input k points.
1287 : : !!
1288 : : !! INPUTS
1289 : : !! bdeigrf = number of bands for which to calculate the second-order eigenvalues.
1290 : : !! clflg(3,mpert)= array on calculated perturbations for eig2rf.
1291 : : !! dim_eig2nkq = 1 if eig2nkq is to be computed.
1292 : : !! eigbrd(2,mband*nsppol,nkpt,3,natom,3,natom) = broadening factors for the
1293 : : !! electronic eigenvalues (optional).
1294 : : !! eigen0(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all K-points:
1295 : : !! <k,n'|H(0)|k,n'> (hartree).
1296 : : !! eigenq(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all shifted K-points:
1297 : : !! <k+Q,n'|H(0)|k+Q,n'> (hartree).
1298 : : !! eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert) = matrix of first-order:
1299 : : !! <k+Q,n'|H(1)|k,n> (hartree) (calculated in dfpt_cgwf).
1300 : : !! eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq) = second derivatives of
1301 : : !! the electronic eigenvalues.
1302 : : !! elph2_imagden = imaginary part of the denominator of the sum-over-state expression
1303 : : !! for the electronic eigenenergy shift due to second-order electron-phonon
1304 : : !! interation.
1305 : : !! ieig2rf = integer for calculation type.
1306 : : !! indsym(4,nsym,natom) = indirect indexing array for atom labels
1307 : : !! (not used yet, but will be used with symmetries).
1308 : : !! mband = maximum number of bands.
1309 : : !! mpert = maximum number of perturbations.
1310 : : !! natom = number of atoms in the unit cell.
1311 : : !! npert = number of phonon perturbations, without taking into account directions:
1312 : : !! natom.
1313 : : !! nsym = number of symmetries (not used yet).
1314 : : !! mpi_enreg = information about MPI parallelization.
1315 : : !! nkpt_rbz = number of k-points for each perturbation.
1316 : : !! nsppol = 1 for unpolarized, 2 for spin-polarized.
1317 : : !! smdelta = integer controling the calculation of electron lifetimes.
1318 : : !! symq(4,2,nsym) = 1 if symmetry preserves present qpoint. From littlegroup_q (not used yet).
1319 : : !! symrec(3,3,nsym) = 3x3 matrices of the group symmetries (reciprocal space)
1320 : : !! (not used yet).
1321 : : !! symrel(3,3,nsym) = array containing the symmetries in real space (not used yet).
1322 : : !! timrev = 1 if time-reversal preserves the q wavevector; 0 otherwise
1323 : : !! (not in use yet).
1324 : : !! dtset = OPTIONAL, dataset structure containing the input variable of the
1325 : : !! calculation. This is required to use the k-interpolation routine.
1326 : : !! eigenq_fine(mband_fine,mkpt_fine,nsppol_fine) = OPTIONAL, 0-order eigenvalues
1327 : : !! at all shifted K-points: <k+Q,n'|H(0)|k+Q,n'> (hartree) of the
1328 : : !! fine grid. This information is read from the WF dense k-grid file.
1329 : : !! hdr_fine = OPTIONAL, header of the WF file of the fine k-point grid. This
1330 : : !! variable is required for the k-interpolation routine.
1331 : : !! hdr0 = header of the GS WF file of the corse k-point grid.
1332 : : !!
1333 : : !!
1334 : : !! OUTPUT
1335 : : !! eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= diagonal part of the
1336 : : !! second-order eigenvalues: E^{(2),diag}_{k,q,j}.
1337 : : !! eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= OPTIONAL, array containing the
1338 : : !! the contribution of each perturbations pair
1339 : : !! to the eigenstate broadening (inverse lifetime)
1340 : : !! computed statically (without phonon frequencies).
1341 : : !!
1342 : : !! SOURCE
1343 : :
1344 : 108 : subroutine eig2tot(dtfil,xred,psps,pawtab,natom,bdeigrf,clflg,dim_eig2nkq,eigen0,eigenq,eigen1,eig2nkq,&
1345 : 54 : & elph2_imagden,esmear,ieig2rf,mband,mpert,npert,mpi_enreg,doccde,&
1346 : 54 : & nkpt_rbz,nsppol,smdelta,rprimd,dtset,occ_rbz,hdr0,eigbrd,eigenq_fine,hdr_fine)
1347 : :
1348 : : !Arguments ------------------------------------
1349 : : !scalars
1350 : : integer,intent(in) :: bdeigrf,dim_eig2nkq,ieig2rf,mband,mpert,natom,nkpt_rbz
1351 : : integer,intent(in) :: npert,nsppol,smdelta
1352 : : real(dp),intent(in) :: elph2_imagden,esmear
1353 : : type(MPI_type),intent(inout) :: mpi_enreg
1354 : : type(datafiles_type), intent(in) :: dtfil
1355 : : type(pseudopotential_type), intent(inout) :: psps
1356 : : !arrays
1357 : : type(dataset_type), intent(in) :: dtset
1358 : : integer,intent(in) :: clflg(3,mpert)
1359 : : real(dp),intent(in) :: doccde(dtset%mband*dtset%nkpt*dtset%nsppol)
1360 : : real(dp),intent(in) :: eigen0(nkpt_rbz*mband*nsppol)
1361 : : real(dp),intent(in) :: eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert)
1362 : : real(dp),intent(in) :: eigenq(nkpt_rbz*mband*nsppol)
1363 : : real(dp),intent(in) :: occ_rbz(mband*nkpt_rbz*nsppol)
1364 : : real(dp),intent(inout) :: eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert*dim_eig2nkq)
1365 : : real(dp),intent(in) :: rprimd(3,3),xred(3,natom)
1366 : : real(dp),intent(inout),optional :: eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)
1367 : : real(dp),intent(in),pointer,optional :: eigenq_fine(:,:,:)
1368 : : type(pawtab_type), intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
1369 : : type(hdr_type),intent(in) :: hdr0
1370 : : type(hdr_type),intent(in),optional :: hdr_fine
1371 : :
1372 : : !Local variables-------------------------------
1373 : : !tolerance for non degenerated levels
1374 : : !scalars
1375 : : integer :: band2tot_index,band_index,bantot,bandtot_index,iband,idir1,idir2
1376 : : integer :: ikpt,ipert1,ipert2,isppol,jband,nkpt_sub,ikpt2,ncid
1377 : : !integer :: ipw
1378 : : character(len=fnlen) :: dscrpt,fname
1379 : : integer :: master,me,spaceworld,ierr
1380 : : integer :: mband_mem, mpert_
1381 : : ! real(dp),parameter :: etol=1.0d-6
1382 : : real(dp),parameter :: etol=1.0d-7
1383 : : !real(dp),parameter :: etol=zero
1384 : : real(dp) :: ar,ai,deltae,den,eig1_i1,eig1_i2,eigen_corr
1385 : : real(dp) :: eig1_r1,eig1_r2,eig2_diai,den_av
1386 : : real(dp) :: eig2_diar,eigbrd_i,eigbrd_r,wgt_int
1387 : : !character(len=500) :: message
1388 : : logical :: remove_inv,test_do_band
1389 [ + + + + : 3402 : type(crystal_t) :: Crystal
+ + + + +
+ + + + +
+ + + + +
+ ]
1390 : 54 : type(ebands_t) :: Bands
1391 : : !type(eigr2d_t) :: eigr2d,eigi2d
1392 : 54 : type(fan_t) :: fan2d
1393 : 54 : type(gkk_t) :: gkk2d
1394 [ + + + + : 3402 : type(ddb_hdr_type) :: ddb_hdr
+ + + + +
+ + + + +
+ + + + +
+ ]
1395 : 54 : type(ddb_type) :: ddb
1396 : : !arrays
1397 : 54 : integer,allocatable :: flg(:,:,:,:)
1398 : 54 : integer,allocatable :: nband_rbz(:)
1399 : 54 : integer,pointer :: kpt_fine_sub(:)
1400 : : real(dp) :: tsec(2)
1401 : 54 : real(dp),allocatable :: center(:)
1402 : 108 : real(dp) :: eigen(mband*nsppol),eigen_prime(mband*nsppol)
1403 : 54 : real(dp),allocatable :: fan(:,:,:,:,:,:,:)
1404 : 54 : real(dp),allocatable :: gkk(:,:,:,:,:)
1405 : 54 : real(dp),allocatable :: smdfun(:,:)
1406 : 54 : real(dp),pointer :: wgt_sub(:)
1407 : :
1408 : : ! *********************************************************************
1409 : :
1410 : : !Init parallelism
1411 : 54 : master =0
1412 : 54 : spaceworld=mpi_enreg%comm_cell
1413 : 54 : me=mpi_enreg%me_kpt
1414 : :
1415 : : !Init interpolation method
1416 : 54 : if(present(eigenq_fine))then
1417 [ # # ]: 0 : ABI_MALLOC(center,(3))
1418 : : end if
1419 : :
1420 : 54 : call timab(148,1,tsec)
1421 : :
1422 [ + + ]: 54 : if(nsppol==2)then
1423 : 1 : ABI_COMMENT('nsppol=2 is still under development. Be careful when using it ...')
1424 : : end if
1425 : :
1426 : 54 : band2tot_index =0
1427 : 54 : bandtot_index=0
1428 : 54 : band_index=0
1429 : :
1430 : : if(xmpi_paral==1) then
1431 [ - + + - : 270 : ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt_rbz,mband,nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
1432 [ - + + - : 162 : ABI_MALLOC(nband_rbz,(nkpt_rbz*nsppol))
+ - + - -
+ - + ]
1433 [ - + ]: 54 : ABI_SFREE(mpi_enreg%my_kpttab)
1434 [ - + + - : 162 : ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt_rbz))
+ - + - -
+ - + -
+ ]
1435 : : ! Assume the number of bands is the same for all k points.
1436 [ + + ]: 1096 : nband_rbz(:)=mband
1437 : 54 : call distrb2(mband,mband_mem,nband_rbz,nkpt_rbz,mpi_enreg%nproc_cell,nsppol,mpi_enreg)
1438 : : end if
1439 : :
1440 [ + + ]: 54 : if(ieig2rf == 4 ) then
1441 [ + - - + : 250 : ABI_MALLOC_OR_DIE(fan,(2*mband*nsppol,dtset%nkpt,3,natom,3,natom*dim_eig2nkq,mband), ierr)
+ - - + +
- + - - +
+ - + - -
+ + - - +
+ - + - +
- + - - +
- + ]
1442 [ + + + + : 1604377 : fan(:,:,:,:,:,:,:) = zero
+ + + + +
+ + + +
+ ]
1443 [ + - ]: 25 : if(present(eigbrd))then
1444 [ + + + + : 229809 : eigbrd(:,:,:,:,:,:,:)=zero
+ + + + +
+ + + +
+ ]
1445 : : end if
1446 : : eigen_corr = 0
1447 : : end if
1448 : :
1449 [ + + ]: 54 : if(ieig2rf == 5 ) then
1450 [ + - - + : 232 : ABI_MALLOC_OR_DIE(gkk,(2*mband*nsppol,dtset%nkpt,3,natom,mband), ierr)
+ - - + +
- + - - +
+ - - + +
- + - + -
+ - - + -
+ ]
1451 [ + + + + : 1504589 : gkk(:,:,:,:,:) = zero
+ + + + +
+ ]
1452 [ + - ]: 29 : if(present(eigbrd))then
1453 [ + + + + : 1117545 : eigbrd(:,:,:,:,:,:,:)=zero
+ + + + +
+ + + +
+ ]
1454 : : end if
1455 : : eigen_corr = 0
1456 : : end if
1457 : :
1458 [ + + ]: 109 : do isppol=1,nsppol
1459 [ + + ]: 1097 : do ikpt =1,nkpt_rbz
1460 : :
1461 [ + + ]: 1042 : if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,me)) then
1462 : 96 : band2tot_index = band2tot_index + 2*mband**2
1463 : 96 : bandtot_index = bandtot_index + mband
1464 : 96 : cycle
1465 : : end if
1466 : :
1467 [ - + ]: 946 : if(present(eigenq_fine))then
1468 : 0 : write(std_out,*) 'Start of the energy denominator interpolation method.'
1469 : 0 : nkpt_sub = 0
1470 : : ! center is the k+q point around which we will average the kpt_fine
1471 [ # # # # : 0 : center = hdr0%kptns(:,ikpt)+ dtset%qptn(:)
# # # # ]
1472 : :
1473 : 0 : call kptfine_av(center,dtset%qptrlatt,hdr_fine%kptns,hdr_fine%nkpt,kpt_fine_sub,nkpt_sub,wgt_sub)
1474 : : write(std_out,'(a,3f8.4,a,i3)') 'Number of k-points of the fine grid &
1475 : 0 : & around the k+Q point ',center,' is:',nkpt_sub
1476 [ # # ]: 0 : write(std_out,'(a,f10.5)') 'The sum of the weights of the k-points is: ',SUM(wgt_sub)
1477 : : end if
1478 : :
1479 [ + - ]: 946 : if(smdelta >0) then !broadening
1480 [ + + ]: 946 : if(.not.allocated(smdfun)) then
1481 [ - + + - : 1108 : ABI_MALLOC(smdfun,(mband,mband))
- + + - +
- + - - +
- + - + ]
1482 : : end if
1483 [ + + + + ]: 143646 : smdfun(:,:) = zero
1484 [ + + ]: 12086 : do iband=1,mband
1485 : 11140 : eigen(iband) = eigen0(iband+bandtot_index)
1486 : 12086 : eigen_prime(iband) =eigenq(iband+bandtot_index)
1487 : : end do
1488 [ + - ]: 946 : if(esmear>tol6) then
1489 : 946 : call smeared_delta(eigen,eigen_prime,esmear,mband,smdelta,smdfun)
1490 : : end if
1491 : : end if
1492 : :
1493 : 946 : ipert1=1 ! Suppose all perturbations lead to the same number of planewaves
1494 : :
1495 [ + + ]: 12086 : do iband=1,bdeigrf
1496 : :
1497 : : ! If the k point and band belong to me, compute the contribution
1498 : 11140 : test_do_band=.true.
1499 [ + - ]: 11140 : if(mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me)test_do_band=.false.
1500 : :
1501 : 946 : if(test_do_band)then
1502 : : ! ------------------------------------------------------------------------------------------------------!
1503 : : ! ------- ieig2rf ==3 : Non dynamic traditional AHC theory with Sternheimer (computed in eig2stern.F90)-!
1504 : : ! ------------------------------------------------------------------------------------------------------!
1505 : : ! Note that ieig2rf==4 and ieig2rf==5 also goes into that part only for later printing of the ZPR in the ouput of abinit
1506 : : ! later in the code
1507 [ + - ]: 11140 : if(ieig2rf==3 .or. ieig2rf==4 .or. ieig2rf==5) then
1508 [ + + ]: 33420 : do ipert1=1,npert
1509 [ + + ]: 100260 : do idir1=1,3
1510 [ + - ]: 66840 : if(clflg(idir1,ipert1)==0) cycle
1511 [ + + ]: 222800 : do ipert2=1,npert
1512 [ + + ]: 601560 : do idir2=1,3
1513 [ + - ]: 401040 : if(clflg(idir2,ipert2)==0)cycle
1514 : : eig2_diar = zero ; eig2_diai = zero ; eigbrd_r = zero ; eigbrd_i = zero
1515 [ + + ]: 5137200 : do jband=1,mband
1516 : 4736160 : eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1517 : 4736160 : eig1_r2 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir2,ipert2)
1518 : 4736160 : eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1519 : 4736160 : eig1_i2 = - eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir2,ipert2) !the negative sign is from the CC
1520 : : ! If no interpolation, fallback on to the previous
1521 : : ! implementation
1522 [ + - ]: 4736160 : if(.not. present(eigenq_fine))then
1523 : 4736160 : deltae=eigenq(jband+bandtot_index)-eigen0(iband+bandtot_index)
1524 : : end if
1525 : 4736160 : ar=eig1_r1*eig1_r2-eig1_i1*eig1_i2
1526 : 4736160 : ai=eig1_r1*eig1_i2+eig1_i1*eig1_r2
1527 : :
1528 : : ! Sum over all active space to retrieve the diagonal gauge
1529 : : ! if(abs(deltae)>etol) then ! This is commented because
1530 : : ! there is no problem with divergencies with elph2_imag != 0
1531 [ - + ]: 4736160 : if( present(eigenq_fine))then
1532 : 0 : den_av = zero
1533 : 0 : wgt_int = zero
1534 [ # # ]: 0 : do ikpt2=1,nkpt_sub
1535 : : deltae=eigenq_fine(jband,kpt_fine_sub(ikpt2),1)&
1536 : 0 : & -eigen0(iband+bandtot_index)
1537 : 0 : den_av = den_av-(wgt_sub(ikpt2)*deltae)/(deltae**2+elph2_imagden**2)
1538 : 0 : wgt_int = wgt_int+wgt_sub(ikpt2)
1539 : : end do
1540 : 0 : den = den_av/wgt_int
1541 : : else
1542 [ - + ]: 4736160 : if(abs(elph2_imagden) < etol) then
1543 [ # # ]: 0 : if(abs(deltae)>etol) then
1544 : 0 : den=-one/(deltae**2+elph2_imagden**2)
1545 : : else
1546 : : den= zero
1547 : : end if
1548 : : else
1549 : 4736160 : den=-one/(deltae**2+elph2_imagden**2)
1550 : : end if
1551 : : end if
1552 : :
1553 [ - + ]: 4736160 : if( present(eigenq_fine))then
1554 : 0 : eig2_diar=eig2_diar+ar*den
1555 : 0 : eig2_diai=eig2_diai+ai*den
1556 : : else
1557 : 4736160 : eig2_diar=eig2_diar+ar*deltae*den
1558 : 4736160 : eig2_diai=eig2_diai+ai*deltae*den
1559 : : end if
1560 : :
1561 [ + - ]: 5137200 : if(present(eigbrd))then
1562 [ + - ]: 4736160 : if(smdelta >0) then !broadening
1563 : 4736160 : eigbrd_r = eigbrd_r + ar*smdfun(iband,jband)
1564 : 4736160 : eigbrd_i = eigbrd_i + ai*smdfun(iband,jband)
1565 : : end if
1566 : : end if
1567 : : end do !jband
1568 : :
1569 : : ! Store the contribution
1570 : : eig2nkq(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = &
1571 : 401040 : & eig2nkq(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) + eig2_diar
1572 : : eig2nkq(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = &
1573 : 401040 : & eig2nkq(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) + eig2_diai
1574 : :
1575 [ - + ]: 534720 : if(present(eigbrd))then
1576 [ - + ]: 401040 : if(smdelta >0) then !broadening
1577 : 401040 : eigbrd(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_r
1578 : 401040 : eigbrd(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_i
1579 : : end if
1580 : : end if
1581 : :
1582 : : end do !idir2
1583 : : end do !ipert2
1584 : : end do !idir1
1585 : : end do !ipert1
1586 : : end if !ieig2rf 3
1587 : :
1588 : : ! -------------------------------------------------------------------------------------------!
1589 : : ! ------- ieig2rf ==4 Dynamic AHC using second quantization and Sternheimer from eig2stern -!
1590 : : ! -------------------------------------------------------------------------------------------!
1591 [ + + ]: 11140 : if(ieig2rf ==4 ) then
1592 [ + + ]: 3264 : do ipert1=1,npert
1593 [ + + ]: 9792 : do idir1=1,3
1594 [ + - ]: 6528 : if(clflg(idir1,ipert1)==0) cycle
1595 [ + + ]: 21760 : do ipert2=1,npert
1596 [ + + ]: 58752 : do idir2=1,3
1597 [ + - ]: 39168 : if(clflg(idir2,ipert2)==0)cycle
1598 [ + + ]: 464640 : do jband=1,mband
1599 : 412416 : eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1600 : 412416 : eig1_r2 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir2,ipert2)
1601 : 412416 : eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1602 : 412416 : eig1_i2 = - eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir2,ipert2) !the negative sign is from the CC
1603 : 412416 : ar=eig1_r1*eig1_r2-eig1_i1*eig1_i2
1604 : 412416 : ai=eig1_r1*eig1_i2+eig1_i1*eig1_r2
1605 : : ! Store the contribution
1606 : : fan(2*iband-1+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) = &
1607 : 412416 : & fan(2*iband-1+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) + ar
1608 : : fan(2*iband+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) = &
1609 : 451584 : & fan(2*iband+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) + ai
1610 : : end do !jband
1611 : : end do !idir2
1612 : : end do !ipert2
1613 : : end do !idir1
1614 : : end do !ipert1
1615 : : end if !ieig2rf 4
1616 : : ! --------------------------------------------------------------------------------!
1617 : : ! ------- ieig2rf ==5 Dynamic AHC with Sternheimer from eig2stern but print GKK -!
1618 : : ! --------------------------------------------------------------------------------!
1619 [ + + ]: 11140 : if(ieig2rf ==5 ) then
1620 [ + + ]: 30156 : do ipert1=1,npert
1621 [ + + ]: 90468 : do idir1=1,3
1622 [ + - ]: 60312 : if(clflg(idir1,ipert1)==0) cycle
1623 [ + + ]: 801040 : do jband=1,mband
1624 : 720624 : eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1625 : 720624 : eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1626 : : ! Store the contribution
1627 : : gkk(2*iband-1+2*band_index,ikpt,idir1,ipert1,jband) = &
1628 : 720624 : & gkk(2*iband-1+2*band_index,ikpt,idir1,ipert1,jband) + eig1_r1
1629 : : gkk(2*iband+2*band_index,ikpt,idir1,ipert1,jband) = &
1630 : 780936 : & gkk(2*iband+2*band_index,ikpt,idir1,ipert1,jband) + eig1_i1
1631 : : end do !jband
1632 : : end do !idir1
1633 : : end do !ipert1
1634 : : end if !ieig2rf 5
1635 : : end if ! Selection of processor
1636 : : end do !iband
1637 : :
1638 : 946 : band2tot_index = band2tot_index + 2*mband**2
1639 : 946 : bandtot_index = bandtot_index + mband
1640 : :
1641 [ + - ]: 1001 : if(present(eigenq_fine))then
1642 [ # # ]: 0 : ABI_FREE(kpt_fine_sub) ! Deallocate the variable
1643 [ # # ]: 0 : ABI_FREE(wgt_sub)
1644 : : end if
1645 : :
1646 : : end do !ikpt
1647 : 109 : band_index = band_index + mband
1648 : : end do !isppol
1649 : :
1650 : : !Accumulate eig2nkq and/or eigbrd
1651 : : if(xmpi_paral==1) then
1652 [ - + ]: 54 : if(ieig2rf == 3) then
1653 : 0 : call xmpi_sum(eig2nkq,spaceworld,ierr)
1654 : : end if
1655 [ + + ]: 54 : if(ieig2rf == 4) then
1656 : 25 : call xmpi_sum(eig2nkq,spaceworld,ierr)
1657 : 25 : call xmpi_sum(fan,spaceworld,ierr)
1658 : : end if
1659 [ + + ]: 54 : if(ieig2rf == 5) then
1660 : 29 : call xmpi_sum(eig2nkq,spaceworld,ierr)
1661 : 29 : call xmpi_sum(gkk,spaceworld,ierr)
1662 : : end if
1663 [ + - + - ]: 54 : if(present(eigbrd) .and. (ieig2rf == 3 .or. ieig2rf == 4 .or. ieig2rf == 5))then
1664 [ + - ]: 54 : if(smdelta >0) then
1665 : 54 : call xmpi_sum(eigbrd,spaceworld,ierr)
1666 : : end if
1667 : : end if
1668 [ - + ]: 54 : ABI_FREE(nband_rbz)
1669 [ - + ]: 54 : ABI_FREE(mpi_enreg%proc_distrb)
1670 [ - + ]: 54 : ABI_FREE(mpi_enreg%my_kpttab)
1671 : : end if
1672 : :
1673 [ + - ]: 54 : if (ieig2rf > 2) then
1674 : : ! SP: Important: the second-order derivatives of the electronic energy printed here is the total one, including
1675 : : ! both the Sternheimer and active-space part. Instead, the file _EIGR2D produced when ieig2rf > 2
1676 : : ! contains ONLY the Sternheimer part and is therefore not the same values as here.
1677 : : ! Note that in the case of ieig2rf == 1 or 2, the _EIGR2D file does contain the full one.
1678 : 54 : write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGR2D.'
1679 : 54 : write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1680 : 54 : band_index = 0
1681 [ + + ]: 109 : do isppol=1,dtset%nsppol
1682 [ + + ]: 220 : do idir1=1,3
1683 [ + + ]: 715 : do idir2=1,3
1684 [ - + ]: 495 : ar=eig2nkq(1,1+band_index,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1685 [ + + ]: 495 : ai=eig2nkq(2,1+band_index,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1686 : 660 : write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1687 : : end do ! idir2
1688 : : end do ! idir1
1689 : 55 : band_index = band_index + mband
1690 : 109 : write(ab_out,'(a)')' '
1691 : : end do
1692 : : end if
1693 : :
1694 [ + - ]: 54 : if(present(eigbrd))then
1695 [ + - ]: 54 : if(smdelta >0) then !broadening
1696 : 54 : write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGI2D.'
1697 : 54 : write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1698 : 54 : band_index = 0
1699 [ + + ]: 109 : do isppol=1,dtset%nsppol
1700 [ + + ]: 220 : do idir1=1,3
1701 [ + + ]: 715 : do idir2=1,3
1702 [ + + ]: 495 : ar=eigbrd(1,1+band_index,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1703 [ + + ]: 495 : ai=eigbrd(2,1+band_index,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1704 : 660 : write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1705 : : end do
1706 : : end do
1707 : 55 : band_index = band_index + mband
1708 : 109 : write(ab_out,'(a)')' '
1709 : : end do
1710 : : end if
1711 : : end if
1712 : :
1713 [ + - ]: 54 : if(allocated(smdfun)) then
1714 : 54 : ABI_FREE(smdfun)
1715 : : end if
1716 [ - + ]: 54 : if(present(eigenq_fine))then
1717 [ # # ]: 0 : ABI_FREE(center)
1718 : : end if
1719 : :
1720 : : ! print _FAN file for this perturbation. Note that the Fan file will only be produced if
1721 : : ! abinit is compiled with netcdf.
1722 : :
1723 : : ! Initialize crystal structure for FAN.nc and GKK.nc files
1724 : 54 : remove_inv=.false.
1725 [ - + - - ]: 54 : if(dtset%nspden==4 .and. dtset%usedmft==1) remove_inv=.true.
1726 : : call crystal%init(dtset%amu_orig(:,1),dtset%spgroup,dtset%natom,dtset%npsp,psps%ntypat, &
1727 : : & dtset%nsym,rprimd,dtset%typat,xred,dtset%ziontypat,dtset%znucl,1,&
1728 : : & dtset%nspden==2.and.dtset%nsppol==1,remove_inv,hdr0%title,&
1729 [ + + + - ]: 108 : & dtset%symrel,dtset%tnons,dtset%symafm)
1730 : : ! Electronic band energies.
1731 : 54 : bantot= dtset%mband*dtset%nkpt*dtset%nsppol
1732 : : call bands%init(bantot, dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,&
1733 : : & doccde,eigen0,hdr0%istwfk,hdr0%kptns,&
1734 : : & hdr0%nband, hdr0%nkpt,hdr0%npwarr,hdr0%nsppol,hdr0%nspinor,&
1735 : : & hdr0%tphysel,hdr0%tsmear,hdr0%occopt,hdr0%occ,hdr0%wtk,&
1736 : : & hdr0%cellcharge, hdr0%kptopt, hdr0%kptrlatt_orig, hdr0%nshiftk_orig, hdr0%shiftk_orig, &
1737 : 54 : & hdr0%kptrlatt, hdr0%nshiftk, hdr0%shiftk)
1738 : : !
1739 [ + + ]: 54 : if(ieig2rf == 4 ) then
1740 : : ! Output of the Fan.nc file.
1741 [ + - ]: 25 : fname = strcat(dtfil%filnam_ds(4),"_FAN.nc")
1742 : 25 : call fan_init(fan,fan2d,dtset%mband,hdr0%nsppol,nkpt_rbz,dtset%natom)
1743 [ - + ]: 25 : NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating FAN file")
1744 [ - + ]: 25 : NCF_CHECK(crystal%ncwrite(ncid))
1745 [ - + ]: 25 : NCF_CHECK(Bands%ncwrite(ncid))
1746 : 25 : call fan_ncwrite(fan2d,dtset%qptn(:),dtset%wtq, ncid)
1747 [ - + ]: 25 : NCF_CHECK(nf90_close(ncid))
1748 [ - + ]: 25 : ABI_FREE(fan)
1749 : : end if
1750 : : ! print _GKK.nc file for this perturbation. Note that the GKK file will only be produced if
1751 : : ! abinit is compiled with netcdf.
1752 [ + + ]: 54 : if(ieig2rf == 5 ) then
1753 : : ! Output of the GKK.nc file.
1754 [ + - ]: 29 : fname = strcat(dtfil%filnam_ds(4),"_GKK.nc")
1755 : 29 : call gkk_init(gkk,gkk2d,dtset%mband,hdr0%nsppol,nkpt_rbz,dtset%natom,3)
1756 [ - + ]: 29 : NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating GKK file")
1757 [ - + ]: 29 : NCF_CHECK(crystal%ncwrite(ncid))
1758 [ - + ]: 29 : NCF_CHECK(bands%ncwrite(ncid))
1759 : 29 : call gkk_ncwrite(gkk2d,dtset%qptn(:),dtset%wtq, ncid)
1760 [ - + ]: 29 : NCF_CHECK(nf90_close(ncid))
1761 [ - + ]: 29 : ABI_FREE(gkk)
1762 : : end if
1763 : :
1764 : : ! print _EIGI2D file for this perturbation
1765 [ + + ]: 54 : if (ieig2rf /= 5 ) then
1766 [ + - ]: 25 : if(smdelta>0) then
1767 : :
1768 : 25 : mpert_ = dtset%natom
1769 [ - + + - : 125 : ABI_MALLOC(flg,(3,mpert_,3,mpert_))
+ - - + +
- + - + -
- + - + ]
1770 [ + + + + : 1425 : flg = one
+ + + + ]
1771 : : call ddb%init(dtset, 1, mpert_, &
1772 : : mband=bdeigrf,&
1773 : : nkpt=nkpt_rbz,&
1774 : : kpt=dtset%kptns(:,1:nkpt_rbz),&
1775 : 25 : with_d2eig=.true.)
1776 : :
1777 : : ! Create the ddb header
1778 : 25 : dscrpt=' Note : temporary (transfer) database '
1779 : : call ddb_hdr%init(dtset,psps,pawtab,dscrpt,1,&
1780 : : mpert=mpert_,&
1781 : : xred=xred,occ=occ_rbz,&
1782 : : mband=bdeigrf / dtset%nsppol,&
1783 : : nkpt=nkpt_rbz,&
1784 : 25 : kpt=dtset%kptns(:,1:nkpt_rbz))
1785 : :
1786 : 25 : call ddb%set_qpt(1, dtset%qptn)
1787 : 25 : call ddb%set_d2eig_reshape(1, eigbrd, flg, blktyp=BLKTYP_d2eig_im)
1788 : :
1789 : 25 : call ddb_hdr%set_typ(ddb%nblok, ddb%typ)
1790 : :
1791 : 25 : call ddb_hdr%open_write(dtfil%fnameabo_eigi2d, with_psps=1)
1792 : 25 : call ddb%write_d2eig(ddb_hdr, 1)
1793 : :
1794 : 25 : call ddb_hdr%close()
1795 : 25 : call ddb_hdr%free()
1796 : 25 : call ddb%free()
1797 : :
1798 [ - + ]: 25 : ABI_FREE(flg)
1799 : :
1800 : : end if !smdelta
1801 : : end if
1802 : : !end if ! master
1803 : :
1804 [ - + ]: 54 : ABI_SFREE(fan)
1805 [ - + ]: 54 : ABI_SFREE(gkk)
1806 : :
1807 : 54 : call crystal%free()
1808 : 54 : call Bands%free()
1809 [ + + ]: 54 : call fan_free(fan2d)
1810 : 54 : call gkk_free(gkk2d)
1811 : :
1812 : 54 : call timab(148,2,tsec)
1813 : :
1814 [ + - - + : 162 : end subroutine eig2tot
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - - - -
- - - - -
- - - - -
- - - - -
- - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + ]
1815 : : !!***
1816 : :
1817 : : !!****f* m_eig2d/outbsd
1818 : : !! NAME
1819 : : !! outbsd
1820 : : !!
1821 : : !! FUNCTION
1822 : : !! output bsd file for one perturbation (used for elphon calculations in anaddb)
1823 : : !!
1824 : : !! INPUTS
1825 : : !! bdeigrf=number of bands for which the derivatives of the eigenvalues have been computed
1826 : : !! dtset = dataset variable for run flags
1827 : : !! eig2nkq= second ordre eigenvalue (or electron lifetime) that must be printed out
1828 : : !! mpert= maximum number of perturbations
1829 : : !! nkpt_rbz= number of k-points for perturbation
1830 : : !! unitout= writting unit of file
1831 : : !!
1832 : : !! OUTPUTS
1833 : : !! to file
1834 : : !!
1835 : : !! NOTE
1836 : : !! This function is deprecated. One should write through ddb object instead.
1837 : : !!
1838 : : !! SOURCE
1839 : :
1840 : 0 : subroutine outbsd(bdeigrf,dtset,eig2nkq,mpert,nkpt_rbz,unitout)
1841 : :
1842 : : !Arguments ------------------------------------
1843 : : !scalars
1844 : : integer,intent(in) :: bdeigrf,mpert,nkpt_rbz,unitout
1845 : : type(dataset_type),intent(in) :: dtset
1846 : : !arrays
1847 : : real(dp),intent(in) :: eig2nkq(2,dtset%mband*dtset%nsppol,nkpt_rbz,3,mpert,3,mpert)
1848 : :
1849 : : !Local variables -------------------------
1850 : : !scalars
1851 : : integer :: bandtot_index,iband,idir1,idir2,ikpt,ipert1,ipert2,isppol
1852 : :
1853 : : ! *********************************************************************
1854 : :
1855 : :
1856 : : !output information in this file
1857 : 0 : write(unitout,*)
1858 : 0 : write(unitout,'(a,i8)') ' 2nd eigenvalue derivatives - # elements :', 9*dtset%natom**2
1859 : 0 : write(unitout,'(a,3es16.8,a)') ' qpt', dtset%qptn(:), ' 1.0'
1860 : :
1861 : : !output RF eigenvalues
1862 : :
1863 [ # # ]: 0 : do ikpt=1,nkpt_rbz
1864 : : ! bandtot_index differs from zero only in the spin-polarized case
1865 : 0 : bandtot_index=0
1866 : 0 : write (unitout,'(a,3es16.8)') ' K-point:', dtset%kptns(:,ikpt)
1867 [ # # ]: 0 : do isppol=1,dtset%nsppol
1868 [ # # ]: 0 : do iband=1,bdeigrf
1869 : 0 : write (unitout,'(a,i5)') ' Band:', iband+bandtot_index
1870 : : ! write (unitout,*) 'ipert1 ','idir1 ','ipert2 ','idir2 ','Real ','Im '
1871 [ # # ]: 0 : do ipert2=1,mpert
1872 [ # # ]: 0 : do idir2=1,3
1873 [ # # ]: 0 : do ipert1=1,mpert
1874 [ # # ]: 0 : do idir1=1,3
1875 : 0 : write (unitout,'(4i4,2d22.14)') idir1,ipert1,idir2,ipert2,&
1876 : 0 : & eig2nkq(1,iband+bandtot_index,ikpt,idir1,ipert1,idir2,ipert2),&
1877 : 0 : & eig2nkq(2,iband+bandtot_index,ikpt,idir1,ipert1,idir2,ipert2)
1878 : : end do !idir2
1879 : : end do !ipert2
1880 : : end do !idir1
1881 : : end do !ipert1
1882 : : end do !iband
1883 : 0 : bandtot_index = bandtot_index + dtset%mband
1884 : : end do !isppol
1885 : : end do !ikpt
1886 : :
1887 : : !close bsd file
1888 : 0 : close (unitout)
1889 : :
1890 : 0 : end subroutine outbsd
1891 : : !!***
1892 : :
1893 : : !!****f* m-eig2d/smeared_delta
1894 : : !! NAME
1895 : : !! smeared_delta
1896 : : !!
1897 : : !! FUNCTION
1898 : : !! This subroutine calculates the smeared delta that weights matrix elements:
1899 : : !! \delta (\epsilon_{kn}-\epsilon_{k+Q,n'})
1900 : : !!
1901 : : !! INPUTS
1902 : : !! eigen0(mband*nsppol) : Eigenvalues at point K
1903 : : !! eigenq(mband*nsppol) : Eigenvalues at point K+Q
1904 : : !! mband : maximum number of bands
1905 : : !! smdelta : Variable controlling the smearinf scheme
1906 : : !!
1907 : : !! OUTPUT
1908 : : !! smdfunc(mband,mband) : Smeared delta function weight corresponding to \delta(\epsilon_{n,k} - \epsilon_{n',k+Q})
1909 : : !!
1910 : : !! SOURCE
1911 : :
1912 : 2143 : subroutine smeared_delta(eigen0,eigenq,esmear,mband,smdelta,smdfunc)
1913 : :
1914 : : !Arguments ------------------------------------
1915 : : !scalars
1916 : : integer,intent(in) :: mband,smdelta
1917 : : !arrays
1918 : : real(dp),intent(in) :: eigen0(mband),eigenq(mband),esmear
1919 : : real(dp),intent(out) :: smdfunc(mband,mband)
1920 : :
1921 : : !Local variables-------------------------------
1922 : : !tolerance for non degenerated levels
1923 : : !scalars
1924 : : integer :: ii,jj
1925 : : real(dp) :: aa,dsqrpi,gauss,xx
1926 : : character(len=500) :: message
1927 : :
1928 : : ! *********************************************************************
1929 : :
1930 : :
1931 : : !---------------------------------------------------------
1932 : : !Ordinary (unique) smearing function
1933 : : !---------------------------------------------------------
1934 : :
1935 [ + - ]: 2143 : if(smdelta==1)then
1936 : :
1937 : : ! Fermi-Dirac
1938 [ + + ]: 26119 : do ii=1,mband
1939 [ + + ]: 302719 : do jj= 1,mband
1940 : 276600 : xx= ( eigen0(ii) - eigenq(jj) )/esmear
1941 : 300576 : smdfunc(ii,jj)=0.25_dp/esmear/(cosh(xx/2.0_dp))**2
1942 : : end do
1943 : : end do
1944 : :
1945 [ # # ]: 0 : else if(smdelta==2 .or. smdelta==3)then
1946 : :
1947 : : ! Cold smearing of Marzari, two values of the "a" parameter being possible
1948 : : ! first value gives minimization of the bump
1949 : : if(smdelta==2)aa=-.5634
1950 : : ! second value gives monotonic occupation function
1951 [ # # ]: 0 : if(smdelta==3)aa=-.8165
1952 : :
1953 : 0 : dsqrpi=1.0_dp/sqrt(pi)
1954 [ # # ]: 0 : do ii=1,mband
1955 [ # # ]: 0 : do jj=1,mband
1956 : 0 : xx= ( eigen0(ii) - eigenq(jj) ) / esmear
1957 : 0 : gauss=dsqrpi*exp(-xx**2)/esmear
1958 : 0 : smdfunc(ii,jj)=gauss*(1.5_dp+xx*(-aa*1.5_dp+xx*(-1.0_dp+aa*xx)))
1959 : : end do
1960 : : end do
1961 : :
1962 [ # # ]: 0 : else if(smdelta==4)then
1963 : :
1964 : : ! First order Hermite-Gaussian of Paxton and Methfessel
1965 : 0 : dsqrpi=1.0_dp/sqrt(pi)
1966 [ # # ]: 0 : do ii=1,mband
1967 [ # # ]: 0 : do jj=1,mband
1968 : 0 : xx= ( eigen0(ii) - eigenq (jj) ) / esmear
1969 : 0 : smdfunc(ii,jj)=dsqrpi*(1.5_dp-xx**2)*exp(-xx**2)/esmear
1970 : : end do
1971 : : end do
1972 : :
1973 [ # # ]: 0 : else if(smdelta==5)then
1974 : :
1975 : : ! Gaussian smearing
1976 : 0 : dsqrpi=1.0_dp/sqrt(pi)
1977 [ # # ]: 0 : do ii=1,mband
1978 [ # # ]: 0 : do jj=1,mband
1979 : 0 : xx= ( eigen0(ii) - eigenq (jj) ) / esmear
1980 : 0 : smdfunc(ii,jj)=dsqrpi*exp(-xx**2)/esmear
1981 : : end do
1982 : : end do
1983 : :
1984 : : else
1985 : 0 : write(message, '(a,i0,a)' )' Smdelta= ',smdelta,' is not allowed in smdfunc'
1986 : 0 : ABI_BUG(message)
1987 : : end if
1988 : :
1989 : 2143 : end subroutine smeared_delta
1990 : : !!***
1991 : :
1992 : : !!****f* m_eig2d/elph2_fanddw
1993 : : !! NAME
1994 : : !! elph2_fanddw
1995 : : !!
1996 : : !! FUNCTION
1997 : : !! This routine calculates the zero-point motion corrections
1998 : : !! due to the Fan term or to the DDW term..
1999 : : !!
2000 : : !! INPUTS
2001 : : !! dim_eig2nkq=1 if eig2nkq is to be computed
2002 : : !! displ(2*3*natom*3*natom)=the displacements of atoms in cartesian coordinates.
2003 : : !! eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq)=one half second derivatives of the electronic eigenvalues
2004 : : !! gprimd(3,3)=dimensional primitive translations for reciprocal space ($\textrm{bohr}^{-1}$)
2005 : : !! mband= maximum number of bands
2006 : : !! natom= number of atoms in the unit cell
2007 : : !! nkpt= number of k-points
2008 : : !! nsppol= 1 for unpolarized, 2 for spin-polarized
2009 : : !! option 1 for Fan term, 2 for DDW term
2010 : : !! phfrq(3*natom)=phonon frequencies
2011 : : !! (prtvol > 4) if the mode decomposition is to be printed
2012 : : !!
2013 : : !! OUTPUT
2014 : : !! eigen_corr(mband*nkpt*nsppol)= T=0 correction to the electronic eigenvalues, due to the Fan term.
2015 : : !!
2016 : : !! SOURCE
2017 : :
2018 : 97 : subroutine elph2_fanddw(dim_eig2nkq,displ,eig2nkq,eigen_corr,gprimd,mband,natom,nkpt,nsppol,option,phfrq,prtvol)
2019 : :
2020 : : !Arguments ------------------------------------
2021 : : !scalars
2022 : : integer,intent(in) :: dim_eig2nkq,mband,natom,nkpt,nsppol,option,prtvol
2023 : :
2024 : : !arrays
2025 : : real(dp) :: gprimd(3,3)
2026 : : real(dp),intent(in) :: displ(2*3*natom*3*natom)
2027 : : real(dp),intent(in) :: eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq)
2028 : : real(dp),intent(in) :: phfrq(3*natom)
2029 : : real(dp),intent(out) :: eigen_corr(mband*nkpt*nsppol)
2030 : :
2031 : : !Local variables-------------------------------
2032 : : !scalars
2033 : : integer,parameter :: neigs_per_line=6
2034 : : integer :: iatom1,iatom2,idir1,idir2,iband,ikpt,imode,index,isppol, imin, ii
2035 : : real(dp) :: d_at1_dir1_re,d_at1_dir1_im
2036 : : real(dp) :: d_at1_dir2_re,d_at1_dir2_im
2037 : : real(dp) :: d_at2_dir1_re,d_at2_dir1_im
2038 : : real(dp) :: d_at2_dir2_re,d_at2_dir2_im
2039 : : real(dp) :: e2_im,e2_re
2040 : 97 : real(dp), allocatable :: eigen_corr_mode(:)
2041 : : character(len=500) :: message
2042 : : character(len=20) :: eig_format, line_format
2043 : : !arrays
2044 : : real(dp) :: displ2cart(2,3,3),displ2red(2,3,3),tmp_displ2(2,3,3)
2045 : :
2046 : : ! *********************************************************************
2047 : :
2048 : :
2049 [ - + ]: 97 : if(option/=1 .and. option/=2)then
2050 : 0 : write(message,'(a,i0)')' The argument option should be 1 or 2, while it is found that option=',option
2051 : 0 : ABI_BUG(message)
2052 : : end if
2053 : :
2054 : : !printing options
2055 : 97 : eig_format='f16.8'
2056 : 97 : write(line_format,'(a,i1,a6,a)') '(',neigs_per_line,eig_format,')'
2057 : :
2058 [ - + ]: 97 : if (prtvol > 4) then
2059 : 0 : write(message,'(a,a)')ch10,' ================================================================================'
2060 : 0 : call wrtout(ab_out_default,message,'COLL')
2061 [ # # ]: 0 : if (option==1) then
2062 : 0 : write(message,'(a)') ' ---- Begin Fan contributions to eigenvalues renormalization by mode ----'
2063 : 0 : call wrtout(ab_out_default,message,'COLL')
2064 [ # # ]: 0 : else if (option==2) then
2065 : 0 : write(message,'(a)') ' ---- Begin DDW contributions to eigenvalues renormalization by mode ----'
2066 : 0 : call wrtout(ab_out_default,message,'COLL')
2067 : : end if
2068 : : end if
2069 : :
2070 [ - + + - : 291 : ABI_MALLOC(eigen_corr_mode,(mband*nkpt*nsppol))
+ - + - -
+ + - ]
2071 : :
2072 [ + + ]: 16533 : eigen_corr(:)=zero
2073 [ + + ]: 667 : do imode=1,3*natom
2074 [ + + ]: 98802 : eigen_corr_mode(:)=zero
2075 : :
2076 [ + + ]: 570 : if (phfrq(imode)>tol6) then
2077 [ + + ]: 1452 : do iatom1=1,natom
2078 [ + + ]: 5502 : do iatom2=1,natom
2079 : :
2080 [ + + ]: 16200 : do idir1=1,3
2081 [ + + ]: 52650 : do idir2=1,3
2082 : : ! Compute the mean cartesian displacements
2083 : 36450 : d_at1_dir1_re=displ(1 + 2*(idir1-1 +3*(iatom1-1 +natom*(imode-1))))
2084 : 36450 : d_at1_dir1_im=displ(2 + 2*(idir1-1 +3*(iatom1-1 +natom*(imode-1))))
2085 : 36450 : d_at2_dir2_re=displ(1 + 2*(idir2-1 +3*(iatom2-1 +natom*(imode-1))))
2086 : 36450 : d_at2_dir2_im=displ(2 + 2*(idir2-1 +3*(iatom2-1 +natom*(imode-1))))
2087 : :
2088 [ + + ]: 48600 : if(option==1)then
2089 : : ! Compute the mean displacement correlation at T=0.
2090 : : ! Consistent with Eqs.(7) and (8) of PRB51, 8610 (1995) [[cite:Lee1995]], specialized for the contribution of one q point.
2091 : : ! but generalized to two different atoms. Note that the complex conjugate is taken on the second direction.
2092 : : displ2cart(1,idir1,idir2)=(d_at1_dir1_re*d_at2_dir2_re+ &
2093 : 22005 : & d_at1_dir1_im*d_at2_dir2_im )/(two*phfrq(imode))
2094 : : displ2cart(2,idir1,idir2)=(d_at1_dir1_im*d_at2_dir2_re- &
2095 : 22005 : & d_at1_dir1_re*d_at2_dir2_im )/(two*phfrq(imode))
2096 [ + - ]: 14445 : else if(option==2)then
2097 : : ! Compute the mean square displacement correlation of each atom at T=0, and take mean over iatom1 and iatom2.
2098 : : ! See Eqs.(7) and (8) of PRB51, 8610 (1995) [[cite:Lee1995]], specialized for the contribution of one q point.
2099 : : ! Note that the complex conjugate is taken on the second direction.
2100 : : ! Also, note the overall negative sign, to make it opposite to the Fan term.
2101 : 14445 : d_at1_dir2_re=displ(1 + 2*(idir2-1 +3*(iatom1-1 +natom*(imode-1))))
2102 : 14445 : d_at1_dir2_im=displ(2 + 2*(idir2-1 +3*(iatom1-1 +natom*(imode-1))))
2103 : 14445 : d_at2_dir1_re=displ(1 + 2*(idir1-1 +3*(iatom2-1 +natom*(imode-1))))
2104 : 14445 : d_at2_dir1_im=displ(2 + 2*(idir1-1 +3*(iatom2-1 +natom*(imode-1))))
2105 : : displ2cart(1,idir1,idir2)=-(d_at1_dir1_re*d_at1_dir2_re+ &
2106 : : & d_at1_dir1_im*d_at1_dir2_im+ &
2107 : : & d_at2_dir1_re*d_at2_dir2_re+ &
2108 : 14445 : & d_at2_dir1_im*d_at2_dir2_im )/(four*phfrq(imode))
2109 : : displ2cart(2,idir1,idir2)=-(d_at1_dir1_im*d_at1_dir2_re- &
2110 : : & d_at1_dir1_re*d_at1_dir2_im+ &
2111 : : & d_at2_dir1_im*d_at2_dir2_re- &
2112 : 14445 : & d_at2_dir1_re*d_at2_dir2_im )/(four*phfrq(imode))
2113 : : end if
2114 : : end do
2115 : : end do
2116 : : ! Switch to reduced coordinates in two steps
2117 : 4050 : tmp_displ2(:,:,:)=zero
2118 [ + + ]: 16200 : do idir1=1,3
2119 [ + + ]: 52650 : do idir2=1,3
2120 [ + + + + ]: 376650 : tmp_displ2(:,:,idir1)=tmp_displ2(:,:,idir1)+displ2cart(:,:,idir2)*gprimd(idir2,idir1)
2121 : : end do
2122 : : end do
2123 : 4050 : displ2red(:,:,:)=zero
2124 [ + + ]: 16200 : do idir1=1,3
2125 [ + + ]: 52650 : do idir2=1,3
2126 [ + + + + ]: 376650 : displ2red(:,idir1,:)=displ2red(:,idir1,:)+tmp_displ2(:,idir2,:)*gprimd(idir2,idir1)
2127 : : end do
2128 : : end do
2129 : : ! Compute the T=0 shift due to this q point
2130 [ + + ]: 17238 : do idir1=1,3
2131 [ + + ]: 52650 : do idir2=1,3
2132 [ + + ]: 296424 : do ikpt=1,nkpt
2133 [ + + ]: 532170 : do isppol=1,nsppol
2134 [ + + ]: 3559464 : do iband=1,mband
2135 : 3063744 : index=iband+mband*(isppol-1 + nsppol*(ikpt-1))
2136 : 3063744 : e2_re=eig2nkq(1,iband+mband*(isppol-1),ikpt,idir1,iatom1,idir2,iatom2)
2137 : 3063744 : e2_im=eig2nkq(2,iband+mband*(isppol-1),ikpt,idir1,iatom1,idir2,iatom2)
2138 : : eigen_corr(index)=eigen_corr(index)+&
2139 : 3063744 : & e2_re*displ2red(1,idir1,idir2)-e2_im*displ2red(2,idir1,idir2)
2140 : : eigen_corr_mode(index)=eigen_corr_mode(index)+&
2141 : 3311640 : & e2_re*displ2red(1,idir1,idir2)-e2_im*displ2red(2,idir1,idir2)
2142 : : end do ! band
2143 : : end do ! spin
2144 : : end do ! kpt
2145 : : end do ! dir2
2146 : : end do ! dir1
2147 : : end do ! atom2
2148 : : end do ! atom1
2149 : : end if
2150 : :
2151 [ - + ]: 667 : if (prtvol > 4) then
2152 : : ! Print the corrections by mode
2153 : 0 : write(message,'(a,i1)') ' imode= ',imode
2154 : 0 : call wrtout(ab_out_default,message,'COLL')
2155 : :
2156 [ # # ]: 0 : do ikpt=1,nkpt
2157 [ # # ]: 0 : do isppol=1,nsppol
2158 : 0 : write(message,'(a,i4,a,i1)')' ikpt= ',ikpt,' ispin= ',isppol
2159 : 0 : call wrtout(ab_out_default,message,'COLL')
2160 : :
2161 : 0 : imin = mband * (isppol-1 + nsppol*(ikpt-1))
2162 [ # # ]: 0 : do ii=0, (mband-1)/neigs_per_line
2163 : 0 : write(message, line_format) (eigen_corr_mode(iband+imin), &
2164 [ # # # # ]: 0 : & iband = 1 + ii * neigs_per_line, min(mband, (ii+1)*neigs_per_line))
2165 : 0 : call wrtout(ab_out_default,message,'COLL')
2166 : : end do
2167 : : end do
2168 : : end do
2169 : : end if
2170 : :
2171 : : end do ! mode
2172 : :
2173 [ - + ]: 97 : if (prtvol > 4) then
2174 [ # # ]: 0 : if (option==1) then
2175 : 0 : write(message,'(a)') ' ---- End Fan contribution to eigenvalues renormalization by mode ----'
2176 : 0 : call wrtout(ab_out_default,message,'COLL')
2177 [ # # ]: 0 : else if (option==2) then
2178 : 0 : write(message,'(a)') ' ---- End DDW contribution to eigenvalues renormalization by mode ----'
2179 : 0 : call wrtout(ab_out_default,message,'COLL')
2180 : : end if
2181 : 0 : write(message,'(a,a)')' ================================================================================', ch10
2182 : 0 : call wrtout(ab_out_default,message,'COLL')
2183 : : end if
2184 : :
2185 [ - + ]: 97 : ABI_FREE(eigen_corr_mode)
2186 : :
2187 : 97 : end subroutine elph2_fanddw
2188 : : !!***
2189 : :
2190 [ # # # # : 0 : END MODULE m_eig2d
# # # # #
# # # ]
2191 : : !!***
|