├── README.md ├── src ├── epa_BoltzTraP2 ├── epa_boltztrap-1.2.5 └── epa_q-e-qe-6.2.1 └── test ├── HfCoSb ├── Co.pbe-spn-rrkjus_psl.1.0.0.UPF.gz ├── Hf.pbe-spn-rrkjus_psl.1.0.0.UPF.gz ├── HfCoSb.boltztrap.out.gz ├── HfCoSb.def.gz ├── HfCoSb.energy.gz ├── HfCoSb.epa.e.gz ├── HfCoSb.epa.in ├── HfCoSb.epa.out.gz ├── HfCoSb.intrans.gz ├── HfCoSb.ke0j.gz ├── HfCoSb.nscf.in ├── HfCoSb.nscf.out.gz ├── HfCoSb.outputtrans.gz ├── HfCoSb.ph1.in ├── HfCoSb.ph1.out.gz ├── HfCoSb.ph2.in ├── HfCoSb.ph2.out.gz ├── HfCoSb.scf.in ├── HfCoSb.scf.out.gz ├── HfCoSb.struct.gz ├── HfCoSb.trace.gz ├── HfCoSb.transdos.gz ├── HfCoSb_boltz.png ├── HfCoSb_tau.png ├── Sb.pbe-dn-rrkjus_psl.1.0.0.UPF.gz ├── plot_boltz.py ├── plot_tau.py ├── qe2boltz.out.gz ├── qe2boltz.py ├── submit1.sh └── submit2.sh ├── silicon ├── Si.bhs.gz ├── plot_boltz.py ├── plot_tau.py ├── qe2boltz.out.gz ├── qe2boltz.py ├── silicon.boltztrap.out.gz ├── silicon.def.gz ├── silicon.energy.gz ├── silicon.epa.e.gz ├── silicon.epa.in ├── silicon.epa.out.gz ├── silicon.intrans.gz ├── silicon.ke0j.gz ├── silicon.nscf.in ├── silicon.nscf.out.gz ├── silicon.outputtrans.gz ├── silicon.ph1.in ├── silicon.ph1.out.gz ├── silicon.ph2.in ├── silicon.ph2.out.gz ├── silicon.scf.in ├── silicon.scf.out.gz ├── silicon.struct.gz ├── silicon.trace.gz ├── silicon.transdos.gz ├── silicon_boltz.png ├── silicon_tau.png ├── submit1.sh └── submit2.sh └── silicon2 ├── README.md ├── silicon.energy.gz ├── silicon.epa.e.gz ├── silicon.structure.gz ├── silicon_crt.py └── silicon_epa.py /README.md: -------------------------------------------------------------------------------- 1 | # Electron-Phonon Averaged (EPA) Approximation 2 | 3 | The electron-phonon averaged (EPA) approximation is described in [Adv. Energy Mater. 2018, 1800246](https://doi.org/10.1002/aenm.201800246) and [arXiv:1511.08115](https://arxiv.org/abs/1511.08115). 4 | 5 | There are two examples, silicon and half-Heusler HfCoSb (from the paper above), containing all the input and output files (output files are gzipped). Each example has two job submission scripts, **submit1.sh** and **submit2.sh**, which follow the same computational workflow (see below). There are several python scripts called from **submit2.sh**, they require python package [BRAVE](https://github.com/mir-group/BRAVE) to convert QE output to BoltzTraP input. Alternatively, this conversion can be performed using python script **qe2boltz.py** included in boltztrap-1.2.5. 6 | 7 | ## Workflow 8 | 9 | 1. Run **pw.x** to obtain the SCF solution 10 | 2. Run **ph.x** with `fildvscf = 'dvscf'` to compute derivatives of the SCF potential 11 | 3. Run **ph.x** with `electron_phonon = 'epa'` to compute the electron-phonon coupling matrix elements and write them to file 'silicon.epa.k' 12 | 4. Run **pw.x** with `calculation = 'nscf'` to obtain the eigenvalues on a fine k-grid 13 | 5. Run **epa.x** to read the electron-phonon coupling matrix elements from file 'silicon.epa.k', average their absolute squared values over wavevector directions, and write them to file 'silicon.epa.e' 14 | 6. Run **BoltzTraP** to read the averaged squared absolute electron-phonon coupling matrix elements from file 'silicon.epa.e' and compute the transport properties 15 | 16 | ## Step 1 17 | 18 | You have to use metallic occupations even for semiconducting systems. This is because the electron-phonon coupling in **ph.x** is only implemented for metallic systems. It works fine for semiconducting systems, but only by using this trick with metallic occupations. Note that for semiconducting systems you can legitimately use any occupations (fixed or smearing) and they produce identical results, but not the other way around—using fixed occupations for metallic systems is not allowed. 19 | 20 | ## Step 5 21 | 22 | Format of the input file 'silicon.epa.in' for **epa.x**: 23 | 24 | | Content | Description | 25 | |------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| 26 | | `silicon.epa.k` | input data used by **epa.x** (contains electron-phonon coupling matrix elements in momentum-space, produced by **ph.x**) | 27 | | `silicon.epa.e` | output data produced by **epa.x** (contains averaged squared absolute electron-phonon coupling matrix elements in energy-space, used by **BoltzTraP**) | 28 | | `egrid` | job type, 'egrid' for the standard EPA averaging procedure from momentum to energy space, 'bpair' for the obsolete procedure (kept for testing purposes) | 29 | | `6.146000 -0.4 10 0 0` | valence energy grid edge (VBM energy), grid step (negative = downwards from VBM), number of bins, range of valence bands (0 0 = all valence bands) | 30 | | `6.602500 0.4 10 0 0` | conduction energy grid edge (CBM energy), grid step (positive = updards from CBM), number of bins, range of conduction bands (0 0 = all conduction bands) | 31 | | `0.0 0 0` | parameters used by job type 'gdist' for plotting a distribution of squared absolute electron-phonon coupling matrix elements | 32 | 33 | Both valence and conduction energy grids consist of 10 bins of 0.4 eV width (these could be different for the two grids). The valence energy grid extends 4 eV below the VBM (valence band maximum) and the conduction energy grid extends 4 eV above the CBM (conduction band minimum). All energies are in eV. 34 | 35 | Transitions between the valence and conduction energy grids are not implemented, there are only valence-to-valence and conduction-to-conduction transitions. This is only valid if the band gap is larger than the highest phonon energy. 36 | 37 | In case of a metal or a narrow-gap semiconductor, you can define a single energy grid that spans both valence and conduction bands. For example, if the Fermi level is at 5 eV, the energy grids can be set as follows: 38 | 39 | | Content | Description | 40 | |------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| 41 | | `2.0 -10.0 1 0 0` | valence energy grid is 3 eV below the Fermi level and is not functional | 42 | | `2.0 0.5 12 0 0` | conduction energy grid spans the range from 2 eV to 8 eV, that is, from 3 eV below the Fermi level to 3 eV above the Fermi level | 43 | 44 | ## Energy Grids 45 | 46 | The extents of valence and conduction energy grids are determined by the range of chemical potential for which you wish to compute the transport properties. Let's say the chemical potential spans from 2 eV below the VBM to 2 eV above the CBM. Then the valence and conduction energy grids have to cover that range, plus the largest phonon energy (because the electron energy can change by as much as the largest phonon energy during the electron-phonon scattering, so all electrons in that energy range will contribute to the transport properties). Extending the energy grids outside of that range won't have any effect on the transport properties (since it doesn't affect electronic transitions in the desired range of chemical potentials). Let's say the largest phonon energy is 0.2 eV, then the energy grids have to cover the range from 2.2 eV below the VBM to 2.2 eV above the CBM. If the grid steps for the valence and conduction energy grids are set to 0.2 eV and 0.5 eV, then the numbers of bins in each grid respectively should be set to 11 and 5. 47 | 48 | Look at your band structure to determine the energy range covered by the valence and conduction energy grids. Break them down into several energy bins, then run **epa.x**, and examine the output. Look at the numbers in `countv` and `countc` columns. These are numbers of eigenvalues that fall in each energy bin. If these numbers are large you can refine the energy grids by decreasing grid steps and increasing numbers of bins. For example, if your valence energy grid spans 2 eV below the VBM, you can divide this 2 eV range into increasing numbers of bins, such as 4 bins of 0.5 eV width, 5 bins of 0.4 eV width, 6 bins of 0.33 eV width, 7 bins of 0.29 eV width, 8 bins of 0.25 eV width, etc. You can continue the process until you start hitting zeros in `countv` and `countc` columns. If you want to further refine the energy grids you will need to increase the numbers of k- and/or q-points and rerun **pw.x** and **ph.x**. 49 | 50 | There are several points to note about `countv` and `countc` values: 51 | * The electron energy dispersion is usually not homogeneous, which means that for the same grid step, some energy bins will have small values of `countv` and `countc` while other energy bins with have large values of `countv` and `countc`. 52 | * If the energy grids span multiple manifolds of bands separated by gaps (zero-DOS regions), the energy bins within these gaps will have zeros in `countv` and `countc` columns. These zeros can be safely ignored. 53 | * If the numbers of bins in the valence and conduction energy grids are different, the undefined energy bins will be padded with zeros in `countv` and `countc` columns. These zeros can be safely ignored. 54 | * Some of the energy bins in finite-DOS regions may have zeros in `countv` and `countc` columns due to grid steps which are too small. This will cause spikes in the tau-epsilon dependence (inverse tau dropping to zero and tau jumping to infinity in these energy bins), which in turn will result in spikes or oscillations in transport integrals. You must increase energy grid steps or increase the numbers of k- and/or q-points to get rid of these zeros. 55 | 56 | ## Step 6 57 | 58 | Add the following line to BoltzTraP input file 'silicon.def' to switch BoltzTraP to the EPA mode: 59 | ``` 60 | 88, 'silicon.epa.e', 'old', 'formatted', 0 61 | ``` 62 | If BoltzTraP is unable to open file 'silicon.epa.e' or read its content, it will automatically fall back to the CRT (constant relaxation time) mode. 63 | 64 | Create file 'silicon.ke0j' with content '.TRUE.' and add the following line to BoltzTraP input file 'silicon.def' to make BoltzTraP compute the electronic part of the thermal conductivity at zero electric current: 65 | ``` 66 | 89, 'silicon.ke0j', 'old', 'formatted', 0 67 | ``` 68 | 69 | ## License 70 | 71 | EPA patches to [Quantum ESPRESSO](https://github.com/QEF/q-e), [BoltzTraP](https://owncloud.tuwien.ac.at/index.php/s/s2d55LYlZnioa3s), and [BoltzTraP2](https://gitlab.com/sousaw/BoltzTraP2) are distributed under [GPL-2.0](https://github.com/QEF/q-e/blob/master/License), [LGPL-3.0+](http://www.gnu.org/licenses/lgpl-3.0.txt), and [GPL-3.0+](https://gitlab.com/sousaw/BoltzTraP2/blob/public/LICENSE.txt) licenses, respectively. 72 | -------------------------------------------------------------------------------- /src/epa_BoltzTraP2: -------------------------------------------------------------------------------- 1 | diff -ur BoltzTraP2_original/BoltzTraP2/bandlib.py BoltzTraP2/BoltzTraP2/bandlib.py 2 | --- BoltzTraP2_original/BoltzTraP2/bandlib.py 2021-11-07 06:04:56.652761000 -0800 3 | +++ BoltzTraP2/BoltzTraP2/bandlib.py 2021-11-07 06:06:06.229697823 -0800 4 | @@ -393,7 +393,15 @@ 5 | return BOLTZMANN_SI * nruter 6 | 7 | 8 | -def fermiintegrals(epsilon, dos, sigma, mur, Tr, dosweight=2., cdos=None): 9 | +def fermiintegrals(epsilon, 10 | + dos, 11 | + sigma, 12 | + mur, 13 | + Tr, 14 | + dosweight=2., 15 | + cdos=None, 16 | + scattering_model=None, 17 | + scattering_file=None): 18 | """Compute the moments of the FD distribution over the band structure. 19 | 20 | Args: 21 | @@ -404,6 +412,12 @@ 22 | Tr: array of temperature values 23 | dosweight: maximum occupancy of an electron mode 24 | cdos: "curvature DOS" if available 25 | + scattering_model: model to be used for the electron lifetimes. This is 26 | + identical to scattering_model in BTPDOS except that here the model 27 | + can be mu- and T-dependent. The following choices are available: 28 | + - "epa": EPA (electron-phonon averaged) approximation 29 | + scattering_file: name of file containing parameters of the scattering 30 | + model 31 | 32 | Returns: 33 | Five numpy arrays, namely: 34 | @@ -420,6 +434,8 @@ 35 | taking the occupancies into account. 36 | where nT and nmu are the sizes of Tr and mur, respectively. 37 | """ 38 | + if isinstance(scattering_model, str) and scattering_model == "epa": 39 | + epa_params = epa_init(scattering_file) 40 | kBTr = np.array(Tr) * BOLTZMANN 41 | iu0 = np.triu_indices(3) 42 | ido = np.tril_indices(3, -1) 43 | @@ -437,16 +453,27 @@ 44 | de = epsilon[1] - epsilon[0] 45 | for iT, kBT in enumerate(kBTr): 46 | for imu, mu in enumerate(mur): 47 | + if isinstance(scattering_model, str) and scattering_model == "epa": 48 | + tau = epa_calc( 49 | + mu, kBT, epsilon, epsilon, dos, epa_params) 50 | + sigma_scat = sigma * tau 51 | + if cdos is not None: 52 | + cdos_scat = cdos * tau ** 2 53 | + else: 54 | + cdos_scat = cdos 55 | + else: 56 | + sigma_scat = sigma 57 | + cdos_scat = cdos 58 | N[iT, imu] = -(dosweight * dos * FD(epsilon, mu, kBT)).sum() * de 59 | int0 = -dosweight * dFDde(epsilon, mu, kBT) 60 | - intn = int0 * sigma 61 | + intn = int0 * sigma_scat 62 | L0[iT, imu] = intn.sum(axis=2) * de 63 | intn *= epsilon - mu 64 | L1[iT, imu] = -intn.sum(axis=2) * de 65 | intn *= epsilon - mu 66 | L2[iT, imu] = intn.sum(axis=2) * de 67 | - if cdos is not None: 68 | - cint = int0 * cdos 69 | + if cdos_scat is not None: 70 | + cint = int0 * cdos_scat 71 | L11[iT, imu] = -cint.sum(axis=3) * de 72 | return N, L0, L1, L2, L11 73 | 74 | @@ -569,3 +596,109 @@ 75 | nruter = eband.copy() 76 | nruter[conduction_mask, :] += delta 77 | return nruter 78 | + 79 | + 80 | +def epa_init(epa_file=None): 81 | + """Read parameters of the EPA approximation from a file. 82 | + 83 | + Args: 84 | + epa_file: name of file containing the EPA parameters. 85 | + 86 | + Returns: 87 | + epa_params: list of EPA parameters. 88 | + 89 | + The electron-phonon averaged (EPA) approximation is described in 90 | + G. Samsonidze & B. Kozinsky, Adv. Energy Mater. 2018, 1800246 91 | + doi:10.1002/aenm.201800246 arXiv:1511.08115 92 | + """ 93 | + with open(epa_file, 'rb') as ff: 94 | + tt = ff.readline().split() 95 | + ngrid = int(tt[0]) 96 | + nmode = int(tt[1]) 97 | + 98 | + edge = np.empty(ngrid, float) 99 | + step = np.empty(ngrid, float) 100 | + nbin = np.empty(ngrid, int) 101 | + for ii in range(ngrid): 102 | + tt = ff.readline().split() 103 | + edge[ii] = float(tt[0]) 104 | + step[ii] = float(tt[1]) 105 | + nbin[ii] = int(tt[2]) 106 | + 107 | + wavg = np.fromfile(ff, dtype = float, count = nmode, sep = ' ') 108 | + nbinmax = np.amax(nbin) 109 | + gavg = np.loadtxt(ff, dtype = float, usecols = (ii for ii in range( 110 | + 3, 3 + nmode))).reshape(ngrid, nbinmax, nbinmax, nmode) 111 | + 112 | + wavg *= 100 * 2 * math.pi * hbar_SI / qe_SI * Clight_SI 113 | + edge, step, wavg, gavg = (xx * eV for xx in (edge, step, wavg, gavg)) 114 | + epa_params = [ngrid, nmode, nbinmax, edge, step, nbin, wavg, gavg] 115 | + 116 | + return epa_params 117 | + 118 | + 119 | +def epa_calc(mu, kBT, en, epsilon, dos, epa_params): 120 | + """Compute the electron relaxation time within the EPA approximation. 121 | + 122 | + Args: 123 | + mu: chemical potential. 124 | + kBT: temperature. 125 | + en: array of energies at which to compute tau. 126 | + epsilon: array of energies at which the DOS is available. 127 | + dos: density of states. 128 | + epa_params: list of EPA parameters returned by epa_init. 129 | + 130 | + Returns: 131 | + tau: electron relaxation time, in seconds, same shape as en. 132 | + 133 | + The electron-phonon averaged (EPA) approximation is described in 134 | + G. Samsonidze & B. Kozinsky, Adv. Energy Mater. 2018, 1800246 135 | + doi:10.1002/aenm.201800246 arXiv:1511.08115 136 | + """ 137 | + ngrid, nmode, nbinmax, edge, step, nbin, wavg, gavg = epa_params 138 | + 139 | + EPS12 = 1e-12 140 | + nepa = en.shape[0] 141 | + # avoid the infrared divergence of the Bose-Einstein distribution 142 | + ww = np.clip(wavg, 20.0, None) 143 | + 144 | + gj = np.empty(nbinmax, float) 145 | + gk = np.empty(2, float) 146 | + invtau = np.empty(nepa, float) 147 | + 148 | + for nn in range(nepa): 149 | + dummy = 0.0 150 | + for ll in range(nmode): 151 | + nw = 1 / (np.exp(ww[ll] / kBT) - 1) 152 | + fa = 1 / (np.exp((en[nn] + ww[ll] - mu) / kBT) + 1) 153 | + fe = 1 / (np.exp((en[nn] - ww[ll] - mu) / kBT) + 1) 154 | + dosa = np.interp(en[nn] + ww[ll], epsilon, dos) 155 | + dose = np.interp(en[nn] - ww[ll], epsilon, dos) 156 | + 157 | + if (en[nn] < np.sum(edge) / ngrid): 158 | + ii = 0 159 | + else: 160 | + ii = 1 161 | + if (nbin[ii] == 1): 162 | + gk[:] = gavg[ii, 0, 0, ll] 163 | + else: 164 | + xx = (en[nn] - edge[ii]) / step[ii] 165 | + xx = max(xx, EPS12) 166 | + xx = min(xx, nbin[ii] - EPS12) 167 | + jj = int(xx) 168 | + for kk in range(nbinmax): 169 | + gj[kk] = gavg[ii, jj, kk, ll] 170 | + for mm in range(2): 171 | + xx = (en[nn] + ww[ll] * (1 - 2 * mm) - edge[ii]) / step[ii] 172 | + xx = max(xx, EPS12) 173 | + xx = min(xx, nbin[ii] - EPS12) 174 | + kk = int(xx) 175 | + gk[mm] = gj[kk] 176 | + 177 | + dummy += gk[0] * (nw + fa) * dosa + gk[1] * (nw + 1 - fe) * dose 178 | + invtau[nn] = dummy 179 | + 180 | + invtau *= 2 * math.pi * qe_SI / hbar_SI 181 | + tau = np.divide(1.0, np.maximum(invtau, 1e9)) 182 | + 183 | + return tau 184 | -------------------------------------------------------------------------------- /src/epa_boltztrap-1.2.5: -------------------------------------------------------------------------------- 1 | diff -ur boltztrap-1.2.5_original/src/BoltzTraP.F90 boltztrap-1.2.5/src/BoltzTraP.F90 2 | --- boltztrap-1.2.5_original/src/BoltzTraP.F90 2013-11-20 10:29:02.000000000 -0800 3 | +++ boltztrap-1.2.5/src/BoltzTraP.F90 2021-11-07 05:37:29.222193161 -0800 4 | @@ -75,6 +75,9 @@ 5 | integer :: un_phdosxy = 53 6 | integer :: un_phdosxyz = 54 7 | 8 | + integer :: un_epa = 88 9 | + integer :: un_ke0j = 89 10 | + 11 | 12 | WRITE(6,*) '================ BoltzTraP vs 1.2.5 =============' 13 | CALL gtfnam(deffn,errfn,iproc) 14 | @@ -334,7 +337,7 @@ 15 | ELSE IF(modus2=='BOLTZ' .or. modus2=='DRAG') THEN 16 | ! dos and fermiint communicate via file units un_dos, un_dosxy, un_dosxyz = 49-51. 17 | write (6,*) 'Calling FermiIntegrals' 18 | - CALL fermiintegrals(cell, spinorbit,bs%icut1,vbm,cbm, fradix, un_dos, un_dosxy, un_dosxyz) 19 | + CALL fermiintegrals(cell, spinorbit,bs%icut1,vbm,cbm, fradix, un_dos, un_dosxy, un_dosxyz, un_epa, un_ke0j) 20 | ELSE IF(modus2=='PHBLZ') then 21 | write (6,*) 'Calling BoseIntegrals for thermal transport' 22 | call boseintegrals(cell, fradix, un_phdos, un_phdosxy, un_phdosxyz) 23 | diff -ur boltztrap-1.2.5_original/src/fermiintegrals.F90 boltztrap-1.2.5/src/fermiintegrals.F90 24 | --- boltztrap-1.2.5_original/src/fermiintegrals.F90 2013-11-20 09:21:58.000000000 -0800 25 | +++ boltztrap-1.2.5/src/fermiintegrals.F90 2021-11-07 05:38:29.882584331 -0800 26 | @@ -1,4 +1,4 @@ 27 | -SUBROUTINE fermiintegrals(cell, spinorbit,icut1,vbm,cbm, fradix, un, unxy, unxyz) 28 | +SUBROUTINE fermiintegrals(cell, spinorbit,icut1,vbm,cbm, fradix, un, unxy, unxyz, unepa, unke0j) 29 | USE constants 30 | USE input 31 | USE bandstructure 32 | @@ -7,7 +7,7 @@ 33 | IMPLICIT NONE 34 | type(cell_type), intent(in) :: cell 35 | INTEGER, INTENT(IN) :: icut1 36 | - INTEGER, INTENT(IN) :: un, unxy, unxyz 37 | + INTEGER, INTENT(IN) :: un, unxy, unxyz, unepa, unke0j 38 | REAL(8), INTENT(IN) :: spinorbit 39 | REAL(8), INTENT(INOUT) :: vbm,cbm 40 | character(80), intent(in) :: fradix 41 | @@ -30,6 +30,11 @@ 42 | integer :: un_tr, un_ct, un_ht, un_trfix, un_ctfix, un_htfix 43 | CHARACTER(len=20) :: dummystring 44 | 45 | + INTEGER :: ii, jj, kk, ll, mm, nn, oo, ngrid, nmodes, nbinmax, iepa, ike0j 46 | + INTEGER, ALLOCATABLE :: nbin(:) 47 | + REAL(8), ALLOCATABLE :: edge(:), step(:), wavg(:), gavg(:,:,:,:) 48 | + LOGICAL :: kappaelzeroj 49 | + 50 | type(fermispl_type) :: splobj 51 | integer :: nspl 52 | 53 | @@ -88,6 +93,54 @@ 54 | & " kappa0(x,x')" 55 | WRITE(un_ht,'(a)') "# Ef[Ry] T [K] N 27 Hall coefficients" 56 | 57 | +! Read parameters of the EPA approximation from a file 58 | +! 59 | +! The electron-phonon averaged (EPA) approximation is described in 60 | +! G. Samsonidze & B. Kozinsky, Adv. Energy Mater. 2018, 1800246 61 | +! doi:10.1002/aenm.201800246 arXiv:1511.08115 62 | +! 63 | + READ(unepa, *, iostat = iepa) ngrid, nmodes 64 | + IF (iepa == 0) THEN 65 | + ALLOCATE(edge(ngrid)) 66 | + ALLOCATE(step(ngrid)) 67 | + ALLOCATE(nbin(ngrid)) 68 | + do ii = 1, ngrid 69 | + READ(unepa, *) edge(ii), step(ii), nbin(ii) ! edge & step in eV 70 | + enddo 71 | + ALLOCATE(wavg(nmodes)) 72 | + READ(unepa, *) (wavg(ll), ll = 1, nmodes) ! in cm^-1 73 | + nbinmax = maxval(nbin) 74 | + ALLOCATE(gavg(nmodes, nbinmax, nbinmax, ngrid)) 75 | + do ii = 1, ngrid 76 | + do jj = 1, nbin(ii) 77 | + do kk = 1, nbin(ii) 78 | + READ(unepa, *) mm, nn, oo, (gavg(ll, kk, jj, ii), ll = 1, nmodes) ! <|g|^2> in eV^2 79 | + enddo 80 | + enddo 81 | + enddo 82 | + 83 | + ! avoid the infrared divergence of the Bose-Einstein distribution 84 | + do ll = 1, nmodes 85 | + wavg(ll) = max(wavg(ll), 20.0d0) 86 | + enddo 87 | + 88 | + ! convert edge & step from eV to Ha 89 | + edge(:) = edge(:) * EV 90 | + step(:) = step(:) * EV 91 | + ! convert from cm^-1 to Ha 92 | + wavg(:) = wavg(:) * (2.0d0 * PI * Hbar_SI * JOULE) * (1.0d2 * Clight_SI) 93 | + ! convert <|g|^2> from eV^2 to Ha^2 94 | + gavg(:,:,:,:) = gavg(:,:,:,:) * EV**2 95 | + 96 | + WRITE(6,'(2X,A)') 'EPA is on' 97 | + ELSE 98 | + WRITE(6,'(2X,A)') 'EPA is off' 99 | + ENDIF 100 | + 101 | + kappaelzeroj = .FALSE. 102 | + READ(unke0j, *, iostat = ike0j) kappaelzeroj 103 | + WRITE(6,'(2X,A,L1)') 'kappaelzeroj = ', kappaelzeroj 104 | + 105 | ! set up fermi spline object 106 | ! argmin = (ebmin-ebmax)/deltat ! force set to -40 107 | ! argmax = (ebmax-ebmin)/deltat ! force set to +40 108 | @@ -118,7 +171,8 @@ 109 | DO it=1,itmax 110 | temp=it*deltat 111 | call fermiint_fix_ef_T(cell%volume, efermi, deltaef, ebmin, temp, & 112 | - un_tr, un_ct, un_ht, npoints, dos1, dos_sigxy, dos_sigxyz, spinorbit, icut1, 1, splobj) 113 | + un_tr, un_ct, un_ht, npoints, dos1, dos_sigxy, dos_sigxyz, spinorbit, icut1, 1, splobj, & 114 | + iepa, ngrid, nmodes, nbinmax, edge, step, nbin, wavg, gavg, kappaelzeroj) 115 | ENDDO 116 | ENDDO 117 | 118 | @@ -183,7 +237,8 @@ 119 | end if 120 | 121 | call fermiint_fix_ef_T(cell%volume, efermi, deltaef, ebmin, temp, & 122 | - un_trfix, un_ctfix, un_htfix, npoints, dos1, dos_sigxy, dos_sigxyz, spinorbit, icut1, 0, splobj) 123 | + un_trfix, un_ctfix, un_htfix, npoints, dos1, dos_sigxy, dos_sigxyz, spinorbit, icut1, 0, splobj, & 124 | + iepa, ngrid, nmodes, nbinmax, edge, step, nbin, wavg, gavg, kappaelzeroj) 125 | end do 126 | WRITE (un_trfix,*) 127 | WRITE (un_ctfix,*) 128 | @@ -203,6 +258,14 @@ 129 | close (un_ctfix) 130 | close (un_htfix) 131 | 132 | + IF (iepa == 0) THEN 133 | + DEALLOCATE(edge) 134 | + DEALLOCATE(step) 135 | + DEALLOCATE(nbin) 136 | + DEALLOCATE(wavg) 137 | + DEALLOCATE(gavg) 138 | + ENDIF 139 | + 140 | END SUBROUTINE fermiintegrals 141 | 142 | 143 | @@ -214,7 +277,7 @@ 144 | !---------------------------------------------------------------------------- 145 | subroutine fermiint_fix_ef_T(volume, efermi, deltaef, ebmin, temp, & 146 | unit_tr, unit_cond, unit_hall, npoints, dos1, dos_sigxy, dos_sigxyz, spinorbit, icut1, prtef, & 147 | - splobj) 148 | + splobj, iepa, ngrid, nmodes, nbinmax, edge, step, nbin, wavg, gavg, kappaelzeroj) 149 | 150 | USE constants 151 | USE input 152 | @@ -234,6 +297,10 @@ 153 | 154 | type(fermispl_type), intent(in) :: splobj 155 | 156 | + integer, intent(in) :: iepa, ngrid, nmodes, nbinmax, nbin(ngrid) 157 | + real(8), intent(in) :: edge(ngrid), step(ngrid), wavg(nmodes), gavg(nmodes, nbinmax, nbinmax, ngrid) 158 | + logical, intent(in) :: kappaelzeroj 159 | + 160 | ! local vars 161 | INTEGER :: ialp,ibet 162 | INTEGER :: i,j,k 163 | @@ -249,9 +316,15 @@ 164 | REAL(8) :: cond(3,3),nu(3,3),kappa(3,3),sigxyz(3,3,3) 165 | REAL(8) :: minv_sigxy(3,3),seebeck(3,3),thermal(3,3),hall(3,3,3) 166 | 167 | + INTEGER :: ii, jj, kk, ll, mm 168 | + REAL(8) :: invtau, kt, nn, fa, fe, dosa, dose, xx, gk(2) 169 | + REAL(8), ALLOCATABLE :: gj(:) 170 | + 171 | ! functions 172 | REAL(8) :: fermi,dfermide,dfermidt 173 | 174 | + ALLOCATE(gj(nbinmax)) 175 | + 176 | !source 177 | specheat=ZERO 178 | sumelec=ZERO 179 | @@ -287,6 +360,67 @@ 180 | & * taureffact)) ) 181 | end if 182 | 183 | +! Compute the electron relaxation time within the EPA approximation 184 | +! 185 | +! The electron-phonon averaged (EPA) approximation is described in 186 | +! G. Samsonidze & B. Kozinsky, Adv. Energy Mater. 2018, 1800246 187 | +! doi:10.1002/aenm.201800246 arXiv:1511.08115 188 | +! 189 | + if (iepa == 0) then 190 | + kt = temp * BOLTZMANN ! convert T from K to Ha 191 | + invtau = 0.0d0 192 | + xx = wavg(nmodes) / deltaef 193 | + ialp = int(xx) + 1 194 | + 195 | + if (i .GE. ialp .AND. i .LE. npoints - ialp) then 196 | + do ll = 1, nmodes 197 | + nn = 1.0d0 / (exp(wavg(ll) / kt) - 1.0d0) 198 | + fa = 1.0d0 / (exp((ene + wavg(ll) - efermi) / kt) + 1.0d0) 199 | + fe = 1.0d0 / (exp((ene - wavg(ll) - efermi) / kt) + 1.0d0) 200 | + 201 | + xx = wavg(ll) / deltaef 202 | + ibet = int(xx) 203 | + xx = xx - dble(ibet) 204 | + ! interpolate and convert DOS from state/spin/Ha/bohr^3 to state/spin/Ha/unitcell 205 | + dosa = volume * (dos1(i + ibet) * (1.0d0 - xx) + dos1(i + ibet + 1) * xx) 206 | + dose = volume * (dos1(i - ibet - 1) * xx + dos1(i - ibet) * (1.0d0 - xx)) 207 | + 208 | + if (ene .LT. sum(edge) / ngrid) then 209 | + ii = 1 210 | + else 211 | + ii = 2 212 | + endif 213 | + if (nbin(ii) .eq. 1) then 214 | + gk(:) = gavg(ll, 1, 1, ii) 215 | + else 216 | + xx = (ene - edge(ii)) / step(ii) 217 | + xx = max(xx, 1.0d-12) 218 | + xx = min(xx, nbin(ii) - 1.0d-12) 219 | + jj = int(xx) + 1 220 | + do kk = 1, nbinmax 221 | + gj(kk) = gavg(ll, kk, jj, ii) 222 | + enddo 223 | + do mm = 1, 2 224 | + xx = (ene + wavg(ll) * (3 - 2 * mm) - edge(ii)) / step(ii) 225 | + xx = max(xx, 1.0d-12) 226 | + xx = min(xx, nbin(ii) - 1.0d-12) 227 | + kk = int(xx) + 1 228 | + gk(mm) = gj(kk) 229 | + enddo 230 | + endif 231 | + 232 | + invtau = invtau + gk(1) * (nn + fa) * dosa + gk(2) * (nn + 1.0d0 - fe) * dose 233 | + enddo 234 | + invtau = invtau * (2.0d0 * PI) / (Hbar_SI * JOULE) 235 | + endif 236 | + 237 | + if (invtau .GT. 1.0d0) then 238 | + lifetime = 1.0d0 / invtau 239 | + else 240 | + lifetime = 0.0d0 241 | + endif 242 | + endif 243 | + 244 | factor1=fermi(ene,efermi,temp)*spinorbit 245 | factor2=dfermide(ene,efermi,temp)*spinorbit 246 | factor3=dfermidt(ene,efermi,temp)*spinorbit 247 | @@ -326,6 +460,28 @@ 248 | ENDDO 249 | ENDDO 250 | thermal(1:3,1:3)=kappa(1:3,1:3) 251 | + 252 | +! Compute kappael at zero electric current according to Eq. (18) of 253 | +! G.K.H. Madsen & D.J. Singh, Comput. Phys. Commun. 175, 67 (2006) 254 | +! doi:10.1016/j.cpc.2006.03.007 255 | +! 256 | +! This is generic formula suitable for anisotropic systems. 257 | +! For isotropic systems you can compute it as follows: 258 | +! kappael = kappa0 - s S^2 T 259 | +! using data from case.trace file. 260 | +! 261 | + IF (kappaelzeroj) THEN 262 | + DO i=1,3 263 | + DO j=1,3 264 | + DO ialp=1,3 265 | + DO ibet=1,3 266 | + thermal(i,j)=thermal(i,j)-temp*nu(i,ialp)*minv_sigxy(ibet,ialp)*nu(ibet,j) 267 | + ENDDO 268 | + ENDDO 269 | + ENDDO 270 | + ENDDO 271 | + ENDIF 272 | + 273 | hall(1:3,1:3,1:3)=ZERO 274 | DO i=1,3 275 | DO j=1,3 276 | @@ -360,6 +516,8 @@ 277 | WRITE(unit_hall,102) temp,sumelec,hall(1:3,1:3,1:3),efermi/RYDBERG ! **** c11,15,25 are yzx,zxy,xyz respectively *** 278 | end if 279 | 280 | + DEALLOCATE(gj) 281 | + 282 | !100 FORMAT(F10.5,F10.4,F16.8,F16.8,9E16.8) 283 | 101 FORMAT(F10.5,F10.4,F16.8,27E16.8) 284 | ! same without the Fermi energy 285 | diff -ur boltztrap-1.2.5_original/src/m_interfaces.F90 boltztrap-1.2.5/src/m_interfaces.F90 286 | --- boltztrap-1.2.5_original/src/m_interfaces.F90 2013-11-20 09:21:58.000000000 -0800 287 | +++ boltztrap-1.2.5/src/m_interfaces.F90 2021-11-07 05:37:29.225182016 -0800 288 | @@ -119,13 +119,13 @@ 289 | end interface 290 | 291 | interface 292 | -SUBROUTINE fermiintegrals(cell, spinorbit,icut1,vbm,cbm,fradix,un, unxy, unxyz) 293 | +SUBROUTINE fermiintegrals(cell, spinorbit,icut1,vbm,cbm,fradix,un, unxy, unxyz, unepa, unke0j) 294 | USE constants 295 | USE input 296 | USE bandstructure 297 | IMPLICIT NONE 298 | type(cell_type), intent(in) :: cell 299 | - INTEGER, INTENT(IN) :: un, unxy, unxyz 300 | + INTEGER, INTENT(IN) :: un, unxy, unxyz, unepa, unke0j 301 | INTEGER, INTENT(IN) :: icut1 302 | REAL(8), INTENT(IN) :: spinorbit 303 | REAL(8), INTENT(INOUT) :: vbm,cbm 304 | @@ -137,7 +137,7 @@ 305 | interface 306 | subroutine fermiint_fix_ef_T(volume, efermi, deltaef, ebmin, temp, & 307 | unit_tr, unit_cond, unit_hall, npoints, dos1, dos_sigxy, dos_sigxyz, spinorbit, icut1, prtef, & 308 | - splobj) 309 | + splobj, iepa, ngrid, nmodes, nbinmax, edge, step, nbin, wavg, gavg, kappaelzeroj) 310 | USE constants 311 | USE input 312 | USE bandstructure 313 | @@ -153,6 +153,9 @@ 314 | real(8), intent(in) :: dos_sigxy(3,3,0:npoints) 315 | real(8), intent(in) :: dos_sigxyz(3,3,3,0:npoints) 316 | type(fermispl_type),intent(in) :: splobj 317 | + integer, intent(in) :: iepa, ngrid, nmodes, nbinmax, nbin(ngrid) 318 | + real(8), intent(in) :: edge(ngrid), step(ngrid), wavg(nmodes), gavg(nmodes, nbinmax, nbinmax, ngrid) 319 | + logical, intent(in) :: kappaelzeroj 320 | 321 | end subroutine fermiint_fix_ef_T 322 | end interface 323 | -------------------------------------------------------------------------------- /src/epa_q-e-qe-6.2.1: -------------------------------------------------------------------------------- 1 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/check_initial_status.f90 q-e-qe-6.2.1/PHonon/PH/check_initial_status.f90 2 | --- q-e-qe-6.2.1_original/PHonon/PH/check_initial_status.f90 2020-01-27 07:26:21.661514311 -0800 3 | +++ q-e-qe-6.2.1/PHonon/PH/check_initial_status.f90 2020-01-27 07:27:44.382857438 -0800 4 | @@ -72,7 +72,7 @@ 5 | USE io_files, ONLY : tmp_dir 6 | USE lsda_mod, ONLY : nspin 7 | USE scf, ONLY : rho 8 | - USE disp, ONLY : nqs, x_q, comp_iq, nq1, nq2, nq3, & 9 | + USE disp, ONLY : nqs, x_q, wq, comp_iq, nq1, nq2, nq3, & 10 | done_iq, lgamma_iq 11 | USE qpoint, ONLY : xq 12 | USE control_lr, ONLY : lgamma 13 | @@ -138,8 +138,10 @@ 14 | nqs = 1 15 | last_q = 1 16 | ALLOCATE(x_q(3,1)) 17 | + ALLOCATE(wq(1)) 18 | ALLOCATE(lgamma_iq(1)) 19 | x_q(:,1)=xq(:) 20 | + wq(1)=1.0d0 21 | lgamma_iq(1)=lgamma 22 | ! 23 | END IF 24 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/do_phonon.f90 q-e-qe-6.2.1/PHonon/PH/do_phonon.f90 25 | --- q-e-qe-6.2.1_original/PHonon/PH/do_phonon.f90 2020-01-27 07:26:21.661514311 -0800 26 | +++ q-e-qe-6.2.1/PHonon/PH/do_phonon.f90 2020-01-27 07:27:44.386859438 -0800 27 | @@ -33,7 +33,7 @@ 28 | USE disp, ONLY : nqs 29 | USE control_ph, ONLY : epsil, trans, qplot, only_init, & 30 | only_wfc, rec_code, where_rec 31 | - USE el_phon, ONLY : elph, elph_mat, elph_simple 32 | + USE el_phon, ONLY : elph, elph_mat, elph_simple, elph_epa 33 | ! 34 | ! YAMBO > 35 | USE YAMBO, ONLY : elph_yambo 36 | @@ -116,6 +116,8 @@ 37 | CALL elphsum_wannier(iq) 38 | ELSEIF( elph_simple ) THEN 39 | CALL elphsum_simple() 40 | + ELSEIF( elph_epa ) THEN 41 | + CALL elphfil_epa(iq) 42 | ELSEIF( elph_yambo ) THEN 43 | CALL elph_yambo_eval_and_IO() 44 | ELSEIF(elph_tetra == 1) THEN 45 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/elph.f90 q-e-qe-6.2.1/PHonon/PH/elph.f90 46 | --- q-e-qe-6.2.1_original/PHonon/PH/elph.f90 2020-01-27 07:26:21.661514311 -0800 47 | +++ q-e-qe-6.2.1/PHonon/PH/elph.f90 2020-01-27 07:27:44.386859438 -0800 48 | @@ -12,7 +12,7 @@ 49 | ! 50 | SAVE 51 | ! 52 | - LOGICAL :: elph, elph_mat, elph_simple 53 | + LOGICAL :: elph, elph_mat, elph_simple, elph_epa 54 | INTEGER :: elph_nbnd_min, elph_nbnd_max 55 | INTEGER :: el_ph_ngauss, el_ph_nsigma 56 | INTEGER :: iunwfcwann, lrwfcr 57 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/elphon.f90 q-e-qe-6.2.1/PHonon/PH/elphon.f90 58 | --- q-e-qe-6.2.1_original/PHonon/PH/elphon.f90 2020-01-27 07:26:21.661514311 -0800 59 | +++ q-e-qe-6.2.1/PHonon/PH/elphon.f90 2020-01-27 07:27:44.386859438 -0800 60 | @@ -1140,6 +1140,296 @@ 61 | END SUBROUTINE elphsum_simple 62 | 63 | !----------------------------------------------------------------------- 64 | +SUBROUTINE elphfil_epa(iq) 65 | + !----------------------------------------------------------------------- 66 | + ! 67 | + ! Writes electron-phonon matrix elements to a file 68 | + ! which is subsequently processed by the epa code 69 | + ! Original routine written by Georgy Samsonidze 70 | + ! 71 | + !----------------------------------------------------------------------- 72 | + USE cell_base, ONLY : ibrav, alat, omega, tpiba, at, bg 73 | + USE disp, ONLY : nq1, nq2, nq3, nqs, x_q, wq, lgamma_iq 74 | + USE dynmat, ONLY : dyn, w2 75 | + USE el_phon, ONLY : el_ph_mat, done_elph 76 | + USE fft_base, ONLY : dfftp, dffts, dfftb 77 | + USE gvect, ONLY : ngm_g, ecutrho 78 | + USE io_global, ONLY : ionode, ionode_id 79 | + USE ions_base, ONLY : nat, nsp, atm, ityp, tau 80 | + USE kinds, ONLY : DP 81 | + USE klist, ONLY : xk, wk, nelec, nks, nkstot, ngk 82 | + USE lsda_mod, ONLY : nspin, isk 83 | + USE modes, ONLY : nirr, nmodes, npert, npertx, u, t, tmq, & 84 | + name_rap_mode, num_rap_mode 85 | + USE lr_symm_base, ONLY : irgq, nsymq, irotmq, rtau, gi, gimq, & 86 | + minus_q, invsymq 87 | + USE mp, ONLY : mp_bcast, mp_sum 88 | + USE mp_images, ONLY : intra_image_comm 89 | + USE mp_pools, ONLY : npool, intra_pool_comm 90 | + USE qpoint, ONLY : nksq, nksqtot, ikks, ikqs, eigqts 91 | + USE start_k, ONLY : nk1, nk2, nk3, k1, k2, k3 92 | + USE symm_base, ONLY : s, invs, ftau, nrot, nsym, nsym_ns, & 93 | + nsym_na, ft, sr, sname, t_rev, irt, time_reversal, & 94 | + invsym, nofrac, allfrac, nosym, nosym_evc, no_t_rev 95 | + USE wvfct, ONLY : nbnd, et, wg 96 | + USE gvecw, ONLY : ecutwfc 97 | + USE io_files, ONLY : prefix 98 | + 99 | + IMPLICIT NONE 100 | + 101 | + INTEGER, INTENT(IN) :: iq 102 | + 103 | + INTEGER :: iuelph, ios, irr, ii, jj, kk, ll 104 | + character :: cdate*9, ctime*9, sdate*32, stime*32, & 105 | + stitle*32, myaccess*10, mystatus*7 106 | + CHARACTER(LEN=80) :: filelph 107 | + 108 | + REAL(DP), ALLOCATABLE :: xk_collect(:,:), wk_collect(:) 109 | + REAL(DP), ALLOCATABLE :: et_collect(:,:), wg_collect(:,:) 110 | + INTEGER, ALLOCATABLE :: ngk_collect(:) 111 | + INTEGER, ALLOCATABLE :: ikks_collect(:), ikqs_collect(:) 112 | + COMPLEX(DP), ALLOCATABLE :: el_ph_mat_collect(:,:,:,:) 113 | + 114 | + INTEGER, EXTERNAL :: find_free_unit, atomic_number 115 | + 116 | + filelph = TRIM(prefix) // '.epa.k' 117 | + 118 | + DO irr = 1, nirr 119 | + IF (.NOT. done_elph(irr)) RETURN 120 | + ENDDO 121 | + 122 | + IF (iq .EQ. 1) THEN 123 | + myaccess = 'sequential' 124 | + mystatus = 'replace' 125 | + ELSE 126 | + myaccess = 'append' 127 | + mystatus = 'old' 128 | + ENDIF 129 | + IF (ionode) THEN 130 | + iuelph = find_free_unit() 131 | + OPEN(unit = iuelph, file = TRIM(filelph), form = 'unformatted', & 132 | + access = myaccess, status = mystatus, iostat = ios) 133 | + ELSE 134 | + iuelph = 0 135 | + ENDIF 136 | + CALL mp_bcast(ios, ionode_id, intra_image_comm) 137 | + CALL errore('elphfil_epa', 'opening file ' // filelph, ABS(ios)) 138 | + 139 | + IF (iq .EQ. 1) THEN 140 | + CALL date_and_tim(cdate, ctime) 141 | + WRITE(sdate, '(A2,"-",A3,"-",A4,21X)') cdate(1:2), cdate(3:5), cdate(6:9) 142 | + WRITE(stime, '(A8,24X)') ctime(1:8) 143 | + WRITE(stitle, '("EPA-Complex",21X)') 144 | + CALL cryst_to_cart(nqs, x_q, at, -1) 145 | + ! write header 146 | + IF (ionode) THEN 147 | + WRITE(iuelph) stitle, sdate, stime 148 | + WRITE(iuelph) ibrav, nat, nsp, nrot, nsym, nsym_ns, nsym_na, & 149 | + ngm_g, nspin, nbnd, nmodes, nqs 150 | + WRITE(iuelph) nq1, nq2, nq3, nk1, nk2, nk3, k1, k2, k3 151 | + WRITE(iuelph) time_reversal, invsym, nofrac, allfrac, nosym, & 152 | + nosym_evc, no_t_rev 153 | + WRITE(iuelph) alat, omega, tpiba, nelec, ecutrho, ecutwfc 154 | + WRITE(iuelph) dfftp%nr1, dfftp%nr2, dfftp%nr3 155 | + WRITE(iuelph) dffts%nr1, dffts%nr2, dffts%nr3 156 | + WRITE(iuelph) dfftb%nr1, dfftb%nr2, dfftb%nr3 157 | + WRITE(iuelph) ((at(ii, jj), ii = 1, 3), jj = 1, 3) 158 | + WRITE(iuelph) ((bg(ii, jj), ii = 1, 3), jj = 1, 3) 159 | + WRITE(iuelph) (atomic_number(atm(ii)), ii = 1, nsp) 160 | + WRITE(iuelph) (ityp(ii), ii = 1, nat) 161 | + WRITE(iuelph) ((tau(ii, jj), ii = 1, 3), jj = 1, nat) 162 | + WRITE(iuelph) ((x_q(ii, jj), ii = 1, 3), jj = 1, nqs) 163 | + WRITE(iuelph) (wq(ii), ii = 1, nqs) 164 | + WRITE(iuelph) (lgamma_iq(ii), ii = 1, nqs) 165 | + ENDIF 166 | + CALL cryst_to_cart(nqs, x_q, bg, 1) 167 | + ENDIF 168 | + 169 | + ! collect data for current q-point 170 | + ALLOCATE(xk_collect(3, nkstot)) 171 | + ALLOCATE(wk_collect(nkstot)) 172 | + ALLOCATE(et_collect(nbnd, nkstot)) 173 | + ALLOCATE(wg_collect(nbnd, nkstot)) 174 | + ALLOCATE(ngk_collect(nkstot)) 175 | + ALLOCATE(ikks_collect(nksqtot)) 176 | + ALLOCATE(ikqs_collect(nksqtot)) 177 | + ALLOCATE(el_ph_mat_collect(nbnd, nbnd, nksqtot, nmodes)) 178 | + IF (npool > 1) THEN 179 | + CALL poolcollect(3, nks, xk, nkstot, xk_collect) 180 | + CALL poolcollect(1, nks, wk, nkstot, wk_collect) 181 | + CALL poolcollect(nbnd, nks, et, nkstot, et_collect) 182 | + CALL poolcollect(nbnd, nks, wg, nkstot, wg_collect) 183 | + CALL ipoolcollect(1, nks, ngk, nkstot, ngk_collect) 184 | + CALL jpoolcollect(1, nksq, ikks, nksqtot, ikks_collect) 185 | + CALL jpoolcollect(1, nksq, ikqs, nksqtot, ikqs_collect) 186 | + CALL el_ph_collect(nmodes, el_ph_mat, el_ph_mat_collect, nksqtot, nksq) 187 | + ELSE 188 | + xk_collect(1:3, 1:nks) = xk(1:3, 1:nks) 189 | + wk_collect(1:nks) = wk(1:nks) 190 | + et_collect(1:nbnd, 1:nks) = et(1:nbnd, 1:nks) 191 | + wg_collect(1:nbnd, 1:nks) = wg(1:nbnd, 1:nks) 192 | + ngk_collect(1:nks) = ngk(1:nks) 193 | + ikks_collect(1:nksq) = ikks(1:nksq) 194 | + ikqs_collect(1:nksq) = ikqs(1:nksq) 195 | + el_ph_mat_collect(1:nbnd, 1:nbnd, 1:nksq, 1:nmodes) = & 196 | + el_ph_mat(1:nbnd, 1:nbnd, 1:nksq, 1:nmodes) 197 | + ENDIF 198 | + CALL cryst_to_cart(nkstot, xk_collect, at, -1) 199 | + ! write data for current q-point 200 | + IF (ionode) THEN 201 | + WRITE(iuelph) nsymq, irotmq, nirr, npertx, nkstot, nksqtot 202 | + WRITE(iuelph) minus_q, invsymq 203 | + WRITE(iuelph) (irgq(ii), ii = 1, 48) 204 | + WRITE(iuelph) (npert(ii), ii = 1, nmodes) 205 | + WRITE(iuelph) (((rtau(ii, jj, kk), ii = 1, 3), jj = 1, 48), & 206 | + kk = 1, nat) 207 | + WRITE(iuelph) ((gi(ii, jj), ii = 1, 3), jj = 1, 48) 208 | + WRITE(iuelph) (gimq(ii), ii = 1, 3) 209 | + WRITE(iuelph) ((u(ii, jj), ii = 1, nmodes), jj = 1, nmodes) 210 | + WRITE(iuelph) ((((t(ii, jj, kk, ll), ii = 1, npertx), & 211 | + jj = 1, npertx), kk = 1, 48), ll = 1, nmodes) 212 | + WRITE(iuelph) (((tmq(ii, jj, kk), ii = 1, npertx), & 213 | + jj = 1, npertx), kk = 1, nmodes) 214 | + WRITE(iuelph) (name_rap_mode(ii), ii = 1, nmodes) 215 | + WRITE(iuelph) (num_rap_mode(ii), ii = 1, nmodes) 216 | + WRITE(iuelph) (((s(ii, jj, kk), ii = 1, 3), jj = 1, 3), kk = 1, 48) 217 | + WRITE(iuelph) (invs(ii), ii = 1, 48) 218 | + WRITE(iuelph) ((ftau(ii, jj), ii = 1, 3), jj = 1, 48) 219 | + WRITE(iuelph) ((ft(ii, jj), ii = 1, 3), jj = 1, 48) 220 | + WRITE(iuelph) (((sr(ii, jj, kk), ii = 1, 3), jj = 1, 3), kk = 1, 48) 221 | + WRITE(iuelph) (sname(ii), ii = 1, 48) 222 | + WRITE(iuelph) (t_rev(ii), ii = 1, 48) 223 | + WRITE(iuelph) ((irt(ii, jj), ii = 1, 48), jj = 1, nat) 224 | + WRITE(iuelph) ((xk_collect(ii, jj), ii = 1, 3), jj = 1, nkstot) 225 | + WRITE(iuelph) (wk_collect(ii), ii = 1, nkstot) 226 | + WRITE(iuelph) ((et_collect(ii, jj), ii = 1, nbnd), jj = 1, nkstot) 227 | + WRITE(iuelph) ((wg_collect(ii, jj), ii = 1, nbnd), jj = 1, nkstot) 228 | + WRITE(iuelph) (isk(ii), ii = 1, nkstot) 229 | + WRITE(iuelph) (ngk_collect(ii), ii = 1, nkstot) 230 | + WRITE(iuelph) (ikks_collect(ii), ii = 1, nksqtot) 231 | + WRITE(iuelph) (ikqs_collect(ii), ii = 1, nksqtot) 232 | + WRITE(iuelph) (eigqts(ii), ii = 1, nat) 233 | + WRITE(iuelph) (w2(ii), ii = 1, nmodes) 234 | + WRITE(iuelph) ((dyn(ii, jj), ii = 1, nmodes), jj = 1, nmodes) 235 | + WRITE(iuelph) ((((el_ph_mat_collect(ii, jj, kk, ll), ii = 1, nbnd), & 236 | + jj = 1, nbnd), kk = 1, nksqtot), ll = 1, nmodes) 237 | + CLOSE (unit = iuelph, status = 'keep') 238 | + ENDIF 239 | + CALL cryst_to_cart(nkstot, xk_collect, bg, 1) 240 | + DEALLOCATE(xk_collect) 241 | + DEALLOCATE(wk_collect) 242 | + DEALLOCATE(et_collect) 243 | + DEALLOCATE(wg_collect) 244 | + DEALLOCATE(ngk_collect) 245 | + DEALLOCATE(ikks_collect) 246 | + DEALLOCATE(ikqs_collect) 247 | + DEALLOCATE(el_ph_mat_collect) 248 | + 249 | + RETURN 250 | + 251 | +END SUBROUTINE elphfil_epa 252 | + 253 | +!---------------------------------------------------------------------------- 254 | +SUBROUTINE ipoolcollect( length, nks, f_in, nkstot, f_out ) 255 | + !---------------------------------------------------------------------------- 256 | + ! 257 | + ! ... as poolcollect, for an integer vector 258 | + ! 259 | + USE mp_pools, ONLY : my_pool_id, npool, kunit, & 260 | + inter_pool_comm, intra_pool_comm 261 | + USE mp, ONLY : mp_sum 262 | + ! 263 | + IMPLICIT NONE 264 | + ! 265 | + INTEGER, INTENT(IN) :: length, nks, nkstot 266 | + ! first dimension of arrays 267 | + ! number of k-points per pool 268 | + ! total number of k-points 269 | + INTEGER, INTENT(IN) :: f_in (length,nks) 270 | + ! pool-distributed function 271 | + INTEGER, INTENT(OUT) :: f_out(length,nkstot) 272 | + ! pool-collected function 273 | + ! 274 | + INTEGER :: nbase, rest, nks1 275 | + ! 276 | + nks1 = kunit * ( nkstot / kunit / npool ) 277 | + ! 278 | + rest = ( nkstot - nks1 * npool ) / kunit 279 | + ! 280 | + IF ( ( my_pool_id + 1 ) <= rest ) nks1 = nks1 + kunit 281 | + ! 282 | + IF (nks1.ne.nks) & 283 | + call errore('ipoolcollect','inconsistent number of k-points',1) 284 | + ! 285 | + ! ... calculates nbase = the position in the list of the first point that 286 | + ! ... belong to this npool - 1 287 | + ! 288 | + nbase = nks * my_pool_id 289 | + ! 290 | + IF ( ( my_pool_id + 1 ) > rest ) nbase = nbase + rest * kunit 291 | + ! 292 | + ! copy the original points in the correct position of the list 293 | + ! 294 | + f_out=0 295 | + f_out(:,nbase+1:nbase+nks) = f_in(:,1:nks) 296 | + ! 297 | + CALL mp_sum( f_out, inter_pool_comm ) 298 | + ! 299 | + RETURN 300 | + ! 301 | +END SUBROUTINE ipoolcollect 302 | + 303 | +!---------------------------------------------------------------------------- 304 | +SUBROUTINE jpoolcollect( length, nks, f_in, nkstot, f_out ) 305 | + !---------------------------------------------------------------------------- 306 | + ! 307 | + ! ... as ipoolcollect, without kunit and with an index shift 308 | + ! 309 | + USE mp_pools, ONLY : my_pool_id, npool, kunit, & 310 | + inter_pool_comm, intra_pool_comm 311 | + USE mp, ONLY : mp_sum 312 | + ! 313 | + IMPLICIT NONE 314 | + ! 315 | + INTEGER, INTENT(IN) :: length, nks, nkstot 316 | + ! first dimension of arrays 317 | + ! number of k-points per pool 318 | + ! total number of k-points 319 | + INTEGER, INTENT(IN) :: f_in (length,nks) 320 | + ! pool-distributed function 321 | + INTEGER, INTENT(OUT) :: f_out(length,nkstot) 322 | + ! pool-collected function 323 | + ! 324 | + INTEGER :: nbase, rest, nks1 325 | + ! 326 | + nks1 = ( nkstot / npool ) 327 | + ! 328 | + rest = ( nkstot - nks1 * npool ) 329 | + ! 330 | + IF ( ( my_pool_id + 1 ) <= rest ) nks1 = nks1 + 1 331 | + ! 332 | + IF (nks1.ne.nks) & 333 | + call errore('jpoolcollect','inconsistent number of k-points',1) 334 | + ! 335 | + ! ... calculates nbase = the position in the list of the first point that 336 | + ! ... belong to this npool - 1 337 | + ! 338 | + nbase = nks * my_pool_id 339 | + ! 340 | + IF ( ( my_pool_id + 1 ) > rest ) nbase = nbase + rest 341 | + ! 342 | + ! copy the original points in the correct position of the list 343 | + ! 344 | + f_out=0 345 | + f_out(:,nbase+1:nbase+nks) = f_in(:,1:nks) + nbase * kunit 346 | + ! 347 | + CALL mp_sum( f_out, inter_pool_comm ) 348 | + ! 349 | + RETURN 350 | + ! 351 | +END SUBROUTINE jpoolcollect 352 | + 353 | +!----------------------------------------------------------------------- 354 | FUNCTION dos_ef (ngauss, degauss, ef, et, wk, nks, nbnd) 355 | !----------------------------------------------------------------------- 356 | ! 357 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/epa.f90 q-e-qe-6.2.1/PHonon/PH/epa.f90 358 | --- q-e-qe-6.2.1_original/PHonon/PH/epa.f90 2020-01-27 07:26:21.661514311 -0800 359 | +++ q-e-qe-6.2.1/PHonon/PH/epa.f90 2020-01-27 07:42:03.051674500 -0800 360 | @@ -0,0 +1,565 @@ 361 | +! 362 | +! Copyright (C) 2018 Quantum ESPRESSO group 363 | +! This file is distributed under the terms of the 364 | +! GNU General Public License. See the file `License' 365 | +! in the root directory of the present distribution, 366 | +! or http://www.gnu.org/copyleft/gpl.txt . 367 | +! 368 | +!---------------------------------------------------------------------------- 369 | +program epa 370 | + !---------------------------------------------------------------------------- 371 | + ! 372 | + !! epa.x: 373 | + !! reads electron-phonon coupling matrix elements produced by the 374 | + !! phonon code with electron_phonon = 'epa', and makes a transformation 375 | + !! from momentum to energy space according to electron-phonon averaged 376 | + !! (EPA) approximation as described in G. Samsonidze & B. Kozinsky, 377 | + !! Adv. Energy Mater. 2018, 1800246 doi:10.1002/aenm.201800246 378 | + !! arXiv:1511.08115 379 | + !! 380 | + !! Input data: 381 | + !! 382 | + !! fin 383 | + !! fout 384 | + !! job 385 | + !! edgev, stepv, nbinv, ivmin, ivmax 386 | + !! edgec, stepc, nbinc, icmin, icmax 387 | + !! stepg, nbing, ngmax 388 | + !! 389 | + !! fin : input file produced by the phonon code 390 | + !! fout : output file used by the BoltzTraP code 391 | + !! job : job type determines how to average the matrix elements 392 | + !! - 'egrid' is to average within bins of regular energy 393 | + !! grids (standard procedure) 394 | + !! - 'bpair' is to average over individual pairs of bands 395 | + !! (obsolete procedure) 396 | + !! - 'ghist' is to construct the histogram for plotting 397 | + !! a distribution of squared matrix elements 398 | + !! edgev : grid edge of the valence energy grid (in eV), set to 399 | + !! the valence band maximum 400 | + !! stepv : grid step of the valence energy grid (in eV), set to 401 | + !! a small negative value 402 | + !! nbinv : number of bins in the valence energy grid 403 | + !! ivmin/max : range of valence bands (0/0 for all valence bands) 404 | + !! edgec : grid edge of the conduction energy grid (in eV), set to 405 | + !! the conduction band minimum 406 | + !! stepc : grid step of the conduction energy grid (in eV), set to 407 | + !! a small positive value 408 | + !! nbinc : number of bins in the conduction energy grid 409 | + !! icmin/max : range of conduction bands (0/0 for all conduction bands) 410 | + !! stepg : grid step for the histogram (in eV^2) 411 | + !! nbing : number of bins for the histogram 412 | + !! ngmax : maximum number of elements in one bin of the histogram 413 | + !! 414 | + !! For more details on how to set up the energy grids please refer to 415 | + !! online documentation at https://github.com/mir-group/EPA 416 | + ! 417 | + use kinds, only : dp 418 | + use constants, only : ry_to_cmm1, rytoev, degspin, eps12 419 | + implicit none 420 | + 421 | + integer, parameter :: ngrid = 2 422 | + integer, parameter :: uni = 101 423 | + integer, parameter :: uno = 102 424 | + real(dp), parameter :: epsw2 = (20_dp / ry_to_cmm1)**2 425 | + 426 | + logical :: minus_q 427 | + integer :: nmodes, nqs, nspin, nbnd, nkstot, nksqtot, & 428 | + nat, nsymq, irotmq, iq, ik, ikk, ikq, ibnd, jbnd, & 429 | + nu, mu, vu, ipert, jpert, ii, jj, kk, ll, ijob, & 430 | + nbinv, ivmin, ivmax, nbinc, icmin, icmax, nbing, ngmax, & 431 | + nbinmax, nbin(ngrid), nhist(ngrid), bpair(2, ngrid), & 432 | + s(3, 3, 48), invs(48) 433 | + real(dp) :: wtot, weight, factor, gbuf, gsum, & 434 | + stepg, edgev, stepv, edgec, stepc, wspin, & 435 | + edge(ngrid), step(ngrid), xq(3), at(3, 3), bg(3, 3) 436 | + character(len=256) :: fin, fout, job, fmt 437 | + character(len=32) :: s1, s2, s3, s4, s5 438 | + 439 | + real(dp), allocatable :: ghist(:,:,:) 440 | + real(dp), allocatable :: gdist(:,:,:) 441 | + real(dp), allocatable :: gavg(:,:,:,:) 442 | + real(dp), allocatable :: wavg(:) 443 | + real(dp), allocatable :: gtot(:,:,:) 444 | + integer, allocatable :: gnum(:,:,:) 445 | + real(dp), allocatable :: egrid(:,:,:) 446 | + real(dp), allocatable :: x_q(:,:) 447 | + real(dp), allocatable :: wq(:) 448 | + real(dp), allocatable :: w2(:) 449 | + complex(dp), allocatable :: dyn(:,:) 450 | + real(dp), allocatable :: wk(:) 451 | + real(dp), allocatable :: et(:,:) 452 | + integer, allocatable :: ikks(:) 453 | + integer, allocatable :: ikqs(:) 454 | + integer, allocatable :: irt(:,:) 455 | + real(dp), allocatable :: rtau(:,:,:) 456 | + complex(dp), pointer :: u(:,:) 457 | + complex(dp), allocatable :: el_ph_mat(:,:,:,:) 458 | + complex(dp), allocatable :: el_ph_sum(:,:) 459 | + 460 | + write(6, '("Reading standard input")') 461 | + read(5, '(a)') fin 462 | + read(5, '(a)') fout 463 | + read(5, '(a)') job 464 | + read(5, *) edgev, stepv, nbinv, ivmin, ivmax 465 | + read(5, *) edgec, stepc, nbinc, icmin, icmax 466 | + read(5, *) stepg, nbing, ngmax 467 | + 468 | + write(6, '(" input file name: ", a)') trim(fin) 469 | + write(6, '(" output file name: ", a)') trim(fout) 470 | + write(6, '(" job type: ", a)') trim(job) 471 | + write(s1, '(f16.8)') edgev 472 | + write(s2, '(f16.8)') stepv 473 | + write(s3, '(i8)') nbinv 474 | + write(s4, '(i8)') ivmin 475 | + write(s5, '(i8)') ivmax 476 | + write(6, '(" edgev = ", a, " eV stepv = ", a, " eV nbinv = ", & 477 | + a, " ivmin = ", a, " ivmax = ", a)') trim(adjustl(s1)), & 478 | + trim(adjustl(s2)), trim(adjustl(s3)), trim(adjustl(s4)), & 479 | + trim(adjustl(s5)) 480 | + write(s1, '(f16.8)') edgec 481 | + write(s2, '(f16.8)') stepc 482 | + write(s3, '(i8)') nbinc 483 | + write(s4, '(i8)') icmin 484 | + write(s5, '(i8)') icmax 485 | + write(6, '(" edgec = ", a, " eV stepc = ", a, " eV nbinc = ", & 486 | + a, " icmin = ", a, " icmax = ", a)') trim(adjustl(s1)), & 487 | + trim(adjustl(s2)), trim(adjustl(s3)), trim(adjustl(s4)), & 488 | + trim(adjustl(s5)) 489 | + write(s1, '(f16.8)') stepg 490 | + write(s2, '(i8)') nbing 491 | + write(s3, '(i8)') ngmax 492 | + write(6, '(" stepg = ", a, " eV^2 nbing = ", a, " ngmax = ", & 493 | + a)') trim(adjustl(s1)), trim(adjustl(s2)), trim(adjustl(s3)) 494 | + 495 | + if (trim(job) .eq. 'bpair') then 496 | + ijob = 1 497 | + elseif (trim(job) .eq. 'egrid') then 498 | + ijob = 2 499 | + elseif (trim(job) .eq. 'ghist') then 500 | + ijob = 3 501 | + else 502 | + write(0, '("Error: wrong job type")') 503 | + stop 1 504 | + endif 505 | + 506 | + open(uni, file = fin, form = 'unformatted', status = 'old') 507 | + write(6, '("Reading file ", a)') trim(fin) 508 | + read(uni) s1, s2, s3 509 | + write(6, '(" title: ", a, ", date: ", a, ", time: ", a)') & 510 | + trim(s1), trim(s2), trim(s3) 511 | + read(uni) ii, nat, ii, ii, ii, ii, ii, & 512 | + ii, nspin, nbnd, nmodes, nqs 513 | + write(s1, '(i8)') nqs 514 | + write(s2, '(i8)') nbnd 515 | + write(s3, '(i8)') nspin 516 | + write(s4, '(i8)') nmodes 517 | + write(6, '(" nqs = ", a, " nbnd = ", a, " nspin = ", a, & 518 | + " nmodes = ", a)') trim(adjustl(s1)), trim(adjustl(s2)), & 519 | + trim(adjustl(s3)), trim(adjustl(s4)) 520 | + 521 | + if (nspin .eq. 1) then 522 | + wspin = 1.0d0 / degspin 523 | + else 524 | + wspin = 1.0d0 525 | + endif 526 | + 527 | + edge = (/edgev, edgec/) 528 | + step = (/stepv, stepc/) 529 | + nbin = (/nbinv, nbinc/) 530 | + nbinmax = maxval(nbin) 531 | + bpair = reshape((/ivmin, ivmax, icmin, icmax/), shape(bpair)) 532 | + do ii = 1, ngrid 533 | + if (bpair(1, ii) .lt. 1 .or. bpair(1, ii) .gt. nbnd) bpair(1, ii) = 1 534 | + if (bpair(2, ii) .lt. 1 .or. bpair(2, ii) .gt. nbnd) bpair(2, ii) = nbnd 535 | + enddo 536 | + if (ijob .eq. 1) then 537 | + allocate(gavg(nmodes, nbnd, nbnd, 1)) 538 | + allocate(gtot(1, 1, 1)) 539 | + elseif (ijob .eq. 2) then 540 | + allocate(gavg(nmodes, nbinmax, nbinmax, ngrid)) 541 | + allocate(gtot(nbinmax, nbinmax, ngrid)) 542 | + allocate(gnum(nbinmax, nbinmax, ngrid)) 543 | + allocate(egrid(2, ngrid, nbinmax)) 544 | + elseif (ijob .eq. 3) then 545 | + allocate(ghist(2, nbing, ngrid)) 546 | + allocate(gdist(4, ngmax, ngrid)) 547 | + allocate(egrid(2, ngrid, 1)) 548 | + endif 549 | + if (ijob .eq. 1 .or. ijob .eq. 2) then 550 | + allocate(wavg(nmodes)) 551 | + endif 552 | + if (ijob .eq. 2 .or. ijob .eq. 3) then 553 | + do ii = 1, ngrid 554 | + egrid(ii, ii, 1) = edge(ii) + step(ii) 555 | + egrid(ngrid + 1 - ii, ii, 1) = sum(edge) / ngrid 556 | + enddo 557 | + if (ijob .eq. 2 .and. nbinmax .gt. 1) then 558 | + do jj = 2, nbinmax 559 | + do ii = 1, ngrid 560 | + egrid(ii, ii, jj) = edge(ii) + step(ii) * jj 561 | + egrid(ngrid + 1 - ii, ii, jj) = edge(ii) + step(ii) * (jj - 1) 562 | + enddo 563 | + enddo 564 | + endif 565 | + egrid(:,:,:) = egrid(:,:,:) / rytoev 566 | + endif 567 | + 568 | + allocate(x_q(3, nqs)) 569 | + allocate(wq(nqs)) 570 | + allocate(w2(nmodes)) 571 | + allocate(dyn(nmodes, nmodes)) 572 | + allocate(irt(48, nat)) 573 | + allocate(rtau(3, 48, nat)) 574 | + allocate(u(nmodes, nmodes)) 575 | + allocate(el_ph_sum(nmodes, nmodes)) 576 | + read(uni) 577 | + read(uni) 578 | + read(uni) 579 | + read(uni) 580 | + read(uni) 581 | + read(uni) 582 | + read(uni) ((at(ii, jj), ii = 1, 3), jj = 1, 3) 583 | + read(uni) ((bg(ii, jj), ii = 1, 3), jj = 1, 3) 584 | + read(uni) 585 | + read(uni) 586 | + read(uni) 587 | + read(uni) ((x_q(ii, jj), ii = 1, 3), jj = 1, nqs) 588 | + read(uni) (wq(ii), ii = 1, nqs) 589 | + read(uni) 590 | + call cryst_to_cart(nqs, x_q, bg, 1) 591 | + 592 | + if (ijob .eq. 1 .or. ijob .eq. 2) then 593 | + gavg(:,:,:,:) = 0.0d0 594 | + wavg(:) = 0.0d0 595 | + gtot(:,:,:) = 0.0d0 596 | + wtot = 0.0d0 597 | + elseif (ijob .eq. 3) then 598 | + do ii = 1, ngrid 599 | + do jj = 1, nbing 600 | + ghist(1, jj, ii) = (jj - 1) * stepg 601 | + ghist(2, jj, ii) = 0.0d0 602 | + enddo 603 | + enddo 604 | + nhist(:) = 0 605 | + endif 606 | + if (ijob .eq. 2) gnum(:,:,:) = 0 607 | + do iq = 1, nqs 608 | + xq(:) = x_q(:, iq) 609 | + read(uni) nsymq, irotmq, ii, ii, nkstot, nksqtot 610 | + write(s1, '(i8)') iq 611 | + write(s2, '(i8)') nkstot 612 | + write(s3, '(i8)') nksqtot 613 | + write(6, '(" iq = ", a, " nkstot = ", a, " nksqtot = ", a)') & 614 | + trim(adjustl(s1)), trim(adjustl(s2)), trim(adjustl(s3)) 615 | + allocate(wk(nkstot)) 616 | + allocate(et(nbnd, nkstot)) 617 | + allocate(ikks(nksqtot)) 618 | + allocate(ikqs(nksqtot)) 619 | + allocate(el_ph_mat(nbnd, nbnd, nksqtot, nmodes)) 620 | + read(uni) minus_q 621 | + read(uni) 622 | + read(uni) 623 | + read(uni) (((rtau(ii, jj, kk), ii = 1, 3), jj = 1, 48), kk = 1, nat) 624 | + read(uni) 625 | + read(uni) 626 | + read(uni) ((u(ii, jj), ii = 1, nmodes), jj = 1, nmodes) 627 | + read(uni) 628 | + read(uni) 629 | + read(uni) 630 | + read(uni) 631 | + read(uni) (((s(ii, jj, kk), ii = 1, 3), jj = 1, 3), kk = 1, 48) 632 | + read(uni) (invs(ii), ii = 1, 48) 633 | + read(uni) 634 | + read(uni) 635 | + read(uni) 636 | + read(uni) 637 | + read(uni) 638 | + read(uni) ((irt(ii, jj), ii = 1, 48), jj = 1, nat) 639 | + read(uni) 640 | + read(uni) (wk(ii), ii = 1, nkstot) 641 | + read(uni) ((et(ii, jj), ii = 1, nbnd), jj = 1, nkstot) 642 | + read(uni) 643 | + read(uni) 644 | + read(uni) 645 | + read(uni) (ikks(ii), ii = 1, nksqtot) 646 | + read(uni) (ikqs(ii), ii = 1, nksqtot) 647 | + read(uni) 648 | + read(uni) (w2(ii), ii = 1, nmodes) 649 | + read(uni) ((dyn(ii, jj), ii = 1, nmodes), jj = 1, nmodes) 650 | + read(uni) ((((el_ph_mat(ii, jj, kk, ll), ii = 1, nbnd), & 651 | + jj = 1, nbnd), kk = 1, nksqtot), ll = 1, nmodes) 652 | + 653 | + if (ijob .eq. 1) then 654 | + do ibnd = 1, nbnd 655 | + do jbnd = 1, nbnd 656 | + el_ph_sum(:,:) = (0.0d0, 0.0d0) 657 | + do ik = 1, nksqtot 658 | + ikk = ikks(ik) 659 | + ikq = ikqs(ik) 660 | + weight = wq(iq) * wk(ikk) * wspin 661 | + if (ibnd .eq. 1 .and. jbnd .eq. 1) gtot(1, 1, 1) = & 662 | + gtot(1, 1, 1) + weight 663 | + do jpert = 1, nmodes 664 | + do ipert = 1, nmodes 665 | + el_ph_sum(ipert, jpert) = el_ph_sum(ipert, jpert) & 666 | + + conjg(el_ph_mat(jbnd, ibnd, ik, ipert)) & 667 | + * el_ph_mat(jbnd, ibnd, ik, jpert) * weight 668 | + enddo 669 | + enddo 670 | + enddo 671 | + call symdyn_munu_new(el_ph_sum, u, xq, s, invs, rtau, irt, & 672 | + at, bg, nsymq, nat, irotmq, minus_q) 673 | + do nu = 1, nmodes 674 | + if (w2(nu) > epsw2) then 675 | + factor = rytoev**2 / (2.0d0 * sqrt(w2(nu))) 676 | + else 677 | + factor = 0.0d0 678 | + endif 679 | + gbuf = 0.0d0 680 | + do mu = 1, nmodes 681 | + do vu = 1, nmodes 682 | + gbuf = gbuf + dble(conjg(dyn(mu, nu)) * & 683 | + el_ph_sum(mu, vu) * dyn(vu, nu)) 684 | + enddo 685 | + enddo 686 | + gavg(nu, jbnd, ibnd, 1) = gavg(nu, jbnd, ibnd, 1) + gbuf * factor 687 | + enddo 688 | + enddo 689 | + enddo 690 | + elseif (ijob .eq. 2) then 691 | + do ii = 1, ngrid 692 | + do jj = 1, nbin(ii) 693 | + do kk = 1, nbin(ii) 694 | + el_ph_sum(:,:) = (0.0d0, 0.0d0) 695 | + do ik = 1, nksqtot 696 | + ikk = ikks(ik) 697 | + ikq = ikqs(ik) 698 | + weight = wq(iq) * wk(ikk) * wspin 699 | + do ibnd = bpair(1, ii), bpair(2, ii) 700 | + if (et(ibnd, ikk) .gt. egrid(1, ii, jj) .and. & 701 | + et(ibnd, ikk) .le. egrid(2, ii, jj)) then 702 | + do jbnd = bpair(1, ii), bpair(2, ii) 703 | + if (et(jbnd, ikq) .gt. egrid(1, ii, kk) .and. & 704 | + et(jbnd, ikq) .le. egrid(2, ii, kk)) then 705 | + gnum(kk, jj, ii) = gnum(kk, jj, ii) + 1 706 | + gtot(kk, jj, ii) = gtot(kk, jj, ii) + weight 707 | + do jpert = 1, nmodes 708 | + do ipert = 1, nmodes 709 | + el_ph_sum(ipert, jpert) = el_ph_sum(ipert, jpert) & 710 | + + conjg(el_ph_mat(jbnd, ibnd, ik, ipert)) & 711 | + * el_ph_mat(jbnd, ibnd, ik, jpert) * weight 712 | + enddo 713 | + enddo 714 | + endif 715 | + enddo 716 | + endif 717 | + enddo 718 | + enddo 719 | + call symdyn_munu_new(el_ph_sum, u, xq, s, invs, rtau, irt, at, & 720 | + bg, nsymq, nat, irotmq, minus_q) 721 | + do nu = 1, nmodes 722 | + if (w2(nu) > epsw2) then 723 | + factor = rytoev**2 / (2.0d0 * sqrt(w2(nu))) 724 | + else 725 | + factor = 0.0d0 726 | + endif 727 | + gbuf = 0.0d0 728 | + do mu = 1, nmodes 729 | + do vu = 1, nmodes 730 | + gbuf = gbuf + dble(conjg(dyn(mu, nu)) * & 731 | + el_ph_sum(mu, vu) * dyn(vu, nu)) 732 | + enddo 733 | + enddo 734 | + gavg(nu, kk, jj, ii) = gavg(nu, kk, jj, ii) + gbuf * factor 735 | + enddo 736 | + enddo 737 | + enddo 738 | + enddo 739 | + elseif (ijob .eq. 3) then 740 | + do ii = 1, ngrid 741 | + do ik = 1, nksqtot 742 | + ikk = ikks(ik) 743 | + ikq = ikqs(ik) 744 | + weight = wq(iq) * wk(ikk) * wspin 745 | + do ibnd = bpair(1, ii), bpair(2, ii) 746 | + if (et(ibnd, ikk) .gt. egrid(1, ii, 1) .and. & 747 | + et(ibnd, ikk) .le. egrid(2, ii, 1)) then 748 | + do jbnd = bpair(1, ii), bpair(2, ii) 749 | + if (et(jbnd, ikq) .gt. egrid(1, ii, 1) .and. & 750 | + et(jbnd, ikq) .le. egrid(2, ii, 1)) then 751 | + do jpert = 1, nmodes 752 | + do ipert = 1, nmodes 753 | + el_ph_sum(ipert, jpert) = & 754 | + conjg(el_ph_mat(jbnd, ibnd, ik, ipert)) & 755 | + * el_ph_mat(jbnd, ibnd, ik, jpert) 756 | + enddo 757 | + enddo 758 | + call symdyn_munu_new(el_ph_sum, u, xq, s, invs, & 759 | + rtau, irt, at, bg, nsymq, nat, irotmq, minus_q) 760 | + gsum = 0.0d0 761 | + do nu = 1, nmodes 762 | + if (w2(nu) > epsw2) then 763 | + factor = rytoev**2 / (2.0d0 * sqrt(w2(nu))) 764 | + else 765 | + factor = 0.0d0 766 | + endif 767 | + gbuf = 0.0d0 768 | + do mu = 1, nmodes 769 | + do vu = 1, nmodes 770 | + gbuf = gbuf + dble(conjg(dyn(mu, nu)) * & 771 | + el_ph_sum(mu, vu) * dyn(vu, nu)) 772 | + enddo 773 | + enddo 774 | + gsum = gsum + gbuf * factor 775 | + enddo 776 | + jj = nint(abs(gsum) / stepg) 777 | + if (jj .ge. 1 .and. jj .le. nbing) then 778 | + ghist(2, jj, ii) = ghist(2, jj, ii) + weight / stepg 779 | + endif 780 | + nhist(ii) = nhist(ii) + 1 781 | + gdist(1, nhist(ii), ii) = et(ibnd, ikk) * rytoev - edge(ii) 782 | + gdist(2, nhist(ii), ii) = et(jbnd, ikq) * rytoev - edge(ii) 783 | + gdist(3, nhist(ii), ii) = gsum 784 | + gdist(4, nhist(ii), ii) = weight 785 | + endif 786 | + enddo 787 | + endif 788 | + enddo 789 | + enddo 790 | + enddo 791 | + endif 792 | + 793 | + if (ijob .eq. 1 .or. ijob .eq. 2) then 794 | + weight = wq(iq) 795 | + wtot = wtot + weight 796 | + do nu = 1, nmodes 797 | + if (w2(nu) > epsw2) then 798 | + wavg(nu) = wavg(nu) + weight * sqrt(w2(nu)) 799 | + endif 800 | + enddo 801 | + endif 802 | + 803 | + deallocate(wk) 804 | + deallocate(et) 805 | + deallocate(ikks) 806 | + deallocate(ikqs) 807 | + deallocate(el_ph_mat) 808 | + enddo 809 | + close(uni, status = 'keep') 810 | + 811 | + if (ijob .eq. 1) then 812 | + do ibnd = 1, nbnd 813 | + do jbnd = 1, nbnd 814 | + do nu = 1, nmodes 815 | + gavg(nu, jbnd, ibnd, 1) = gavg(nu, jbnd, ibnd, 1) / gtot(1, 1, 1) 816 | + enddo 817 | + enddo 818 | + enddo 819 | + elseif (ijob .eq. 2) then 820 | + do ii = 1, ngrid 821 | + do jj = 1, nbin(ii) 822 | + do kk = 1, nbin(ii) 823 | + if (gtot(kk, jj, ii) .gt. eps12) then 824 | + do nu = 1, nmodes 825 | + gavg(nu, kk, jj, ii) = gavg(nu, kk, jj, ii) / gtot(kk, jj, ii) 826 | + enddo 827 | + endif 828 | + enddo 829 | + enddo 830 | + enddo 831 | + endif 832 | + 833 | + if (ijob .eq. 1 .or. ijob .eq. 2) then 834 | + do nu = 1, nmodes 835 | + wavg(nu) = wavg(nu) * ry_to_cmm1 / wtot 836 | + enddo 837 | + endif 838 | + 839 | + if (ijob .eq. 2) then 840 | + write(fmt, '("(", i0, "(5x, ""e"", a, "" (eV)"", 4x, ""e"", a, ""''", & 841 | + " (eV)"", 3x, ""<|g"", a, ""|^2> (eV^2)"", 2x, ""count"", a, 5x,", & 842 | + " ""weight"", a))")') ngrid 843 | + write(6, fmt) ('v', ll = 1, 5), ('c', ll = 1, 5) 844 | + write(fmt, '("(", i0, "(2f12.6, e18.8, i8, f12.6))")') ngrid 845 | + do jj = 1, nbinmax 846 | + do kk = 1, nbinmax 847 | + write(6, fmt) ((jj - 0.5d0) * step(ii), (kk - 0.5d0) * step(ii), & 848 | + sum(gavg(:, kk, jj, ii)), gnum(kk, jj, ii), gtot(kk, jj, ii), & 849 | + ii = 1, ngrid) 850 | + enddo 851 | + enddo 852 | + endif 853 | + 854 | + open(uno, file = fout, form = 'formatted', status = 'replace') 855 | + write(6, '("Writing file ", a)') trim(fout) 856 | + if (ijob .eq. 1) then 857 | + write(uno, '(" mode (cm^-1)")') 858 | + write(uno, '("--------------------------")') 859 | + do nu = 1, nmodes 860 | + write(uno, '(i8, e18.8)') nu, wavg(nu) 861 | + enddo 862 | + write(uno, *) 863 | + write(uno, '(" band band mode <|g|^2> (eV^2)")') 864 | + write(uno, '("------------------------------------------")') 865 | + do ibnd = 1, nbnd 866 | + do jbnd = 1, nbnd 867 | + do nu = 1, nmodes 868 | + write(uno, '(3i8, e18.8)') ibnd, jbnd, nu, gavg(nu, jbnd, ibnd, 1) 869 | + enddo 870 | + enddo 871 | + enddo 872 | + elseif (ijob .eq. 2) then 873 | + write(uno, '(2i8)') ngrid, nmodes 874 | + do ii = 1, ngrid 875 | + write(uno, '(2f14.8, i8)') edge(ii), step(ii), nbin(ii) 876 | + enddo 877 | + write(fmt, '("(", i0, "e18.8)")') nmodes 878 | + write(uno, fmt) (wavg(nu), nu = 1, nmodes) 879 | + write(fmt, '("(3i8, ", i0, "e18.8)")') nmodes 880 | + do ii = 1, ngrid 881 | + do jj = 1, nbin(ii) 882 | + do kk = 1, nbin(ii) 883 | + write(uno, fmt) ii, jj, kk, (gavg(nu, kk, jj, ii), & 884 | + nu = 1, nmodes) 885 | + enddo 886 | + enddo 887 | + enddo 888 | + elseif (ijob .eq. 3) then 889 | + write(uno, '(i8)') nbing 890 | + do jj = 1, nbing 891 | + write(uno, '(f14.8, 2e18.8)') ghist(1, jj, 1), ghist(2, jj, 1), & 892 | + ghist(2, jj, 2) 893 | + enddo 894 | + write(uno, '(i8)') (nhist(ii), ii = 1, ngrid) 895 | + do ii = 1, ngrid 896 | + do jj = 1, nhist(ii) 897 | + write(uno, '(2f14.8, 2e18.8)') (gdist(kk, jj, ii), kk = 1, 4) 898 | + enddo 899 | + enddo 900 | + endif 901 | + close(uno, status = 'keep') 902 | + 903 | + if (ijob .eq. 1 .or. ijob .eq. 2) then 904 | + deallocate(gavg) 905 | + deallocate(gtot) 906 | + deallocate(wavg) 907 | + endif 908 | + if (ijob .eq. 2) deallocate(gnum) 909 | + if (ijob .eq. 3) then 910 | + deallocate(ghist) 911 | + deallocate(gdist) 912 | + endif 913 | + if (ijob .eq. 2 .or. ijob .eq. 3) deallocate(egrid) 914 | + deallocate(x_q) 915 | + deallocate(wq) 916 | + deallocate(w2) 917 | + deallocate(dyn) 918 | + deallocate(irt) 919 | + deallocate(rtau) 920 | + deallocate(u) 921 | + deallocate(el_ph_sum) 922 | + 923 | +end program epa 924 | +! 925 | +!---------------------------------------------------------------------------- 926 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/Makefile q-e-qe-6.2.1/PHonon/PH/Makefile 927 | --- q-e-qe-6.2.1_original/PHonon/PH/Makefile 2020-01-27 07:26:21.661514311 -0800 928 | +++ q-e-qe-6.2.1/PHonon/PH/Makefile 2020-01-27 07:27:44.386859438 -0800 929 | @@ -192,7 +192,7 @@ 930 | TLDEPS= bindir mods libs pw-lib lrmods 931 | 932 | all : tldeps libs-ph ph.x dynmat.x matdyn.x q2r.x q2trans.x q2trans_fd.x lambda.x fqha.x q2qstar.x \ 933 | - alpha2f.x 934 | + alpha2f.x epa.x 935 | 936 | libs-ph : libph.a libphaux.a 937 | 938 | @@ -242,6 +242,11 @@ 939 | $(PWOBJS) $(LRMODS) $(QEMODS) $(LIBOBJS) $(LIBS) 940 | - ( cd ../../bin ; ln -fs ../PHonon/PH/$@ . ) 941 | 942 | +epa.x : epa.o libph.a $(PWOBJS) $(LRMODS) $(QEMODS) $(LIBOBJS) 943 | + $(LD) $(LDFLAGS) -o $@ epa.o libph.a \ 944 | + $(PWOBJS) $(LRMODS) $(QEMODS) $(LIBOBJS) $(LIBS) 945 | + - ( cd ../../bin ; ln -fs ../PHonon/PH/$@ . ) 946 | + 947 | #fqha.o : 948 | # $(MPIF90) $(FFLAGS_NOOPT) -c fqha.f90 949 | 950 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/phq_readin.f90 q-e-qe-6.2.1/PHonon/PH/phq_readin.f90 951 | --- q-e-qe-6.2.1_original/PHonon/PH/phq_readin.f90 2020-01-27 07:26:21.661514311 -0800 952 | +++ q-e-qe-6.2.1/PHonon/PH/phq_readin.f90 2020-01-27 07:27:44.386859438 -0800 953 | @@ -68,7 +68,7 @@ 954 | USE cryst_ph, ONLY : magnetic_sym 955 | USE ph_restart, ONLY : ph_readfile 956 | USE xml_io_base, ONLY : create_directory 957 | - USE el_phon, ONLY : elph,elph_mat,elph_simple,elph_nbnd_min, elph_nbnd_max, & 958 | + USE el_phon, ONLY : elph,elph_mat,elph_simple,elph_epa,elph_nbnd_min, elph_nbnd_max, & 959 | el_ph_sigma, el_ph_nsigma, el_ph_ngauss,auxdvscf 960 | USE dfile_star, ONLY : drho_star, dvscf_star 961 | 962 | @@ -377,20 +377,29 @@ 963 | elph=.true. 964 | elph_mat=.false. 965 | elph_simple=.true. 966 | + elph_epa=.false. 967 | + CASE( 'epa' ) 968 | + elph=.true. 969 | + elph_mat=.false. 970 | + elph_simple=.false. 971 | + elph_epa=.true. 972 | CASE( 'Wannier' ) 973 | elph=.true. 974 | elph_mat=.true. 975 | elph_simple=.false. 976 | + elph_epa=.false. 977 | auxdvscf=trim(fildvscf) 978 | CASE( 'interpolated' ) 979 | elph=.true. 980 | elph_mat=.false. 981 | elph_simple=.false. 982 | + elph_epa=.false. 983 | ! YAMBO > 984 | CASE( 'yambo' ) 985 | elph=.true. 986 | elph_mat=.false. 987 | elph_simple=.false. 988 | + elph_epa=.false. 989 | elph_yambo=.true. 990 | nogg=.true. 991 | auxdvscf=trim(fildvscf) 992 | @@ -398,6 +407,7 @@ 993 | elph=.false. 994 | elph_mat=.false. 995 | elph_simple=.false. 996 | + elph_epa=.false. 997 | elph_yambo=.false. 998 | dvscf_yambo=.true. 999 | nogg=.true. 1000 | @@ -425,6 +435,7 @@ 1001 | elph=.false. 1002 | elph_mat=.false. 1003 | elph_simple=.false. 1004 | + elph_epa=.false. 1005 | END SELECT 1006 | ! YAMBO > 1007 | IF (.not.elph_yambo) then 1008 | diff -ur q-e-qe-6.2.1_original/PHonon/PH/q_points.f90 q-e-qe-6.2.1/PHonon/PH/q_points.f90 1009 | --- q-e-qe-6.2.1_original/PHonon/PH/q_points.f90 2020-01-27 07:26:21.661514311 -0800 1010 | +++ q-e-qe-6.2.1/PHonon/PH/q_points.f90 2020-01-27 07:27:44.386859438 -0800 1011 | @@ -11,7 +11,7 @@ 1012 | 1013 | USE kinds, only : dp 1014 | USE io_global, ONLY : stdout, ionode, ionode_id 1015 | - USE disp, ONLY : nq1, nq2, nq3, x_q, nqs, lgamma_iq 1016 | + USE disp, ONLY : nq1, nq2, nq3, x_q, nqs, lgamma_iq, wq 1017 | USE output, ONLY : fildyn 1018 | USE symm_base, ONLY : nsym, s, time_reversal, t_rev, invs 1019 | USE cell_base, ONLY : at, bg 1020 | @@ -25,7 +25,7 @@ 1021 | integer :: i, iq, ierr, iudyn = 26 1022 | logical :: exist_gamma, check, skip_equivalence=.FALSE. 1023 | logical, external :: check_q_points_sym 1024 | - real(DP), allocatable :: xq(:,:), wq(:) 1025 | + real(DP), allocatable :: xq(:,:), w_q(:) 1026 | 1027 | INTEGER :: nqmax 1028 | ! 1029 | @@ -37,20 +37,22 @@ 1030 | 1031 | nqmax= nq1 * nq2 * nq3 1032 | 1033 | - allocate (wq(nqmax)) 1034 | + allocate (w_q(nqmax)) 1035 | allocate (xq(3,nqmax)) 1036 | if(lshift_q) then 1037 | call kpoint_grid( nsym, time_reversal, skip_equivalence, s, t_rev, bg, nqmax,& 1038 | - & 1,1,1, nq1,nq2,nq3, nqs, xq, wq ) 1039 | + & 1,1,1, nq1,nq2,nq3, nqs, xq, w_q ) 1040 | else 1041 | call kpoint_grid( nsym, time_reversal, skip_equivalence, s, t_rev, bg, nqmax,& 1042 | - & 0,0,0, nq1,nq2,nq3, nqs, xq, wq ) 1043 | + & 0,0,0, nq1,nq2,nq3, nqs, xq, w_q ) 1044 | end if 1045 | + allocate(wq(nqs)) 1046 | allocate(x_q(3,nqs)) 1047 | allocate(lgamma_iq(nqs)) 1048 | + wq(:)=w_q(1:nqs) 1049 | x_q(:,:)=xq(:,1:nqs) 1050 | deallocate (xq) 1051 | - deallocate (wq) 1052 | + deallocate (w_q) 1053 | ! 1054 | ! Check if the Gamma point is one of the points and put 1055 | ! it in the first position (it should already be the first) 1056 | -------------------------------------------------------------------------------- /test/HfCoSb/Co.pbe-spn-rrkjus_psl.1.0.0.UPF.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/Co.pbe-spn-rrkjus_psl.1.0.0.UPF.gz -------------------------------------------------------------------------------- /test/HfCoSb/Hf.pbe-spn-rrkjus_psl.1.0.0.UPF.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/Hf.pbe-spn-rrkjus_psl.1.0.0.UPF.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.boltztrap.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.boltztrap.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.def.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.def.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.energy.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.energy.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.epa.e.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.epa.e.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.epa.in: -------------------------------------------------------------------------------- 1 | HfCoSb.epa.k 2 | HfCoSb.epa.e 3 | egrid 4 | 14.996300 -0.2 6 0 0 5 | 16.138700 0.2 6 0 0 6 | 0.0 0 0 7 | -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.epa.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.epa.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.intrans.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.intrans.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.ke0j.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.ke0j.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.nscf.in: -------------------------------------------------------------------------------- 1 | &CONTROL 2 | prefix = 'HfCoSb' 3 | calculation = 'nscf' 4 | verbosity = 'high' 5 | wf_collect = .false. 6 | tstress = .false. 7 | tprnfor = .false. 8 | outdir = '.' 9 | wfcdir = '.' 10 | pseudo_dir = '.' 11 | / 12 | &SYSTEM 13 | ibrav = 2 14 | a = 6.047079072 15 | nat = 3 16 | ntyp = 3 17 | nbnd = 44 18 | ecutwfc = 80.0 19 | ecutrho = 700.0 20 | occupations = 'smearing' 21 | smearing = 'mp' 22 | degauss = 0.01 23 | / 24 | &ELECTRONS 25 | electron_maxstep = 200 26 | conv_thr = 1.0d-10 27 | mixing_mode = 'plain' 28 | mixing_beta = 0.7 29 | mixing_ndim = 8 30 | diagonalization = 'david' 31 | diago_david_ndim = 4 32 | diago_full_acc = .true. 33 | / 34 | ATOMIC_SPECIES 35 | Hf 178.490 Hf.pbe-spn-rrkjus_psl.1.0.0.UPF 36 | Co 58.933 Co.pbe-spn-rrkjus_psl.1.0.0.UPF 37 | Sb 121.760 Sb.pbe-dn-rrkjus_psl.1.0.0.UPF 38 | ATOMIC_POSITIONS crystal 39 | Hf 0.500000000 0.500000000 0.500000000 40 | Co 0.250000000 0.250000000 0.250000000 41 | Sb 0.000000000 0.000000000 0.000000000 42 | K_POINTS automatic 43 | 48 48 48 0 0 0 44 | -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.nscf.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.nscf.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.outputtrans.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.outputtrans.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.ph1.in: -------------------------------------------------------------------------------- 1 | HfCoSb phonons k=888000 q=888000 2 | &inputph 3 | prefix = 'HfCoSb' 4 | outdir = '.' 5 | reduce_io = .true. 6 | tr2_ph = 1.0d-25 7 | niter_ph = 500 8 | alpha_mix(1) = 0.3d0 9 | trans = .true. 10 | fildyn = 'HfCoSb.dyn' 11 | fildvscf = 'dvscf' 12 | electron_phonon = '' 13 | ldisp = .true. 14 | nq1 = 8 15 | nq2 = 8 16 | nq3 = 8 17 | / 18 | -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.ph1.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.ph1.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.ph2.in: -------------------------------------------------------------------------------- 1 | HfCoSb phonons k=888000 q=888000 2 | &inputph 3 | prefix = 'HfCoSb' 4 | outdir = '.' 5 | reduce_io = .true. 6 | tr2_ph = 1.0d-25 7 | niter_ph = 500 8 | alpha_mix(1) = 0.3d0 9 | trans = .false. 10 | fildyn = 'HfCoSb.dyn' 11 | fildvscf = 'dvscf' 12 | electron_phonon = 'epa' 13 | ldisp = .true. 14 | nq1 = 8 15 | nq2 = 8 16 | nq3 = 8 17 | / 18 | -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.ph2.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.ph2.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.scf.in: -------------------------------------------------------------------------------- 1 | &CONTROL 2 | prefix = 'HfCoSb' 3 | calculation = 'scf' 4 | verbosity = 'high' 5 | wf_collect = .true. 6 | tstress = .true. 7 | tprnfor = .true. 8 | outdir = '.' 9 | wfcdir = '.' 10 | pseudo_dir = '.' 11 | / 12 | &SYSTEM 13 | ibrav = 2 14 | a = 6.047079072 15 | nat = 3 16 | ntyp = 3 17 | nbnd = 44 18 | ecutwfc = 80.0 19 | ecutrho = 700.0 20 | occupations = 'smearing' 21 | smearing = 'mp' 22 | degauss = 0.01 23 | / 24 | &ELECTRONS 25 | electron_maxstep = 200 26 | conv_thr = 1.0d-10 27 | mixing_mode = 'plain' 28 | mixing_beta = 0.7 29 | mixing_ndim = 8 30 | diagonalization = 'david' 31 | diago_david_ndim = 4 32 | diago_full_acc = .true. 33 | / 34 | ATOMIC_SPECIES 35 | Hf 178.490 Hf.pbe-spn-rrkjus_psl.1.0.0.UPF 36 | Co 58.933 Co.pbe-spn-rrkjus_psl.1.0.0.UPF 37 | Sb 121.760 Sb.pbe-dn-rrkjus_psl.1.0.0.UPF 38 | ATOMIC_POSITIONS crystal 39 | Hf 0.500000000 0.500000000 0.500000000 40 | Co 0.250000000 0.250000000 0.250000000 41 | Sb 0.000000000 0.000000000 0.000000000 42 | K_POINTS automatic 43 | 8 8 8 0 0 0 44 | -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.scf.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.scf.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.struct.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.struct.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.trace.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.trace.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb.transdos.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb.transdos.gz -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb_boltz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb_boltz.png -------------------------------------------------------------------------------- /test/HfCoSb/HfCoSb_tau.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/HfCoSb_tau.png -------------------------------------------------------------------------------- /test/HfCoSb/Sb.pbe-dn-rrkjus_psl.1.0.0.UPF.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/Sb.pbe-dn-rrkjus_psl.1.0.0.UPF.gz -------------------------------------------------------------------------------- /test/HfCoSb/plot_boltz.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import brave 3 | 4 | name = 'HfCoSb' 5 | ext = 'png' 6 | f1 = ['{0:s}.intrans'.format(name), '{0:s}.trace'.format(name)] 7 | f2 = '{0:s}_boltz.{1:s}'.format(name, ext) 8 | 9 | prop = ['sigma', 'seebeck', 'L'] 10 | scale = [1.0e-5, 1.0e6, 1.0e8] 11 | tauvc = None 12 | kappaelzeroj = False 13 | kappalatvalue = 2.0 14 | tempvalue = 0.0 15 | numelec = -0.06 16 | T_C2K = 273.15 17 | 18 | _kind = 'plot' 19 | _style = ['solid', 'None'] 20 | _color = ['red', 'none', 'none'] 21 | _label = 'EPA' 22 | 23 | xlim = [[0.0, 850.0], [0.0, 850.0], [0.0, 850.0]] 24 | xdel = [[200.0, 200.0], [200.0, 200.0], [200.0, 200.0]] 25 | xlabel = ['$T$ ($^\circ$C)', '$T$ ($^\circ$C)', '$T$ ($^\circ$C)'] 26 | ylim = [[0.0, 2.0], [0.0, 400.0], [0.0, 5.0]] 27 | ydel = [[0.5, 0.5], [100.0, 100.0], [1.0, 1.0]] 28 | ylabel = ['$\sigma$ (1/(m$\Omega$ cm))', 29 | '$S$ ($\mu$V/K)', 30 | '$L$ (10$^{-8}$ W$\Omega$/K$^2$)'] 31 | 32 | _fmt1 = 'Read {0:s} {1:s} ### numelec0 = {2:f} el/uc' 33 | _fmt2 = '{0:s} ${1:s} = {2:.2f}$' 34 | 35 | trn = brave.Transport() 36 | trn.read('boltztrap-out', f1, tauvc, kappaelzeroj) 37 | trn.model_kappalat(kappalatvalue, tempvalue) 38 | trn.calc_kappa() 39 | trn.calc_L() 40 | trn.calc_PF() 41 | trn.calc_ZT() 42 | numelec0 = trn.renorm_numelec() 43 | print(_fmt1.format(name, _label, numelec0)) 44 | 45 | data = [] 46 | kind = [] 47 | style = [] 48 | color = [] 49 | label = [] 50 | for jj in range(len(prop)): 51 | curve = np.empty((2, trn.ntemp), float) 52 | curve[0, :] = trn.temp - T_C2K 53 | curve[1, :] = trn.interpolate_binary(prop[jj], 'numelec', numelec) * scale[jj] 54 | data.append([curve]) 55 | kind.append([_kind]) 56 | style.append([_style]) 57 | color.append([_color]) 58 | label.append([_label]) 59 | 60 | if numelec < 0.0: 61 | doped = 'p' 62 | else: 63 | doped = 'n' 64 | title = _fmt2.format(name, doped, abs(numelec)) 65 | 66 | plt = brave.Plot() 67 | plt.data = data 68 | plt.kind = kind 69 | plt.style = style 70 | plt.color = color 71 | plt.label = label 72 | plt.legend = [['upper right', 1, None], 73 | ['upper left', 1, None], 74 | ['upper right', 1, None]] 75 | plt.xlim = xlim 76 | plt.ylim = ylim 77 | plt.xdel = xdel 78 | plt.ydel = ydel 79 | plt.xlabel = xlabel 80 | plt.ylabel = ylabel 81 | plt.note = [[[0.0, 1.02, 'left', 'bottom', ' (a) ' + title, 'black', 1.0]], 82 | [[0.0, 1.02, 'left', 'bottom', ' (b) ' + title, 'black', 1.0]], 83 | [[0.0, 1.02, 'left', 'bottom', ' (c) ' + title, 'black', 1.0]]] 84 | 85 | plt.pagesize = [6.0, 2.0] 86 | plt.fontsize = 8.0 87 | plt.linewidth = 0.7 88 | plt.markersize = 3.0 89 | plt.labelpad = [2.0, 2.0] 90 | plt.tickpad = [2.0, 2.0, 2.0, 2.0] 91 | plt.ticksize = [3.0, 1.5, 3.0, 1.5] 92 | plt.griddim = [1, 3] 93 | plt.gridpad = [0.5, 1.0, 1.0] 94 | plt.gridpos = [[0, 1, 0, 1], 95 | [0, 1, 1, 2], 96 | [0, 1, 2, 3]] 97 | 98 | plt.write('matplotlib', ext, f2) 99 | -------------------------------------------------------------------------------- /test/HfCoSb/plot_tau.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import brave 3 | 4 | name = 'HfCoSb' 5 | ext = 'png' 6 | f1 = ['{0:s}.intrans'.format(name), '{0:s}.trace'.format(name)] 7 | f2 = ['{0:s}.nscf.out'.format(name)] 8 | f3 = ['{0:s}.intrans'.format(name), '{0:s}.transdos'.format(name)] 9 | f4 = ['{0:s}.intrans'.format(name), '{0:s}.epa.e'.format(name)] 10 | f5 = '{0:s}_tau.{1:s}'.format(name, ext) 11 | 12 | title = '{0:s} ${1:s} = {2:.2f}$ $T = {3:d}^\circ$C' 13 | mode = [r'$\tau = {0:d}$ fs' , 'EPA'] 14 | tauvc = None 15 | kappaelzeroj = False 16 | numelec = -0.06 17 | T_C = 400.0 18 | T_C2K = 273.15 19 | T_K = T_C + T_C2K 20 | 21 | _fmt1 = 'Read {0:s} {1:s} ### numelec0 = {2:f} el/uc' 22 | _fmt2 = ' bandgap = {0:f} eV' 23 | 24 | trn = brave.Transport() 25 | trn.read('boltztrap-out', f1, tauvc, kappaelzeroj) 26 | numelec0 = trn.renorm_numelec() 27 | print(_fmt1.format(name, mode[1], numelec0)) 28 | 29 | bnd = brave.Energy() 30 | bnd.read('pw-out', f2) 31 | evbm, ecbm, kvbm, kcbm = bnd.calc_efermi() 32 | bandgap = ecbm - evbm 33 | print(_fmt2.format(bandgap)) 34 | 35 | epa = brave.EPA() 36 | epa.read('pw-out', f2) 37 | epa.read('boltztrap-dos', f3) 38 | epa.read('epa-out', f4) 39 | 40 | tau_epa = np.empty((2, trn.nmu), float) 41 | en = np.empty(trn.nmu, float) 42 | mu = np.empty(trn.nmu, float) 43 | temp = np.empty(trn.nmu, float) 44 | temp[:] = T_K 45 | mu[:] = trn.convert_argument('mu', [T_K, numelec]) 46 | en[:] = trn.mu[:] 47 | epa.energy = en 48 | epa.mu = mu 49 | epa.temp = temp 50 | epa.calc_invtau() 51 | tau_epa[0, :] = epa.energy 52 | tau_epa[1, :] = np.divide(1.0, np.maximum(epa.invtau * 1.0e-15, 1.0e-6)) 53 | 54 | _mu = trn.convert_argument('mu', [T_K, numelec]) 55 | mu = np.array([[_mu, _mu], [0.0, 120.0]], float) 56 | 57 | xx = bandgap / 2 58 | yy = 1.0e3 59 | gap = np.array([[-xx, -xx, xx, xx, -xx], [-yy, yy, yy, -yy, -yy]], float) 60 | 61 | if numelec < 0: 62 | doped = 'p' 63 | elif numelec > 0: 64 | doped = 'n' 65 | else: 66 | doped = 'x' 67 | 68 | plt = brave.Plot() 69 | plt.data = [[gap, tau_epa, mu]] 70 | plt.kind = [['fill', 'plot', 'plot']] 71 | plt.style = [[['None', 'None'], ['solid', 'None'], [(0, (2, 1)), 'None']]] 72 | plt.color = [[['0.75', 'none'], ['red', 'none', 'none'], ['black', 'none', 'none']]] 73 | plt.label = [['', mode[1], '']] 74 | plt.zorder = [[-3, -2, -1]] 75 | plt.xlim = [[-1.0, 1.0]] 76 | plt.ylim = [[0.0, 20.0]] 77 | plt.xdel = [[0.5, 0.5]] 78 | plt.ydel = [[5.0, 5.0]] 79 | plt.xlabel = ['Energy (eV)'] 80 | plt.ylabel = ['Relaxation time (fs)'] 81 | plt.note = [[[0.5, 1.02, 'center', 'bottom', title.format(name, doped, abs(numelec), int(round(T_C))), 'black', 1.0]]] 82 | 83 | plt.pagesize = [2.6, 2.7] 84 | plt.fontsize = 8.0 85 | plt.linewidth = 0.7 86 | plt.markersize = 3.0 87 | plt.labelpad = [2.0, 2.0] 88 | plt.tickpad = [2.0, 2.0, 2.0, 2.0] 89 | plt.ticksize = [3.0, 1.5, 3.0, 1.5] 90 | 91 | plt.write('matplotlib', ext, f5) 92 | -------------------------------------------------------------------------------- /test/HfCoSb/qe2boltz.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/HfCoSb/qe2boltz.out.gz -------------------------------------------------------------------------------- /test/HfCoSb/qe2boltz.py: -------------------------------------------------------------------------------- 1 | import brave 2 | 3 | name = 'HfCoSb' 4 | f1 = ['{0:s}.nscf.out'.format(name)] 5 | f2 = ['{0:s}.def'.format(name), '{0:s}.intrans'.format(name), '{0:s}.struct'.format(name), '{0:s}.energy'.format(name)] 6 | 7 | bnd = brave.Energy() 8 | bnd.read('pw-out', f1) 9 | 10 | # For insulators, set the Fermi level in the middle of the band gap !!!! DO NOT TRY THIS FOR METALS !!!! 11 | evbm, ecbm, kvbm, kcbm = bnd.calc_efermi() 12 | egap = ecbm - evbm 13 | ss = '{0:s} nelec = {1:.2f} evbm = {2:.6f} ecbm = {3:.6f} egap = {4:.6f} efermi = {5:.6f} kvbm = {6[0]:.3f} {6[1]:.3f} {6[2]:.3f} kcbm = {7[0]:.3f} {7[1]:.3f} {7[2]:.3f}'.format( 14 | name, bnd.nelec, evbm, ecbm, egap, bnd.efermi, kvbm, kcbm) 15 | print(ss) 16 | 17 | # For metals, don't mess with the Fermi level 18 | #ss = '{0:s} nelec = {1:.2f} efermi = {2:.6f}'.format(name, bnd.nelec, bnd.efermi) 19 | #print(ss) 20 | 21 | bnd.write('boltztrap-in', f2) 22 | -------------------------------------------------------------------------------- /test/HfCoSb/submit1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # epa.x dies with I/O errors when ph.x is run with buffered I/O 4 | unset FORT_BUFFERED 5 | unset FORT_BLOCKSIZE 6 | unset FORT_BUFFERCOUNT 7 | 8 | NPOOL=20 9 | MPI="mpirun" 10 | PW="q-e-qe-6.8/bin/pw.x" 11 | PH="q-e-qe-6.8/bin/ph.x" 12 | 13 | $MPI $PW -npool $NPOOL < HfCoSb.scf.in > HfCoSb.scf.out 14 | $MPI $PH -npool $NPOOL < HfCoSb.ph1.in > HfCoSb.ph1.out 15 | $MPI $PH -npool $NPOOL < HfCoSb.ph2.in > HfCoSb.ph2.out 16 | $MPI $PW -npool $NPOOL < HfCoSb.nscf.in > HfCoSb.nscf.out 17 | rm HfCoSb.wfc* 18 | -------------------------------------------------------------------------------- /test/HfCoSb/submit2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | EPA="q-e-qe-6.8/bin/epa.x" 4 | PYTHON="python3" 5 | BOLTZTRAP="boltztrap-1.2.5/src/BoltzTraP" 6 | 7 | $EPA < HfCoSb.epa.in > HfCoSb.epa.out 8 | $PYTHON qe2boltz.py > qe2boltz.out 9 | $BOLTZTRAP HfCoSb.def > HfCoSb.boltztrap.out 10 | -------------------------------------------------------------------------------- /test/silicon/Si.bhs.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/Si.bhs.gz -------------------------------------------------------------------------------- /test/silicon/plot_boltz.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import brave 3 | 4 | name = 'silicon' 5 | ext = 'png' 6 | f1 = ['{0:s}.intrans'.format(name), '{0:s}.trace'.format(name)] 7 | f2 = '{0:s}_boltz.{1:s}'.format(name, ext) 8 | 9 | prop = ['sigma', 'seebeck', 'L'] 10 | scale = [1.0e-5, 1.0e6, 1.0e8] 11 | tauvc = None 12 | kappaelzeroj = False 13 | kappalatvalue = 2.0 14 | tempvalue = 0.0 15 | numelec = -0.01 16 | T_C2K = 273.15 17 | 18 | _kind = 'plot' 19 | _style = ['solid', 'None'] 20 | _color = ['red', 'none', 'none'] 21 | _label = 'EPA' 22 | 23 | xlim = [[0.0, 850.0], [0.0, 850.0], [0.0, 850.0]] 24 | xdel = [[200.0, 200.0], [200.0, 200.0], [200.0, 200.0]] 25 | xlabel = ['$T$ ($^\circ$C)', '$T$ ($^\circ$C)', '$T$ ($^\circ$C)'] 26 | ylim = [[0.0, 10.0], [0.0, 200.0], [0.0, 5.0]] 27 | ydel = [[2.0, 2.0], [50.0, 50.0], [1.0, 1.0]] 28 | ylabel = ['$\sigma$ (1/(m$\Omega$ cm))', 29 | '$S$ ($\mu$V/K)', 30 | '$L$ (10$^{-8}$ W$\Omega$/K$^2$)'] 31 | 32 | _fmt1 = 'Read {0:s} {1:s} ### numelec0 = {2:f} el/uc' 33 | _fmt2 = '{0:s} ${1:s} = {2:.2f}$' 34 | 35 | trn = brave.Transport() 36 | trn.read('boltztrap-out', f1, tauvc, kappaelzeroj) 37 | trn.model_kappalat(kappalatvalue, tempvalue) 38 | trn.calc_kappa() 39 | trn.calc_L() 40 | trn.calc_PF() 41 | trn.calc_ZT() 42 | numelec0 = trn.renorm_numelec() 43 | print(_fmt1.format(name, _label, numelec0)) 44 | 45 | data = [] 46 | kind = [] 47 | style = [] 48 | color = [] 49 | label = [] 50 | for jj in range(len(prop)): 51 | curve = np.empty((2, trn.ntemp), float) 52 | curve[0, :] = trn.temp - T_C2K 53 | curve[1, :] = trn.interpolate_binary(prop[jj], 'numelec', numelec) * scale[jj] 54 | data.append([curve]) 55 | kind.append([_kind]) 56 | style.append([_style]) 57 | color.append([_color]) 58 | label.append([_label]) 59 | 60 | if numelec < 0.0: 61 | doped = 'p' 62 | else: 63 | doped = 'n' 64 | title = _fmt2.format(name, doped, abs(numelec)) 65 | 66 | plt = brave.Plot() 67 | plt.data = data 68 | plt.kind = kind 69 | plt.style = style 70 | plt.color = color 71 | plt.label = label 72 | plt.legend = [['upper right', 1, None], 73 | ['upper left', 1, None], 74 | ['upper right', 1, None]] 75 | plt.xlim = xlim 76 | plt.ylim = ylim 77 | plt.xdel = xdel 78 | plt.ydel = ydel 79 | plt.xlabel = xlabel 80 | plt.ylabel = ylabel 81 | plt.note = [[[0.0, 1.02, 'left', 'bottom', ' (a) ' + title, 'black', 1.0]], 82 | [[0.0, 1.02, 'left', 'bottom', ' (b) ' + title, 'black', 1.0]], 83 | [[0.0, 1.02, 'left', 'bottom', ' (c) ' + title, 'black', 1.0]]] 84 | 85 | plt.pagesize = [6.0, 2.0] 86 | plt.fontsize = 8.0 87 | plt.linewidth = 0.7 88 | plt.markersize = 3.0 89 | plt.labelpad = [2.0, 2.0] 90 | plt.tickpad = [2.0, 2.0, 2.0, 2.0] 91 | plt.ticksize = [3.0, 1.5, 3.0, 1.5] 92 | plt.griddim = [1, 3] 93 | plt.gridpad = [0.5, 1.0, 1.0] 94 | plt.gridpos = [[0, 1, 0, 1], 95 | [0, 1, 1, 2], 96 | [0, 1, 2, 3]] 97 | 98 | plt.write('matplotlib', ext, f2) 99 | -------------------------------------------------------------------------------- /test/silicon/plot_tau.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import brave 3 | 4 | name = 'silicon' 5 | ext = 'png' 6 | f1 = ['{0:s}.intrans'.format(name), '{0:s}.trace'.format(name)] 7 | f2 = ['{0:s}.nscf.out'.format(name)] 8 | f3 = ['{0:s}.intrans'.format(name), '{0:s}.transdos'.format(name)] 9 | f4 = ['{0:s}.intrans'.format(name), '{0:s}.epa.e'.format(name)] 10 | f5 = '{0:s}_tau.{1:s}'.format(name, ext) 11 | 12 | title = '{0:s} ${1:s} = {2:.2f}$ $T = {3:d}$K' 13 | mode = [r'$\tau = {0:d}$ fs' , 'EPA'] 14 | tauvc = None 15 | kappaelzeroj = False 16 | numelec = 0.0 17 | T_K = 300.0 18 | 19 | _fmt1 = 'Read {0:s} {1:s} ### numelec0 = {2:f} el/uc' 20 | _fmt2 = ' bandgap = {0:f} eV' 21 | 22 | trn = brave.Transport() 23 | trn.read('boltztrap-out', f1, tauvc, kappaelzeroj) 24 | numelec0 = trn.renorm_numelec() 25 | print(_fmt1.format(name, mode[1], numelec0)) 26 | 27 | bnd = brave.Energy() 28 | bnd.read('pw-out', f2) 29 | evbm, ecbm, kvbm, kcbm = bnd.calc_efermi() 30 | bandgap = ecbm - evbm 31 | print(_fmt2.format(bandgap)) 32 | 33 | epa = brave.EPA() 34 | epa.read('pw-out', f2) 35 | epa.read('boltztrap-dos', f3) 36 | epa.read('epa-out', f4) 37 | 38 | tau_epa = np.empty((2, trn.nmu), float) 39 | en = np.empty(trn.nmu, float) 40 | mu = np.empty(trn.nmu, float) 41 | temp = np.empty(trn.nmu, float) 42 | temp[:] = T_K 43 | mu[:] = trn.convert_argument('mu', [T_K, numelec]) 44 | en[:] = trn.mu[:] 45 | epa.energy = en 46 | epa.mu = mu 47 | epa.temp = temp 48 | epa.calc_invtau() 49 | tau_epa[0, :] = epa.energy 50 | tau_epa[1, :] = np.divide(1.0, np.maximum(epa.invtau * 1.0e-15, 1.0e-6)) 51 | 52 | _mu = trn.convert_argument('mu', [T_K, numelec]) 53 | mu = np.array([[_mu, _mu], [0.0, 120.0]], float) 54 | 55 | xx = bandgap / 2 56 | yy = 1.0e3 57 | gap = np.array([[-xx, -xx, xx, xx, -xx], [-yy, yy, yy, -yy, -yy]], float) 58 | 59 | if numelec < 0: 60 | doped = 'p' 61 | elif numelec > 0: 62 | doped = 'n' 63 | else: 64 | doped = 'x' 65 | 66 | plt = brave.Plot() 67 | plt.data = [[gap, tau_epa, mu]] 68 | plt.kind = [['fill', 'plot', 'plot']] 69 | plt.style = [[['None', 'None'], ['solid', 'None'], [(0, (2, 1)), 'None']]] 70 | plt.color = [[['0.75', 'none'], ['red', 'none', 'none'], ['black', 'none', 'none']]] 71 | plt.label = [['', mode[1], '']] 72 | plt.zorder = [[-3, -2, -1]] 73 | plt.xlim = [[-4.0, 4.0]] 74 | plt.ylim = [[0.0, 120.0]] 75 | plt.xdel = [[1.0, 1.0]] 76 | plt.ydel = [[20.0, 20.0]] 77 | plt.xlabel = ['Energy (eV)'] 78 | plt.ylabel = ['Relaxation time (fs)'] 79 | plt.note = [[[0.5, 1.02, 'center', 'bottom', title.format(name, doped, abs(numelec), int(round(T_K))), 'black', 1.0]]] 80 | 81 | plt.pagesize = [2.6, 2.7] 82 | plt.fontsize = 8.0 83 | plt.linewidth = 0.7 84 | plt.markersize = 3.0 85 | plt.labelpad = [2.0, 2.0] 86 | plt.tickpad = [2.0, 2.0, 2.0, 2.0] 87 | plt.ticksize = [3.0, 1.5, 3.0, 1.5] 88 | 89 | plt.write('matplotlib', ext, f5) 90 | -------------------------------------------------------------------------------- /test/silicon/qe2boltz.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/qe2boltz.out.gz -------------------------------------------------------------------------------- /test/silicon/qe2boltz.py: -------------------------------------------------------------------------------- 1 | import brave 2 | 3 | name = 'silicon' 4 | f1 = ['{0:s}.nscf.out'.format(name)] 5 | f2 = ['{0:s}.def'.format(name), '{0:s}.intrans'.format(name), '{0:s}.struct'.format(name), '{0:s}.energy'.format(name)] 6 | 7 | bnd = brave.Energy() 8 | bnd.read('pw-out', f1) 9 | 10 | # For insulators, set the Fermi level in the middle of the band gap !!!! DO NOT TRY THIS FOR METALS !!!! 11 | evbm, ecbm, kvbm, kcbm = bnd.calc_efermi() 12 | egap = ecbm - evbm 13 | ss = '{0:s} nelec = {1:.2f} evbm = {2:.6f} ecbm = {3:.6f} egap = {4:.6f} efermi = {5:.6f} kvbm = {6[0]:.3f} {6[1]:.3f} {6[2]:.3f} kcbm = {7[0]:.3f} {7[1]:.3f} {7[2]:.3f}'.format( 14 | name, bnd.nelec, evbm, ecbm, egap, bnd.efermi, kvbm, kcbm) 15 | print(ss) 16 | 17 | # For metals, don't mess with the Fermi level 18 | #ss = '{0:s} nelec = {1:.2f} efermi = {2:.6f}'.format(name, bnd.nelec, bnd.efermi) 19 | #print(ss) 20 | 21 | bnd.write('boltztrap-in', f2) 22 | -------------------------------------------------------------------------------- /test/silicon/silicon.boltztrap.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.boltztrap.out.gz -------------------------------------------------------------------------------- /test/silicon/silicon.def.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.def.gz -------------------------------------------------------------------------------- /test/silicon/silicon.energy.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.energy.gz -------------------------------------------------------------------------------- /test/silicon/silicon.epa.e.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.epa.e.gz -------------------------------------------------------------------------------- /test/silicon/silicon.epa.in: -------------------------------------------------------------------------------- 1 | silicon.epa.k 2 | silicon.epa.e 3 | egrid 4 | 6.146000 -0.4 10 0 0 5 | 6.602500 0.4 10 0 0 6 | 0.0 0 0 7 | -------------------------------------------------------------------------------- /test/silicon/silicon.epa.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.epa.out.gz -------------------------------------------------------------------------------- /test/silicon/silicon.intrans.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.intrans.gz -------------------------------------------------------------------------------- /test/silicon/silicon.ke0j.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.ke0j.gz -------------------------------------------------------------------------------- /test/silicon/silicon.nscf.in: -------------------------------------------------------------------------------- 1 | &control 2 | prefix = 'silicon' 3 | calculation = 'nscf' 4 | verbosity = 'high' 5 | wf_collect = .false. 6 | tstress = .false. 7 | tprnfor = .false. 8 | outdir = '.' 9 | wfcdir = '.' 10 | pseudo_dir = '.' 11 | / 12 | &system 13 | ibrav = 0 14 | a = 5.4 15 | nat = 2 16 | ntyp = 1 17 | nbnd = 33 18 | ecutwfc = 45.0 19 | occupations = 'smearing' 20 | smearing = 'mp' 21 | degauss = 0.01 22 | / 23 | &electrons 24 | electron_maxstep = 100 25 | conv_thr = 1.0d-10 26 | mixing_mode = 'plain' 27 | mixing_beta = 0.7 28 | mixing_ndim = 8 29 | diagonalization = 'david' 30 | diago_david_ndim = 4 31 | diago_full_acc = .true. 32 | startingwfc = 'random' 33 | / 34 | CELL_PARAMETERS alat 35 | 0.000000000 0.500000000 0.500000000 36 | 0.500000000 0.000000000 0.500000000 37 | 0.500000000 0.500000000 0.000000000 38 | ATOMIC_SPECIES 39 | Si 28.086 Si.bhs 40 | ATOMIC_POSITIONS crystal 41 | Si -0.125000000 -0.125000000 -0.125000000 42 | Si 0.125000000 0.125000000 0.125000000 43 | K_POINTS automatic 44 | 48 48 48 0 0 0 45 | -------------------------------------------------------------------------------- /test/silicon/silicon.nscf.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.nscf.out.gz -------------------------------------------------------------------------------- /test/silicon/silicon.outputtrans.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.outputtrans.gz -------------------------------------------------------------------------------- /test/silicon/silicon.ph1.in: -------------------------------------------------------------------------------- 1 | silicon phonons k=888000 q=888000 2 | &inputph 3 | prefix = 'silicon' 4 | outdir = '.' 5 | reduce_io = .true. 6 | tr2_ph = 1.0d-25 7 | niter_ph = 500 8 | alpha_mix(1) = 0.3d0 9 | trans = .true. 10 | fildyn = 'silicon.dyn' 11 | fildvscf = 'dvscf' 12 | electron_phonon = '' 13 | ldisp = .true. 14 | nq1 = 8 15 | nq2 = 8 16 | nq3 = 8 17 | / 18 | -------------------------------------------------------------------------------- /test/silicon/silicon.ph1.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.ph1.out.gz -------------------------------------------------------------------------------- /test/silicon/silicon.ph2.in: -------------------------------------------------------------------------------- 1 | silicon phonons k=888000 q=888000 2 | &inputph 3 | prefix = 'silicon' 4 | outdir = '.' 5 | reduce_io = .true. 6 | tr2_ph = 1.0d-25 7 | niter_ph = 500 8 | alpha_mix(1) = 0.3d0 9 | trans = .false. 10 | fildyn = 'silicon.dyn' 11 | fildvscf = 'dvscf' 12 | electron_phonon = 'epa' 13 | ldisp = .true. 14 | nq1 = 8 15 | nq2 = 8 16 | nq3 = 8 17 | / 18 | -------------------------------------------------------------------------------- /test/silicon/silicon.ph2.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.ph2.out.gz -------------------------------------------------------------------------------- /test/silicon/silicon.scf.in: -------------------------------------------------------------------------------- 1 | &control 2 | prefix = 'silicon' 3 | calculation = 'scf' 4 | verbosity = 'high' 5 | wf_collect = .true. 6 | tstress = .true. 7 | tprnfor = .true. 8 | outdir = '.' 9 | wfcdir = '.' 10 | pseudo_dir = '.' 11 | / 12 | &system 13 | ibrav = 0 14 | a = 5.4 15 | nat = 2 16 | ntyp = 1 17 | nbnd = 33 18 | ecutwfc = 45.0 19 | occupations = 'smearing' 20 | smearing = 'mp' 21 | degauss = 0.01 22 | / 23 | &electrons 24 | electron_maxstep = 100 25 | conv_thr = 1.0d-10 26 | mixing_mode = 'plain' 27 | mixing_beta = 0.7 28 | mixing_ndim = 8 29 | diagonalization = 'david' 30 | diago_david_ndim = 4 31 | diago_full_acc = .true. 32 | startingwfc = 'random' 33 | / 34 | CELL_PARAMETERS alat 35 | 0.000000000 0.500000000 0.500000000 36 | 0.500000000 0.000000000 0.500000000 37 | 0.500000000 0.500000000 0.000000000 38 | ATOMIC_SPECIES 39 | Si 28.086 Si.bhs 40 | ATOMIC_POSITIONS crystal 41 | Si -0.125000000 -0.125000000 -0.125000000 42 | Si 0.125000000 0.125000000 0.125000000 43 | K_POINTS automatic 44 | 8 8 8 0 0 0 45 | -------------------------------------------------------------------------------- /test/silicon/silicon.scf.out.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.scf.out.gz -------------------------------------------------------------------------------- /test/silicon/silicon.struct.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.struct.gz -------------------------------------------------------------------------------- /test/silicon/silicon.trace.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.trace.gz -------------------------------------------------------------------------------- /test/silicon/silicon.transdos.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon.transdos.gz -------------------------------------------------------------------------------- /test/silicon/silicon_boltz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon_boltz.png -------------------------------------------------------------------------------- /test/silicon/silicon_tau.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon/silicon_tau.png -------------------------------------------------------------------------------- /test/silicon/submit1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # epa.x dies with I/O errors when ph.x is run with buffered I/O 4 | unset FORT_BUFFERED 5 | unset FORT_BLOCKSIZE 6 | unset FORT_BUFFERCOUNT 7 | 8 | NPOOL=20 9 | MPI="mpirun" 10 | PW="q-e-qe-6.8/bin/pw.x" 11 | PH="q-e-qe-6.8/bin/ph.x" 12 | 13 | $MPI $PW -npool $NPOOL < silicon.scf.in > silicon.scf.out 14 | $MPI $PH -npool $NPOOL < silicon.ph1.in > silicon.ph1.out 15 | $MPI $PH -npool $NPOOL < silicon.ph2.in > silicon.ph2.out 16 | $MPI $PW -npool $NPOOL < silicon.nscf.in > silicon.nscf.out 17 | rm silicon.wfc* 18 | -------------------------------------------------------------------------------- /test/silicon/submit2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | EPA="q-e-qe-6.8/bin/epa.x" 4 | PYTHON="python3" 5 | BOLTZTRAP="boltztrap-1.2.5/src/BoltzTraP" 6 | 7 | $EPA < silicon.epa.in > silicon.epa.out 8 | $PYTHON qe2boltz.py > qe2boltz.out 9 | $BOLTZTRAP silicon.def > silicon.boltztrap.out 10 | -------------------------------------------------------------------------------- /test/silicon2/README.md: -------------------------------------------------------------------------------- 1 | ## BoltzTraP2 example for silicon 2 | 3 | ### Input files 4 | 5 | | File name | Origin | Modification | 6 | |-----------------------|-------------------------------|----------------------------------| 7 | | **silicon.structure** | **../silicon/silicon.struct** | Substantial | 8 | | **silicon.energy** | **../silicon/silicon.energy** | Added nspin & efermi in 2nd line | 9 | | **silicon.epa.e** | **../silicon/silicon.epa.e** | None | 10 | 11 | ### Output files 12 | 13 | | File name | Produced by | Method | 14 | |--------------------------|-----------------------|--------| 15 | | **silicon_crt.trace** | **silicon_crt.py** | CRT | 16 | | **silicon_crt.condtens** | **silicon_crt.py** | CRT | 17 | | **silicon_epa.trace** | **silicon_epa.py** | EPA | 18 | | **silicon_epa.condtens** | **silicon_epa.py** | EPA | 19 | 20 | -------------------------------------------------------------------------------- /test/silicon2/silicon.energy.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon2/silicon.energy.gz -------------------------------------------------------------------------------- /test/silicon2/silicon.epa.e.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon2/silicon.epa.e.gz -------------------------------------------------------------------------------- /test/silicon2/silicon.structure.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mir-group/EPA/9f3a4eb1d513b74288af8911320859ed38689cd1/test/silicon2/silicon.structure.gz -------------------------------------------------------------------------------- /test/silicon2/silicon_crt.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from BoltzTraP2 import dft 4 | from BoltzTraP2 import sphere 5 | from BoltzTraP2 import fite 6 | from BoltzTraP2 import bandlib 7 | from BoltzTraP2 import units 8 | 9 | dirname = './' 10 | ftr = dirname + 'silicon_crt.trace' 11 | fct = dirname + 'silicon_crt.condtens' 12 | RYDBERG = 0.5 13 | #doping_level = 0.01 14 | tau = 1.0e-14 15 | 16 | ecut, efcut, deltae, tmax, deltat, lpfac = 1.0 * RYDBERG, 0.3 * RYDBERG, 0.0005 * RYDBERG, 1200.0, 10.0, 5 17 | 18 | # Load the input 19 | data = dft.DFTData(dirname) 20 | # Select the interesting bands 21 | data.bandana(emin=data.fermi - ecut, emax=data.fermi + ecut) 22 | # Set up a k point grid with roughly five times the density of the input 23 | equivalences = sphere.get_equivalences(data.atoms, data.magmom, len(data.kpoints) * lpfac) 24 | # Perform the interpolation 25 | coeffs = fite.fitde3D(data, equivalences) 26 | 27 | lattvec = data.get_lattvec() 28 | eband, vvband, cband = fite.getBTPbands(equivalences, coeffs, lattvec) 29 | epsilon, dos, vvdos, cdos = bandlib.BTPDOS(eband, vvband, erange=[data.fermi - ecut, data.fermi + ecut], npts=round(2 * ecut / deltae), scattering_model='uniform_tau') 30 | 31 | # Define the temperatures and chemical potentials we are interested in 32 | Tr = np.arange(deltat, tmax + deltat / 2, deltat) 33 | mur_indices = np.logical_and(epsilon > data.fermi - efcut, epsilon < data.fermi + efcut) 34 | mur = epsilon[mur_indices] 35 | 36 | # Set different chemical potentials at each temperature corresponding to the constant doping level 37 | #Tr = np.arange(deltat, tmax + deltat / 2, deltat) 38 | #mur = np.empty_like(Tr) 39 | #_nelect = data.nelect 40 | #for iT, T in enumerate(Tr): 41 | # mur[iT] = bandlib.solve_for_mu(epsilon, dos, _nelect - doping_level, T, data.dosweight, refine=True) 42 | 43 | # Obtain the Fermi integrals required to get the Onsager coefficients 44 | (N, L0, L1, L2, Lm11) = bandlib.fermiintegrals(epsilon, dos, vvdos, mur=mur, Tr=Tr, dosweight=data.dosweight, cdos=cdos) 45 | #N += data.nelect # incorrect because of missing states due to ecut and efcut 46 | # ??? N -= N[0, round(N.shape[1] / 2)] # zero doping at low T in the middle of the band gap 47 | volume = data.get_volume() 48 | # Translate those into Onsager coefficients 49 | (sigma, seebeck, kappa, Hall) = bandlib.calc_Onsager_coefficients(L0, L1, L2, mur, Tr, volume, Lm11) 50 | 51 | # Rescale the carrier count into a volumetric density in cm^-3 52 | #N = -N / (volume / (units.Meter / 100) ** 3) 53 | # Transform the transport coefficients to more convenient units 54 | sigma *= tau * 1e-5 # kS / cm 55 | seebeck *= 1e6 # uV / K 56 | kappa *= tau * 1e-2 # W / cm / K 57 | # Obtain the scalar conductivity and Seebeck coefficient 58 | sigmatr = sigma.trace(axis1=2, axis2=3) / 3 59 | seebecktr = seebeck.trace(axis1=2, axis2=3) / 3 60 | kappatr = kappa.trace(axis1=2, axis2=3) / 3 61 | # Compute the scalar power factor 62 | #P = sigmatr * seebecktr * seebecktr 63 | #P *= 1e4 # uW / cm / K^2 64 | #lorenz = 1e5 * kappatr / (sigmatr * Tr) # 10^-8 W Ohm / K^2 65 | 66 | h = open(ftr, 'w') 67 | h.write('# Ef[Ry] T [K] N DOS(Ef) S s/t R_H kappa0 c chi\n') 68 | for imu, mu in enumerate(mur): 69 | for iT, T in enumerate(Tr): 70 | h.write(('{:10.5f}{:10.4f}' + '{:16.8f}' * 8 + '\n').format( 71 | mu / RYDBERG, T, N[iT, imu], 0.0, seebecktr[iT, imu], sigmatr[iT, imu], 0.0, kappatr[iT, imu], 0.0, 0.0)) 72 | h.close() 73 | 74 | h = open(fct, 'w') 75 | h.write('# Ef[Ry] T [K] N cond(x,x\')' + ' ' * 130 + 'seebeck(x,x\')' + ' ' * 131 + 'kappa0(x,x\')\n') 76 | for imu, mu in enumerate(mur): 77 | for iT, T in enumerate(Tr): 78 | h.write(('{:10.5f}{:10.4f}' + '{:16.8f}' * 27 + '\n').format( 79 | mu / RYDBERG, T, *tuple(sigma[iT].flatten()), *tuple(seebeck[iT].flatten()), *tuple(kappa[iT].flatten()))) 80 | h.close() 81 | -------------------------------------------------------------------------------- /test/silicon2/silicon_epa.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from BoltzTraP2 import dft 4 | from BoltzTraP2 import sphere 5 | from BoltzTraP2 import fite 6 | from BoltzTraP2 import bandlib 7 | from BoltzTraP2 import units 8 | 9 | dirname = './' 10 | fepa = dirname + 'silicon.epa.e' 11 | ftr = dirname + 'silicon_epa.trace' 12 | fct = dirname + 'silicon_epa.condtens' 13 | RYDBERG = 0.5 14 | #doping_level = 0.01 15 | 16 | ecut, efcut, deltae, tmax, deltat, lpfac = 1.0 * RYDBERG, 0.3 * RYDBERG, 0.0005 * RYDBERG, 1200.0, 10.0, 5 17 | 18 | # Load the input 19 | data = dft.DFTData(dirname) 20 | # Select the interesting bands 21 | data.bandana(emin=data.fermi - ecut, emax=data.fermi + ecut) 22 | # Set up a k point grid with roughly five times the density of the input 23 | equivalences = sphere.get_equivalences(data.atoms, data.magmom, len(data.kpoints) * lpfac) 24 | # Perform the interpolation 25 | coeffs = fite.fitde3D(data, equivalences) 26 | 27 | lattvec = data.get_lattvec() 28 | eband, vvband, cband = fite.getBTPbands(equivalences, coeffs, lattvec) 29 | epsilon, dos, vvdos, cdos = bandlib.BTPDOS(eband, vvband, erange=[data.fermi - ecut, data.fermi + ecut], npts=round(2 * ecut / deltae), scattering_model='uniform_tau') 30 | 31 | # Define the temperatures and chemical potentials we are interested in 32 | Tr = np.arange(deltat, tmax + deltat / 2, deltat) 33 | mur_indices = np.logical_and(epsilon > data.fermi - efcut, epsilon < data.fermi + efcut) 34 | mur = epsilon[mur_indices] 35 | 36 | # Set different chemical potentials at each temperature corresponding to the constant doping level 37 | #Tr = np.arange(deltat, tmax + deltat / 2, deltat) 38 | #mur = np.empty_like(Tr) 39 | #_nelect = data.nelect 40 | #for iT, T in enumerate(Tr): 41 | # mur[iT] = bandlib.solve_for_mu(epsilon, dos, _nelect - doping_level, T, data.dosweight, refine=True) 42 | 43 | # Obtain the Fermi integrals required to get the Onsager coefficients 44 | (N, L0, L1, L2, Lm11) = bandlib.fermiintegrals(epsilon, dos, vvdos, mur=mur, Tr=Tr, dosweight=data.dosweight, cdos=cdos, scattering_model = 'epa', scattering_file = fepa) 45 | #N += data.nelect # incorrect because of missing states due to ecut and efcut 46 | # ??? N -= N[0, round(N.shape[1] / 2)] # zero doping at low T in the middle of the band gap 47 | volume = data.get_volume() 48 | # Translate those into Onsager coefficients 49 | (sigma, seebeck, kappa, Hall) = bandlib.calc_Onsager_coefficients(L0, L1, L2, mur, Tr, volume, Lm11) 50 | 51 | # Rescale the carrier count into a volumetric density in cm^-3 52 | #N = -N / (volume / (units.Meter / 100) ** 3) 53 | # Transform the transport coefficients to more convenient units 54 | sigma *= 1e-5 # kS / cm 55 | seebeck *= 1e6 # uV / K 56 | kappa *= 1e-2 # W / cm / K 57 | # Obtain the scalar conductivity and Seebeck coefficient 58 | sigmatr = sigma.trace(axis1=2, axis2=3) / 3 59 | seebecktr = seebeck.trace(axis1=2, axis2=3) / 3 60 | kappatr = kappa.trace(axis1=2, axis2=3) / 3 61 | # Compute the scalar power factor 62 | #P = sigmatr * seebecktr * seebecktr 63 | #P *= 1e4 # uW / cm / K^2 64 | #lorenz = 1e5 * kappatr / (sigmatr * Tr) # 10^-8 W Ohm / K^2 65 | 66 | h = open(ftr, 'w') 67 | h.write('# Ef[Ry] T [K] N DOS(Ef) S s/t R_H kappa0 c chi\n') 68 | for imu, mu in enumerate(mur): 69 | for iT, T in enumerate(Tr): 70 | h.write(('{:10.5f}{:10.4f}' + '{:16.8f}' * 8 + '\n').format( 71 | mu / RYDBERG, T, N[iT, imu], 0.0, seebecktr[iT, imu], sigmatr[iT, imu], 0.0, kappatr[iT, imu], 0.0, 0.0)) 72 | h.close() 73 | 74 | h = open(fct, 'w') 75 | h.write('# Ef[Ry] T [K] N cond(x,x\')' + ' ' * 130 + 'seebeck(x,x\')' + ' ' * 131 + 'kappa0(x,x\')\n') 76 | for imu, mu in enumerate(mur): 77 | for iT, T in enumerate(Tr): 78 | h.write(('{:10.5f}{:10.4f}' + '{:16.8f}' * 27 + '\n').format( 79 | mu / RYDBERG, T, *tuple(sigma[iT].flatten()), *tuple(seebeck[iT].flatten()), *tuple(kappa[iT].flatten()))) 80 | h.close() 81 | --------------------------------------------------------------------------------