Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
IV.m
Go to the documentation of this file.
1 %% Eotvos Quantum Transport Utilities - IV
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 utilities Utilities
18 %> @{
19 %> @file IV.m
20 %> @brief A class to calculate the I-V curve for a two terminal setup, based on the non-equilibrium Greens function technique of Eur. Phys. J. B 53, 537-549 (2006)
21 %> @}
22 %> @brief A class to calculate the I-V curve for a two terminal setup, based on the non-equilibrium Greens function technique of Eur. Phys. J. B 53, 537-549 (2006)
23 %> @Available
24 %> EQuUs v4.8 or later
25 %%
26 classdef IV < UtilsBase
27 
28 
29  properties (Access = protected)
30  %> The energy array used in the calculations
31  Evec
32  %> The maximal bias to be used in the calculations
33  bias_max
34  %> The number of the energy points in the attribute Evec
35  Edb
36  end
37 
38 
39 methods (Access=public)
40 
41 %% Contructor of the class
42 %> @brief Constructor of the class.
43 %> @param Opt an instance of class #Opt.
44 %> @param varargin Cell array of optional parameters. For details see #InputParsing.
45 %> @return An instance of the class
46  function obj = IV( Opt, varargin )
47 
48  obj = obj@UtilsBase(Opt, varargin{:} );
49 
50  if strcmpi(class(obj), 'IV')
51  obj.InputParsing( varargin{:});
52  end
53 
54 
55  end
56 
57 
58 
59 %% CurrentCalc
60 %> @brief Calculates the current-voltage relation as a function of the bias.
61 %> @param varargin Cell array of optional parameters (https://www.mathworks.com/help/matlab/ref/varargin.html):
62 %> @param 'tuned_contact' String value. Identifies the tuned contact for the calculations. Possible values are: 'right', 'left', 'symmetric'.
63 %> @return [1] The calculated current array.
64 %> @return [2] The calculated voltage bias array.
65 %> @return [3] The calculated differential conductance.
66  function [current, bias, DifferentialConductance_vec] = IVcalc( obj, varargin )
67 
68  p = inputParser;
69  p.addParameter('tuned_contact', 'right', @ischar); %which contact is tuned during the calculations: right, left, symmetric
70 
71  p.parse(varargin{:});
72 
73  tuned_contact = p.Results.tuned_contact;
74 
75  % create energy array if it is empty
76  if isempty( obj.Evec )
77  obj.CreateEnergyArray( 'tuned_contact', tuned_contact );
78  end
79 
80 
81 
82  Evec_tmp = obj.Evec;
83 
84  % preallocating array for the differential conductance
85  DifferentialConductance_vec = zeros( size(Evec_tmp) );
86 
87  % opening the parallel pool
88  poolmanager = Parallel( obj.Opt );
89  poolmanager.openPool();
90 
91  %
92  cNTerminal_loc = obj.junction;
93 
94  % creating function handles for the parfor loop
95  hDifferentialConductanceT0 = @(Energy, cNTerminal_loc)(obj.DifferentialConductanceT0(Energy, cNTerminal_loc));
96 
97  parfor (iidx = 1:length(Evec_tmp), poolmanager.NumWorkers)
98  Energy = Evec_tmp(iidx);
99  DifferentialConductance_vec(iidx) = feval(hDifferentialConductanceT0, Energy, cNTerminal_loc);
100  end
101 
102  % closing the parallel pool
103  poolmanager.closePool();
104 
105  % Calculate the IV curve
106  if strcmpi( tuned_contact, 'right') || strcmpi( tuned_contact, 'left')
107  current = zeros( size(Evec_tmp) );
108  for idx = 2:length(Evec_tmp)
109  current(idx) = obj.currentcalc( DifferentialConductance_vec(1:idx), Evec_tmp(1:idx), tuned_contact );
110  end
111 
112  indexes = (0 <= Evec_tmp & Evec_tmp <= obj.bias_max);
113  bias = Evec_tmp(indexes);
114  current = current(indexes);
115  DifferentialConductance_vec = DifferentialConductance_vec(indexes);
116 
117  elseif strcmpi( tuned_contact, 'symmetric' )
118  Evec_length = floor(length( Evec_tmp )/2);
119  current = zeros( Evec_length, 1 );
120  for idx = 2:Evec_length
121  current(idx) = obj.currentcalc( DifferentialConductance_vec(Evec_length-idx+1: Evec_length+idx-1), Evec_tmp(Evec_length-idx+1: Evec_length+idx-1), tuned_contact );
122  end
123  bias = [ 0, Evec_tmp(end-Evec_length+1:end) - Evec_tmp(Evec_length:-1:1)];
124  DifferentialConductance_vec = [DifferentialConductance_vec(Evec_length+1), DifferentialConductance_vec(Evec_length:-1:1) + DifferentialConductance_vec(end-Evec_length+1:end)];
125  indexes = 1;
126  end
127 
128 
129 
130 
131 
132  end
133 
134 
135 
136 
137 end % public methods
138 
139 
140 
141 methods (Access=protected)
142 
143 %> @brief Calculates the current by integrating the differential conductance in a bias window
144 %> @param differentialConductance Array of differential conductance
145 %> @param Evec Array of energy values
146 %> @param tuned_contact String value. Identifies the tuned contact for the calculations. Possible values are: 'right', 'left', 'symmetric'.
147 %> @return Returns with the calculated current
148  function current = currentcalc( obj, differentialConductance, Evec, tuned_contact )
149 
150  deltaEvec = [0, diff(Evec)];
151 
152  % defining the Fermi functions for the individual leads
153  if strcmpi( tuned_contact, 'right')
154  Fermi_left = @(E)(obj.Fermi( E ));
155  Fermi_right = @(E)(obj.Fermi( E-obj.bias_max ));
156  elseif strcmpi( tuned_contact, 'left')
157  Fermi_left = @(E)(obj.Fermi( E-obj.bias_max ));
158  Fermi_right = @(E)(obj.Fermi( E ));
159  elseif strcmpi( tuned_contact, 'symmetric')
160  Fermi_left = @(E)(obj.Fermi( E+obj.bias_max/2 ));
161  Fermi_right = @(E)(obj.Fermi( E-obj.bias_max/2 ));
162  else
163  current = [];
164  return
165  end
166 
167  % including temperature
168  differentialConductance = differentialConductance.*(Fermi_right(Evec) - Fermi_left(Evec));
169 
170  if mod(length( obj.Evec ),2) == 0
171  current = obj.SimphsonInt( differentialConductance(1:end-1).*deltaEvec(1:end-1) );
172  current = current + (differentialConductance(end-1) + differentialConductance(end) )*deltaEvec(end)/2;
173  else
174  current = obj.SimphsonInt( differentialConductance.*deltaEvec );
175  end
176 
177  end
178 
179 
180 
181 %% create_scatter_GreensFunction
182 %> @brief Calculates the surface Green operator of the scattering region.
183 %> @param varargin Cell array of optional parameters (https://www.mathworks.com/help/matlab/ref/varargin.html):
184 %> @param 'gauge_trans' Logical value. Set true (default) to perform gauge transformation on the Green's function and on the Hamiltonians, or false otherwise.
185 %> @param 'junction' An instance of class #NTerminal or its subclass.
186 %> @return The inverse of the Green operator.
187  function gfininv = create_scatter_GreensFunction( obj, varargin )
188 
189  p = inputParser;
190  p.addParameter('gauge_trans', true); % logical: true if want to perform gauge transformation on the Green's function and Hamiltonians
191  p.addParameter('junction', obj.junction); %for parallel computations
192  p.parse(varargin{:});
193  gauge_trans = p.Results.gauge_trans;
194  junction_loc = p.Results.junction;
195 
196  if obj.gfininvfromHamiltonian
197  %calculating the Greens function from the Hamiltonian
198  junction_loc.CalcFiniteGreensFunctionFromHamiltonian('onlyGinv', true, 'gauge_trans', false, 'scatterPotential', obj.scatterPotential );
199  else
200  % Calculating the Greens function by the fast way optimized for translational invariant systems
201  junction_loc.CalcFiniteGreensFunction('onlyGinv', true, 'gauge_trans', false);
202  end
203  [~, gfininv] = junction_loc.GetFiniteGreensFunction();
204  coordinates_scatter = junction_loc.getCoordinates();
205 
206 
207  % gauge transformation of the vector potential in the effective Hamiltonians
208  if gauge_trans && ~isempty( junction_loc.PeierlsTransform_Scatter )
209  gfininv = junction_loc.PeierlsTransform_Scatter.gaugeTransformation( gfininv, coordinates_scatter, junction_loc.gauge_field );
210  %NTerminal_loc.PeierlsTransform_Scatter.gaugeTransformationOnLead( NTerminal_loc.Surface_tmp, NTerminal_loc.gauge_field );
211  end
212 
213 
214  end
215 
216 
217 end
218 
219 
220 methods (Access=protected) %NEW
221 
222 %% DifferentialConductanceT0
223 %> @brief Calculates the zero temperature differential conductance for a given energy
224 %> @param Energy The energy value (use the same units as in the Hamiltonian)
225 %> @param junction An instance of class #NTerminal or its subclass.
226 %> @return Returns with the calculated zero temperature differential conductance.
227  function ret = DifferentialConductanceT0( obj, Energy, junction )
228 
229  % setting the energy value
230  obj.SetEnergy( Energy, 'junction', junction );
231  cTransport_Interface = junction.FL_handles;
232 
233  % calculating the Green function of the scattering reigon
234  gfininv = obj.create_scatter_GreensFunction('junction', junction);
235 
236  % setting the function handle for the Dyson equation
237  Dysonfunc = @()(junction.CustomDysonFunc( 'decimate', true, 'gfininv', gfininv, 'constant_channels', false, ...
238  'SelfEnergy', obj.useSelfEnergy) );
239 
240  cTransport_Interface.DysonEq( 'CustomDyson', Dysonfunc );
241 
242 
243  ret = cTransport_Interface.Conductance2();
244 
245  end
246 
247 
248 
249 %% CreateEnergyArray
250 %> @brief Creates the array of energy values for the integration
251 %> @param varargin Cell array of optional parameters (https://www.mathworks.com/help/matlab/ref/varargin.html):
252 %> @param 'tuned_contact' String value. Identifies the tuned contact for the calculations. Possible values are: 'right', 'left', 'symmetric'.
253  function CreateEnergyArray( obj, varargin )
254 
255  p = inputParser;
256  p.addParameter('tuned_contact', 'right', @ischar); %which contact is tuned during the calculations: right, left, symmetric
257 
258  p.parse(varargin{:});
259 
260  tuned_contact = p.Results.tuned_contact;
261 
262  if ~isscalar( obj.T )
263  error( 'EQuUs:Utils:IV:CreateEnergyArray', 'Temperature should be a scalar.');
264  end
265 
266  if obj.T < obj.T_treshold
267 
268  if strcmpi( tuned_contact, 'right')
269  mu_left = 0;
270  mu_right = obj.bias_max;
271  Emin = min( [mu_left, mu_right]);
272  Emax = max( [mu_left, mu_right]);
273  obj.Evec = Emin:(Emax-Emin)/(obj.Edb+1):Emax;
274  return
275 
276  elseif strcmpi( tuned_contact, 'left')
277  mu_left = obj.bias_max;
278  mu_right = 0;
279  Emin = min( [mu_left, mu_right]);
280  Emax = max( [mu_left, mu_right]);
281  obj.Evec = Emin:(Emax-Emin)/(obj.Edb+1):Emax;
282  return
283 
284  elseif strcmpi( tuned_contact, 'symmetric' )
285  mu_left = -obj.bias_max/2;
286  mu_right = obj.bias_max/2;
287  Emin = min( [mu_left, mu_right]);
288  Emax = max( [mu_left, mu_right]);
289  Emean = (Emax+Emin)/2;
290  deltaEvec = (Emax-Emin)/obj.Edb;
291  obj.Evec = [sort(Emean-deltaEvec:-deltaEvec:Emin, 'ascend'), Emean:deltaEvec:Emax];
292  return
293 
294  else
295  error( 'EQuUs:Utils:IV:CreateEnergyArray', 'Undefined contact to be tuned');
296  end
297 
298  else
299  tolerance = 1e-5;
300 
301  if strcmpi( tuned_contact, 'right')
302  mu_left = 0;
303  mu_right = obj.bias_max;
304  Fermi_left = @(E)(obj.Fermi( E-mu_left ));
305  Fermi_right = @(E)(obj.Fermi( E-mu_right ));
306  Emin = fzero(@(x)(Fermi_left(x)-1+tolerance), mu_left);
307  Emax = fzero(@(x)(Fermi_right(x)-tolerance), mu_right);
308  obj.Evec = Emin:(Emax-Emin)/(obj.Edb+1):Emax;
309  return
310 
311  elseif strcmpi( tuned_contact, 'left')
312 
313  mu_left = obj.bias_max; %relative to the Fermi level
314  mu_right = 0;
315  Fermi_left = @(E)(obj.Fermi( E-mu_left ));
316  Fermi_right = @(E)(obj.Fermi( E-mu_right ));
317  Emin = fzero(@(x)(Fermi_left(x)-tolerance), mu_left);
318  Emax = fzero(@(x)(Fermi_right(x)-1+tolerance), mu_right);
319  obj.Evec = Emin:(Emax-Emin)/(obj.Edb+1):Emax;
320  return
321 
322  elseif strcmpi( tuned_contact, 'symmetric' )
323  mu_left = obj.junction.getFermiEnergy() -obj.bias_max/2;
324  mu_right = obj.junction.getFermiEnergy() + obj.bias_max/2;
325  Fermi_left = @(E)(obj.Fermi( E-mu_left));
326  Fermi_right = @(E)(obj.Fermi( E-mu_right ));
327  if obj.bias_max > 0
328  Emin = fzero(@(x)(Fermi_left(x)-1+tolerance), mu_left);
329  Emax = fzero(@(x)(Fermi_right(x)-tolerance), mu_right);
330  elseif obj.bias_max < 0
331  Emin = fzero(@(x)(Fermi_left(x)-tolerance), mu_left);
332  Emax = fzero(@(x)(Fermi_right(x)-1+tolerance), mu_right);
333  else
334  obj.Evec = [];
335  return
336  end
337 
338  Emean = (Emax+Emin)/2;
339  deltaEvec = (Emax-Emin)/obj.Edb;
340  obj.Evec = [sort(Emean-deltaEvec:-deltaEvec:Emin, 'ascend'), Emean:deltaEvec:Emax];
341  return
342  else
343  error( 'EQuUs:Utils:IV:CreateEnergyArray', 'Undefined contact to be tuned');
344  end
345 
346  end
347 
348  end
349 
350 
351 
352 %% InputParsing
353 %> @brief Parses the optional parameters for the class constructor.
354 %> @param varargin Cell array of optional parameters (https://www.mathworks.com/help/matlab/ref/varargin.html):
355 %> @param 'T' The temperature in Kelvin (scalar or an array)
356 %> @param 'scatterPotential' A function handle pot=f( #coordinates ) or pot=f( #CreateHamiltonians, Energy) for the potential to be applied in the Hamiltonian (used when FiniteGreensFunctionFromHamiltonian=true).
357 %> @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).
358 %> @param 'useSelfEnergy' Logical value. Set true to use the self energies of the leads in the Dyson equation, or false (default) to use the surface Green function instead.
359 %> @param 'junction' An instance of class #NTerminal (or its derived class) representing the junction.
360 %> @param 'bias_max' The maximal bias to be used in the calculations
361 %> @param 'Edb' The number of the energy points in the attribute #Evec
362  function InputParsing( obj, varargin )
363 
364 
365  p = inputParser;
366  p.addParameter('T', obj.T, @isscalar);
367  p.addParameter('junction', obj.junction); %NEW changed parameter name
368  p.addParameter('scatterPotential', []);
369  p.addParameter('gfininvfromHamiltonian', false);
370  p.addParameter('useSelfEnergy', true);
371  p.addParameter('bias_max', 0); % The maximal bias to be used in the calculations %NEW
372  p.addParameter('Edb', 300); % The number of the energy points in the attribute Evec %NEW
373 
374  p.parse(varargin{:});
375 
376  InputParsing@UtilsBase( obj, 'T', p.Results.T, ...
377  'junction', p.Results.junction, ...
378  'scatterPotential', p.Results.scatterPotential, ...
379  'gfininvfromHamiltonian', p.Results.gfininvfromHamiltonian, ...
380  'useSelfEnergy', p.Results.useSelfEnergy);
381 
382  obj.bias_max = p.Results.bias_max;
383  obj.Edb = p.Results.Edb;
384 
385  if obj.bias_max <= 0
386  error(['EQuUs:Utils:', class(obj.junction), ':InputParsing'], 'Maximal bias should be greater than zero.');
387  end
388 
389 
390  end
391 
392 
393 end % protected methods
394 
395 end
A class for controlling the parallel pool for paralell computations.
Definition: Parallel.m:26
Structure Opt contains the basic computational parameters used in EQuUs.
Definition: structures.m:60
A class to calculate the I-V curve for a two terminal setup, based on the non-equilibrium Greens func...
Definition: IV.m:26
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.
function()
Structure param contains data structures describing the physical parameters of the scattering center ...
Definition: structures.m:45
gauge
String containining a bult-in vector potential. Possible values are: 'LandauX', 'LandauY'.
Definition: structures.m:72
This class is a base class containing common properties and methods utilized in several other classes...
Definition: UtilsBase.m:26