Line data Source code
1 : !!****m* ABINIT/m_frohlich
2 : !! NAME
3 : !! m_frohlich
4 : !!
5 : !! FUNCTION
6 : !! Description
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2018-2026 ABINIT group (VV, XG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_frohlich
23 :
24 : use defs_basis
25 : use m_abicore
26 : use m_errors
27 : use m_crystal
28 : use m_ebands
29 : use m_efmas_defs
30 : use m_ifc
31 : use m_dtset
32 :
33 : use m_fstrings, only : sjoin, itoa
34 : use m_gaussian_quadrature, only : cgqf
35 :
36 : implicit none
37 :
38 : private
39 : !!***
40 :
41 : !----------------------------------------------------------------------
42 :
43 : !!****t* m_frohlich/frohlich_t
44 : !! NAME
45 : !! frohlich_t
46 : !!
47 : !! FUNCTION
48 : !! Description
49 : !!
50 : !! SOURCE
51 :
52 : type,public :: frohlich_t
53 :
54 : integer :: kind = 0
55 : ! Type of the Fr\"ohlich model
56 : ! used to access the calculations of various properties
57 : ! 0 -> ndeg != 1 && ndeg != 3, generalized Fr\"ohlich model
58 : ! 1 -> ndeg = 1, standard (possibly anisotropic) Fr\"ohlich model
59 : ! 2 -> ndeg = 3, cubic generalized Fr\"ohlich model with 3-fold degeneracy
60 :
61 : ! Geometry ------------------------------------
62 :
63 : real(dp) :: ucvol
64 : ! Real space unit cell volume
65 :
66 : real(dp) :: gmet(3,3)
67 : ! Reciprocal space metric
68 :
69 :
70 : ! Electroncic subspace -----------------------
71 :
72 : logical :: isinitel = .false.
73 : ! Flag indicating that the electronic subspace has been initialized
74 :
75 : real(dp) :: kpt(3)
76 : ! k-point characterizing the electronic subspace, i.e. the k-point at which
77 : ! the effective mass tensor is obtained (usually, CBM or VBM)
78 :
79 : integer :: ndeg
80 : ! Number of degenerate bands taken into account
81 :
82 : complex(dp), allocatable :: eig2_diag_cart(:,:,:,:)
83 : ! Band curvature double tensor in Cartesian coordinates
84 : ! (3, 3, ndeg, ndeg)
85 :
86 : real(dp) :: band_params(3)
87 : ! Parameters describing electronic bands
88 : ! The meaning of this arrayd depends on the value of the kind variable
89 : ! kind = 0 -> undefined
90 : ! kind = 1 -> inverse effetive masses along the 100, 010 and 001 directions
91 : ! kind = 2 -> Luttinger-Kohn parameters A, B, C
92 :
93 : logical :: lutt_warn(3) = .false.
94 :
95 : real(dp), allocatable :: sqrt_efmas_avg(:)
96 : ! Square root of effective mass averaged over q-sphere for each band
97 : ! (ndeg)
98 :
99 : logical, allocatable :: saddle_warn(:)
100 : ! Signals if the k-point characterizing the electronic subspace is a
101 : ! saddle-point for each of the degenerate bands
102 : ! (ndeg)
103 :
104 : real(dp) :: sqrt_efmas_tot
105 : ! Total square root of effective mass average
106 :
107 : real(dp), allocatable :: invefmas(:,:)
108 : ! Inverse electronic effective masses along
109 : ! kind = 1 -> 100, 010, 001 directions
110 : ! kind = 2 -> 100, 110, 111 directions
111 : ! (ndeg, 3)
112 :
113 :
114 : ! Vibrational (phonon) subspace ---------------
115 :
116 : logical :: isinitph = .false.
117 : ! Flag indicating that the phonon subspace has been initialized
118 :
119 : integer :: natom
120 : ! Number of atoms in the cell
121 :
122 : integer :: nqdir
123 : ! Number of points for spherical integration used to compute ZPR and other
124 : ! quantities
125 :
126 : real(dp), allocatable :: unit_qdir(:,:)
127 : ! Unit q-vectors representing reciprocal space directions used to compute
128 : ! ZPR and other quantities
129 : ! (3, nqdir)
130 :
131 : real(dp), allocatable :: weights_qdir(:)
132 : ! Gaussian quadrature weights used for spherical intragraion over q-vectors
133 : ! (nqdir)
134 :
135 : real(dp), allocatable :: dielt_qdir(:)
136 : ! High-frequency dielectric constant for each q-vector direction
137 : ! (nqdir)
138 :
139 : real(dp), allocatable :: phfreq_qdir(:,:)
140 : ! Phonon frequencies for each mode and q-vector direction
141 : ! (3*natom, nqdir)
142 :
143 : real(dp), allocatable :: polarity_qdir(:,:,:)
144 : ! Mode polarity vectors for each mode and q-vector direction
145 : ! (3, 3*natom, nqdir)
146 :
147 : real(dp), allocatable :: proj_polarity_qdir(:,:)
148 : ! Projections of mode polarity vectors for each mode and q-vector direction
149 : ! (3*natom, nqdir)
150 :
151 : real(dp), allocatable :: investar(:,:)
152 : ! Inverse effective dielectric constant for each mode and q-vector
153 : ! (3*natom, nqdir)
154 :
155 : real(dp), allocatable :: dielavg(:)
156 : ! Dielectric average over q-vectors for each mode (Eq. (26) of [deMelo2023])
157 : ! (3*natom)
158 :
159 : logical, allocatable :: isiractive(:)
160 : ! Flags to detect the infrared-active phonon modes
161 : ! (3*natom)
162 :
163 : real(dp) :: dielt_eff
164 : ! Effective dielectric constant in the strong-coupling regime
165 :
166 : real(dp) :: phfreq_eff
167 : ! Effective LO phonon frequency in the strong-coupling regime
168 :
169 :
170 : ! Weak-coupling parameters --------------------
171 :
172 : real(dp), allocatable :: zpr_band(:)
173 : ! Zero-point renormalization energy for each band (Eq. (17) of [deMelo2023])
174 : ! (ndeg)
175 :
176 : logical :: sign_warn = .false.
177 : ! Sginals an error if a saddle-point is encountered or bands contribute to
178 : ! the ZPR with different signs
179 :
180 : real(dp) :: zpr_gamma
181 : ! Correction to the ZPR taking into account the infrared divergence of the
182 : ! electron-phonon coupling in the Fr\"ohlich model
183 :
184 : real(dp) :: zpr
185 : ! Total ZPR for these bands and k-point
186 :
187 : real(dp) :: enpol_wc
188 : ! Fr\"ohlich polaron formation energy in the weak-coupling regime
189 : ! (Eq. (26) of [deMelo2023])
190 :
191 : real(dp), allocatable :: zpr_k(:,:,:)
192 : ! Direction dependent ZPR (Eq. (86) of [Guster2021])
193 : ! (3, ndeg, 3)
194 :
195 : real(dp), allocatable :: invpolmas(:,:)
196 : ! Inverse Fr\"ohlich polaron effective masses in the weak-coupling regime
197 : ! (Sec. III A, B of [Guster2021])
198 : ! kind = 1 -> 100, 010, 001 directions
199 : ! kind = 2 -> 100, 110, 111 directions
200 : ! (ndeg, 3)
201 :
202 :
203 : contains
204 :
205 : procedure :: init_ph => frohlich_init_ph
206 : ! Initialization of a vibrational (phonon) subspace parameters
207 :
208 : procedure :: init_el => frohlich_init_el
209 : ! Initialization of an electronic subspace parameters
210 :
211 : procedure :: free_ph => frohlich_free_ph
212 : ! Free memory allocated to the vibrational subspace
213 :
214 : procedure :: free_el => frohlich_free_el
215 : ! Free memory allocated to the electronic subspace
216 : ! and other related quantities
217 :
218 : procedure :: calc_zpr => frohlich_calc_zpr
219 : ! Calculate the zero-point renormalization energy corresponding to the
220 : ! weak-coupling treatment of the Fr\"ohlich model
221 :
222 : procedure :: calc_polaronmass => frohlich_calc_polaronmass
223 : ! Calculate the polaron effective mass corresponding to the weak-coupling
224 : ! treatment of the Fr\"ohlich model; available for kind = 1 or 2
225 :
226 : ! procedure :: ncwrite => frohlich_ncwrite
227 : ! Write main dimensions and header on a netcdf file
228 :
229 :
230 : end type frohlich_t
231 : !!***
232 :
233 : public :: frohlichmodel_zpr ! Main routine to compute ZPR
234 : public :: frohlichmodel_polaronmass ! Main routine to compute polaron effective
235 : ! masses
236 :
237 : contains !=====================================================================
238 : !!***
239 :
240 : !!****f* m_frohlich/frohlichmodel_polaronmass
241 : !! NAME
242 : !! frohlichmodel_polaronmass
243 : !!
244 : !! FUNCTION
245 : !! Main routine to compute the polaron effective masses of the generalized
246 : !! Fr\"ohlich model and other related quantities
247 : !!
248 : !! INPUTS
249 : !! cryst<crystal_t>=Structure defining the unit cell
250 : !! dtset<dataset_type>=All input variables for this dataset.
251 : !! efmasdeg(nkpt_rbz) <type(efmasdeg_type)>= information about the band
252 : !! degeneracy at each k point
253 : !! efmasval(mband,nkpt_rbz) <type(efmasdeg_type)>= double tensor datastructure
254 : !! efmasval(:,:)%eig2_diag band curvature double tensor
255 : !! ifc<ifc_type>=contains the dynamical matrix and the IFCs.
256 : !!
257 : !! NOTES
258 : !! This routine has to be merged with the frohlichmodel_zpr routine, and their
259 : !! text output needs to be refined. For now, they are being kept to be
260 : !! compatible with the legacy unit tests.
261 : !!
262 : !! SOURCE
263 :
264 1 : subroutine frohlichmodel_polaronmass(frohlich, cryst, dtset, efmasdeg, efmasval, ifc)
265 :
266 : !Arguments ------------------------------------
267 : !scalars
268 : class(frohlich_t),intent(inout) :: frohlich
269 : type(crystal_t),intent(in) :: cryst
270 : type(dataset_type),intent(in) :: dtset
271 : type(ifc_type),intent(in) :: ifc
272 : !arrays
273 : type(efmasdeg_type), intent(in) :: efmasdeg(:)
274 : type(efmasval_type), intent(in) :: efmasval(:,:)
275 :
276 : !Local variables-------------------------------
277 : !scalar
278 : integer :: nu, ikpt, ideg, ndeg
279 : integer :: iqdir
280 : !arrays
281 : real(dp) :: kpt(3)
282 :
283 : ! *************************************************************************
284 :
285 : ! Initalize phonon and dielectric subspace
286 1 : call frohlich%init_ph(cryst, dtset%efmas_ntheta, ifc)
287 :
288 : ! For each k-point (with possible degeneracy), initialize an inistance of the
289 : ! generalize Fr\"ohlich model and calculate related quantities
290 2 : do ikpt=1,dtset%nkpt
291 4 : kpt(:) = dtset%kptns(:, ikpt)
292 :
293 4 : do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
294 : ndeg = efmasdeg(ikpt)%degs_bounds(2, ideg) - &
295 2 : efmasdeg(ikpt)%degs_bounds(1, ideg) + 1
296 :
297 2 : call frohlich%init_el(cryst, kpt, ndeg, efmasval(ideg, ikpt)%eig2_diag)
298 2 : call frohlich%calc_zpr()
299 2 : call frohlich%calc_polaronmass()
300 :
301 : ! Luttinger parameters if applicable
302 2 : if (frohlich%ndeg == 3) then
303 :
304 4 : if (.not. (any(frohlich%saddle_warn))) then
305 4 : if (any(frohlich%lutt_warn)) then
306 :
307 0 : write(ab_out, '(2a)') ch10, &
308 0 : ' Luttinger parameters could not be determined:'
309 :
310 0 : if (frohlich%lutt_warn(1)) then
311 : write(ab_out, '(a)') ' Predicted degeneracies for &
312 0 : °_dim = 3 are not met for (100) direction.'
313 : endif
314 :
315 0 : if (frohlich%lutt_warn(2)) then
316 : write(ab_out, '(a)') ' Predicted degeneracies for &
317 0 : °_dim = 3 are not met for (111) direction.'
318 : endif
319 :
320 0 : if (frohlich%lutt_warn(3)) then
321 : write(ab_out, '(a)') ' Predicted degeneracies for &
322 0 : °_dim = 3 are not met for (110) direction.'
323 : endif
324 :
325 0 : write(ab_out, '(a)') ch10
326 : else
327 : write(ab_out, '(a,3f14.6)') &
328 1 : ' Luttinger parameters (A, B, C) (a.u.): ', &
329 2 : frohlich%band_params(:)
330 : endif
331 : endif
332 :
333 : ! Print inverse electronic effective masses in the output
334 1 : write(ab_out, '(a)') repeat('-', 80)
335 : write(ab_out, '(a)') ' Polaron properties from the generalized &
336 1 : &Froehlich model'
337 1 : write(ab_out, '(a)') repeat('-', 80)
338 1 : write(ab_out, '(a)') ' Polar modes'
339 1 : write(ab_out, '(a)') ' ## Frequency(meV) Epsilon*'
340 :
341 : ! For a cubic material, dielectric tensor and phonon frequencies at Gamma
342 : ! do not depend on the q-vector direction
343 1 : iqdir = 1
344 4 : do nu = 4,3*cryst%natom
345 4 : if (frohlich%isiractive(nu)) then
346 1 : write(ab_out,'(2x,i3,5x,f15.6,5x,f15.6)') nu, &
347 1 : frohlich%phfreq_qdir(nu, iqdir)*Ha_eV*1000.0_dp, &
348 2 : one/frohlich%investar(nu, iqdir)
349 : endif
350 : enddo
351 :
352 1 : write(ab_out, '(a)') ' '
353 1 : write(ab_out, '(a,f10.2)') ' ZPR (meV): ', &
354 2 : frohlich%zpr_k(1, 1, 1)*Ha_eV*1000.0_dp
355 1 : write(ab_out, '(a)') ' '
356 : write(ab_out, '(a)') ' Electronic effective mass (a.u.) &
357 1 : &along 3 directions'
358 1 : write(ab_out, '(a, 3f15.6)')' Direction 100: ', &
359 5 : one/frohlich%invefmas(:, 1)
360 1 : write(ab_out, '(a, 3f15.6)')' Direction 110: ', &
361 5 : one/frohlich%invefmas(:, 2)
362 1 : write(ab_out, '(a, 3f15.6)')' Direction 111: ', &
363 5 : one/frohlich%invefmas(:, 3)
364 :
365 : ! Print inverse polaron effective masses in the output
366 1 : write(ab_out, '(a)') ' '
367 1 : write(ab_out, '(a)') ' Polaron effective mass (a.u.) along 3 directions'
368 1 : write(ab_out, '(a, 3f15.6)') ' Direction 100: ', &
369 5 : one/frohlich%invpolmas(:, 1)
370 1 : write(ab_out, '(a, 3f15.6)') ' Direction 110: ', &
371 5 : one/frohlich%invpolmas(:, 2)
372 1 : write(ab_out, '(a, 3f15.6)') ' Direction 111: ', &
373 5 : one/frohlich%invpolmas(:, 3)
374 1 : write(ab_out, '(a)')' '
375 : write(ab_out, '(a)')' Sum rule of inverse polaron masses check-up &
376 1 : &(for convergence purposes):'
377 1 : write(ab_out,'(a, 3f15.6)')' Direction 100: ', &
378 5 : sum(frohlich%invpolmas(:, 1))
379 1 : write(ab_out,'(a, 3f15.6)')' Direction 110: ', &
380 5 : sum(frohlich%invpolmas(:, 2))
381 1 : write(ab_out,'(a, 3f15.6)')' Direction 111: ', &
382 5 : sum(frohlich%invpolmas(:, 3))
383 : endif
384 :
385 3 : call frohlich%free_el()
386 : enddo
387 : enddo
388 :
389 1 : call frohlich%free_ph()
390 :
391 1 : end subroutine frohlichmodel_polaronmass
392 : !!***
393 :
394 :
395 : !!****f* m_frohlich/frohlichmodel_zpr
396 : !! NAME
397 : !! frohlichmodel_zpr
398 : !!
399 : !! FUNCTION
400 : !! Main routine to compute the ZPR of the generalized Fr\"ohlich model and
401 : !! other related quantities
402 : !!
403 : !! INPUTS
404 : !! cryst<crystal_t>=Structure defining the unit cell
405 : !! dtset<dataset_type>=All input variables for this dataset.
406 : !! efmasdeg(nkpt_rbz) <type(efmasdeg_type)>= information about the band
407 : !! degeneracy at each k point
408 : !! efmasval(mband,nkpt_rbz) <type(efmasdeg_type)>= double tensor datastructure
409 : !! efmasval(:,:)%eig2_diag band curvature double tensor
410 : !! ifc<ifc_type>=contains the dynamical matrix and the IFCs.
411 : !!
412 : !! SOURCE
413 :
414 2 : subroutine frohlichmodel_zpr(frohlich, cryst, dtset, efmasdeg, efmasval, ifc)
415 :
416 : !Arguments ------------------------------------
417 : !scalars
418 : class(frohlich_t),intent(inout) :: frohlich
419 : type(crystal_t),intent(in) :: cryst
420 : type(dataset_type),intent(in) :: dtset
421 : type(ifc_type),intent(in) :: ifc
422 : !arrays
423 : type(efmasdeg_type), intent(in) :: efmasdeg(:)
424 : type(efmasval_type), intent(in) :: efmasval(:,:)
425 :
426 : !Local variables-------------------------------
427 : !scalar
428 : integer :: nu, ikpt, ideg, ndeg, iband
429 : !arrays
430 : real(dp) :: kpt(3)
431 :
432 : ! *************************************************************************
433 :
434 : ! Initalize phonon and dielectric subspace
435 2 : call frohlich%init_ph(cryst, dtset%efmas_ntheta, ifc)
436 :
437 : ! Dielectric average
438 2 : write(ab_out, '(a)') repeat('-', 80)
439 2 : write(ab_out, '(a)') ' Dielectric average (EQ. 25 Melo2022)'
440 2 : write(ab_out, '(a)') repeat('-', 80)
441 : write(ab_out, '(a)') &
442 2 : ' Mode <1/epsilon*SQRT(w_LO/2)> Cumulative sum'
443 :
444 11 : do nu=4,3*cryst%natom
445 9 : write(ab_out, '(i5,f28.12,f28.12)') nu, &
446 74 : frohlich%dielavg(nu), sum(frohlich%dielavg(1:nu))
447 : enddo
448 2 : write(ab_out, '(a)') repeat('-', 80)
449 :
450 : ! Infrared ZPR correction (does not depend on the electronic subspace)
451 2 : write(ab_out, '(6a,f14.6,a,f14.6,a)') ch10, &
452 : ' Rough correction to the ZPR, to take into account the missing q=0 piece &
453 2 : &using Frohlich model:', ch10, &
454 : ' (+ for occupied states, - for unoccupied states) * zpr_q0_fact / &
455 2 : &(Nqpt_full_bz)**(1/3) ', ch10, &
456 2 : ' where Nqpt_full_bz=number of q wavevectors in full BZ, and zpr_q0_fact=',&
457 4 : frohlich%zpr_gamma, ' Ha=', frohlich%zpr_gamma*Ha_eV, ' eV'
458 :
459 : ! For each k-point (with possible degeneracy), initialize an inistance of the
460 : ! generalize Fr\"ohlich model and calculate ZPR and other related quantities
461 6 : do ikpt=1,dtset%nkpt
462 16 : kpt(:) = dtset%kptns(:, ikpt)
463 :
464 17 : do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
465 : ndeg = efmasdeg(ikpt)%degs_bounds(2, ideg) - &
466 11 : efmasdeg(ikpt)%degs_bounds(1, ideg) + 1
467 :
468 11 : call frohlich%init_el(cryst, kpt, ndeg, efmasval(ideg, ikpt)%eig2_diag)
469 11 : call frohlich%calc_zpr()
470 :
471 : ! Print ZPR results for each k-point
472 11 : if (ndeg == 1) then
473 9 : write(ab_out, '(2a,3(f6.3,a),i5)') ch10, &
474 9 : ' - At k-point (', kpt(1), ',', kpt(2), ',', kpt(3), '), band ', &
475 18 : efmasdeg(ikpt)%degs_bounds(1,ideg)
476 : else
477 2 : write(ab_out, '(2a,3(f6.3,a),i5,a,i5)') ch10, &
478 2 : ' - At k-point (', kpt(1), ',', kpt(2), ',', kpt(3), '), bands ', &
479 2 : efmasdeg(ikpt)%degs_bounds(1,ideg), ' through ', &
480 4 : efmasdeg(ikpt)%degs_bounds(2,ideg)
481 : endif
482 :
483 : ! Luttinger parameters if applicable
484 11 : if (frohlich%kind == 2) then
485 :
486 4 : if (.not. (any(frohlich%saddle_warn))) then
487 4 : if (any(frohlich%lutt_warn)) then
488 :
489 0 : write(ab_out, '(2a)') ch10, &
490 0 : ' Luttinger parameters could not be determined:'
491 :
492 0 : if (frohlich%lutt_warn(1)) then
493 : write(ab_out, '(a)') ' Predicted degeneracies for &
494 0 : °_dim = 3 are not met for (100) direction.'
495 : endif
496 :
497 0 : if (frohlich%lutt_warn(2)) then
498 : write(ab_out, '(a)') ' Predicted degeneracies for &
499 0 : °_dim = 3 are not met for (111) direction.'
500 : endif
501 :
502 0 : if (frohlich%lutt_warn(3)) then
503 : write(ab_out, '(a)') ' Predicted degeneracies for &
504 0 : °_dim = 3 are not met for (110) direction.'
505 : endif
506 :
507 0 : write(ab_out, '(a)') ch10
508 : else
509 : write(ab_out, '(a,3f14.6)') &
510 1 : ' Luttinger parameters (A, B, C) [at. units]: ', &
511 2 : frohlich%band_params(:)
512 : endif
513 : endif
514 : endif
515 :
516 : ! Effective mass average and ZPR
517 25 : do iband=1,ndeg
518 25 : if (frohlich%saddle_warn(iband)) then
519 5 : write(ab_out, '(a,i5,a)') ' Band ', &
520 5 : efmasdeg(ikpt)%degs_bounds(1, ideg) + iband - 1, ' SADDLE POINT - &
521 10 : &Frohlich effective mass and ZPR cannot be defined. '
522 : else
523 9 : write(ab_out, '(a,i5,a,f14.10)') ' Band ', &
524 9 : efmasdeg(ikpt)%degs_bounds(1, ideg) + iband - 1, ' Angular average &
525 9 : &effective mass for Frohlich model (<m**0.5>)**2= ', &
526 : sign(frohlich%sqrt_efmas_avg(iband)**2, &
527 18 : frohlich%sqrt_efmas_avg(iband))
528 : endif
529 : enddo
530 :
531 11 : if (.not. frohlich%sign_warn) then
532 : write(ab_out, '(2a)') &
533 7 : ' Angular and band average effective mass and ZPR for Frohlich model.'
534 :
535 7 : write(ab_out, '(a,es16.6)') ' Value of (<<m**0.5>>)**2 = ', &
536 23 : (sum(abs(frohlich%sqrt_efmas_avg(:))) / ndeg)**2
537 :
538 7 : write(ab_out, '(a,es16.6)') ' Absolute Value of <<m**0.5>> = ', &
539 23 : (sum(abs(frohlich%sqrt_efmas_avg(:))) / ndeg)
540 :
541 : write(ab_out, '(a,es16.6,a,es16.6,a)') &
542 7 : ' ZPR from Frohlich model = ', frohlich%zpr, ' Ha=', &
543 14 : frohlich%zpr*Ha_eV,' eV'
544 : else
545 : write(ab_out, '(a)') ' Angular and band average effective mass for &
546 4 : &Frohlich model cannot be defined because of a sign problem.'
547 : endif
548 :
549 15 : call frohlich%free_el()
550 : enddo
551 : enddo
552 :
553 2 : call frohlich%free_ph()
554 :
555 2 : end subroutine frohlichmodel_zpr
556 : !!***
557 :
558 :
559 : !!****f* m_frohlich/frohlich_free_el
560 : !! NAME
561 : !! frohlich_free_el
562 : !!
563 : !! FUNCTION
564 : !! Deallocate dynamic memory related to the electronic subspace and other
565 : !! related quantities
566 : !!
567 : !! INPUTS
568 : !!
569 : !! SOURCE
570 :
571 13 : subroutine frohlich_free_el(self)
572 :
573 : !Arguments ------------------------------------
574 : class(frohlich_t),intent(inout) :: self
575 : ! *************************************************************************
576 :
577 13 : self%isinitel = .false.
578 :
579 : ! real
580 13 : ABI_SFREE(self%sqrt_efmas_avg)
581 13 : ABI_SFREE(self%zpr_band)
582 13 : ABI_SFREE(self%invpolmas)
583 13 : ABI_SFREE(self%zpr_k)
584 13 : ABI_SFREE(self%invefmas)
585 :
586 : ! complex
587 13 : ABI_SFREE(self%eig2_diag_cart)
588 :
589 : ! logical
590 13 : ABI_SFREE(self%saddle_warn)
591 :
592 13 : end subroutine frohlich_free_el
593 : !!***
594 :
595 :
596 : !!****f* m_frohlich/frohlich_free_ph
597 : !! NAME
598 : !! frohlich_free_ph
599 : !!
600 : !! FUNCTION
601 : !! Deallocate dynamic memory related to the vibrational subspace
602 : !!
603 : !! INPUTS
604 : !!
605 : !! SOURCE
606 :
607 3 : subroutine frohlich_free_ph(self)
608 :
609 : !Arguments ------------------------------------
610 : class(frohlich_t),intent(inout) :: self
611 : ! *************************************************************************
612 :
613 3 : self%isinitph = .false.
614 :
615 : ! real
616 3 : ABI_SFREE(self%unit_qdir)
617 3 : ABI_SFREE(self%weights_qdir)
618 3 : ABI_SFREE(self%dielt_qdir)
619 3 : ABI_SFREE(self%phfreq_qdir)
620 3 : ABI_SFREE(self%polarity_qdir)
621 3 : ABI_SFREE(self%proj_polarity_qdir)
622 3 : ABI_SFREE(self%investar)
623 3 : ABI_SFREE(self%dielavg)
624 :
625 : ! logical
626 3 : ABI_SFREE(self%isiractive)
627 :
628 3 : end subroutine frohlich_free_ph
629 : !!***
630 :
631 :
632 : !!****f* m_frohlich/frohlich_calc_polaronmass
633 : !! NAME
634 : !! frohlich_calc_polaronmass
635 : !!
636 : !! FUNCTION
637 : !! Description
638 : !!
639 : !! INPUTS
640 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
641 : !!
642 : !! OUTPUT
643 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
644 : !!
645 : !! SOURCE
646 :
647 2 : subroutine frohlich_calc_polaronmass(self)
648 :
649 : !Arguments ------------------------------------
650 : !scalars
651 : class(frohlich_t), intent(inout) :: self
652 :
653 : !Local variables-------------------------------
654 : !scalars
655 : integer :: ii
656 : integer :: ikdir, nkdir
657 : integer :: ik, nkgrid
658 : integer :: lwork, info
659 : integer :: nu, iband
660 : integer :: ixi, nxi
661 : integer :: iqdir
662 : integer :: sigma
663 : real(dp) :: deltak, minefmas
664 : real(dp) :: xi, qlen
665 : real(dp) :: tmp
666 : !arrays
667 : real(dp) :: id33(3, 3)
668 : real(dp) :: kpt(3), unit_kdir(3, 3)
669 : real(dp) :: k_plus_q(3)
670 2 : real(dp), allocatable :: eigenvec(:,:), eigenval(:)
671 2 : real(dp), allocatable :: invefmas(:,:)
672 2 : real(dp), allocatable :: lutt_eigenvec(:,:,:,:), lutt_eigenval(:,:,:)
673 2 : real(dp), allocatable :: lk_h(:,:)
674 2 : real(dp), allocatable :: phfreq(:), investar(:)
675 2 : real(dp), allocatable :: intsum(:,:,:,:)
676 2 : real(dp), allocatable :: zpr(:,:,:), zpr_ddk(:,:)
677 2 : real(dp), allocatable :: intsuminv(:,:)
678 2 : complex(dp), allocatable :: work(:)
679 : ! *************************************************************************
680 :
681 : ! TODO: check if the electronic and phonon parts are initialized
682 6 : ABI_MALLOC(self%invpolmas, (self%ndeg, 3))
683 :
684 2 : if (self%kind == 2) then
685 : ! Polaron effective masses in the triply-degenerate case
686 : ! (Eq. (86) of [Guster2021])
687 :
688 : ! Initialization of the diagonalization routine
689 : ! TODO: this part is common for many routines -> initialize once and store
690 : ! necessary variables as local state constants in the datatype
691 4 : ABI_MALLOC(eigenvec, (self%ndeg, self%ndeg))
692 3 : ABI_MALLOC(eigenval, (self%ndeg))
693 3 : ABI_MALLOC(work, (3*self%ndeg - 2))
694 1 : lwork = -1
695 : call dsyev('V', 'U', self%ndeg, eigenvec(:,:), self%ndeg, eigenval(:), &
696 1 : work, lwork, info)
697 1 : lwork = int(work(1))
698 1 : ABI_FREE(work)
699 3 : ABI_MALLOC(work, (lwork))
700 :
701 : ! Inverse effectiv mass tensor for 100, 110 and 111 directions
702 : ! used to obtain the material-dependent characteristic wavevector length
703 : nkdir = 3
704 4 : unit_kdir(:, 1) = (/1, 0, 0/)
705 4 : unit_kdir(:, 2) = (/1, 1, 0/)/sqrt(2.0)
706 4 : unit_kdir(:, 3) = (/1, 1, 1/)/sqrt(3.0)
707 3 : ABI_MALLOC(invefmas, (self%ndeg, nkdir))
708 2 : ABI_MALLOC(self%invefmas, (self%ndeg, nkdir))
709 :
710 : ! 100: 2A, 2B (two-fold)
711 1 : invefmas(1, 1) = two*self%band_params(1)
712 1 : invefmas(2, 1) = two*self%band_params(2)
713 1 : invefmas(3, 1) = two*self%band_params(2)
714 : ! 110: A + B + C, 2B, A + B - C
715 : invefmas(1, 2) = self%band_params(1) + self%band_params(2) + &
716 1 : self%band_params(3)
717 : invefmas(2, 2) = min(two*self%band_params(2), self%band_params(1) + &
718 1 : self%band_params(2) - self%band_params(3))
719 : invefmas(3, 2) = max(two*self%band_params(2), self%band_params(1) + &
720 1 : self%band_params(2) - self%band_params(3))
721 : ! 111: 2/3*(A + 2B + 2C), 2/3*(A + 2B - C) (two-fold)
722 : invefmas(1, 3) = two*(self%band_params(1) + two*self%band_params(2) + &
723 1 : two*self%band_params(3)) / three
724 : invefmas(2, 3) = two*(self%band_params(1) + two*self%band_params(2) - &
725 1 : self%band_params(3)) / three
726 1 : invefmas(3, 3) = invefmas(2, 3)
727 :
728 13 : self%invefmas(:,:) = invefmas(:,:)
729 :
730 : ! Setting up the parameter to obtain the second derivative of the ZPR with
731 : ! the finite differences (FD) method (Eqs. (80), (86) of [Guster2021])
732 : ! FD: number of points
733 : nkgrid = 3
734 : ! FD: material-dependent length scale <--> lowest optical frequency
735 4 : iqdir = 1
736 13 : minefmas = one / maxval(abs(invefmas(:,:)))
737 1 : deltak = sqrt(two*minefmas*self%phfreq_qdir(4, iqdir) / 1000.0)
738 :
739 : ! FD: Luttinger eigenvalues and eigenvectors in the symmetry inequivalent
740 : ! cubic directions to be used in the ZPR calculations
741 6 : ABI_MALLOC(lutt_eigenvec, (self%ndeg, self%ndeg, nkgrid, nkdir))
742 4 : ABI_MALLOC(lutt_eigenval, (self%ndeg, nkgrid, nkdir))
743 :
744 40 : lutt_eigenval(:,:,:) = zero
745 4 : do ikdir=1,nkdir
746 13 : do ik=1,nkgrid
747 36 : kpt(:) = (ik - one)*deltak*unit_kdir(:, ikdir)
748 : call lk_hamiltonian(self%band_params(:), kpt(:), &
749 9 : lutt_eigenvec(:,:, ik, ikdir))
750 : call dsyev('V', 'U', self%ndeg, lutt_eigenvec(:,:, ik, ikdir), &
751 12 : self%ndeg, lutt_eigenval(:, ik, ikdir), work(:), lwork, info)
752 : enddo
753 : enddo
754 :
755 : ! Cubic system is assumed: phonon frequencies and permitivity at Gamma
756 : ! do not depend on the q-vector direction
757 1 : iqdir = 1
758 3 : ABI_MALLOC(phfreq, (3*self%natom))
759 2 : ABI_MALLOC(investar, (3*self%natom))
760 7 : phfreq(:) = self%phfreq_qdir(:, iqdir)
761 7 : investar(:) = self%investar(:, iqdir)
762 :
763 : ! Effective mass sign
764 1 : sigma = 1
765 1 : if (self%band_params(1) < 0) sigma = -1
766 :
767 : ! 3x3 Identity matrix
768 1 : id33(:,:) = zero
769 4 : do ii=1,3
770 4 : id33(ii, ii) = one
771 : enddo
772 :
773 : ! FD: main loop
774 : ! nqidr = 2*ntheta**2 (ntheta = nxi)
775 1 : nxi = sqrt(one*self%nqdir/2)
776 6 : ABI_MALLOC(intsum, (self%ndeg, self%ndeg, nkgrid, nkdir))
777 4 : ABI_MALLOC(zpr, (nkgrid, self%ndeg, nkdir))
778 2 : ABI_MALLOC(self%zpr_k, (nkgrid, self%ndeg, nkdir))
779 4 : ABI_MALLOC(lk_h, (self%ndeg, self%ndeg))
780 3 : ABI_MALLOC(intsuminv, (self%ndeg, self%ndeg))
781 :
782 : ! Values of ZPR (Eq. (86) of [Guster2021]) to be used in FD
783 40 : zpr(:,:,:) = zero
784 4 : do nu=4,3*self%natom
785 :
786 : ! Summation over the infrared-active phonon modes
787 4 : if (self%isiractive(nu)) then
788 :
789 4 : do ikdir=1,nkdir
790 13 : do iband=1,self%ndeg
791 39 : do ik=1,nkgrid
792 108 : kpt(:) = (ik - one)*deltak*unit_kdir(:, ikdir)
793 :
794 2763 : do ixi=0,nxi
795 2727 : xi = ixi*pi / (two*nxi)
796 2727 : if (ixi == nxi) xi = xi - tol8
797 :
798 : ! q-vector length = (omega/A)^{1/2}*tan(xi)
799 2727 : qlen = sqrt(phfreq(nu) / abs(self%band_params(1)))*tan(xi)
800 54542754 : do iqdir=1,self%nqdir
801 218160000 : k_plus_q(:) = kpt(:) + qlen*self%unit_qdir(:, iqdir)
802 : call lk_hamiltonian(self%band_params(:), k_plus_q(:), &
803 54540000 : lk_h(:,:))
804 :
805 : intsum(:,:, ik, ikdir) = &
806 : abs(lutt_eigenval(iband, ik, ikdir)*id33(:,:)) - (sigma * &
807 709020000 : lk_h(:,:) + phfreq(nu)*id33(:,:))
808 :
809 54540000 : call mat3inv(intsum(:,:, ik, ikdir), intsuminv(:,:))
810 :
811 : tmp = dot_product(lutt_eigenvec(:, iband, 2, ikdir), &
812 1145340000 : matmul(intsuminv(:,:), lutt_eigenvec(:, iband, 2, ikdir)))
813 :
814 : zpr(ik, iband, ikdir) = zpr(ik, iband, ikdir) + &
815 : investar(nu)*phfreq(nu)*tmp*sqrt(phfreq(nu) / &
816 : abs(self%band_params(1))) / cos(xi)**2 * &
817 54542727 : self%weights_qdir(iqdir)
818 : enddo
819 : enddo
820 : enddo
821 : enddo
822 : enddo
823 :
824 : endif
825 : enddo
826 40 : zpr(:,:,:) = half*quarter*piinv*sigma/nxi * zpr(:,:,:)
827 40 : self%zpr_k(:,:,:) = zpr(:,:,:)
828 :
829 : ! FD: actual finite differences to obtain the second derivative of ZPR
830 : ! (Eq. (80) of [Guster2021])
831 3 : ABI_MALLOC(zpr_ddk, (self%ndeg, nkdir))
832 :
833 13 : zpr_ddk(:,:) = zero
834 4 : do ikdir=1,nkdir
835 13 : do iband=1,self%ndeg
836 : ! Copied from the previous implementation
837 : ! Does not look like a usual FD expression...
838 : zpr_ddk(iband, ikdir) = four/three *(zpr(2, iband, ikdir) - &
839 : zpr(1, iband, ikdir) - (zpr(3, iband, ikdir) - &
840 12 : zpr(1, iband, ikdir)) / 16.0_dp) * two/deltak**2
841 : enddo
842 : enddo
843 :
844 4 : do ikdir=1,nkdir
845 13 : do iband=1,self%ndeg
846 : self%invpolmas(iband, ikdir) = &
847 12 : two/deltak**2 * lutt_eigenval(iband, 2, ikdir) + zpr_ddk(iband, ikdir)
848 : enddo
849 : enddo
850 :
851 1 : ABI_FREE(eigenvec)
852 1 : ABI_FREE(eigenval)
853 1 : ABI_FREE(work)
854 1 : ABI_FREE(invefmas)
855 1 : ABI_FREE(lutt_eigenvec)
856 1 : ABI_FREE(lutt_eigenval)
857 1 : ABI_FREE(phfreq)
858 1 : ABI_FREE(investar)
859 1 : ABI_FREE(intsum)
860 1 : ABI_FREE(zpr)
861 1 : ABI_FREE(lk_h)
862 1 : ABI_FREE(zpr_ddk)
863 1 : ABI_FREE(intsuminv)
864 : endif
865 :
866 2 : end subroutine frohlich_calc_polaronmass
867 : !!***
868 :
869 :
870 : !!****f* m_frohlich/frohlich_calc_zpr
871 : !! NAME
872 : !! frohlich_calc_zpr
873 : !!
874 : !! FUNCTION
875 : !! Description
876 : !!
877 : !! INPUTS
878 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
879 : !!
880 : !! OUTPUT
881 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
882 : !!
883 : !! SOURCE
884 :
885 13 : subroutine frohlich_calc_zpr(self)
886 :
887 : !Arguments ------------------------------------
888 : !scalars
889 : class(frohlich_t), intent(inout) :: self
890 :
891 : !Local variables-------------------------------
892 : !scalars
893 : integer :: iqdir, nu
894 : integer :: iband, jband
895 : integer :: lwork, info
896 : !arrays
897 13 : real(dp), allocatable :: efmas_qdir(:,:)
898 13 : real(dp), allocatable :: invefmas_avg(:)
899 13 : real(dp), allocatable :: eigenval(:), rwork(:)
900 13 : complex(dp), allocatable :: eigenvec(:,:), work(:)
901 13 : complex(dp), allocatable :: f3d(:,:)
902 13 : logical, allocatable :: efmas_pos(:)
903 : ! *************************************************************************
904 :
905 : ! TODO: check if the electronic and phonon parts are initialized
906 :
907 : ! Initialization of the diagonalization routine for degenerate case
908 39 : ABI_MALLOC(eigenval, (self%ndeg))
909 13 : if (self%ndeg > 1) then
910 12 : ABI_MALLOC(eigenvec, (self%ndeg, self%ndeg))
911 3 : lwork = -1
912 9 : ABI_MALLOC(rwork, (3*self%ndeg - 2))
913 3 : ABI_MALLOC(work, (1))
914 : call zheev('V', 'U', self%ndeg, eigenvec(:,:), self%ndeg, eigenval(:), &
915 3 : work(:), lwork, rwork(:), info)
916 3 : lwork = int(work(1))
917 3 : ABI_FREE(work)
918 9 : ABI_MALLOC(work, (lwork))
919 : endif
920 :
921 52 : ABI_MALLOC(f3d, (self%ndeg, self%ndeg))
922 39 : ABI_MALLOC(invefmas_avg, (self%ndeg))
923 39 : ABI_MALLOC(efmas_pos, (self%ndeg))
924 52 : ABI_MALLOC(efmas_qdir, (self%ndeg, self%nqdir))
925 26 : ABI_MALLOC(self%sqrt_efmas_avg, (self%ndeg))
926 26 : ABI_MALLOC(self%saddle_warn, (self%ndeg))
927 26 : ABI_MALLOC(self%zpr_band, (self%ndeg))
928 :
929 : ! Effective mass tensor in q-vector directions
930 260013 : do iqdir=1,self%nqdir
931 :
932 : ! Band curvature tensor (inverse effective mass)
933 620000 : do iband=1,self%ndeg
934 1260000 : do jband=1,self%ndeg
935 1920000 : f3d(iband, jband) = dot_product(self%unit_qdir(:, iqdir), matmul( &
936 20840000 : self%eig2_diag_cart(:,:, iband, jband), self%unit_qdir(:, iqdir)))
937 : enddo
938 : enddo
939 :
940 : ! Band curvature tensor diagonalization
941 260000 : if (self%ndeg == 1) then
942 200000 : eigenval(1) = f3d(1, 1)
943 : else
944 660000 : eigenvec(:,:) = f3d(:,:)
945 220000 : eigenval(:) = zero
946 320000 : work(:) = zero
947 420000 : rwork(:) = zero
948 : call zheev('V', 'U', self%ndeg, eigenvec(:,:), self%ndeg, eigenval(:), &
949 60000 : work(:), lwork, rwork(:), info)
950 60000 : ABI_CHECK(info == 0, sjoin("zheev returned info: ", itoa(info)))
951 : endif
952 :
953 620013 : efmas_qdir(:, iqdir) = one/eigenval(:)
954 : enddo
955 :
956 : ! Integration over the q-sphere: square root of the effective mass average and
957 : ! ZPR for each band (Eq. (17) of [deMelo2023])
958 31 : self%saddle_warn(:) = .false.
959 31 : self%sqrt_efmas_avg(:) = zero
960 31 : self%zpr_band(:) = zero
961 31 : invefmas_avg(:) = zero
962 260013 : do iqdir=1,self%nqdir
963 : ! square root of the effective mass average
964 : self%sqrt_efmas_avg(:) = self%sqrt_efmas_avg(:) + &
965 620000 : self%weights_qdir(iqdir)*sqrt(abs(efmas_qdir(:, iqdir)))
966 :
967 : ! ZPR
968 1460000 : do nu=4,3*self%natom
969 : self%zpr_band(:) = self%zpr_band(:) + (self%weights_qdir(iqdir) * &
970 : self%investar(nu, iqdir)*sqrt(self%phfreq_qdir(nu, iqdir) * &
971 2960000 : abs(efmas_qdir(:, iqdir))))
972 : enddo
973 :
974 : ! Inverse effective mass average: used to obtain the sign of the ZPR
975 : invefmas_avg(:) = invefmas_avg(:) + &
976 620000 : self%weights_qdir(iqdir)/efmas_qdir(:, iqdir)
977 :
978 : ! Check for saddle-points
979 260018 : if (iqdir == 1) efmas_pos(:) = (efmas_qdir(:, iqdir) > 0)
980 620013 : do iband=1,self%ndeg
981 620000 : if (efmas_pos(iband) .neqv. (efmas_qdir(iband, iqdir) > 0)) then
982 26700 : self%saddle_warn(iband) = .true.
983 : endif
984 : enddo
985 : enddo
986 31 : self%sqrt_efmas_avg(:) = quarter*piinv*self%sqrt_efmas_avg(:)
987 31 : self%zpr_band(:) = sqrthalf*quarter*piinv*self%zpr_band(:)
988 31 : invefmas_avg(:) = quarter*piinv*invefmas_avg(:)
989 :
990 : ! Check for the sign problem and caclulate total ZPR and polaron formation
991 : ! energy in the weak-coupling regime
992 13 : self%sign_warn = .false.
993 31 : do iband=1,self%ndeg
994 18 : if (self%saddle_warn(iband) .or. &
995 13 : (efmas_pos(iband) .neqv. efmas_pos(1))) then
996 5 : self%sign_warn = .true.
997 : else
998 : self%sqrt_efmas_avg(iband) = &
999 13 : sign(self%sqrt_efmas_avg(iband), invefmas_avg(iband))
1000 :
1001 13 : self%zpr_band(iband) = sign(self%zpr_band(iband), invefmas_avg(iband))
1002 : endif
1003 : enddo
1004 :
1005 13 : if (.not. self%sign_warn) then
1006 22 : self%zpr = -sum(self%zpr_band(:)) / self%ndeg
1007 22 : self%sqrt_efmas_tot = sum(self%sqrt_efmas_avg(:)) / self%ndeg
1008 75 : self%enpol_wc = -self%sqrt_efmas_tot*sum(self%dielavg(:))
1009 : endif
1010 :
1011 13 : ABI_FREE(eigenval)
1012 13 : ABI_FREE(f3d)
1013 13 : ABI_FREE(invefmas_avg)
1014 13 : ABI_FREE(efmas_pos)
1015 13 : ABI_FREE(efmas_qdir)
1016 13 : if (self%ndeg > 1) then
1017 3 : ABI_FREE(eigenvec)
1018 3 : ABI_FREE(rwork)
1019 3 : ABI_FREE(work)
1020 : endif
1021 :
1022 13 : end subroutine frohlich_calc_zpr
1023 : !!***
1024 :
1025 :
1026 : !!****f* m_frohlich/frohlich_init_el
1027 : !! NAME
1028 : !! frohlich_init_el
1029 : !!
1030 : !! FUNCTION
1031 : !! Description
1032 : !!
1033 : !! INPUTS
1034 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
1035 : !! cryst<crystal_t> = Structure defining the unit cell
1036 : !! %rprimd(3, 3) = real space primitvie vectors
1037 : !! kpt(3) = k-point characterizing the electronic subspace
1038 : !! ndeg = Number of degenerate bands
1039 : !! eig2_diag(3, 3, ndeg, ndeg) = Band curvature double tensor
1040 : !!
1041 : !! OUTPUT
1042 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
1043 : !!
1044 : !! SOURCE
1045 :
1046 13 : subroutine frohlich_init_el(self, cryst, kpt, ndeg, eig2_diag)
1047 :
1048 : !Arguments ------------------------------------
1049 : !scalars
1050 : class(frohlich_t), intent(inout) :: self
1051 : type(crystal_t), intent(in) :: cryst
1052 : integer,intent(in) :: ndeg
1053 : !arrays
1054 : real(dp), intent(in) :: kpt(3)
1055 : complex(dp), intent(in) :: eig2_diag(3, 3, ndeg, ndeg)
1056 :
1057 : !Local variables-------------------------------
1058 : !scalars
1059 : integer :: lwork, info
1060 : integer :: iband, jband
1061 : integer :: idir, ipar
1062 : !arrays
1063 : real(dp) :: unit_kdir(3, 3)
1064 26 : real(dp) :: eigenval(ndeg), lutt_eigenval(ndeg, ndeg)
1065 13 : real(dp), allocatable :: rwork(:)
1066 26 : complex(dp) :: eigenvec(ndeg, ndeg), lutt_eigenvec(ndeg, ndeg)
1067 13 : complex(dp), allocatable :: work(:)
1068 : logical :: lutt_found(3)
1069 : ! *************************************************************************
1070 :
1071 52 : self%kpt(:) = kpt(:)
1072 13 : self%ndeg = ndeg
1073 :
1074 : ! Initialize the band curvatutre double tensor in Cartesian coordiantes
1075 52 : ABI_MALLOC(self%eig2_diag_cart, (3, 3, ndeg, ndeg))
1076 :
1077 31 : do iband=1,ndeg
1078 63 : do jband=1,ndeg
1079 : self%eig2_diag_cart(:,:, iband, jband) = one/two_pi**2 * &
1080 : matmul(matmul(cryst%rprimd(:,:),eig2_diag(:,:, iband, jband)), &
1081 4114 : transpose(cryst%rprimd(:,:)))
1082 : enddo
1083 : enddo
1084 :
1085 : ! Determine the type of the Fr\"ohlich model
1086 : ! TODO: check if a material actually has cubic symmetry for kind = 3?
1087 13 : if (ndeg == 1) then
1088 : ! Standard or Anisotropic Fr\"ohlich model
1089 10 : self%kind = 1
1090 :
1091 : ! Assuming the single band is parabolic in the three Cartesian directions
1092 40 : unit_kdir(:, 1) = (/1, 0, 0/)
1093 40 : unit_kdir(:, 2) = (/0, 1, 0/)
1094 40 : unit_kdir(:, 3) = (/0, 0, 1/)
1095 :
1096 40 : do idir=1,3
1097 : self%band_params(idir) = dot_product(unit_kdir(:, idir), &
1098 670 : matmul(self%eig2_diag_cart(:,:, 1, 1), unit_kdir(:, idir)))
1099 : enddo
1100 :
1101 3 : else if (ndeg == 3) then
1102 : ! Cubic generalized Fr\"ohlich model with triply degenerate bands
1103 2 : self%kind = 2
1104 :
1105 : ! Symmety inequivalent cubic directions to obtain the Luttinger parameters
1106 8 : unit_kdir(:, 1) = (/1, 0, 0/)
1107 8 : unit_kdir(:, 2) = (/1, 1, 0/)/sqrt(2.0)
1108 8 : unit_kdir(:, 3) = (/1, 1, 1/)/sqrt(3.0)
1109 :
1110 : ! Initialize the diagonalization routine
1111 2 : lwork = -1
1112 6 : ABI_MALLOC(rwork, (3*ndeg - 2))
1113 2 : ABI_MALLOC(work, (1))
1114 : call zheev('V', 'U', ndeg, eigenvec(:,:), ndeg, eigenval, work(:), lwork, &
1115 2 : rwork(:), info)
1116 2 : lwork=int(work(1))
1117 2 : ABI_FREE(work)
1118 6 : ABI_MALLOC(work, (lwork))
1119 :
1120 26 : lutt_eigenval(:, :) = zero
1121 : ! Inverse effective mass tensor in the symmetry inequivalent directions
1122 8 : do idir=1,3
1123 :
1124 24 : do iband=1,ndeg
1125 78 : do jband=1,ndeg
1126 : lutt_eigenvec(iband, jband) = dot_product(unit_kdir(:, idir), &
1127 1800 : matmul(self%eig2_diag_cart(:, :, iband, jband), unit_kdir(:, idir)))
1128 : enddo
1129 : enddo
1130 :
1131 36 : work(:) = zero
1132 48 : rwork(:) = zero
1133 : call zheev('V', 'U', ndeg, lutt_eigenvec(:,:), ndeg, &
1134 42 : lutt_eigenval(idir, :), work(:), lwork, rwork(:), info)
1135 8 : ABI_CHECK(info == 0, sjoin("zheev returned info: ", itoa(info)))
1136 : enddo
1137 :
1138 2 : ABI_FREE(work)
1139 2 : ABI_FREE(rwork)
1140 :
1141 : ! TODO: this looks ugly
1142 : ! is there any better wa to analyze and set the Luttinger parameters?
1143 :
1144 : ! Check degeneracies in the (100) direction, get A and B luttinger params
1145 : ! Inverse effective masses are: 2*A and 2*B (twofold)
1146 2 : if (abs(lutt_eigenval(1, 2) - lutt_eigenval(1, 3)) < tol5) then
1147 2 : self%band_params(1)=half*lutt_eigenval(1, 1)
1148 2 : self%band_params(2)=half*half*(lutt_eigenval(1, 2) + lutt_eigenval(1, 3))
1149 0 : else if (abs(lutt_eigenval(1, 2) - lutt_eigenval(1, 1)) < tol5) then
1150 0 : self%band_params(1) = half*half*(lutt_eigenval(1, 2) + lutt_eigenval(1, 1))
1151 0 : self%band_params(2) = half*lutt_eigenval(1, 3)
1152 : else
1153 0 : self%lutt_warn(1) = .true.
1154 : endif
1155 :
1156 : ! Check degeneracies in the (111) direction, get C luttinger parameter
1157 : ! Inverse effective masses are 2/3*(A + 2B - C) (twofold) and
1158 : ! 2/3*(A + 2B + 2C)
1159 2 : if (abs(lutt_eigenval(3, 2) - lutt_eigenval(3, 3)) < tol5) then
1160 : self%band_params(3) = self%band_params(1) + 2*self%band_params(2) - &
1161 2 : onehalf*half*(lutt_eigenval(3, 2) + lutt_eigenval(3, 3))
1162 0 : else if (abs(lutt_eigenval(3, 2) - lutt_eigenval(3, 1)) < tol5) then
1163 : self%band_params(3) = self%band_params(1) + 2*self%band_params(2) - &
1164 0 : onehalf*half*(lutt_eigenval(3, 2) + lutt_eigenval(3, 1))
1165 : else
1166 0 : self%lutt_warn(2) = .true.
1167 : endif
1168 :
1169 : ! Verifty that the (110) direction inverse effective masses are coherent
1170 : ! with the Luttinger parameters: 2*B, A + B + C, A + B - C
1171 2 : lutt_found(:) = .false.
1172 8 : do ipar=1,ndeg
1173 8 : if (abs(lutt_eigenval(2, ipar) - 2*self%band_params(2)) < tol4) then
1174 2 : lutt_found(1) = .true.
1175 4 : else if (abs(lutt_eigenval(2, ipar) - (self%band_params(1) + &
1176 : self%band_params(2) - self%band_params(3))) < tol4) then
1177 2 : lutt_found(2) = .true.
1178 2 : else if (abs(lutt_eigenval(2, ipar) - (self%band_params(1) + &
1179 : self%band_params(2) + self%band_params(3))) < tol4) then
1180 2 : lutt_found(3) = .true.
1181 : endif
1182 : enddo
1183 :
1184 8 : if (.not. (all(lutt_found))) self%lutt_warn(3) = .true.
1185 :
1186 : else
1187 : ! Generalized Fr\"ohlich model
1188 1 : self%kind = 0
1189 : endif
1190 :
1191 : ! The electronic subspace has been initialized
1192 13 : self%isinitel = .true.
1193 :
1194 13 : end subroutine frohlich_init_el
1195 : !!***
1196 :
1197 :
1198 : !!****f* m_frohlich/frohlich_init_ph
1199 : !! NAME
1200 : !! frohlich_init_ph
1201 : !!
1202 : !! FUNCTION
1203 : !! Description
1204 : !!
1205 : !! INPUTS
1206 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
1207 : !! cryst<crystal_t> = Structure defining the unit cell
1208 : !! %natom = number of atoms in the unit cell
1209 : !! %ucvol = real space unit cell volume
1210 : !! efmas_ntheta = number of points required for spherical integration used
1211 : !! to obtain the effective mass tensor [Laflamme2016]
1212 : !! ifc<ifc_type> = Dynamical matrix and interatomic force constants
1213 : !!
1214 : !! OUTPUT
1215 : !! self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
1216 : !!
1217 : !! SOURCE
1218 :
1219 3 : subroutine frohlich_init_ph(self, cryst, efmas_ntheta, ifc)
1220 :
1221 : !Arguments ------------------------------------
1222 : !scalars
1223 : class(frohlich_t), intent(inout) :: self
1224 : type(crystal_t), intent(in) :: cryst
1225 : type(ifc_type), intent(in) :: ifc
1226 : integer, intent(in) :: efmas_ntheta
1227 : !arrays
1228 :
1229 : !Local variables-------------------------------
1230 : !scalars
1231 : integer :: ntheta, nphi, nqdir
1232 : integer :: iphi, itheta, iqdir, nu
1233 : ! integer :: ikpt, ideg, iband, jband
1234 : ! integer :: ndeg
1235 : real(dp) :: weight
1236 : real(dp) :: weight_phi, phi_radians
1237 : real(dp) :: costheta, sintheta, cosphi, sinphi
1238 : !arrays
1239 : ! real(dp) :: kpt(3)
1240 3 : real(dp), allocatable :: gq_points_theta(:), gq_weights_theta(:)
1241 3 : real(dp), allocatable :: gq_points_cosphi(:), gq_points_sinphi(:)
1242 :
1243 : ! *************************************************************************
1244 :
1245 3 : self%natom = cryst%natom
1246 3 : self%ucvol = cryst%ucvol
1247 39 : self%gmet(:,:) = cryst%gmet(:,:)
1248 :
1249 : ! Initialization of integrals
1250 : ! This part allocates and initializes arrays unit_qdir(3,nqdir) and
1251 : ! weights_qdir(nqdir) used for spherical integration over q-points directions
1252 3 : ntheta = efmas_ntheta
1253 3 : nphi = 2*ntheta
1254 3 : nqdir = nphi*ntheta
1255 :
1256 9 : ABI_MALLOC(gq_points_theta, (ntheta))
1257 6 : ABI_MALLOC(gq_weights_theta, (ntheta))
1258 9 : ABI_MALLOC(gq_points_cosphi, (nphi))
1259 6 : ABI_MALLOC(gq_points_sinphi, (nphi))
1260 :
1261 3 : self%nqdir = nqdir
1262 9 : ABI_MALLOC(self%unit_qdir, (3, nqdir))
1263 9 : ABI_MALLOC(self%weights_qdir, (nqdir))
1264 :
1265 3 : call cgqf(ntheta, 1, zero, zero, zero, pi, gq_points_theta, gq_weights_theta)
1266 3 : weight_phi = two*pi/real(nphi, dp)
1267 :
1268 603 : do iphi=1,nphi
1269 600 : phi_radians = weight_phi * (iphi-1)
1270 600 : gq_points_cosphi(iphi) = cos(phi_radians)
1271 603 : gq_points_sinphi(iphi) = sin(phi_radians)
1272 : enddo
1273 :
1274 3 : nqdir = 0
1275 303 : do itheta=1,ntheta
1276 300 : costheta = cos(gq_points_theta(itheta))
1277 300 : sintheta = sin(gq_points_theta(itheta))
1278 300 : weight = gq_weights_theta(itheta)*weight_phi*sintheta
1279 :
1280 60303 : do iphi=1,nphi
1281 60000 : cosphi = gq_points_cosphi(iphi)
1282 60000 : sinphi = gq_points_sinphi(iphi)
1283 60000 : nqdir = nqdir + 1
1284 :
1285 60000 : self%unit_qdir(1, nqdir) = sintheta*cosphi
1286 60000 : self%unit_qdir(2, nqdir) = sintheta*sinphi
1287 60000 : self%unit_qdir(3, nqdir) = costheta
1288 60300 : self%weights_qdir(nqdir) = weight
1289 : enddo
1290 : enddo
1291 :
1292 3 : ABI_FREE(gq_points_theta)
1293 3 : ABI_FREE(gq_weights_theta)
1294 3 : ABI_FREE(gq_points_cosphi)
1295 3 : ABI_FREE(gq_points_sinphi)
1296 :
1297 : ! Initialization of the generalized Fr\"ohlich parameters
1298 :
1299 9 : ABI_MALLOC(self%dielt_qdir, (nqdir))
1300 12 : ABI_MALLOC(self%phfreq_qdir, (3*self%natom, nqdir))
1301 12 : ABI_MALLOC(self%polarity_qdir, (3, 3*self%natom, nqdir))
1302 9 : ABI_MALLOC(self%proj_polarity_qdir, (3*self%natom, nqdir))
1303 9 : ABI_MALLOC(self%investar, (3*self%natom, nqdir))
1304 9 : ABI_MALLOC(self%dielavg, (3*self%natom))
1305 9 : ABI_MALLOC(self%isiractive, (3*self%natom))
1306 :
1307 : ! Phonon frequencies and mode polarity vectors for each q-vector direction
1308 : call ifc%calcnwrite_nana_terms(cryst, nqdir, self%unit_qdir(:,:), &
1309 3 : phfrq2l=self%phfreq_qdir, polarity2l=self%polarity_qdir)
1310 :
1311 : ! High-frequency dielectric constant for each q-vector direction
1312 60003 : do iqdir=1,nqdir
1313 : self%dielt_qdir(iqdir) = dot_product(self%unit_qdir(:, iqdir), &
1314 960003 : matmul(ifc%dielt(:,:), self%unit_qdir(:, iqdir)))
1315 : enddo
1316 :
1317 480003 : self%investar(:,:) = zero
1318 24 : self%dielavg(:) = zero
1319 : ! Prjections of mode polarities on unit q-vectors,
1320 : ! inverse effective dielectric constants for each mode and q-vector directions
1321 : ! and dielectric average over q-vectors (Eqs. (22), (26) of [deMelo2023])
1322 60003 : do iqdir=1,nqdir
1323 300003 : do nu=4,3*self%natom
1324 : self%proj_polarity_qdir(nu, iqdir) = &
1325 960000 : dot_product(self%unit_qdir(:, iqdir), self%polarity_qdir(:, nu, iqdir))
1326 :
1327 : self%investar(nu, iqdir) = (self%proj_polarity_qdir(nu, iqdir) / &
1328 : self%dielt_qdir(iqdir) / self%phfreq_qdir(nu, iqdir))**2 * &
1329 240000 : four*pi/self%ucvol
1330 :
1331 : self%dielavg(nu) = self%dielavg(nu) + (self%weights_qdir(iqdir) * &
1332 300000 : self%investar(nu, iqdir)*sqrt(self%phfreq_qdir(nu, iqdir)))
1333 : enddo
1334 : enddo
1335 24 : self%dielavg(:) = sqrthalf*quarter*piinv * self%dielavg(:)
1336 :
1337 24 : self%isiractive(:) = .false.
1338 : ! Check for the infrared-active phonon modes: dielectric average is non-zero
1339 15 : do nu=4,3*self%natom
1340 15 : if (self%dielavg(nu) > tol10) self%isiractive(nu) = .true.
1341 : enddo
1342 :
1343 : ! Rough correction for the ZPR in the infrared limit of the Fr\"ohlich model
1344 3 : self%zpr_gamma = zero
1345 15 : do nu=4,3*self%natom
1346 240015 : do iqdir=1,self%nqdir
1347 : self%zpr_gamma = self%zpr_gamma + &
1348 240012 : self%investar(nu, iqdir)*self%weights_qdir(iqdir)
1349 : enddo
1350 : enddo
1351 : !Do not remove this useless line: a bug in the ifx2025 compiler is avoided thanks to it ...
1352 3 : write(std_out,'(a,es16.6)')' frohlich_init_ph : after the loop, self%zpr_gamma=',self%zpr_gamma
1353 3 : self%zpr_gamma = quarter*piinv*self%zpr_gamma
1354 3 : self%zpr_gamma = two*(three*quarter*piinv/self%ucvol)**third * self%zpr_gamma
1355 :
1356 : ! The phonon subspace has been initialized
1357 3 : self%isinitph = .true.
1358 :
1359 3 : end subroutine frohlich_init_ph
1360 : !!***
1361 :
1362 :
1363 : !!****f* m_frohlich/mat3inv
1364 : !! NAME
1365 : !! mat3inv
1366 : !!
1367 : !! FUNCTION
1368 : !! Inverts a 3x3 matrix of real elements
1369 : !!
1370 : !! INPUTS
1371 : !! mm(3, 3) = real matrix to be inverted
1372 : !!
1373 : !! OUTPUT
1374 : !! mit(3, 3) = inverse of the input matrix
1375 : !!
1376 : !! SOURCE
1377 :
1378 54540000 : subroutine mat3inv(mm, mit)
1379 :
1380 : !Arguments ------------------------------------
1381 : !arrays
1382 : real(dp), intent(in) :: mm(3, 3)
1383 : real(dp), intent(out) :: mit(3, 3)
1384 :
1385 : !Local variables-------------------------------
1386 : !scalars
1387 : real(dp) :: dd
1388 : character(len=500) :: msg
1389 : !arrays
1390 : real(dp) :: tt(3, 3)
1391 :
1392 : ! *************************************************************************
1393 :
1394 : ! Minors and determinant
1395 54540000 : tt(1, 1) = mm(2, 2)*mm(3, 3) - mm(3, 2)*mm(2, 3)
1396 54540000 : tt(1, 2) = mm(1, 3)*mm(3, 2) - mm(1, 2)*mm(3, 3)
1397 54540000 : tt(1, 3) = mm(1, 2)*mm(2, 3) - mm(1, 3)*mm(2, 2)
1398 54540000 : tt(2, 1) = mm(2, 3)*mm(3, 1) - mm(2, 1)*mm(3, 3)
1399 54540000 : tt(2, 2) = mm(1, 1)*mm(3, 3) - mm(3, 1)*mm(1, 3)
1400 54540000 : tt(2, 3) = mm(1, 3)*mm(2, 1) - mm(1, 1)*mm(2, 3)
1401 54540000 : tt(3, 1) = mm(2, 1)*mm(3, 2) - mm(2, 2)*mm(3, 1)
1402 54540000 : tt(3, 2) = mm(1, 2)*mm(3, 1) - mm(1, 1)*mm(3, 2)
1403 54540000 : tt(3, 3) = mm(1, 1)*mm(2, 2) - mm(2, 1)*mm(1, 2)
1404 :
1405 54540000 : dd = mm(1, 1)*tt(1, 1) + mm(2, 1)*tt(2, 1) + mm(3, 1)*tt(3, 1)
1406 :
1407 : ! Make sure the matrix is not singular
1408 54540000 : if (dd /=0) then
1409 709020000 : mit(:,:) = tt(:,:) / dd
1410 : else
1411 0 : write(msg, '(2a,2x,9(i0,1x),a)') 'Attempting to invert real array',ch10, &
1412 0 : mm,' ==> determinant is zero.'
1413 0 : ABI_ERROR(msg)
1414 : endif
1415 :
1416 54540000 : end subroutine mat3inv
1417 : !!***
1418 :
1419 :
1420 : !!****f* m_frohlich/lk_hamiltonian
1421 : !! NAME
1422 : !! lk_hamiltonian
1423 : !!
1424 : !! FUNCTION
1425 : !! Construct a Luttinger-Kohn Hamiltonian at a given k-point for a set of the
1426 : !! Luttinger-Kohn parameters A, B, C
1427 : !!
1428 : !! INPUTS
1429 : !! band_params(3) = Luttinger-Kohn parameters A, B, C
1430 : !! kpt(3) = wavevector at which the Hamiltonian is obtained (dimensional)
1431 : !!
1432 : !! OUTPUT
1433 : !! h_lk(3, 3) = Luttingher-Kohn Hamiltonian, H(k)
1434 : !!
1435 : !! SOURCE
1436 :
1437 54540009 : subroutine lk_hamiltonian(band_params, kpt, h_lk)
1438 :
1439 : !Arguments ------------------------------------
1440 : !arrays
1441 : real(dp), intent(in) :: band_params(3)
1442 : real(dp), intent(in) :: kpt(3)
1443 : real(dp), intent(out) :: h_lk(3, 3)
1444 :
1445 : ! *************************************************************************
1446 :
1447 54540009 : h_lk(1, 1) = band_params(1)*kpt(1)**2 + band_params(2)*(kpt(2)**2 + kpt(3)**2)
1448 54540009 : h_lk(2, 2) = band_params(1)*kpt(2)**2 + band_params(2)*(kpt(1)**2 + kpt(3)**2)
1449 54540009 : h_lk(3, 3) = band_params(1)*kpt(3)**2 + band_params(2)*(kpt(1)**2 + kpt(2)**2)
1450 54540009 : h_lk(1, 2) = band_params(3)*kpt(1)*kpt(2)
1451 54540009 : h_lk(1, 3) = band_params(3)*kpt(1)*kpt(3)
1452 54540009 : h_lk(2, 3) = band_params(3)*kpt(2)*kpt(3)
1453 : ! Symmetric matrix
1454 54540009 : h_lk(2, 1) = h_lk(1, 2)
1455 54540009 : h_lk(3, 1) = h_lk(1, 3)
1456 54540009 : h_lk(3, 2) = h_lk(2, 3)
1457 :
1458 54540009 : end subroutine lk_hamiltonian
1459 : !!***
1460 :
1461 55180084 : end module m_frohlich
1462 : !!***
|