File: EffMass.m

package info (click to toggle)
abinit 9.10.4-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 518,712 kB
  • sloc: xml: 877,568; f90: 577,240; python: 80,760; perl: 7,019; ansic: 4,585; sh: 1,925; javascript: 601; fortran: 557; cpp: 454; objc: 323; makefile: 77; csh: 42; pascal: 31
file content (92 lines) | stat: -rw-r--r-- 4,016 bytes parent folder | download
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