1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
%EffMass Effective Mass of semiconductors
% EffMass(filename, Band, nDataSet) analyse the eigenenergies of datasets in output
% file of ABINIT to get the curvature of band structure at Conduction Band Minimum
% and Valence Band Maximum. According to the formula,
% ( 1/Mass_eff )ij = ( 1/h_bar^2 ) * 2nd_Derivative( CBM/VBM eigenenergies )
% with respect to ki to kj.
% We can easily acquire the three main components of effective mass tensors,
% Mass_eff_xx, Mass_eff_yy, Mass_eff_zz.
%
% [EffectiveMass, K, eigenE] = EffMass(filename, Band, nDataSet)
% Varible Band indicates which band requires to be analysed.
% Varible nDataSet indicates the number of dataset contained in 'filename' output file.
% Because the data is derived from band structure calculation following a SCF total
% energy calculation, the nDataSet refers to dataset 2 to (1+nDataSet).
%
% Written by Mike Zhang, 8/11/2002, copyright reserved.
% Used by your own warranty, Mike Zhang(mz24cn@hotmail.com)
% Copyright (C) 2002-2022 ABINIT group (Mike Zhang)
% This file is distributed under the terms of the
% GNU General Public License, see ~abinit/COPYING
% or http://www.gnu.org/copyleft/gpl.txt .
% For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
function [EffectiveMass, K, eigenE] = EffMass(filename, Band, nDataSet)
% Currently we presumably nBand and nKpt of every dataset are same.
nBand = mexData([1 1], filename, '== DATASET 2 ==', 'newkpt: treating', '', '');
nKpt = mexData([1 1], filename, '== DATASET 2 ==', 'Eigenvalues ( eV ) for nkpt=', '', '');
% Find the HOMO(Highest Occupied Molecule Orbit) and LUMO(Lowest Unoccupied Molecule Orbit)
occ = mexData([1 nBand], filename, '-outvars: echo values of preprocessed input variables --------', 'occ', '', '');
i = 1;
while occ(i) ~= 0
i = i + 1;
end
HOMO = i - 1;
LUMO = i;
nGroup = fix(nKpt / 2); % Output nGroup groups Effective Mass data
eigenE = mexData([nKpt nBand nDataSet], filename, '== DATASET 2 ==', '(reduced coord)', 'Eigenvalues ( eV ) for nkpt=', '');
% Search CBM/VBM
indexExtreE(nDataSet) = 0;
for i = 1:nDataSet
indexExtreE(i) = 1;
for n = 1:nKpt
if eigenE(n, LUMO, i) <= eigenE(indexExtreE(i), LUMO, i)
indexExtreE(i) = n;
end
end
end
eigenEha = eigenE / 27.2113961; % eigenEha is in atom unit (Bohr)
k = mexData([nKpt 3 nDataSet], filename, '== DATASET 2 ==', 'kpt=', 'Eigenvalues ( eV ) for nkpt=', '');
% Now alter k from reduced coordinates to cartesian coordinates in atom unit
unitK1 = mexData([1 3], filename, '== DATASET 2 ==', 'G(1)=', '', '');
unitK2 = mexData([1 3], filename, '== DATASET 2 ==', 'G(2)=', '', '');
unitK3 = mexData([1 3], filename, '== DATASET 2 ==', 'G(3)=', '', '');
K(nKpt, 3, nDataSet) = 0;
for i = 1:3
K(:, i, :) = (k(:, 1, :)*unitK1(i) + k(:, 2, :)*unitK2(i) + k(:, 3, :)*unitK3(i)) * 2 * pi;
end
scalarK(nKpt, nDataSet) = 0;
for i = 1:nDataSet
scalarK(:, i) = sqrt((K(:, 1, i)-K(1, 1, i)).^2 + (K(:, 2, i)-K(1, 2, i)).^2 + (K(:, 3, i)-K(1, 3, i)).^2);
end
% Now solve the three main components of effective mass tensor
Curvature(nGroup, 3, nDataSet) = 0;
% Enter main loop of nDataSet datasets
for i = 1:nDataSet
for j = 1:nGroup
nMin = indexExtreE(i) - j;
if nMin < 1
nMin = 1;
end
nMax = indexExtreE(i) + j;
if nMax > nKpt
nMax = nKpt;
end
if nMax-nMin < 3
if nMin == 1
nMax = 3;
else
nMin = nMax -3;
end
end
Curvature(j, :, i) = polyfit(scalarK(nMin:nMax, i), eigenEha(nMin:nMax, Band, i), 2); % K(nMin:nMax, 1, i)
end
end
EffectiveMass = 0.5 ./ Curvature(:, 1, :); % 2nd_Derivative( CBM/VBM eigenenergies ) = 2 * Curvature
EffectiveMass
|