Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
InterfaceRegion.m
Go to the documentation of this file.
1 %% Eotvos Quantum Transport Utilities - InterfaceRegion
2 % Copyright (C) 2009-2016 Peter Rakyta, Ph.D.
3 %
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.
8 %
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.
13 %
14 % You should have received a copy of the GNU General Public License
15 % along with this program. If not, see http://www.gnu.org/licenses/.
16 %
17 %> @addtogroup basic Basic Functionalities
18 %> @{
19 %> @file InterfaceRegion.m
20 %> @brief A class describing the interface region between the scattering region and a lead.
21 %> @}
22 %> @brief A class describing the interface region between the scattering region and a lead.
23 %> @Available
24 %> EQuUs v4.8 or later
25 %%
27 
28 
29 properties ( Access = protected )
30  %> Effective Hamiltonian of the interface region
31  K00
32  %> Hinterface -E*Sinterface
33  Kinterface
34  %> Hamiltonian of the interface region
35  Hinterface
36  %> Hcoupling-E*Scoupling
37  Kcoupling
38  %> Hcouplingadj-E*Scoupling'
39  Kcouplingadj
40  %> Coupling Hamiltonian from the interface region to the scattering region
41  Hcoupling
42  %> Coupling Hamiltonian from the scattering region to the interface region
43  Hcouplingadj
44  %> Overlap integrals corresponding to Hcoupling
45  Scoupling
46  %> Overlap integrals corresponding to Hinterface
47  Sinterface
48  %> Coordinates of the surface sites of the scattering region to be connected to.
49  coordinates2
50 end
51 
52 
53 
54 
55 
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{:} );
65 
66  if strcmpi(class(obj), 'InterfaceRegion')
67  obj.Reset();
68  end
69  end
70 
71 
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)
76 
77  if obj.OverlapApplied
78  obj.display('EQuUs:InterfaceRegion:ApplyOverlapMatrices: Overlap matrices were already applied.');
79  return;
80  end
81 
82  ApplyOverlapMatrices@CreateLeadHamiltonians( obj, E );
83 
84  if ~isempty( obj.Scoupling )
85  obj.Kcoupling = obj.Hcoupling - E*obj.Scoupling;
86  obj.Kcouplingadj = obj.Hcouplingadj - E*obj.Scoupling';
87  else
88  obj.Kcoupling = obj.Hcoupling;
89  obj.Kcouplingadj = obj.Hcouplingadj;
90  end
91 
92  if ~isempty( obj.Sinterface )
93  obj.Kinterface = obj.Hinterface - E*obj.Sinterface;
94  else
95  obj.Kinterface = obj.Hinterface;
96  end
97 
98  end
99 
100 
101 %% Transform2BdG
102 %> @brief Transforms the Hamiltonians and the overlap matrices into the BdG model.
103  function Transform2BdG( obj )
104 
105  if isempty(obj.Opt.BdG) || ~obj.Opt.BdG
106  return
107  end
108 
109  if ~isempty( obj.coordinates.BdG_u )
110  % already transformed into BdG model
111  return
112  end
113 
114  Transform2BdG@CreateLeadHamiltonians( obj );
115 
116  if isempty( obj.coordinates2 )
117  fnames = fieldnames( obj.coordinates2 );
118  for idx = 1:length(fnames)
119  fname = fnames{idx};
120  if strcmp(fname, 'a') || strcmp(fname, 'b')
121  continue
122  end
123  obj.coordinates2.(fname) = [ obj.coordinates2.(fname); obj.coordinates2.(fname) ];
124  end
125  obj.coordinates2.BdG_u = [ true(size(obj.H0,1),1); false(size(obj.H0,1),1)];
126  end
127 
128 
129  pair_potential = obj.params.pair_potential;
130 
131  % transforming the coupling Hamiltonians and overlaps
132  if isempty(obj.Scoupling)
133  Scoupling = sparse([],[],[], size(obj.Hcoupling,1), size(obj.Hcoupling,2));
134  else
135  Scoupling = obj.Scoupling;
136  end
137 
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)];
140 
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];
143  end
144 
145 
146  end
147 
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://www.mathworks.com/help/matlab/ref/varargin.html):
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 )
154 
155  p = inputParser;
156  p.addParameter('Lead', []);
157  p.parse(varargin{:});
158  Lead = p.Results.Lead;
159 
160  obj.ApplyOverlapMatrices(E);
161 
162 
163  if ~isempty(obj.kulso_szabfokok) && length(obj.kulso_szabfokok) ~= size(obj.K0,1)
164  obj.Decimate_Hamiltonians();
165  return
166  elseif Lead.Read('is_SVD_transformed')
167  obj.SVD_transform( Lead );
168  return
169  else
170  % in case no SVD regularization or simple decimation is needed
171  obj.Neff = size(obj.K0,1);
172  obj.K00 = obj.K0;
173  return
174  end
175 
176 
177 
178 
179  end
180 
181 
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  function [K0_eff, K1_eff, K1adj_eff, Kcoupling, Kcouplingadj] = Get_Effective_Hamiltonians(obj)
190  if isempty(obj.next_SVD_cycle)
191  K0_eff = obj.K00;
192  if obj.Lead_Orientation == 1
193  K1_eff = obj.K1;
194  K1adj_eff = obj.K1adj;
195  elseif obj.Lead_Orientation == -1
196  K1_eff = obj.K1adj;
197  K1adj_eff = obj.K1;
198  end
199  Kcoupling = obj.Kcoupling;
200  Kcouplingadj = obj.Kcouplingadj;
201  elseif strcmpi( class(obj.next_SVD_cycle), 'InterfaceRegion' )
202  [K0_eff, K1_eff, K1adj_eff, Kcoupling, Kcouplingadj] = obj.next_SVD_cycle.Get_Effective_Hamiltonians();
203  else
204  error('EQuUs:InterfaceRegion:Get_Effective_Hamiltonians', 'Unrecognized type of attribute next_SVD_cycle');
205  end
206 
207  end
208 
209 
210 %% Unitary_Transform
211 %> @brief Transforms the effective Hamiltonians by a unitary transformation
212 %> @param Umtx The matrix of the unitary transformation.
213  function Unitary_Transform(obj, Umtx)
214 
215  if isempty(obj.next_SVD_cycle)
216  obj.K00 = Umtx*obj.K00*Umtx';
217  obj.K1 = Umtx*obj.K1*Umtx';
218  obj.K1adj = Umtx*obj.K1adj*Umtx';
219  %obj.Kcoupling = Umtx*obj.Kcoupling;
220  %obj.Kcouplingadj = obj.Kcouplingadj*Umtx';
221  %5
222  elseif strcmpi( class(obj.next_SVD_cycle), 'InterfaceRegion' )
223  obj.next_SVD_cycle.Unitary_Transform(Umtx);
224  else
225  error('EQuUs:InterfaceRegion:Unitary_Transform', 'Unrecognized type of attribute next_SVD_cycle');
226  end
227 
228  end
229 
230 %% SVD_transform
231 %> @brief Transforms the Hamiltonians of the interface region according to the SVD regularization in the lead.
232 %> @param Lead an instance of class #SVDregularizationLead or its subclass representing the attached lead.
233  function SVD_transform( obj, Lead )
234 
235 
236  obj.Neff = Lead.Read('Neff');
237 
238  if ~Lead.Read('is_SVD_transformed')
239  return
240  end
241 
242  if obj.Lead_Orientation == 1
243  obj.V = Lead.Read('V');
244  U = obj.V;
245  elseif obj.Lead_Orientation == -1
246  obj.U = Lead.Read('U');
247  U = obj.U;
248  end
249 
250 
251  %> Performing SVD regularization
252 
253  if length(obj.q) < 2 && ~isempty(obj.q) && ~obj.HamiltoniansDecimated
254  K0 = obj.K0;
255  K0 = K0 + obj.K1_transverse*diag(exp(1i*obj.q)) + obj.K1_transverse'*diag(exp(-1i*obj.q));
256  else
257  K0 = Lead.Read('K0');
258  end
259 
260  % Eqs (48) in PRB 78, 035407
261  % here we use diiferent transformation for the leads with diffferent orientation
262  Neff = obj.Neff;
263  K0 = U'*K0*U;
264  K1 = obj.K1;
265  K1adj = obj.K1adj;
266  K1(1:Neff,1:Neff) = U'*obj.K1(1:Neff,1:Neff)*U;
267  K1adj(1:Neff,1:Neff) = U'*obj.K1adj(1:Neff,1:Neff)*U;
268 
269  if isempty(obj.K00)
270  K00 = K0;
271  else
272  K00 = obj.K00;
273  K00(1:Neff, 1:Neff) = U'*obj.K00(1:Neff, 1:Neff)*U;
274  K00(1:Neff, end-Neff+1:end) = U'*obj.K00(1:Neff, end-Neff+1:end);
275  K00(end-Neff+1:end, 1:Neff) = obj.K00(end-Neff+1:end, 1:Neff)*U;
276  end
277 
278  S = abs(Lead.Read('S'));
279  non_singular_sites_slab = transpose(find(S > obj.tolerance*max(S)));
280 
281  if obj.Lead_Orientation == 1
282  K = [K0, K1; K1adj, K00];
283  non_singular_sites = [non_singular_sites_slab, size(K0,1)+1:size(K0,1)+size(K00,1)];
284  elseif obj.Lead_Orientation == -1
285  K = [K00, K1; K1adj, K0];
286  non_singular_sites = [1:size(K00,1), size(K00,1) + non_singular_sites_slab];
287  end
288 
289 
290 
291 
292  CreateH = CreateHamiltonians(obj.Opt, obj.param);
293  CreateH.Write('Hscatter', K);
294  CreateH.Write('kulso_szabfokok', non_singular_sites);
295  CreateH.Write('HamiltoniansCreated', true);
296  CreateH.Write('HamiltoniansDecimated', false);
297 
298  Decimation_Procedure = Decimation(obj.Opt);
299  Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
300 
301  K = CreateH.Read('Hscatter');
302  CreateH.Clear('Hscatter');
303 
304  Neff_new = length(non_singular_sites_slab);
305 
306  if obj.Lead_Orientation == 1
307  K00 = K(Neff_new+1:end, Neff_new+1:end);
308  K1 = K(1:Neff_new, Neff_new+1:end);
309  K1adj = K(Neff_new+1:end, 1:Neff_new);
310  elseif obj.Lead_Orientation == -1
311  K00 = K(1:end-Neff_new, 1:end-Neff_new);
312  K1 = K(1:end-Neff_new, end-Neff_new+1:end);
313  K1adj = K(end-Neff_new+1:end, 1:end-Neff_new);
314  end
315 
316 
317  obj.HamiltoniansDecimated = true;
318 
319  %> SVD transform the coupling Hamiltonians
320  Kcoupling = obj.Kcoupling;
321  Kcouplingadj = obj.Kcouplingadj;
322  if obj.Lead_Orientation == 1
323  Kcoupling(1:Neff,:) = U'*Kcoupling(1:Neff,:);
324  Kcouplingadj(:,1:Neff) = Kcouplingadj(:,1:Neff)*U;
325  else
326  Kcoupling(1:Neff,:) = U'*Kcoupling(1:Neff,:);
327  Kcouplingadj(:,1:Neff) = Kcouplingadj(:,1:Neff)*U;
328  end
329 
330 
331  obj.next_SVD_cycle = InterfaceRegion(obj.Opt, obj.param, obj.varargin{:});
332  obj.next_SVD_cycle.Write('K00', K00);
333  obj.next_SVD_cycle.Write('K1', K1);
334  obj.next_SVD_cycle.Write('K1adj', K1adj);
335  obj.next_SVD_cycle.Write('Kcoupling', Kcoupling);
336  obj.next_SVD_cycle.Write('Kcouplingadj', Kcouplingadj);
337  obj.next_SVD_cycle.Write('HamiltoniansDecimated', true);
338  obj.next_SVD_cycle.Write('Neff', Neff_new);
339 
340  obj.is_SVD_transformed = true;
341  obj.HamiltoniansDecimated = true;
342 
343  if ~isempty(obj.next_SVD_cycle) && strcmpi( class(obj.next_SVD_cycle), 'InterfaceRegion' )
344  obj.next_SVD_cycle.SVD_transform( Lead.Read('next_SVD_cycle') );
345  elseif ~isempty(obj.next_SVD_cycle)
346  error('EQuUs:InterfaceRegion:Calc_Effective_Hamiltonians', 'Unrecognized type of attribute next_SVD_cycle');
347  end
348 
349  end
350 
351 %% Decimate_Interface
352 %> @brief Decimates the Hamiltonians of the interface region.
353  function Decimate_Hamiltonians( obj )
354  if ~isempty(obj.q)
355  K0loc = obj.K0 + obj.K1_transverse*diag(exp(1i*obj.q)) + obj.K1_transverse'*diag(exp(-1i*obj.q));
356  else
357  K0loc = obj.K0;
358  end
359  K = [K0loc,obj.K1;obj.K1adj,K0loc];
360 
361  non_singular_sites_slab = obj.kulso_szabfokok;
362  Neff_new = length(non_singular_sites_slab);
363 
364 
365  non_singular_sites = [non_singular_sites_slab, size(K,1)/2+1:size(K,1)];
366 
367  CreateH = CreateHamiltonians(obj.Opt, obj.param);
368  CreateH.Write('Hscatter', K);
369  CreateH.Write('kulso_szabfokok', non_singular_sites);
370  CreateH.Write('HamiltoniansCreated', true);
371  CreateH.Write('HamiltoniansDecimated', false);
372 
373  Decimation_Procedure = Decimation(obj.Opt);
374  Decimation_Procedure.DecimationFunc(0, CreateH, 'Hscatter', 'kulso_szabfokok');
375 
376  K = CreateH.Read('Hscatter');
377  CreateH.Clear('Hscatter');
378 
379  cCoordinates = obj.coordinates;
380  coord_fieldnames = fieldnames(cCoordinates);
381  if obj.Lead_Orientation == 1
382  K00 = K(Neff_new+1:end, Neff_new+1:end);
383  K1 = K(1:Neff_new, Neff_new+1:end);
384  K1adj = K(Neff_new+1:end, 1:Neff_new);
385 
386  % reordering the sites to get the non-singular sites at the top corner
387  indexes = false( size(K00,1), 1);
388  indexes(non_singular_sites_slab) = true;
389  K00 = [K00(indexes, indexes), K00(indexes, ~indexes); K00(~indexes, indexes), K00(~indexes, ~indexes)];
390  K1 = [K1(:, indexes), K1(:, ~indexes)];
391  K1adj = [K1adj(indexes, :); K1adj(~indexes, :)];
392  Kcoupling = obj.Kcoupling;
393  Kcoupling = [Kcoupling(indexes, :); Kcoupling(~indexes, :)];
394  Kcouplingadj = obj.Kcouplingadj;
395  Kcouplingadj = [Kcouplingadj(:,indexes), Kcouplingadj(:, ~indexes)];
396 
397  % reordering the sites to get the non-singular sites at the top corner
398  for idx = 1:length(coord_fieldnames)
399  fieldname = coord_fieldnames{idx};
400  if strcmpi(fieldname, 'a') || strcmpi(fieldname, 'b') || strcmpi(fieldname, 'LatticeConstant')
401  continue
402  elseif ~isempty(cCoordinates.(fieldname))
403  tmp = cCoordinates.(fieldname);
404  cCoordinates.(fieldname) = [tmp(indexes); tmp(~indexes)];
405  end
406  end
407 
408  elseif obj.Lead_Orientation == -1
409  % keeping only regular sites
410  K00 = K(1:Neff_new, 1:Neff_new);
411  K1 = K(1:Neff_new, Neff_new+non_singular_sites_slab);
412  K1adj = K(Neff_new+non_singular_sites_slab, 1:Neff_new);
413  Kcoupling = obj.Kcoupling;
414  Kcouplingadj = obj.Kcouplingadj;
415 
416  % keeping only regular sites
417  cCoordinates = cCoordinates.KeepSites(non_singular_sites_slab);
418  else
419  error('EQuUs:InterfaceRegion:Decimate_Interface', 'Unknown lead orientation');
420  end
421 
422  obj.next_SVD_cycle = InterfaceRegion(obj.Opt, obj.param, obj.varargin{:});
423  obj.next_SVD_cycle.Write('K00', K00);
424  obj.next_SVD_cycle.Write('K1', K1);
425  obj.next_SVD_cycle.Write('K1adj', K1adj);
426  obj.next_SVD_cycle.Write('Kcoupling', Kcoupling);
427  obj.next_SVD_cycle.Write('Kcouplingadj', Kcouplingadj);
428  obj.next_SVD_cycle.Write('HamiltoniansDecimated', true);
429  obj.next_SVD_cycle.Write('Neff', Neff_new);
430  obj.next_SVD_cycle.Write('coordinates', cCoordinates);
431 
432 
433  obj.HamiltoniansDecimated = true;
434  obj.Neff = size(obj.K0,1);
435 
436  end
437 
438 
439 %% Get_Neff
440 %> @brief Gets the effective number of sites after the elimination of the singular values.
441 %> @return Returns with the effective number of sites
442  function Neff = Get_Neff(obj)
443  if isempty(obj.next_SVD_cycle)
444  Neff = obj.Neff;
445  elseif strcmpi( class(obj.next_SVD_cycle), 'InterfaceRegion' )
446  Neff = obj.next_SVD_cycle.Get_Neff();
447  else
448  error('EQuUs:InterfaceRegion:Get_Neff', 'Unrecognized type of attribute next_SVD_cycle');
449  end
450 
451  end
452 
453 
454 %% CreateClone
455 %> @brief Creates a clone of the present class.
456 %> @return Returns with the cloned object.
457  function ret = CreateClone( obj )
458 
459 
460  ret = InterfaceRegion(obj.Opt, obj.param,...
461  'Hanyadik_Lead', obj.Hanyadik_Lead,...
462  'Lead_Orientation', obj.Lead_Orientation, ...
463  'q', obj.q);
464 
465  meta_data = metaclass(obj);
466 
467  for idx = 1:length(meta_data.PropertyList)
468  prop_name = meta_data.PropertyList(idx).Name;
469  if strcmpi( prop_name, 'next_SVD_cycle' )
470  if ~isempty( obj.next_SVD_cycle )
471  ret.next_SVD_cycle = obj.next_SVD_cycle.CreateClone();
472  end
473  else
474  ret.Write( prop_name, obj.(prop_name));
475  end
476  end
477 
478  end
479 
480 %% Reset
481 %> @brief Resets all elements in the object.
482  function Reset( obj )
483 
484  if strcmpi( class(obj), 'InterfaceRegion' )
485  meta_data = metaclass(obj);
486 
487  for idx = 1:length(meta_data.PropertyList)
488  prop_name = meta_data.PropertyList(idx).Name;
489  if strcmp(prop_name, 'Opt') || strcmp( prop_name, 'param') || strcmp(prop_name, 'varargin')
490  continue
491  end
492  obj.Clear( prop_name );
493  end
494  end
495 
496  Reset@SVDregularizationLead( obj );
497 
498  end
499 
500 %% Write
501 %> @brief Sets the value of an attribute in the interface.
502 %> @param MemberName The name of the attribute to be set.
503 %> @param input The value to be set.
504  function Write(obj, MemberName, input)
505 
506 
507  if strcmp(MemberName, 'param') || strcmp(MemberName, 'params')
508  Write@CreateLeadHamiltonians( obj, MemberName, input );
509  return
510  else
511  try
512  obj.(MemberName) = input;
513  catch
514  error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
515  end
516  end
517 
518  end
519 %% Read
520 %> @brief Query for the value of an attribute in the interface.
521 %> @param MemberName The name of the attribute to be set.
522 %> @return Returns with the value of the attribute.
523  function ret = Read(obj, MemberName)
524 
525  try
526  ret = obj.(MemberName);
527  catch
528  error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
529  end
530 
531  end
532 %% Clear
533 %> @brief Clears the value of an attribute in the interface.
534 %> @param MemberName The name of the attribute to be cleared.
535  function Clear(obj, MemberName)
536  try
537  obj.(MemberName) = [];
538  catch
539  error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
540  end
541 
542  end
543 
544 end
545 
546 %------------------------------------------------------------------
547 end % Global End
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.
Definition: structures.m:60
Class to create and store Hamiltonian of the translational invariant leads.
Property Neff
Effective number of sites after the elimination of the singular values.
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...
Definition: Decimation.m:29
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...
Definition: Lead.m:29
function()
Structure param contains data structures describing the physical parameters of the scattering center ...
Definition: structures.m:45
Structure sites contains data to identify the individual sites in a matrix.
Definition: structures.m:187
function Read(MemberName)
Query for the value of an attribute in the class.
function Lead(Opt, param, varargin)
Constructor of the class.
A class to create and store Hamiltonian of the scattering region.