2 % Copyright (C) 2009-2017 Peter Rakyta, Ph.D.
4 % This program is free software: you can redistribute it and/or modify
5 % it under the terms of the GNU General Public License as published by
6 % the Free Software Foundation, either version 3 of the License, or
7 % (at your option) any later version.
9 % This program is distributed in the hope that it will be useful,
10 % but WITHOUT ANY WARRANTY; without even the implied warranty of
11 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 % GNU General Public License
for more details.
14 % You should have received a copy of the GNU General Public License
15 % along with
this program. If not, see http:
17 %> @addtogroup utilities Utilities
20 %> @brief A
class to calculate the onsite desnity useful
for self-consistent calculations.
22 %> @brief A
class to calculate the onsite desnity useful for self-consistent calculations.
24 %> EQuUs v4.9 or later
28 properties ( Access =
public )
34 methods (Access=public)
36 %% Contructor of the class
37 %> @brief Constructor of the class.
38 %> @
param Opt An instance of structure
#Opt. 39 %> @
param varargin Cell array of optional parameters. For details see #InputParsing.
40 %> @
return An instance of the
class 43 obj = obj@
DOS(
Opt, varargin{:} );
45 if strcmpi(
class(obj),
'Density')
46 obj.InputParsing( obj.varargin{:} );
55 %> @brief Calculates the onsite desnity
using the method in Nanotechnology 25 (2014), 465201
56 %> @
param varargin Cell array of optional parameters:
57 %> @
param 'Edb' The number of the energy points over the contour integral.
58 %> @
param 'DeltaPhi' A parameter to control the incident angle of the integration contour near the real axis. (Default value is $$\Delta\Phi=0.5\pi$$.
59 %> @
param 'Evec' The complex energy points in
case of custom integration path. (Overrides all other optional parameters.)
60 %> @
param 'Emin' The minimum of the energy array.
61 %> @
param 'JustScatter' Logical value. True
if only an isolated scattering center should be considered in the
self-consistent calculations,
false otherwise.
62 %> @
return An array of the calculated density and a structure describing the geometry of the
sites.
66 p.addParameter(
'Edb', 511 ); % number of energy points on the contour
67 p.addParameter(
'DeltaPhi', 0.5*pi );
68 p.addParameter(
'Evec', [] );
69 p.addParameter(
'Emin', [] );
70 p.addParameter(
'JustScatter',
false ); %logical value. True
if only an isolated scattering center should be considered in the
self-consistent calculations,
false otherwise.
74 Evec = p.Results.Evec;
75 DeltaPhi = p.Results.DeltaPhi;
76 Emin = p.Results.Emin;
77 JustScatter = p.Results.JustScatter;
79 obj.create_Hamiltonians(
'junction', obj.junction )
81 phivec = (0.5 + 0.5*sin( -0.5*pi:pi/(Edb+1):0.5*pi )) * DeltaPhi + (pi-DeltaPhi)/2;
83 obj.display([
'EQuUs:Utils:',
class(obj),
':DensityCalc: Calculating the on-site density.'], 1)
85 if JustScatter && isempty(Emin)
87 Hscatter = obj.junction.CreateH.Read(
'Hscatter');
88 Emin = -abs(eigs( Hscatter, 1,
'lm'))*1.05;
91 Emin = min([-obj.BandWidth.Lead.Emax,-obj.BandWidth.Scatter.Emax])*1.2;
96 Emax = obj.junction.getFermiEnergy();
103 radius = abs( Emax-Emin) /2;
104 R = radius/sin(DeltaPhi/2);
106 Evec = R*(cos(phivec) + 1i*sin(phivec)) - radius + Emax - 1i*R*sin((pi-DeltaPhi)/2);
108 deltaEvec = [0, diff(Evec)];
110 obj.display([
'EQuUs:Utils:',
class(obj),
':DensityCalc: Calculating the density between Emin = ', num2str(min(Evec)),
' and Emax = ',num2str(max(Evec)),],1);
114 %> determine the number of
sites in the calculations to preallocate memory
116 Hscatter = obj.junction.CreateH.Read(
'Hscatter');
117 number_of_sites = size(Hscatter,1);
119 Hscatter = obj.junction.CreateH.Read(
'Hscatter');
120 Leads = obj.junction.FL_handles.Read(
'Leads');
121 size_K0_leads = zeros(length(Leads), 1);
122 size_K0_interface = zeros(length(Leads), 1);
123 for kdx = 1:length(Leads)
124 Leads{kdx}.Calc_Effective_Hamiltonians( Evec(1) );
125 K0_lead = Leads{kdx}.Get_Effective_Hamiltonians();
126 size_K0_leads(kdx) = size(K0_lead,1);
128 obj.junction.CreateInterface( kdx )
129 K0_interface = obj.junction.Interface_Regions{kdx}.Get_Effective_Hamiltonians();
130 size_K0_interface(kdx) = size(K0_interface,1);
134 number_of_sites = size(Hscatter,1) + sum(size_K0_interface); %2*
interface region
136 number_of_sites = size(Hscatter,1) + sum(size_K0_interface) + sum(size_K0_leads); %2*lead + 2*
interface region
140 %> preallocate memory
for Densitysurf
141 Densitysurf = complex(zeros( length(Evec), length(obj.T), number_of_sites ));
143 % starting parallel pool
144 poolmanager =
Parallel( obj.junction.FL_handles.Read(
'Opt') );
147 %> creating
function handles
for parallel
for 148 hdisplay = @obj.display;
149 hSetEnergy = @obj.SetEnergy;
150 hcomplexDensity = @obj.complexDensity;
151 hcreate_scatter = @obj.create_scatter;
153 junction_loc = obj.junction;
157 %
for iidx = 1:length(Evec)
158 parfor (iidx = 1:length(Evec), poolmanager.NumWorkers)
160 %> setting the current energy
161 feval(hSetEnergy, Evec(iidx),
'junction', junction_loc );
163 %> creating the Hamiltonian of the scattering region
164 feval(hcreate_scatter,
'junction', junction_loc );
167 %> evaluating the energy resolved density
168 [densityvec2int, junction_sites_tmp] = feval(hcomplexDensity, junction_loc, JustScatter);
170 feval(hdisplay, [
'EQuUs:Utils:',
class(obj),
':DensityCalc: Error at energy point E = ', num2str(Evec(iidx)),
' caused by:'], 1);
171 feval(hdisplay, errCause.identifier, 1 );
172 for jjjdx = 1:length(errCause.stack)
173 feval(hdisplay, ['file: ',errCause.stack(jjjdx).file], 1 );
174 feval(hdisplay, ['name: ',errCause.stack(jjjdx).name], 1 );
175 feval(hdisplay, ['line: ', num2str(errCause.stack(jjjdx).line)], 1 );
177 feval(hdisplay, ['EQuUs:Utils:', class(obj), ':
DensityCalc: Giving NaN for the calculated current at the given energy point and phase difference.'], 1);
178 densityvec2int = NaN;
181 Densitysurf( iidx, :, : ) = densityvec2int;
189 %> closing the parallel pool
190 poolmanager.closePool();
193 %> calculating the contour integrals
194 density_vec = cell( size(obj.T) );
195 for kkdx = 1:length( obj.T )
196 density_vec{kkdx} = zeros(number_of_sites, 1);
197 for jjdx = 1:number_of_sites
198 densityvec2integrate = Densitysurf(:,kkdx,jjdx);
199 % omitting NaNs by substituting interpolated values
200 indexes = isnan(densityvec2integrate);
201 indexesall = 1:length(densityvec2integrate);
203 densityvec2integrate(indexes) = interp1(indexesall(~indexes), densityvec2integrate(~indexes), indexesall(indexes),
'spline' );
204 density = imag(obj.SimphsonInt( densityvec2integrate.*transpose(deltaEvec) ))/(pi);
205 density_vec{kkdx}( jjdx ) = density_vec{kkdx}( jjdx ) + density;
208 if length(obj.T) == 1
209 density_vec = density_vec{1};
212 obj.display([
'EQuUs:Utils:',
class(obj),
':DensityCalc: Process finished.'], 1)
214 %reset the system
for a
new calculation
215 obj.InputParsing( obj.varargin{:} );
228 %> @brief Calculates the onsite desnity
using the method in Nanotechnology 25 (2014), 465201. This method is usable
for small isolated scattering centers
for which an exact diagonalization can be performed
229 %> @
param num_occupied_states Number of occupied states
230 %> @
return An array of the calculated density and a structure describing the geometry of the
sites.
231 function [density_vec,
junction_sites, num_occupied_states] = DensityCalcSmall( obj, num_occupied_states )
234 obj.create_scatter();
235 Hscatter = obj.junction.CreateH.Read(
'Hscatter');
236 coordinates = obj.junction.CreateH.Read(
'coordinates');
238 if size(Hscatter,1) > Max_size
239 error(
'EQuUs:Utils:Density:DensityCalcSmall',
'Matrix size is too large');
246 [eigenvectors, eigenvalues] = eig(full(Hscatter),
'nobalance');
248 eigenvalues = diag(eigenvalues);
250 [eigenvalues,IX] = sort(eigenvalues,
'ascend');
252 %eigenvalues = eigenvalues( 1:num_occupied_states );
254 if ~exist(
'num_occupied_states',
'var') || isempty(num_occupied_states)
255 num_occupied_states = find(eigenvalues < obj.junction.EF, 1,
'last');
259 eigenvectors = eigenvectors( :, IX(1:num_occupied_states) );
260 density_vec = sum(transpose(eigenvectors.^2));
261 density_vec = reshape( density_vec, numel(density_vec), 1);
264 %>creating site indexes corresponding to the elements of the density vector
276 %> @brief Determines the band width of the leads and of the scattering region.
277 %> @
return ret An instance of structure
BandWidth containing the bandwidths.
278 function ret = getBandWidth( obj )
279 obj.display(
'Getting Bandwidths', 1);
281 if ~isempty(obj.BandWidth)
285 poolmanager =
Parallel( obj.junction.FL_handles.Read('
Opt') );
286 poolmanager.openPool();
288 Surface_1 = obj.junction.FL_handles.SurfaceGreenFunctionCalculator(1, 'Just_Create_Hamiltonians', true, 'q', obj.junction.q, 'leadmodel', obj.junction.leadmodel, ...
289 'CustomHamiltonian', obj.junction.cCustom_Hamiltonians);
290 W = BandWidthCalculator( Surface_1 );
292 param = obj.junction.FL_handles.Read( '
param' );
293 pair_potential = min([abs(
param.Leads{1}.pair_potential), abs(
param.
Leads{2}.pair_potential)]);
295 obj.BandWidth.Lead =
structures(
'BandWidthLimits');
296 obj.BandWidth.Lead.Emin = abs(pair_potential);
297 obj.BandWidth.Lead.Emax = W;
300 if strcmpi(
class(obj.junction),
'Ribbon' )
301 obj.junction.CreateRibbon('justHamiltonians', true);
302 W = BandWidthCalculator( obj.junction.Scatter_UC );
303 elseif strcmpi( class(obj.junction), '
NTerminal' )
304 obj.junction.CreateScatter();
305 W = 1.3*BandWidthCalculatorMolecule( obj.junction.CreateH ); % multiplied by 1.3 just for sure to include normal bound states
313 poolmanager.closePool();
317 %--------------------------------------------
319 function W = BandWidthCalculator( Scatter_UC )
321 H0 = Scatter_UC.Read('H0');
322 if ~isempty( obj.junction.q )
323 H1_transverse = Scatter_UC.Read('H1_transverse');
324 H0 = H0 + H1_transverse*exp(1i*obj.junction.q) + H1_transverse'*exp(-1i*obj.junction.q);
326 H1 = Scatter_UC.Read('H1');
327 u = rand(size(H0,1));
330 hgetMaxEigenvalue = @getMaxEigenvalue;
333 arnoldi = zeros( length(k),1);
334 parfor (idx = 1:length(k), poolmanager.NumWorkers)
335 Heff = feval(hsecular_H,H0,H1,k(idx));
336 arnoldi(idx) = abs(feval(hgetMaxEigenvalue, Heff ));
341 % --------------------------------------
342 % Hamiltonian for the secular equation
344 H = H0 + H1*exp(1i*k) + H1'*exp(-1i*k);
347 %--------------------------------------------
348 % getting the maximal eigenvalue with Arnoldi iteration
349 % Numerical Linear Algebra" by Trefethen and Bau. (p250) or
351 function ret = getMaxEigenvalue( Heff )
352 %u = rand(size(H0,1));
360 norm_new = norm(u_new);
361 lambda_new = norm_new/norm(u);
363 if abs((lambda - lambda_new)/lambda) < tolerance
374 %--------------------------------------------
375 function W = BandWidthCalculatorMolecule( CreateH )
376 Hscatter = CreateH.Read('Hscatter');
377 W = abs(eigs(Hscatter,1));
380 % end nested functions
388 methods (Access=protected)
391 %> @brief Calculates the density at a complex energy
392 %> @
param junction_loc An instance of class
#NTerminal or its subclass describing the junction. 393 %> @
param JustScatter Logical value. True
if only an isolated scattering center should be considered in the
self-consistent calculations,
false otherwise.
394 function [density,
junction_sites] = complexDensity( obj, junction_loc, JustScatter )
397 [spectral_function,
junction_sites] = obj.complexSpectral( junction_loc, JustScatter );
400 fE = obj.Fermi(junction_loc.getEnergy());
402 density = zeros(length( fE ), length(spectral_function) );
404 for idx = 1:length( fE )
405 spectral_function_tmp = spectral_function;
406 if junction_loc.Opt.BdG
407 coordinates = junction_loc.CreateH.Read(
'coordinates');
408 BdG_indexes = coordinates.BdG_u;
409 spectral_function_tmp( BdG_indexes) = spectral_function_tmp( BdG_indexes)*fE(idx);
410 spectral_function_tmp( ~BdG_indexes) = spectral_function_tmp( ~BdG_indexes)*(1-fE(idx));
412 spectral_function_tmp = spectral_function_tmp*fE(idx);
415 density(idx,:) = spectral_function_tmp;
426 %> @brief Parses the optional parameters
for the
class constructor.
427 %> @
param varargin Cell array of optional parameters (https:
428 %> @
param 'T' The absolute temperature in Kelvins.
429 %> @
param 'silent' Set
true to suppress output messages.
430 %> @
param 'scatterPotential' A
function handle y=f( #coordinates coords ) or y=f( #
CreateHamiltonians CreateH, E ) of the potential across the junction.
431 %> @
param 'useSelfEnergy' Logical value. Set true (
default) to solve the Dyson equation with the
self energies of the leads, or
false to use the surface Green operators.
432 %> @
param 'gfininvfromHamiltonian' Logical value. Set
true calculate the surface Greens
function of the scattering region from the Hamiltonaian of the scattering region, or false (
default) to calculate it by the fast way (see Phys. Rev. B 90, 125428 (2014)
for details).
433 %> @
param 'junction' An instance of a
class #
NTerminal or its subclass describing the junction.
434 function InputParsing( obj, varargin )
437 p.addParameter(
'T', obj.T);
438 p.addParameter(
'scatterPotential', []);
439 p.addParameter(
'useSelfEnergy',
true);
440 p.addParameter(
'gfininvfromHamiltonian',
false);
441 p.addParameter(
'junction', []);
443 p.parse( varargin{:});
445 InputParsing@
DOS( obj,
'T', p.Results.T, ...
446 'junction', p.Results.junction, ...
447 'scatterPotential', p.Results.scatterPotential, ...
448 'gfininvfromHamiltonian', p.Results.gfininvfromHamiltonian, ...
449 'useSelfEnergy', p.Results.useSelfEnergy);
456 end %
protected methods
A class describing an N-terminal geometry for equilibrium calculations mostly in the zero temperature...
lead_param Leads
A list of structures lead_param containing the physical parameters for the scattering region.
A class for controlling the parallel pool for paralell computations.
Structure Opt contains the basic computational parameters used in EQuUs.
function Transport(Energy, B)
Calculates the conductance at a given energy value.
function DensityCalc(filling_factor)
Calculates the density using the predefined graphene lattice framework (Ribbon class)
Structure containg the energy resolved density of states.
function secular_H(H0, H1, k)
Hamiltonian for the secular equation.
Structure BandWidthLimits contains the bandwidth limits.
A class to calculate the onsite desnity useful for self-consistent calculations.
Structure param contains data structures describing the physical parameters of the scattering center ...
site_indexes
An array containing the site indexes of the given system part.
Structure BandWidth describes the bandwidth in the lead and in the scattering center.
Structure sites contains data to identify the individual sites in a matrix.
coordinates
An instance of structure coordinates describing the geometry.
sites Scatter
Structure sites describing the geometry of the scattering region.
function structures(name)
function openPool()
Opens a parallel pool for parallel computations.
Structure junction_sites contains data to identify the individual sites of the leads,...
A class to create and store Hamiltonian of the scattering region.