2 % Copyright (C) 2009-2016 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 basic Basic Functionalities
20 %> @brief A
class describing the interface region between the scattering region and a lead.
22 %> @brief A
class describing the interface region between the scattering region and a lead.
24 %> EQuUs v4.8 or later
29 properties ( Access =
protected )
30 %> Effective Hamiltonian of the
interface region
32 %> Hinterface -E*Sinterface
34 %> Hamiltonian of the
interface region
36 %> Hcoupling-E*Scoupling
38 %> Hcouplingadj-E*Scoupling
' 40 %> Coupling Hamiltonian from the interface region to the scattering region 42 %> Coupling Hamiltonian from the scattering region to the interface region 44 %> Overlap integrals corresponding to Hcoupling 46 %> Overlap integrals corresponding to Hinterface 48 %> Coordinates of the surface sites of the scattering region to be connected to. 56 methods ( Access = public ) 57 %% constructorof the class 58 %> @brief Constructor of the class. 59 %> @param Opt An instance of the structure #Opt. 60 %> @param param An instance of structure #param. 61 %> @param varargin Cell array of optional parameters identical to #SVDregularizationLead.SVDregularizationLead. 62 %> @return An instance of the class 63 function obj = InterfaceRegion(Opt, param, varargin) 64 obj = obj@SVDregularizationLead( Opt, param, varargin{:} ); 72 %% ApplyOverlapMatrices 73 %> @brief Applies the overlap matrices to the Hamiltonians: K = H-ES 74 %> @param E The energy value. 75 function ApplyOverlapMatrices(obj, E) 78 obj.display('EQuUs:
InterfaceRegion:ApplyOverlapMatrices: Overlap matrices were already applied.
'); 82 ApplyOverlapMatrices@CreateLeadHamiltonians( obj, E ); 84 if ~isempty( obj.Scoupling ) 85 obj.Kcoupling = obj.Hcoupling - E*obj.Scoupling; 86 obj.Kcouplingadj = obj.Hcouplingadj - E*obj.Scoupling';
89 obj.Kcouplingadj = obj.Hcouplingadj;
92 if ~isempty( obj.Sinterface )
93 obj.Kinterface = obj.Hinterface - E*obj.Sinterface;
95 obj.Kinterface = obj.Hinterface;
102 %> @brief Transforms the
Hamiltonians and the overlap matrices into the BdG model.
103 function Transform2BdG( obj )
105 if isempty(obj.
Opt.BdG) || ~obj.
Opt.BdG
109 if ~isempty( obj.coordinates.BdG_u )
110 % already transformed into BdG model
116 if isempty( obj.coordinates2 )
117 fnames = fieldnames( obj.coordinates2 );
118 for idx = 1:length(fnames)
120 if strcmp(fname,
'a') || strcmp(fname,
'b')
123 obj.coordinates2.(fname) = [ obj.coordinates2.(fname); obj.coordinates2.(fname) ];
125 obj.coordinates2.BdG_u = [ true(size(obj.H0,1),1); false(size(obj.H0,1),1)];
129 pair_potential = obj.params.pair_potential;
132 if isempty(obj.Scoupling)
133 Scoupling = sparse([],[],[], size(obj.Hcoupling,1), size(obj.Hcoupling,2));
135 Scoupling = obj.Scoupling;
138 obj.Hcoupling = [obj.Hcoupling, Scoupling*pair_potential; Scoupling*conj(pair_potential), -conj(obj.Hcoupling)];
139 obj.Hcouplingadj = [obj.Hcouplingadj, Scoupling'*pair_potential; Scoupling'*conj(pair_potential), -conj(obj.Hcouplingadj)];
141 if ~isempty( obj.Scoupling )
142 obj.Scoupling = [obj.Scoupling, sparse([], [], [], size(obj.Scoupling,1), size(obj.Scoupling,2)); sparse([], [], [], size(obj.Scoupling,1), size(obj.Scoupling,2)), obj.Scoupling];
148 %% Calc_Effective_Hamiltonians
149 %> @brief Calculates the effective
Hamiltonians according to Eq (48) of of PRB 78, 035407
150 %> @
param E The energy value
151 %> @
param varargin Cell array of optional parameters (https:
152 %> @
param '
Lead' An instance of class
#SVDregularizationLead (or its subclass) providing a source for the SVD matrices. 153 function Calc_Effective_Hamiltonians( obj, E, varargin )
156 p.addParameter(
'Lead', []);
157 p.parse(varargin{:});
160 obj.ApplyOverlapMatrices(E);
163 if ~isempty(obj.kulso_szabfokok) && length(obj.kulso_szabfokok) ~= size(obj.K0,1)
164 obj.Decimate_Hamiltonians();
166 elseif
Lead.Read('is_SVD_transformed')
167 obj.SVD_transform(
Lead );
170 % in case no SVD regularization or simple decimation is needed
171 obj.Neff = size(obj.K0,1);
182 %% Get_Effective_Hamiltonians
183 %> @brief Gets the effective
Hamiltonians of the interface region
184 %> @return [1] The effective Hamiltonian of the unit cell
185 %> @return [2] The effective coupling between the unit cells
186 %> @return [3] The adjungate of the effective coupling between the unit cells
187 %> @return [4] The effective coupling between the lead and the scattering region
188 %> @return [5] The adjungate of the effective coupling between the lead and the scattering region
189 %> @return [6] The class conatining the coordinates of the interface region
190 function [K0_eff, K1_eff, K1adj_eff, Kcoupling, Kcouplingadj, coordinates] = Get_Effective_Hamiltonians(obj)
191 if isempty(obj.next_SVD_cycle)
192 [~, K1, K1adj, Kcoupling, Kcouplingadj] = obj.qDependentHamiltonians();
195 % applying transverse coupling
196 if ~isempty( obj.q ) && ~isempty( obj.K1_transverse )
197 K0_eff = K0_eff + obj.K1_transverse*exp(1i*obj.q) + obj.K1_transverse'*exp(-1i*obj.q);
200 if obj.Lead_Orientation == 1
203 elseif obj.Lead_Orientation == -1
208 % retriving the coordinates
209 coordinates = obj.coordinates;
212 [K0_eff, K1_eff, K1adj_eff, Kcoupling, Kcouplingadj, coordinates] = obj.next_SVD_cycle.Get_Effective_Hamiltonians();
214 error('EQuUs:
InterfaceRegion:Get_Effective_Hamiltonians', 'Unrecognized type of attribute next_SVD_cycle');
219 %% qDependentHamiltonians
220 %> @brief Construct a K0 and K1
Hamiltonians (transformed to the grand canonical potential) for a given subspace of the transverse momentum number
#q. 221 %> @
return [1] the transverse momentum dependent Hamiltonian of the unit cell.
222 %> @
return [2] the transverse momentum dependent Hamiltonian of the coupling between the unit cells.
223 %> @
return [3] the transverse momentum dependent Hamiltonian of the coupling between the unit cells in the opposite direction.
224 %> @
return [4] the transverse momentum dependent Hamiltonian of the coupling from the scattering center to the lead.
225 %> @
return [5] the transverse momentum dependent Hamiltonian of the coupling from the lead to the scattering center.
226 function [K0, K1, K1adj, Kcoupling, Kcouplingadj] = qDependentHamiltonians( obj )
230 Kcoupling = obj.Kcoupling;
231 Kcouplingadj = obj.Kcouplingadj;
234 if obj.HamiltoniansDecimated
238 Kcouplingadj = Kcoupling
'; 248 %> @brief Transforms the effective Hamiltonians by a unitary transformation 249 %> @param Umtx The matrix of the unitary transformation. 250 function Unitary_Transform(obj, Umtx) 252 if isempty(obj.next_SVD_cycle) 253 obj.K00 = Umtx*obj.K00*Umtx';
254 obj.K1 = Umtx*obj.K1*Umtx
'; 255 obj.K1adj = Umtx*obj.K1adj*Umtx';
256 %obj.Kcoupling = Umtx*obj.Kcoupling;
257 %obj.Kcouplingadj = obj.Kcouplingadj*Umtx
'; 260 obj.next_SVD_cycle.Unitary_Transform(Umtx); 262 error('EQuUs:
InterfaceRegion:Unitary_Transform
', 'Unrecognized type of attribute next_SVD_cycle
'); 268 %> @brief Transforms the Hamiltonians of the interface region according to the SVD regularization in the lead. 269 %> @param Lead an instance of class #SVDregularizationLead or its subclass representing the attached lead. 270 function SVD_transform( obj, Lead ) 273 obj.Neff = Lead.Read('Neff
'); 275 if ~Lead.Read('is_SVD_transformed
') 279 if obj.Lead_Orientation == 1 280 obj.V = Lead.Read('V
'); 282 elseif obj.Lead_Orientation == -1 283 obj.U = Lead.Read('U
'); 288 %> Performing SVD regularization 289 % determine the Hamiltonians K0 and K1, K1adj used in transport calculations 290 [K0, K1, K1adj] = obj.qDependentHamiltonians(); 292 % Eqs (48) in PRB 78, 035407 293 % here we use diiferent transformation for the leads with diffferent orientation 296 K1(1:Neff,1:Neff) = U
'*obj.K1(1:Neff,1:Neff)*U; 297 K1adj(1:Neff,1:Neff) = U'*obj.
K1adj(1:Neff,1:Neff)*U;
303 K00(1:Neff, 1:Neff) = U'*obj.K00(1:Neff, 1:Neff)*U;
304 K00(1:Neff, end-Neff+1:end) = U'*obj.K00(1:Neff, end-Neff+1:end);
305 K00(end-Neff+1:end, 1:Neff) = obj.K00(end-Neff+1:end, 1:Neff)*U;
308 S = abs(
Lead.Read('S'));
309 non_singular_sites_slab = transpose(find(S > obj.tolerance*max(S)));
311 if obj.Lead_Orientation == 1
312 K = [K0, K1; K1adj, K00];
313 non_singular_sites = [non_singular_sites_slab, size(K0,1)+1:size(K0,1)+size(K00,1)];
314 elseif obj.Lead_Orientation == -1
315 K = [K00, K1; K1adj, K0];
316 non_singular_sites = [1:size(K00,1), size(K00,1) + non_singular_sites_slab];
323 CreateH.Write('Hscatter', K);
324 CreateH.Write('kulso_szabfokok', non_singular_sites);
325 CreateH.Write('HamiltoniansCreated', true);
326 CreateH.Write('HamiltoniansDecimated', false);
329 Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
331 K = CreateH.Read('Hscatter');
332 CreateH.Clear('Hscatter');
334 Neff_new = length(non_singular_sites_slab);
336 if obj.Lead_Orientation == 1
337 K00 = K(Neff_new+1:end, Neff_new+1:end);
338 K1 = K(1:Neff_new, Neff_new+1:end);
339 K1adj = K(Neff_new+1:end, 1:Neff_new);
340 elseif obj.Lead_Orientation == -1
341 K00 = K(1:end-Neff_new, 1:end-Neff_new);
342 K1 = K(1:end-Neff_new, end-Neff_new+1:end);
343 K1adj = K(end-Neff_new+1:end, 1:end-Neff_new);
347 obj.HamiltoniansDecimated = true;
350 Kcoupling = obj.Kcoupling;
351 Kcouplingadj = obj.Kcouplingadj;
352 if obj.Lead_Orientation == 1
353 Kcoupling(1:Neff,:) = U'*Kcoupling(1:Neff,:);
354 Kcouplingadj(:,1:Neff) = Kcouplingadj(:,1:Neff)*U;
356 Kcoupling(1:Neff,:) = U'*Kcoupling(1:Neff,:);
357 Kcouplingadj(:,1:Neff) = Kcouplingadj(:,1:Neff)*U;
363 obj.next_SVD_cycle.Write(
'K1', K1);
364 obj.next_SVD_cycle.Write(
'K1adj', K1adj);
365 obj.next_SVD_cycle.Write(
'Kcoupling', Kcoupling);
366 obj.next_SVD_cycle.Write(
'Kcouplingadj', Kcouplingadj);
367 obj.next_SVD_cycle.Write(
'HamiltoniansDecimated',
true);
368 obj.next_SVD_cycle.Write(
'Neff', Neff_new);
370 obj.is_SVD_transformed =
true;
371 obj.HamiltoniansDecimated =
true;
373 if ~isempty(obj.next_SVD_cycle) && strcmpi(
class(obj.next_SVD_cycle),
'InterfaceRegion' )
374 obj.next_SVD_cycle.SVD_transform(
Lead.Read('next_SVD_cycle') );
375 elseif ~isempty(obj.next_SVD_cycle)
376 error('EQuUs:
InterfaceRegion:Calc_Effective_Hamiltonians', 'Unrecognized type of attribute next_SVD_cycle');
381 %% Decimate_Interface
382 %> @brief Decimates the
Hamiltonians of the interface region.
383 function Decimate_Hamiltonians( obj )
385 % determine the
Hamiltonians K0 and K1, K1adj used in transport calculations
386 [K0loc, K1loc, K1adjloc] = obj.qDependentHamiltonians();
388 K = [K0loc,K1loc; K1adjloc, K0loc];
390 non_singular_sites_slab = obj.kulso_szabfokok;
391 Neff_new = length(non_singular_sites_slab);
394 non_singular_sites = [non_singular_sites_slab, size(K,1)/2+1:size(K,1)];
397 CreateH.Write('Hscatter', K);
398 CreateH.Write('kulso_szabfokok', non_singular_sites);
399 CreateH.Write('HamiltoniansCreated', true);
400 CreateH.Write('HamiltoniansDecimated', false);
403 Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
405 K = CreateH.Read('Hscatter');
406 CreateH.Clear('Hscatter');
408 cCoordinates = obj.coordinates;
409 coord_fieldnames = fieldnames(cCoordinates);
410 if obj.Lead_Orientation == 1
411 K00 = K(Neff_new+1:end, Neff_new+1:end);
412 K1 = K(1:Neff_new, Neff_new+1:end);
413 K1adj = K(Neff_new+1:end, 1:Neff_new);
415 % reordering the
sites to get the non-singular
sites at the top corner
416 indexes = false( size(K00,1), 1);
417 indexes(non_singular_sites_slab) = true;
418 K00 = [K00(indexes, indexes), K00(indexes, ~indexes); K00(~indexes, indexes), K00(~indexes, ~indexes)];
419 K1 = [K1(:, indexes), K1(:, ~indexes)];
420 K1adj = [K1adj(indexes, :); K1adj(~indexes, :)];
421 Kcoupling = obj.Kcoupling;
422 Kcoupling = [Kcoupling(indexes, :); Kcoupling(~indexes, :)];
423 Kcouplingadj = obj.Kcouplingadj;
424 Kcouplingadj = [Kcouplingadj(:,indexes), Kcouplingadj(:, ~indexes)];
426 % reordering the
sites to get the non-singular
sites at the top corner
427 for idx = 1:length(coord_fieldnames)
428 fieldname = coord_fieldnames{idx};
429 if strcmpi(fieldname,
'a') || strcmpi(fieldname,
'b') || strcmpi(fieldname,
'LatticeConstant')
431 elseif ~isempty(cCoordinates.(fieldname))
432 tmp = cCoordinates.(fieldname);
433 cCoordinates.(fieldname) = [tmp(indexes); tmp(~indexes)];
437 elseif obj.Lead_Orientation == -1
438 % keeping only regular
sites 439 K00 = K(1:Neff_new, 1:Neff_new);
440 K1 = K(1:Neff_new, Neff_new+non_singular_sites_slab);
441 K1adj = K(Neff_new+non_singular_sites_slab, 1:Neff_new);
442 Kcoupling = obj.Kcoupling;
443 Kcouplingadj = obj.Kcouplingadj;
445 % keeping only regular
sites 446 cCoordinates = cCoordinates.KeepSites(non_singular_sites_slab);
448 error('EQuUs:
InterfaceRegion:Decimate_Interface', 'Unknown lead orientation');
453 obj.next_SVD_cycle.Write(
'K1', K1);
454 obj.next_SVD_cycle.Write(
'K1adj', K1adj);
455 obj.next_SVD_cycle.Write(
'Kcoupling', Kcoupling);
456 obj.next_SVD_cycle.Write(
'Kcouplingadj', Kcouplingadj);
457 obj.next_SVD_cycle.Write(
'HamiltoniansDecimated',
true);
458 obj.next_SVD_cycle.Write(
'Neff', Neff_new);
459 obj.next_SVD_cycle.Write(
'coordinates', cCoordinates);
462 obj.HamiltoniansDecimated =
true;
463 obj.Neff = size(obj.K0,1);
469 %> @brief Gets the effective number of
sites after the elimination of the singular values.
470 %> @
return Returns with the effective number of
sites 471 function Neff = Get_Neff(obj)
472 if isempty(obj.next_SVD_cycle)
475 Neff = obj.next_SVD_cycle.Get_Neff();
477 error('EQuUs:
InterfaceRegion:Get_Neff', 'Unrecognized type of attribute next_SVD_cycle');
484 %> @brief Creates a clone of the present class.
485 %> @return Returns with the cloned
object.
486 function ret = CreateClone( obj )
490 'Hanyadik_Lead', obj.Hanyadik_Lead,...
491 'Lead_Orientation', obj.Lead_Orientation, ...
494 meta_data = metaclass(obj);
496 for idx = 1:length(meta_data.PropertyList)
497 prop_name = meta_data.PropertyList(idx).Name;
498 if strcmpi( prop_name, 'next_SVD_cycle' )
499 if ~isempty( obj.next_SVD_cycle )
500 ret.next_SVD_cycle = obj.next_SVD_cycle.CreateClone();
503 ret.Write( prop_name, obj.(prop_name));
510 %> @brief Resets all elements in the
object.
511 function Reset( obj )
514 meta_data = metaclass(obj);
516 for idx = 1:length(meta_data.PropertyList)
517 prop_name = meta_data.PropertyList(idx).Name;
518 if strcmp(prop_name, '
Opt') || strcmp( prop_name, '
param') || strcmp(prop_name, 'varargin')
521 obj.Clear( prop_name );
530 %> @brief Sets the value of an attribute in the interface.
531 %> @
param MemberName The name of the attribute to be set.
532 %> @
param input The value to be set.
533 function Write(obj, MemberName, input)
536 if strcmp(MemberName, '
param') || strcmp(MemberName, 'params')
541 obj.(MemberName) = input;
543 error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
549 %> @brief Query for the value of an attribute in the interface.
550 %> @
param MemberName The name of the attribute to be set.
551 %> @return Returns with the value of the attribute.
552 function ret = Read(obj, MemberName)
555 ret = obj.(MemberName);
557 error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
562 %> @brief Clears the value of an attribute in the interface.
563 %> @
param MemberName The name of the attribute to be cleared.
564 function Clear(obj, MemberName)
566 obj.(MemberName) = [];
568 error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
575 %------------------------------------------------------------------
Property next_SVD_cycle
Somethimes it is needed to perform another SVD cycle to regularize the H1 matrix.
Structure Opt contains the basic computational parameters used in EQuUs.
Class to create and store Hamiltonian of the translational invariant leads.
function Transport(Energy, B)
Calculates the conductance at a given energy value.
function Hamiltonians(varargin)
Function to create the custom Hamiltonians for the 1D chain.
A class providing function handle to reduce the number of sites in the Hamiltonian via decimation pro...
Class to regulerize the H1 problem of the leads by SVD decompozition.
A class containing common basic functionalities.
A class describing the interface region between the scattering region and a lead.
Property Kcoupling
Hcoupling-E*Scoupling.
A class to calculate the Green functions and self energies of a translational invariant lead The nota...
Structure param contains data structures describing the physical parameters of the scattering center ...
Structure sites contains data to identify the individual sites in a matrix.
function Lead(Opt, param, varargin)
Constructor of the class.
Property K1adj
K1adj=H1adj-E*S1', see Eq (4) of PRB 78, 035407.
A class to create and store Hamiltonian of the scattering region.