2 % Copyright (C) 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 Class to regulerize the H1 problem of the leads by SVD decompozition.
22 %> @brief Class to regulerize the H1 problem of the leads by SVD decompozition.
23 %> The notations and the structure of the Hamiltonian is defined accroding to the following image:
24 %> @image html Lead_Hamiltonian.jpg
25 %> @image latex Lead_Hamiltonian.jpg
27 %> EQuUs v4.8 or later
32 properties ( Access =
protected )
33 %>
true if the
Hamiltonians were SVD transformed,
false otherwise
35 %> U matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
37 %> S matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
39 %> V matrix from the SVD decompozition, see Eq (41) of PRB 78, 035407
41 %> SVD tolerance to identify singular values
43 %> Somethimes it is needed to perform another SVD cycle to regularize the H1 matrix
45 %> Effective number of
sites after the elimination of the singular values
55 methods ( Access = public )
56 %% constructorof the class
57 %> @brief Constructor of the class.
58 %> @
param Opt An instance of the structure
#Opt. 61 %> @
return An instance of the
class 69 %> @brief Calculates the SVD decomposition of the matrix H1
70 %> @
param The transverse momentum dependent coulping between the unit cell (K1 is transverse momentum dependent, only
if skew coupling #H1_skew_right or #H1_skew_left and the transverse momentum #q are not empty).
71 function SVDdecompozition( obj, K1 )
73 [obj.U, obj.S, obj.V] = svd(full(K1));
75 [obj.U, obj.S, obj.V] = svd(K1);
78 obj.U = sparse(obj.U);
79 obj.V = sparse(obj.V);
85 %> @brief Decides whether SVD regularization is needed or not.
86 %> @
return Returns with
true if SVD regularization is needed,
false otherwise
87 function ret = is_SVD_needed(obj)
88 if 1/condest(obj.H1)<obj.tolerance
96 %% Calc_Effective_Hamiltonians
97 %> @brief Calculates the effective
Hamiltonians according to Eq (48) of of PRB 78, 035407
98 %> @
param E The energy value
99 function Calc_Effective_Hamiltonians( obj, E )
101 obj.ApplyOverlapMatrices(E);
103 if ~isempty(obj.kulso_szabfokok) && length(obj.kulso_szabfokok) ~= size(obj.K0,1)
104 obj.Decimate_Hamiltonians();
106 elseif 1/condest(obj.K1)<obj.tolerance && isempty(obj.V)
110 % in case no SVD regularization or simple decimation is needed
111 obj.Neff = size(obj.K0,1);
119 %% Get_Effective_Hamiltonians
120 %> @brief Gets the effective
Hamiltonians K0_eff, K1_eff, K1adj_eff according to Eq (48) of of PRB 78, 035407
121 %> @return [1] The effective Hamiltonian of one unit cell
122 %> @return [2] The effective coupling between unit cells K1_eff
123 %> @return [3] The adjungate of the effective coupling between unit cells K1adj_eff
124 function [K0_eff, K1_eff, K1adj_eff] = Get_Effective_Hamiltonians(obj)
125 if isempty(obj.next_SVD_cycle)
126 [K0_eff, K1_eff, K1adj_eff] = obj.qDependentHamiltonians();
128 [K0_eff, K1_eff, K1adj_eff] = obj.next_SVD_cycle.Get_Effective_Hamiltonians();
130 error('EQuUs:
SVDregularizationLead:Get_Effective_Hamiltonians', 'Unrecognized type of attribute next_SVD_cycle');
135 %% Get_Effective_Overlaps
136 %> @brief Gets the effective
Hamiltonians S0_eff, S1_eff, S1adj_eff according to Eq (48) of of PRB 78, 035407
137 %> @return [1] The effective overlap matrix of one unit cell S0_eff
138 %> @return [2] The effective overlap matrix between unit cells S1_eff
139 %> @return [3] The adjungate of the effective overlap matrix between unit cells S1adj_eff
140 function [S0_eff, S1_eff, S1adj_eff] = Get_Effective_Overlaps(obj)
141 if isempty(obj.next_SVD_cycle)
142 [S0_eff, S1_eff, S1adj_eff] = obj.qDependentOverlaps();
144 [S0_eff, S1_eff, S1adj_eff] = obj.next_SVD_cycle.Get_Effective_Overlaps();
146 error('EQuUs:
SVDregularizationLead:Get_Effective_Overlaps', 'Unrecognized type of attribute next_SVD_cycle');
151 %% Get_Effective_Coordinates
152 %> @brief Gets the coordinates of the
sites of the effective
Hamiltonians. (Has sense if the singular
sites were given directly)
153 %> @return [1] A class
Coordinates containing the coordinates of the
sites of the effective Hamiltonian
154 function coordinates = Get_Effective_Coordinates(obj)
155 if isempty(obj.next_SVD_cycle)
156 coordinates = obj.coordinates;
158 coordinates = obj.next_SVD_cycle.Get_Effective_Coordinates();
160 error('EQuUs:
SVDregularizationLead:Get_Effective_Coordinates', 'Unrecognized type of attribute next_SVD_cycle');
167 %> @brief Regularize the
Hamiltonians of the lead by SVD regularization
168 function SVD_transform( obj )
170 % determine the
Hamiltonians K0 and K1, K1adj used in transport calculations
171 [K0, K1, K1adj] = obj.qDependentHamiltonians();
173 obj.SVDdecompozition( K1 );
175 % Eqs (48) in PRB 78, 035407
176 % here we use diiferent transformation for the leads with diffferent orientation
177 if obj.Lead_Orientation == 1
179 elseif obj.Lead_Orientation == -1
186 obj.Neff = size(obj.K0, 1);
188 % determine singular values
190 regular_sites_slab = transpose(find(S > obj.tolerance*max(S)));
192 K = [K0, K1; K1adj, K0];
195 regular_sites = [regular_sites_slab, size(K0,1)+regular_sites_slab];
198 CreateH.Write('Hscatter', K);
199 CreateH.Write('kulso_szabfokok', regular_sites);
200 CreateH.Write('HamiltoniansCreated', true);
201 CreateH.Write('HamiltoniansDecimated', false);
204 Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
206 K = CreateH.Read('Hscatter');
207 CreateH.Clear('Hscatter');
209 Neff_new = length(regular_sites_slab);
211 if obj.Lead_Orientation == 1
212 K0 = K(Neff_new+1:end, Neff_new+1:end);
213 elseif obj.Lead_Orientation == -1
214 K0 = K(1:Neff_new, 1:Neff_new);
216 K1 = K(1:Neff_new, Neff_new+1:end);
217 K1adj = K(Neff_new+1:end, 1:Neff_new);
222 obj.next_SVD_cycle.Write(
'K1', K1);
223 obj.next_SVD_cycle.Write(
'K1adj', K1adj);
224 obj.next_SVD_cycle.Write(
'OverlapApplied',
true);
225 obj.next_SVD_cycle.Write(
'HamiltoniansDecimated',
true);
226 obj.next_SVD_cycle.Write(
'Neff', Neff_new);
229 obj.is_SVD_transformed =
true;
230 obj.HamiltoniansDecimated =
true;
233 condition_num = 1/condest(K1);
235 condition_num = rcond(K1);
238 if condition_num<obj.tolerance
239 obj.next_SVD_cycle.Calc_Effective_Hamiltonians( 0 );
243 %% Decimate_Hamiltonians
245 function Decimate_Hamiltonians( obj )
246 % determine the
Hamiltonians K0 and K1, K1adj used in transport calculations
247 [K0loc, K1loc, K1adjloc] = obj.qDependentHamiltonians();
252 regular_sites_slab = obj.kulso_szabfokok;
253 regular_sites = [regular_sites_slab, size(obj.K0,1)+regular_sites_slab];
257 CreateH.Write(
'Hscatter', K);
258 CreateH.Write(
'kulso_szabfokok', regular_sites);
259 CreateH.Write(
'HamiltoniansCreated',
true);
260 CreateH.Write(
'HamiltoniansDecimated',
false);
263 Decimation_Procedure.DecimationFunc(0, CreateH,
'Hscatter',
'kulso_szabfokok');
265 K = CreateH.Read(
'Hscatter');
266 CreateH.Clear(
'Hscatter');
267 coordinates = CreateH.Read(
'coordinates');
269 Neff_new = length(regular_sites_slab);
271 K0 = K(Neff_new+1:end, Neff_new+1:end);
272 K1 = K(1:Neff_new, Neff_new+1:end);
273 K1adj = K(Neff_new+1:end, 1:Neff_new);
276 obj.next_SVD_cycle.Write(
'K0', K0);
277 obj.next_SVD_cycle.Write(
'K1', K1);
278 obj.next_SVD_cycle.Write(
'K1adj', K1adj);
279 obj.next_SVD_cycle.Write(
'OverlapApplied',
true);
280 obj.next_SVD_cycle.Write(
'HamiltoniansDecimated',
true);
281 obj.next_SVD_cycle.Write(
'Neff', Neff_new);
284 obj.HamiltoniansDecimated =
true;
287 % determine the truncated coordinates
288 indexes2remove =
true( size( obj.coordinates.x ) );
289 indexes2remove( regular_sites_slab ) =
false;
290 coordinates = obj.coordinates.RemoveSites( indexes2remove );
291 obj.next_SVD_cycle.Write(
'coordinates', coordinates);
295 % Decimation_Procedure_Lead =
Decimation(obj.Opt,
'ForcedDecimation', obj.Opt.Decimation);
296 % kulso_szabfokok_tmp = obj.kulso_szabfokok;
297 % obj.kulso_szabfokok = [obj.kulso_szabfokok, obj.kulso_szabfokok+size(obj.H0,1)];
298 % Decimation_Procedure_Lead.DecimationFunc(0, obj,
'Hamiltonian2Dec',
'kulso_szabfokok');
299 % obj.kulso_szabfokok = kulso_szabfokok_tmp;
300 % obj.Neff = size(obj.K0,1);
305 %> @brief Transforms the effective
Hamiltonians by a unitary transformation
306 %> @
param Umtx The matrix of the unitary transformation.
307 function Unitary_Transform(obj, Umtx)
309 if isempty(obj.next_SVD_cycle)
311 obj.K0 = Umtx*obj.K0*Umtx';
315 obj.K1 = Umtx*obj.K1*Umtx';
318 if ~isempty(obj.K1adj)
319 obj.K1adj = Umtx*obj.K1adj*Umtx';
323 obj.next_SVD_cycle.Unitary_Transform(Umtx);
325 error('EQuUs:
SVDregularizationLead:Unitary_Transform', 'Unrecognized type of attribute next_SVD_cycle');
331 %> @brief Gets the effective number of
sites after the elimination of the singular values.
332 %> @return Returns with the effective number of
sites 333 function Neff = Get_Neff(obj)
334 if isempty(obj.next_SVD_cycle)
337 Neff = obj.next_SVD_cycle.Get_Neff();
347 %> @brief Gets the total transformation U related to the SVD transformation
348 %> @return Returns with the total transformation U
349 function Vtot = Get_V(obj)
350 if isempty(obj.next_SVD_cycle)
353 Vtot_tmp = obj.next_SVD_cycle.Get_V();
354 size_V = size(obj.V);
355 size_Vtmp = size(Vtot_tmp);
356 Vtot_tmp = [Vtot_tmp, zeros(size_Vtmp(1), size_V(2)-size_Vtmp(2));
357 zeros(size_V(1)-size_Vtmp(1), size_Vtmp(2)), eye(size_V(1)-size_Vtmp(1))];
358 Vtot = obj.V*Vtot_tmp;
366 %> @brief Creates a clone of the present
object.
367 %> @return Returns with the cloned
object.
368 %> @
param varargin Cell array of optional parameters (https:
369 %> @
param 'empty' Set true to create an empty clone, or false (default) to clone all atributes.
370 %> @return Returns with the cloned
object.
371 function ret = CreateClone( obj, varargin )
374 p.addParameter('empty', false );
376 p.parse(varargin{:});
377 empty = p.Results.empty;
380 'Hanyadik_Lead', obj.Hanyadik_Lead,...
381 'Lead_Orientation', obj.Lead_Orientation, ...
388 meta_data = metaclass(obj);
390 for idx = 1:length(meta_data.PropertyList)
391 prop_name = meta_data.PropertyList(idx).Name;
392 if strcmpi( prop_name, 'next_SVD_cycle' )
393 if ~isempty( obj.next_SVD_cycle )
394 ret.next_SVD_cycle = obj.next_SVD_cycle.CreateClone();
397 ret.Write( prop_name, obj.(prop_name));
405 %> @brief Resets all elements in the
object.
406 function Reset( obj )
409 meta_data = metaclass(obj);
411 for idx = 1:length(meta_data.PropertyList)
412 prop_name = meta_data.PropertyList(idx).Name;
413 if strcmp(prop_name, '
Opt') || strcmp( prop_name, '
param') || strcmp(prop_name, 'varargin')
416 obj.Clear( prop_name );
427 %> @brief Sets the value of an attribute in the interface.
428 %> @
param MemberName The name of the attribute to be set.
429 %> @
param input The value to be set.
430 function Write(obj, MemberName, input)
433 if strcmpi(MemberName, '
param') || strcmp(MemberName, 'params')
438 obj.(MemberName) = input;
440 error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
446 %> @brief Query for the value of an attribute in the interface.
447 %> @
param MemberName The name of the attribute to be set.
448 %> @return Returns with the value of the attribute.
449 function ret = Read(obj, MemberName)
451 if strcmpi(MemberName, 'Hamiltonian2Dec')
456 ret = obj.(MemberName);
458 error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
464 %> @brief Clears the value of an attribute in the interface.
465 %> @
param MemberName The name of the attribute to be cleared.
466 function Clear(obj, MemberName)
469 obj.(MemberName) = [];
471 error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
481 methods (Access=protected)
484 %% Extend_Wavefnc ---- DEVELOPMENT
485 %> @brief Extend a reduced wave function to the original basis before the SVD regularization (Eq (45) in PRB 78 035407
486 %> @
param wavefnc_reduced The reduced wavefunction of the effective system
487 %> @
param expk e^(i*k)
488 %> @return A matrix conatining the extended wave functions.
489 function wavefnc_extended = Extend_Wavefnc(obj, wavefnc_reduced, expk)
492 wavefnc_reduced = obj.next_SVD_cycle.Extend_Wavefnc(wavefnc_reduced, expk);
493 elseif ~isempty(obj.next_SVD_cycle)
494 error('EQuUs:
SVDregularizationLead:Extend_Wavefnc', 'Unrecognized type of attribute next_SVD_cycle');
497 Fn = -obj.invD*(obj.K1adju/expk + obj.C);
498 wavefnc_extended = [wavefnc_reduced; Fn*wavefnc_reduced];
499 wavefnc_extended = obj.U*wavefnc_extended;
506 %> @brief Initializes class properties.
507 function Initialize(obj)
509 obj.tolerance = 1e-12;
510 obj.is_SVD_transformed = false;
516 end % methods protected
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.
function CreateLeadHamiltonians(Opt, param, varargin)
Constructor of the class.
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.
Structure containing the coordinates and other quantum number identifiers of the sites in the Hamilto...
A class to create and store Hamiltonian of the scattering region.