2 % Copyright (C) 2009-2017 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 basic Basic Functionalities
20 %> @brief A
class to evaluate
self-consistent potentials depending on electron (spin resolved) densities.
22 %> @brief A
class to evaluate self-consistent potentials depending on electron (spin resolved) densities.
24 %> EQuUs v4.9 or later
28 properties ( Access =
public )
29 %> An array containing the current density
31 %> structure describing the geometry of the
sites 33 %> The calculated filling factor
35 %> The prescribed magnezitaion direction (+1/-1)
36 magnetizaion_direction
37 %> The current magnetization
39 %> Logical value. Set true to export graphical results for each iteration %NEW
41 %> The
function handle for which the self-consistent iterations are performed: y = fhandle( qvec ), where y is an MxN matrix, and qvec is a vector of transverse momentums containing of M elements.
46 properties ( Access = protected )
47 %> false to supress output messages
49 %> Tolerance in the self-consistent iterations
51 %> Maximal number of iterations
53 %> Logical value. If true, the iteration cintinues with the loaded data, or false (default) otherwise.
55 %> The filename to export the calculated data.
57 %> A list containing previously calculated densities
59 %> A list containing the difference between previously calculated densities
60 delta_densities_iterations
61 %> A list containing previously calculated magnetizations
62 magnetization_iterations
63 %> Scalar value. The weith of the newly calculated density in the iterations.
65 %> list of optional parameters (see http:
71 methods (Access=public)
73 %% Contructor of the class
74 %> @brief Constructor of the class.
75 %> @
param Opt An instance of the structure
#Opt. 76 %> @
param interpq List of transverse momentum points at which #fhandle is calculated via interpolation.
77 %> @
param varargin Cell array of optional parameters. For details see #InputParsing.
78 %> @
return An instance of the
class 82 obj.varargin = varargin;
91 %% runSelfConsistentIterations
92 %> @brief Runs the
self-consistent iterations to obtain the elemets of the
self-consistent densities
for spin-up and spin-down electrons
93 %> @
param fhandle The
function handle to be calculated over the transverse momentum points: y = fhandle( qvec ), where y is an MxN matrix, and qvec is a vector of transverse momentums containing of M elements.
94 function runSelfConsistentIterations( obj, fhandle )
96 obj.display(
'*************************************')
97 obj.display(
'Starting self-consistent iterations.', 1 );
98 obj.display(
'*************************************')
100 if obj.resume && ~isempty(obj.outFileName)
104 loaded_data = HandleForLoad.LoadVariable('obj', 'NoEmpty', 'On');
105 HandleForLoad.ClearLoadedVariables();
107 meta_data = metaclass(loaded_data);
109 for idx = 1:length(meta_data.PropertyList)
110 prop_name = meta_data.PropertyList(idx).Name;
111 obj.(prop_name) = loaded_data.(prop_name);
115 obj.display( 'EQuUs:SelfConsitent:runSelfConsistentIterations: Failed to load data. Restarting calculations.', 1)
119 %> run the first iteration
120 if isempty( obj.density )
126 %> do the rest of the iterations
127 obj.filling_factor = sum(obj.density)/numel(obj.density);
128 for idx = 1:obj.MaxIter
129 % break the iterations if convergence is reached
130 if obj.ConvergenceTest()
134 % densities for the next iterations
135 obj.NewIterationInput();
137 % calculate the current densities
140 % scatter_density = obj.density(obj.
junction_sites.Scatter.site_indexes);
146 obj.filling_factor = sum(obj.density)/numel(obj.density);
148 %> reverting the magnetization direction if necessary
150 scatter_density = obj.density(obj.
junction_sites.Scatter.site_indexes);
151 obj.magnetization = sum(scatter_density(obj.
junction_sites.Scatter.coordinates.spinup) - scatter_density(~obj.
junction_sites.Scatter.coordinates.spinup));
152 if ~isempty(obj.magnetizaion_direction)
153 if sign(obj.magnetization) ~= sign(obj.magnetizaion_direction)
154 density_tmp = scatter_density;
157 obj.density(obj.
junction_sites.Scatter.site_indexes) = scatter_density;
158 obj.magnetization = -obj.magnetization;
163 %> calculating the difference compared to the privous density
164 if ~isempty( obj.densities_iterations{1} )
165 obj.delta_densities_iterations(1) = norm(obj.densities_iterations{1}-obj.density)/norm(obj.densities_iterations{1});
169 %> creating and displaying output messaage
170 message = [
'Iteration = ', num2str(idx),
', filling factor = ', num2str(obj.filling_factor),
', density delta = ', num2str(obj.delta_densities_iterations(1))];
172 message = [message,
', Magnetization = ', num2str(obj.magnetization_iterations(1)),
', magnetization delta = ', num2str(abs((obj.magnetization_iterations(1) - obj.magnetization)/obj.magnetization))];
174 obj.display(message, 1);
176 if obj.plotIterations
177 scatter_density = obj.density(obj.junction_sites.Scatter.site_indexes);
180 plot( obj.junction_sites.Scatter.coordinates.x(obj.junction_sites.Scatter.coordinates.spinup), scatter_density(obj.junction_sites.Scatter.coordinates.spinup),
'b+')
181 plot( obj.junction_sites.Scatter.coordinates.x(~obj.junction_sites.Scatter.coordinates.spinup), scatter_density(~obj.junction_sites.Scatter.coordinates.spinup),
'ro')
184 print('-depsc2', ['Iteration_', num2str(idx), '.eps'])
188 % exporting calculated data
189 if ~isempty( obj.outFileName )
190 save( obj.outFileName, 'obj');
195 if (idx == obj.MaxIter) && ~obj.ConvergenceTest()
196 obj.display( 'EQuUs:SelfConsitent:runSelfConsistentIterations: Iterations failed to converge.')
207 %> @brief Resets the class members.
216 %> @brief Sets the value of an attribute in the class.
217 %> @
param MemberName The name of the attribute to be set.
218 %> @
param input The value to be set.
219 function Write(obj, MemberName, input)
222 obj.(MemberName) = input;
224 error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
229 %> @brief Query for the value of an attribute in the class.
230 %> @
param MemberName The name of the attribute to be set.
231 %> @return Returns with the value of the attribute.
232 function ret = Read(obj, MemberName)
235 ret = obj.(MemberName);
237 error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
242 %> @brief Clears the value of an attribute in the class.
243 %> @
param MemberName The name of the attribute to be cleared.
246 obj.(MemberName) = [];
248 error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
256 methods ( Access = protected )
260 %> @brief Initializes class attributes.
265 obj.filling_factor = [];
269 obj.magnetization = [];
270 obj.magnetizaion_direction = [];
271 obj.plotIterations = [];
272 obj.newIterationWeight = [];
275 iterations_param = 10;
277 obj.densities_iterations = cell(iterations_param,1);
278 obj.delta_densities_iterations = nan(iterations_param,1);
279 obj.magnetization_iterations = nan(iterations_param,1);
281 obj.InputParsing( obj.varargin{:} );
286 %> @brief Creates input
for the next
self-consistent iteration
287 function NewIterationInput(obj)
289 iterations_param = length(obj.delta_densities_iterations);
290 nonzeros = find(obj.delta_densities_iterations);
295 weight_new = 0.2;%1/( iterations_param + 1);
296 indexes = ~isnan(obj.delta_densities_iterations);
297 weights = 1./obj.delta_densities_iterations(indexes);
299 weights = 1 - weight_new;
301 weights = weights/sum(weights);
302 weights = weights/(sum(weights)+weight_new);
308 %> determine
new iteration input by weighting the previous results
310 obj.density = weight_new*obj.density;
311 for iidx = 1:length(obj.densities_iterations)
312 if isempty( obj.densities_iterations{iidx} )
316 obj.density = obj.density + weights(iidx)*obj.densities_iterations{iidx};
319 %> renormalizing the density to the initial norm
320 filling_factor_tmp = sum(obj.density)/numel(obj.density);
321 obj.density = obj.density/filling_factor_tmp*obj.filling_factor;
323 %> calculating the difference compared to the privous density
324 if ~isempty( obj.densities_iterations{1} )
325 obj.delta_densities_iterations(1) = norm(obj.densities_iterations{1}-obj.density)/norm(obj.densities_iterations{1});
328 %> calculating the current magnetization
330 scatter_density = obj.density(obj.junction_sites.Scatter.site_indexes);
331 obj.magnetization = sum(scatter_density(obj.junction_sites.Scatter.coordinates.spinup) - scatter_density(~obj.junction_sites.Scatter.coordinates.spinup));
334 %> shifting iterations factors
335 obj.delta_densities_iterations(2:end) = obj.delta_densities_iterations(1:end-1);
336 for iidx = length(obj.densities_iterations):-1:2
337 obj.densities_iterations{iidx} = obj.densities_iterations{iidx-1};
339 obj.densities_iterations{1} = obj.density;
342 obj.magnetization_iterations(2:end) = obj.magnetization_iterations(1:end-1);
343 obj.magnetization_iterations(1) = obj.magnetization;
352 %> @brief Tests the convergence of the
self-consistent iterations.
353 %> @
return Return with
true if convergence was reached,
false otherwise
354 function ret = ConvergenceTest( obj )
356 if isnan(obj.delta_densities_iterations(1) )
361 ret1 = obj.delta_densities_iterations(1) < obj.tolerance;
363 if ~isempty(obj.Opt.Spin) && obj.Opt.Spin
364 if ~isnan( obj.magnetization_iterations(1) )
365 ret2 = ( abs((obj.magnetization_iterations(1) - obj.magnetization)/obj.magnetization) < obj.tolerance) ...
366 || ( abs(obj.magnetization) < obj.tolerance && abs(obj.magnetization_iterations(1)) < obj.tolerance);
380 %> @brief Parses the optional parameters
for the
class constructor.
381 %> @
param varargin Cell array of optional parameters (https:
382 %> @
param 'resume' Logical value. If
true, the iteration continues with the loaded data, or false (
default) otherwise.
383 %> @
param 'outFileName' The filename to save the calculated data. If it is empty (
default) no data are exported.
384 %> @
param 'silent' Logical value. Set
true to suppress the output messages, or false (
default) otherwise.
385 %> @
param 'magnetizaion_direction' Set +/- 1 to prescribe the magnetization direction, or set empty (
default) to not lock the magnetization direction.
386 %> @
param 'tolerance' Tolerance of the convergence
test. (Default is 2*10^-5)
387 %> @
param 'plotIterations' Set
true to visuelize the results of the
self-consistent iterations.
388 %> @
param 'newIterationWeight' Scalar value. The weith of the newly calculated density in the iterations. (Default value is 0.5)
389 %> @
param 'MaxIter' Maximal number of iterations. (Default value is 500)
390 function InputParsing( obj, varargin )
393 p.addParameter(
'resume', 0);
394 p.addParameter(
'outFileName', []);
395 p.addParameter(
'silent', obj.Opt.Silent);
396 p.addParameter(
'magnetizaion_direction', []);
397 p.addParameter(
'tolerance', 2e-5);
398 p.addParameter(
'plotIterations',
false);
399 p.addParameter(
'newIterationWeight', 0.5);
400 p.addParameter(
'MaxIter', 500);
402 p.parse(varargin{:});
405 obj.resume = p.Results.resume;
406 obj.outFileName = p.Results.outFileName;
407 obj.silent = p.Results.silent;
408 obj.magnetizaion_direction = p.Results.magnetizaion_direction;
409 obj.tolerance = p.Results.tolerance;
410 obj.plotIterations = p.Results.plotIterations;
411 obj.newIterationWeight = p.Results.newIterationWeight;
412 obj.MaxIter = p.Results.MaxIter;
419 end % methods
private function test(arg1, arg2)
Brief description of the function.
A class containing methodes for displaying several standard messages.
Structure Opt contains the basic computational parameters used in EQuUs.
A class to evaluate self-consistent potentials depending on electron (spin resolved) densities.
function Transport(Energy, B)
Calculates the conductance at a given energy value.
A class to calculate the onsite desnity useful for self-consistent calculations.
Structure param contains data structures describing the physical parameters of the scattering center ...
Structure sites contains data to identify the individual sites in a matrix.
A class providing interface to load variables from a file.
Structure junction_sites contains data to identify the individual sites of the leads,...