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