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 utilities Utilities
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)
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)
24 %> EQuUs v4.8 or later
29 properties (Access =
protected)
30 %> The energy array used in the calculations
32 %> The maximal bias to be used in the calculations
34 %> The number of the energy points in the attribute Evec
39 methods (Access=
public)
41 %% Contructor of the
class 42 %> @brief Constructor of the
class.
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 )
50 if strcmpi(
class(obj),
'IV')
60 %> @brief Calculates the current-voltage relation as a
function of the bias.
61 %> @
param varargin Cell array of optional parameters (https:
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 )
69 %p.addParameter(
'Edb', 50, @isscalar); NEW
70 p.addParameter(
'tuned_contact',
'right', @ischar); %which contact is tuned during the calculations: right, left, symmetric
74 tuned_contact = p.Results.tuned_contact;
76 % create energy array
if it is empty
77 if isempty( obj.Evec )
78 obj.CreateEnergyArray(
'tuned_contact', tuned_contact );
85 % preallocating array
for the differential conductance
86 DifferentialConductance_vec = zeros( size(Evec_tmp) );
88 % opening the parallel pool
90 poolmanager.openPool();
93 cNTerminal_loc = obj.junction;
95 % creating
function handles
for the parfor loop
96 hDifferentialConductanceT0 = @(Energy, cNTerminal_loc)(obj.DifferentialConductanceT0(Energy, cNTerminal_loc));
98 parfor (iidx = 1:length(Evec_tmp), poolmanager.NumWorkers)
99 Energy = Evec_tmp(iidx);
100 DifferentialConductance_vec(iidx) = feval(hDifferentialConductanceT0, Energy, cNTerminal_loc);
103 % closing the parallel pool
104 poolmanager.closePool();
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 );
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);
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 );
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)];
142 methods (Access=
protected)
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 )
151 deltaEvec = [0, diff(Evec)];
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 ));
168 % including temperature
169 differentialConductance = differentialConductance.*(Fermi_right(Evec) - Fermi_left(Evec));
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;
175 current = obj.SimphsonInt( differentialConductance.*deltaEvec );
182 %% create_scatter_GreensFunction
183 %> @brief Calculates the surface Green
operator of the scattering region.
184 %> @
param varargin Cell array of optional parameters (https:
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 ) 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;
197 if obj.gfininvfromHamiltonian
198 %calculating the Greens
function from the Hamiltonian
199 junction_loc.CalcFiniteGreensFunctionFromHamiltonian(
'onlyGinv',
true,
'gauge_trans',
false,
'scatterPotential', obj.scatterPotential );
201 % Calculating the Greens
function by the fast way optimized
for translational invariant systems
202 junction_loc.CalcFiniteGreensFunction(
'onlyGinv',
true,
'gauge_trans',
false);
204 [~, gfininv] = junction_loc.GetFiniteGreensFunction();
205 coordinates_scatter = junction_loc.getCoordinates();
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 );
221 methods (Access=
protected) %NEW
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 )
230 % setting the energy value
231 obj.SetEnergy( Energy,
'junction', junction );
234 % calculating the Green
function of the scattering reigon
235 gfininv = obj.create_scatter_GreensFunction(
'junction', junction);
237 % setting the
function handle for the Dyson equation
238 Dysonfunc = @()(junction.CustomDysonFunc(
'decimate',
true,
'gfininv', gfininv,
'constant_channels',
false, ...
239 'SelfEnergy', obj.useSelfEnergy) );
241 cTransport_Interface.DysonEq(
'CustomDyson', Dysonfunc );
244 ret = cTransport_Interface.Conductance2();
251 %> @brief Creates the array of energy values
for the integration
252 %> @
param varargin Cell array of optional parameters (https:
253 %> @
param 'tuned_contact' String value. Identifies the tuned contact
for the calculations. Possible values are:
'right',
'left',
'symmetric'.
254 function CreateEnergyArray( obj, varargin )
257 p.addParameter(
'tuned_contact',
'right', @ischar); %which contact is tuned during the calculations: right, left, symmetric
259 p.parse(varargin{:});
261 tuned_contact = p.Results.tuned_contact;
263 if ~isscalar( obj.T )
264 error(
'EQuUs:Utils:IV:CreateEnergyArray',
'Temperature should be a scalar.');
267 if obj.T < obj.T_treshold
269 if strcmpi( tuned_contact,
'right')
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;
277 elseif strcmpi( tuned_contact,
'left')
278 mu_left = obj.bias_max;
280 Emin = min( [mu_left, mu_right]);
281 Emax = max( [mu_left, mu_right]);
282 obj.Evec = Emin:(Emax-Emin)/(obj.Edb+1):Emax;
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];
296 error(
'EQuUs:Utils:IV:CreateEnergyArray',
'Undefined contact to be tuned');
302 if strcmpi( tuned_contact,
'right')
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;
312 elseif strcmpi( tuned_contact,
'left')
314 mu_left = obj.bias_max; %relative to the Fermi level
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;
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 ));
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);
339 Emean = (Emax+Emin)/2;
340 deltaEvec = (Emax-Emin)/obj.Edb;
341 obj.Evec = [sort(Emean-deltaEvec:-deltaEvec:Emin,
'ascend'), Emean:deltaEvec:Emax];
344 error(
'EQuUs:Utils:IV:CreateEnergyArray',
'Undefined contact to be tuned');
354 %> @brief Parses the optional parameters
for the
class constructor.
355 %> @
param varargin Cell array of optional parameters (https:
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 )
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
375 p.parse(varargin{:});
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);
383 obj.bias_max = p.Results.bias_max;
384 obj.Edb = p.Results.Edb;
387 error([
'EQuUs:Utils:',
class(obj.junction),
':InputParsing'],
'Maximal bias should be greater than zero.');
394 end %
protected methods
A class describing an N-terminal geometry for equilibrium calculations mostly in the zero temperature...
function InputParsing(varargin)
Parses the optional parameters for the class constructor.
A class for controlling the parallel pool for paralell computations.
Structure Opt contains the basic computational parameters used in EQuUs.
A class to calculate the I-V curve for a two terminal setup, based on the non-equilibrium Greens func...
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 ...
gauge
String containining a bult-in vector potential. Possible values are: 'LandauX', 'LandauY'.
This class is a base class containing common properties and methods utilized in several other classes...
Property E
The energy used in the calculations.
Property FL_handles
An instance of class Transport_Interface (or its subclass) for transport calculations.
function InputParsing(varargin)
Parses the optional parameters for the class constructor.
A class to create and store Hamiltonian of the scattering region.