Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
EigenProblemLead.m
Go to the documentation of this file.
1 %% Eotvos Quantum Transport Utilities - EigenProblemLead
2 % Copyright (C) 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 EigenProblemLead.m
20 %> @brief Class to solve the eigenproblem of a translational invariant leads and calculate the group velocities.
21 %> @}
22 %> @brief Class to solve the eigenproblem of a translational invariant leads and calculate the group velocities.
23 %> @Available
24 %> EQuUs v4.8 or later
25 %%
27 
28 
29 properties ( Access = protected )
30 %> true for calculating the retarded Green function, or false for the advanced Green function.
31  retarted
32 %> The unsorted right-sided eigenstates.
33  modusmtx
34 %> The unsorted left-sided eigenstates.
35  modusmtx_left
36 %> The unsorted wave numbers in form exp(1i*k).
37  expk
38 %> The unsorted group velocities.
39  csoportseb
40 %> The wave numbers of the eigenstates, that propagates or decays in the positive direction.
41  expk_p
42 %> The wave numbers of the eigenstates in form exp(1i*k), that propagates or decays in the negative direction.
43  expk_m
44 %> The group velocities of the eigenstates in form exp(1i*k), that propagates or decays in the positive direction.
45  vcsop_p
46 %> The group velocities of the eigenstates, that propagates or decays in the negative direction.
47  vcsop_m
48 %> The right sided wave functions of the eigenstates, that propagates or decays in the positive direction.
49  modusmtx_p
50 %> The right-sided wave functions of the eigenstates, that propagates or decays in the negative direction.
51  modusmtx_m
52 %> The left-sided wave numbers of the eigenstates, that propagates or decays in the positive direction.
53  modusmtx_p_left
54 %> The left-sided wave functions of the eigenstates, that propagates or decays in the negative direction.
55  modusmtx_m_left
56 %> The dual basis of the right-sided wave functions of the eigenstates, that propagates or decays in the positive direction.
57  d_modusmtx_p
58 %> The dual basis of the right-sided wave functions of the eigenstates, that propagates or decays in the negative direction.
59  d_modusmtx_m
60 %> A real number corresponding to the tolerance used to sort the left and right moving (decaying) modes.
61  sort_tolerance
62 %> A structure #open_channels containing info on the open channels
64 %> Logical matrix containing the degenerate k subspaces
65  degenerate_k_subspaces
66 %> The energy value for which the #TrukkosSajatertekek eigenvalue problem was solved.
67  E
68 end
69 
70 
71 
72 
73 methods ( Access = public )
74 %% constructorof the class
75 %> @brief Constructor of the class.
76 %> @param Opt An instance of the structure #Opt.
77 %> @param param An instance of structure #param.
78 %> @param varargin Cell array of optional parameters identical to #SVDregularizationLead.SVDregularizationLead.
79 %> @return An instance of the class
80  function obj = EigenProblemLead(Opt, param, varargin)
81  obj = obj@SVDregularizationLead( Opt, param, varargin{:} );
82  end
83 
84 %% Determine_Open_Channels
85 %> @brief Determines the open channels in the lead. The data are storen within the attribute #open_channels.
86  function Determine_Open_Channels( obj )
87  if isempty(obj.expk_p)
88  obj.display('Right and left going states were not determined yet. Use method EigenProblemLead::szetvalaszto first.', 1);
89  return;
90  end
91  propagating_indexes_p = logical( abs( abs(obj.expk_p) - 1 ) < obj.sort_tolerance );
92  propagating_indexes_m = logical( abs( abs(obj.expk_m) - 1 ) < obj.sort_tolerance );
93 
95  obj.open_channels.num = length(find(propagating_indexes_p));
96  obj.open_channels.open_channels_p = propagating_indexes_p;
97  obj.open_channels.open_channels_m = propagating_indexes_m;
98 
99  coordinates = obj.Get_Effective_Coordinates();
100 
101  if obj.Opt.BdG
102  if obj.isSuperconducting()
103  obj.open_channels.isSuperconducting = true;
104  else
105  obj.open_channels.BdG_u_incoming = logical(diag(obj.modusmtx_p(coordinates.BdG_u,:)'*obj.modusmtx_p(coordinates.BdG_u,:)));
106  obj.open_channels.BdG_u_outgoing = logical(diag(obj.modusmtx_m(coordinates.BdG_u,:)'*obj.modusmtx_m(coordinates.BdG_u,:)));
107  obj.open_channels.isSuperconducting = false;
108  end
109  else
110  obj.open_channels.isSuperconducting = false;
111  end
112 
113  end
114 
115 %% szetvalaszto
116 %> @brief Sorts the left and right propagating (decaying) modes.
117 %> @param tolerance The tolerance to be used during the sort.
118  function szetvalaszto( obj, tolerance )
119 
120  if isempty(obj.csoportseb)
121  return
122  end
123 
124 
125  if ~exist('tolerance', 'var')
126  tolerance = 1e-6;
127  elseif tolerance < 1e-16
128  err = MException(['EQuUs:', class(obj), ':szetvalaszto'], 'Failed to separate the left and right-going states');
129  save(['EQuUs_', class(obj), '_szetvalaszto.mat']);
130  throw(err);
131  end
132 
133  if obj.retarted
134  indexes = (real(obj.csoportseb*obj.Lead_Orientation) > 0 & abs(abs(obj.expk)-1) < tolerance) | (1-abs(obj.expk))*obj.Lead_Orientation > tolerance;
135  else
136  indexes = (real(obj.csoportseb*obj.Lead_Orientation) < 0 & abs(abs(obj.expk)-1) < tolerance) | (1-abs(obj.expk))*obj.Lead_Orientation > tolerance;
137  end
138  obj.expk_p = obj.expk(indexes);
139  obj.vcsop_p = obj.csoportseb(indexes);
140  obj.modusmtx_p = obj.modusmtx(:,indexes);
141  if ~obj.Opt.usingDualModes
142  obj.modusmtx_p_left = obj.modusmtx_left(indexes,:);
143  end
144 
145  obj.expk_m = obj.expk(~indexes);
146  obj.vcsop_m = obj.csoportseb(~indexes);
147  obj.modusmtx_m = obj.modusmtx(:,~indexes);
148  if ~obj.Opt.usingDualModes
149  obj.modusmtx_m_left = obj.modusmtx_left(~indexes,:);
150  end
151 
152  obj.sort_tolerance = tolerance;
153  if length(obj.expk_p) ~= length(obj.expk_m)
154  obj.szetvalaszto( obj.sort_tolerance/10 );
155  else
156  obj.modusmtx = [];
157  obj.csoportseb = [];
158  obj.expk = [];
159  end
160 
161 
162 
163  end
164 
165 %% Group_Velocity
166 %> @brief Calculates the group velocities corresponding to the propagating states. The calculated group velocities are stored within the class.
167  function Group_Velocity(obj)
168 
169  usingDualModes = obj.Opt.usingDualModes;
170 
171  csoportseb = obj.csoportseb;
172 
173  needs_to_be_diagonalized = false;
174 
175  GroupVelocityCalc();
176 
177  if needs_to_be_diagonalized
178  Diagonalize_Current_Operator();
179  GroupVelocityCalc();
180  end
181 
182  obj.csoportseb = diag(csoportseb);
183 
184 
185  %------------------------------------------------------------------
186  % nested functions
187  function Diagonalize_Current_Operator()
188 
189  [U, eigvals] = eig( full(csoportseb));
190 
191  % rotate the wavefunctions
192  obj.modusmtx = obj.modusmtx*U;
193  if ~usingDualModes
194  obj.modusmtx_left = U'*obj.modusmtx_left;
195  end
196  obj.NormalizeModes()
197 
198  % reordering the wavenumbers
199  obj.expk = diag(U'*diag(obj.expk)*U);
200 
201  obj.degenerate_k_subspaces = logical(speye(length(obj.expk)));
202 
203  end
204  %------------------------------------------------------------------
205 
206  %------------------------------------------------------------------
207  function GroupVelocityCalc()
208 
209  [~, K1_eff, K1adj_eff] = obj.Get_Effective_Hamiltonians();
210  Neff = obj.Get_Neff();
211  csoportseb = sparse([],[],[], 2*Neff, 2*Neff);
212  if usingDualModes
213  adj_modusmtx = obj.modusmtx';
214  for idx=1:2*Neff
215  jdx_indexes = obj.degenerate_k_subspaces(idx,:);
216  if ~needs_to_be_diagonalized && length(csoportseb(idx, jdx_indexes)) >1
217  needs_to_be_diagonalized = true;
218  end
219  %Eq (18) in GNew J. Phys 093029 (2014), (modes are already normalized with the overlap integrals)
220  csoportseb(idx, jdx_indexes) = 1i*adj_modusmtx(idx,:)*(K1_eff*obj.expk(idx)-K1adj_eff*(1/obj.expk(idx)) )*obj.modusmtx(:,jdx_indexes);
221  end
222 
223  else
224  %equation (A4) in PRB 78, 035407 (difference in the evanescent group velocities)
225  for idx=1:2*Neff
226  jdx_indexes = obj.degenerate_k_subspaces(idx,:);
227  if ~needs_to_be_diagonalized && length(csoportseb(idx, jdx_indexes)) >1
228  needs_to_be_diagonalized = true;
229  end
230  csoportseb(idx, jdx_indexes) = 1i*obj.modusmtx_left(idx,:)*(K1_eff*obj.expk(idx)-K1adj_eff*(1/obj.expk(idx)) )*obj.modusmtx(:,jdx_indexes);
231  end
232  end
233  end
234  % end nested functions
235  %------------------------------------------------------------------
236 
237 
238 
239  end
240 
241 
242 %% TrukkosSajatertekek
243 %> @brief Calculates the wave numbers corresponding to the propagating states at given energy. The calculated wave numbers are stored by attribute #expk.
244 %> @param E The energy value used in the calculations.
245  function TrukkosSajatertekek(obj, E)
246 
247  if imag(E) < 0
248  obj.retarted = false;
249  else
250  obj.retarted = true;
251  end
252 
253  obj.E = E;
254 
255  % create effective Hamiltonians with SVD regularization if necessary
256  obj.Calc_Effective_Hamiltonians( E );
257  [K0_eff, K1_eff, K1adj_eff] = obj.Get_Effective_Hamiltonians();
258  Neff = obj.Get_Neff();
259 
260  usingDualModes = obj.Opt.usingDualModes;
261 
262  if obj.isSuperconducting() || ~obj.Opt.BdG
263  % if normal system, or if BdG Hamiltonian with nonzero pair potential
264  [obj.modusmtx,obj.expk, obj.modusmtx_left] = calcTrickyEigenvalues( K0_eff, K1_eff, K1adj_eff );
265  else
266  % if BdG Hamiltonian with nonzero pair potential
267  M0 = Neff/2;
268  K0_e = K0_eff(1:M0, 1:M0);
269  K0_h = K0_eff(M0+1:Neff, M0+1:Neff);
270  K1_e = K1_eff(1:M0, 1:M0);
271  K1_h = K1_eff(M0+1:Neff, M0+1:Neff);
272  K1adj_e = K1adj_eff(1:M0, 1:M0);
273  K1adj_h = K1adj_eff(M0+1:Neff, M0+1:Neff);
274 
275  % eigenvalues for electron-like part
276  [modusmtx_e, expk_e, modusmtx_left_e] = calcTrickyEigenvalues( K0_e, K1_e, K1adj_e );
277 
278  %eigenvalues for hole-like part
279  [modusmtx_h, expk_h, modusmtx_left_h] = calcTrickyEigenvalues( K0_h, K1_h, K1adj_h );
280 
281  obj.modusmtx = [ modusmtx_e, zeros( size(modusmtx_e,1), size(modusmtx_e,2)); ...
282  zeros(size(modusmtx_h,1), size(modusmtx_e,2)), modusmtx_h ];
283 
284  obj.expk = [expk_e;expk_h];
285 
286  if ~usingDualModes
287  obj.modusmtx_left = [ modusmtx_left_e, zeros( size(modusmtx_left_e,1), size(modusmtx_left_e,2)); ...
288  zeros(size(modusmtx_left_h,1), size(modusmtx_left_e,2)), modusmtx_left_h ];
289  end
290 
291  end
292 
293  obj.NormalizeModes();
294  obj.Determine_Degenerate_k_subspaces();
295 
296  obj.modusmtx_p = [];
297  obj.modusmtx_m = [];
298  obj.d_modusmtx_p = [];
299  obj.d_modusmtx_m = [];
300 
301 
302 
303 
304 
305  %------------------------------------------------------------------
306  % nested functions
307  % calculates the tricky eigenvalue problem
308  function [modusmtx,expk, modusmtx_left] = calcTrickyEigenvalues( H0, H1, H1adj )
309  M = size(H0, 1);
310  [H_eff,B_eff] = Effective_H(H0,H1,H1adj);
311 
312  if usingDualModes
313  [modusmtx,expk] = eig(H_eff,B_eff);
314  expk = diag(expk);
315  modusmtx_left = [];
316  else
317  [modusmtx, modusmtx_left, expk] = obj.eig(H_eff,B_eff);
318  end
319 
320  if ~usingDualModes
321  % Eq (A3) in PRB 78, 035407
322  %normfactors = diag(modusmtx_left*B_eff*modusmtx);
323  %modusmtx_left = diag(1./normfactors)*modusmtx_left;
324  modusmtx_left = modusmtx_left(:,1:M);
325  modusmtx_left = diag(sqrt(expk))*modusmtx_left;
326  end
327 
328 
329  % Eq (7) in PRB 78, 035407
330  modusmtx = modusmtx(1:M,:);
331  modusmtx = modusmtx*diag(1./sqrt(expk));
332  end
333  %------------------------------------------------------------------
334 
335 
336  %------------------------------------------------------------------
337  % Eq (6) PRB 78 035407
338  function [H_eff,B_eff] = Effective_H(H0,H1,H1adj)
339  M = size(H0,1);
340  %H1inv = H1\eye(size(H1));%inv(H1);
341  H_eff = full([-H0,full(-H1adj);eye(M),zeros(M)]);
342  B_eff = full([ H1, zeros(M); zeros(M), eye(M)]);
343 
344  end
345  %------------------------------------------------------------------
346  % end nested functions
347  end
348 
349 
350 %% AddPotential
351 %> @brief Adds on-site potential to the Hamiltonian H0.
352 %> @param V The potential calculated on the sites.
353  function AddPotential( obj, V )
354 
355  AddPotential@CreateLeadHamiltonians( obj, V );
356  end
357 
358 %% Unitary_Transform
359 %> @brief Transforms the effective Hamiltonians by a unitary transformation
360 %> @param Umtx The matrix of the unitary transformation.
361  function Unitary_Transform(obj, Umtx)
362 
363  Unitary_Transform@SVDregularizationLead( obj, Umtx );
364 
365  if ~isempty(obj.modusmtx_p)
366  obj.modusmtx_p = Umtx*obj.modusmtx_p;
367  end
368 
369  if ~isempty(obj.modusmtx_m)
370  obj.modusmtx_m = Umtx*obj.modusmtx_m;
371  end
372 
373  if ~isempty(obj.modusmtx_p_left)
374  obj.modusmtx_p_left = Umtx*obj.modusmtx_p_left;
375  end
376 
377  if ~isempty(obj.modusmtx_m_left)
378  obj.modusmtx_m_left = Umtx*obj.modusmtx_m_left;
379  end
380 
381  if ~isempty(obj.d_modusmtx_p)
382  obj.d_modusmtx_p = obj.modusmtx_p*Umtx';
383  end
384 
385  if ~isempty(obj.d_modusmtx_m)
386  obj.d_modusmtx_m = obj.modusmtx_m*Umtx';
387  end
388 
389 
390  end
391 
392 %% CreateClone
393 %> @brief Creates a clone of the present object.
394 %> @return Returns with the cloned class.
395 %> @param varargin Cell array of optional parameters:
396 %> @param 'empty' Set true to create an empty class, or false (default) to copy all the attributes.
397 %> @return Returns with an instance of the cloned class.
398  function ret = CreateClone( obj )
399 
400  p = inputParser;
401  p.addParameter('empty', false );
402 
403  p.parse(varargin{:});
404  empty = p.Results.empty;
405 
406  ret = EigenProblemLead(obj.Opt, obj.param,...
407  'Hanyadik_Lead', obj.Hanyadik_Lead,...
408  'Lead_Orientation', obj.Lead_Orientation, ...
409  'q', obj.q);
410  if empty
411  return
412  end
413 
414  meta_data = metaclass(obj);
415 
416  for idx = 1:length(meta_data.PropertyList)
417  prop_name = meta_data.PropertyList(idx).Name;
418  if strcmpi( prop_name, 'next_SVD_cycle' )
419  if ~isempty( obj.next_SVD_cycle )
420  ret.next_SVD_cycle = obj.next_SVD_cycle.CreateClone();
421  end
422  else
423  ret.Write( prop_name, obj.(prop_name));
424  end
425  end
426 
427  end
428 
429 %% Reset
430 %> @brief Resets all elements in the object.
431  function Reset( obj )
432 
433  if strcmpi( class(obj), 'EigenProblemLead' )
434  meta_data = metaclass(obj);
435 
436  for idx = 1:length(meta_data.PropertyList)
437  prop_name = meta_data.PropertyList(idx).Name;
438  if strcmp(prop_name, 'Opt') || strcmp( prop_name, 'param') || strcmp(prop_name, 'varargin')
439  continue
440  end
441  obj.Clear( prop_name );
442  end
443  end
444 
445  obj.Initialize();
446 
447  end
448 
449 %% Write
450 %> @brief Sets the value of an attribute in the class.
451 %> @param MemberName The name of the attribute to be set.
452 %> @param input The value to be set.
453  function Write(obj, MemberName, input)
454 
455  if strcmp(MemberName, 'param') || strcmp(MemberName, 'params')
456  Write@CreateLeadHamiltonians( obj, MemberName, input );
457  return
458  else
459  try
460  obj.(MemberName) = input;
461  catch
462  error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
463  end
464  end
465 
466  end
467 %% Read
468 %> @brief Query for the value of an attribute in the class.
469 %> @param MemberName The name of the attribute to be set.
470 %> @return Returns with the value of the attribute.
471  function ret = Read(obj, MemberName)
472 
473  if strcmp(MemberName, 'Hamiltonian2Dec')
474  ret = Read@CreateLeadHamiltonians( obj, MemberName );
475  return
476  else
477  try
478  ret = obj.(MemberName);
479  catch
480  error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
481  end
482  end
483 
484  end
485 %% Clear
486 %> @brief Clears the value of an attribute in the class.
487 %> @param MemberName The name of the attribute to be cleared.
488  function Clear(obj, MemberName)
489 
490  try
491  obj.(MemberName) = [];
492  catch
493  error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
494  end
495 
496  end
497 
498 end %methods public
499 
500 
501 
502 methods (Access=private)
503 
504 %% Determine_Degenerate_k_subspaces
505 %> @brief Determine the degenerate k subspaces for which the current operator needs to be diagonalized.
506  function Determine_Degenerate_k_subspaces(obj)
507 
508  degeneracy_tolerance = 1e-12;
509 
510  obj.degenerate_k_subspaces = obj.expk*transpose(1./obj.expk);
511  obj.degenerate_k_subspaces = abs(obj.degenerate_k_subspaces - 1) < degeneracy_tolerance;
512 
513  end
514 
515 
516 %% NormalizeModes
517 %> @brief Renormalizes the wave functions with the overlap integrals (Eq (9) in PRB 78 035407
518  function NormalizeModes(obj)
519  usingDualModes = obj.Opt.usingDualModes;
520 
521  modusmtx_adj = obj.modusmtx';
522  [S0, S1, S1adj] = obj.Get_Effective_Overlaps();
523  if ~isempty(S0)
524  for idx = 1:length(obj.expk)
525  expk = obj.expk(idx);
526  if length(obj.q) < 2 && ~isempty(obj.q) && ~obj.HamiltoniansDecimated
527  S0 = S0 + obj.S1_transverse*diag(exp(-1i*obj.q)) + obj.S1_transverse'*diag(exp(1i*obj.q));
528  else
529  S0 = S0;
530  end
531  S = S0 + S1*expk + S1adj*(1/expk);
532 
533  l_n = modusmtx_adj(idx,:)*S*obj.modusmtx(:,idx);
534  obj.modusmtx(:,idx) = obj.modusmtx(:,idx)/sqrt(l_n);
535 
536  % normalize the left sided eigenvectors
537  if ~usingDualModes
538  l_n = obj.modusmtx_left(idx,:)*S*obj.modusmtx(:,idx);
539  obj.modusmtx_left(idx,:) = obj.modusmtx_left(idx,:)/(l_n);
540  end
541  end
542  else
543  %no overlap integrals are present
544  normfactors = diag( modusmtx_adj*obj.modusmtx );
545  obj.modusmtx = obj.modusmtx*diag(1./sqrt(normfactors));
546  if ~usingDualModes
547  normfactors = diag( obj.modusmtx_left*obj.modusmtx );
548  obj.modusmtx_left = diag(1./(normfactors))*obj.modusmtx_left;
549  end
550  end
551  end
552 
553 
554 %% Extend_Wavefncs --- DEVELOPMENT
555 %> @brief Extend the reduced wave functions to the original basis before the SVD regularization (Eq (45) in PRB 78 035407) This function is in a development stage.
556  function Extend_Wavefncs(obj) %NEW
557  wavefnc_extended = zeros(obj.M, obj.Get_Neff());
558  for idx = 1:length(obj.expk)
559  wavefnc_extended(:,idx) = obj.Extend_Wavefnc( obj.modusmtx(:,idx), obj.expk(idx) );
560  end
561 
562  obj.modusmtx = wavefnc_extended;
563  end
564 
565 
566 
567 
568 end % methods private
569 
570 
571 methods (Access=protected)
572 
573 %% Initialize
574 %> @brief Initializes object properties.
575  function Initialize(obj)
576  Initialize@SVDregularizationLead(obj);
577  obj.sort_tolerance = 1e-6;
578  end
579 
580 end
581 
582 
583 
584 end
Structure hole contains the data about the antidot used in class antidot.
Definition: structures.m:23
Structure Opt contains the basic computational parameters used in EQuUs.
Definition: structures.m:60
Structure open_channels describes the open channel in the individual leads.
Definition: structures.m:159
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.
Class to regulerize the H1 problem of the leads by SVD decompozition.
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 SVDregularizationLead(Opt, param, varargin)
Constructor of the class.
Class to solve the eigenproblem of a translational invariant leads and calculate the group velocities...
function structures(name)