Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
SelfConsistent.m
Go to the documentation of this file.
1 %% Eotvos Quantum Transport Utilities - SelfConsistent
2 % Copyright (C) 2009-2017 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 SelfConsistent.m
20 %> @brief A class to evaluate self-consistent potentials depending on electron (spin resolved) densities.
21 %> @}
22 %> @brief A class to evaluate self-consistent potentials depending on electron (spin resolved) densities.
23 %> @Available
24 %> EQuUs v4.9 or later
25 %%
27 
28  properties ( Access = public )
29 %> An array containing the current density
30  density
31 %> structure describing the geometry of the sites
33 %> The calculated filling factor
34  filling_factor
35 %> The prescribed magnezitaion direction (+1/-1)
36  magnetizaion_direction
37 %> The current magnetization
38  magnetization
39 %> Logical value. Set true to export graphical results for each iteration %NEW
40  plotIterations
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.
42  fhandle
43  end
44 
45 
46  properties ( Access = protected )
47 %> false to supress output messages
48  silent
49  %> Tolerance in the self-consistent iterations
50  tolerance
51 %> Maximal number of iterations
52  MaxIter
53 %> Logical value. If true, the iteration cintinues with the loaded data, or false (default) otherwise.
54  resume
55 %> The filename to export the calculated data.
56  outFileName
57 %> A list containing previously calculated densities
58  densities_iterations
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.
64  newIterationWeight
65 %> list of optional parameters (see http://www.mathworks.com/help/matlab/ref/varargin.html for details)
66  varargin
67  end
68 
69 
70 
71 methods (Access=public)
72 
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
79  function obj = SelfConsistent( Opt, varargin )
80 
81  obj = obj@Messages( Opt );
82  obj.varargin = varargin;
83 
84  obj.Initialize();
85 
86 
87 
88  end
89 
90 
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 )
95 
96  obj.display( '*************************************')
97  obj.display( 'Starting self-consistent iterations.', 1 );
98  obj.display( '*************************************')
99 
100  if obj.resume && ~isempty(obj.outFileName)
101 
102  try
103  HandleForLoad = LoadFromFile( obj.outFileName );
104  loaded_data = HandleForLoad.LoadVariable('obj', 'NoEmpty', 'On');
105  HandleForLoad.ClearLoadedVariables();
106 
107  meta_data = metaclass(loaded_data);
108 
109  for idx = 1:length(meta_data.PropertyList)
110  prop_name = meta_data.PropertyList(idx).Name;
111  obj.(prop_name) = loaded_data.(prop_name);
112  end
113 
114  catch err
115  obj.display( 'EQuUs:SelfConsitent:runSelfConsistentIterations: Failed to load data. Restarting calculations.', 1)
116  end
117  end
118 
119  %> run the first iteration
120  if isempty( obj.density )
121  obj.Initialize();
122  [obj.density, obj.junction_sites] = feval(fhandle);
123  end
124 
125 
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()
131  break;
132  end
133 
134  % densities for the next iterations
135  obj.NewIterationInput();
136 
137  % calculate the current densities
138  [obj.density, obj.junction_sites] = feval(fhandle);
139 
140 % scatter_density = obj.density(obj.junction_sites.Scatter.site_indexes);
141 % figure
142 % hold on
143 % plot( obj.junction_sites.Scatter.coordinates.x(obj.junction_sites.Scatter.coordinates.spinup), scatter_density(obj.junction_sites.Scatter.coordinates.spinup))
144 % plot( obj.junction_sites.Scatter.coordinates.x(~obj.junction_sites.Scatter.coordinates.spinup), scatter_density(~obj.junction_sites.Scatter.coordinates.spinup), 'r')
145 
146  obj.filling_factor = sum(obj.density)/numel(obj.density);
147 
148  %> reverting the magnetization direction if necessary
149  if obj.Opt.Spin
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;
155  scatter_density(obj.junction_sites.Scatter.coordinates.spinup) = density_tmp(~obj.junction_sites.Scatter.coordinates.spinup);
156  scatter_density(~obj.junction_sites.Scatter.coordinates.spinup) = density_tmp(obj.junction_sites.Scatter.coordinates.spinup);
157  obj.density(obj.junction_sites.Scatter.site_indexes) = scatter_density;
158  obj.magnetization = -obj.magnetization;
159  end
160  end
161  end
162 
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});
166  end
167 
168 
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))];
171  if obj.Opt.Spin
172  message = [message, ', Magnetization = ', num2str(obj.magnetization_iterations(1)), ', magnetization delta = ', num2str(abs((obj.magnetization_iterations(1) - obj.magnetization)/obj.magnetization))];
173  end
174  obj.display(message, 1);
175 
176  if obj.plotIterations
177  scatter_density = obj.density(obj.junction_sites.Scatter.site_indexes);
178  figure1 = figure;
179  hold on
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')
182  xlabel('x')
183  ylabel('Density')
184  print('-depsc2', ['Iteration_', num2str(idx), '.eps'])
185  close(figure1);
186  end
187 
188  % exporting calculated data
189  if ~isempty( obj.outFileName )
190  save( obj.outFileName, 'obj');
191  end
192 
193  end
194 
195  if (idx == obj.MaxIter) && ~obj.ConvergenceTest()
196  obj.display( 'EQuUs:SelfConsitent:runSelfConsistentIterations: Iterations failed to converge.')
197  end
198 
199 
200 
201 
202 
203 
204  end
205 
206 %% Reset
207 %> @brief Resets the class members.
208  function Reset( obj )
209 
210  obj.Initialize();
211 
212  end
213 
214 
215 %% Write
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)
220 
221  try
222  obj.(MemberName) = input;
223  catch
224  error(['EQuUs:', class(obj), ':Read'], ['No property to write with name: ', MemberName]);
225  end
226 
227  end
228 %% Read
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)
233 
234  try
235  ret = obj.(MemberName);
236  catch
237  error(['EQuUs:', class(obj), ':Read'], ['No property to read with name: ', MemberName]);
238  end
239 
240  end
241 %% Clear
242 %> @brief Clears the value of an attribute in the class.
243 %> @param MemberName The name of the attribute to be cleared.
244  function Clear(obj, MemberName)
245  try
246  obj.(MemberName) = [];
247  catch
248  error(['EQuUs:', class(obj), ':Clear'], ['No property to clear with name: ', MemberName]);
249  end
250 
251  end
252 
253 end % public methods
254 
255 
256 methods ( Access = protected )
257 
258 
259 %% Initialize
260 %> @brief Initializes class attributes.
261  function Initialize(obj)
262 
263  obj.density = [];
264  obj.junction_sites = [];
265  obj.filling_factor = [];
266  obj.tolerance = [];
267  obj.MaxIter = 1e3;
268 
269  obj.magnetization = [];
270  obj.magnetizaion_direction = [];
271  obj.plotIterations = [];
272  obj.newIterationWeight = [];
273 
274 
275  iterations_param = 10;
276 
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);
280 
281  obj.InputParsing( obj.varargin{:} );
282  end
283 
284 
285 %% NewIterationInput
286 %> @brief Creates input for the next self-consistent iteration
287  function NewIterationInput(obj)
288 
289  iterations_param = length(obj.delta_densities_iterations);
290  nonzeros = find(obj.delta_densities_iterations);
291 
292  if isempty(nonzeros)
293  weight_new = 1;
294  else
295  weight_new = 0.2;%1/( iterations_param + 1);
296  indexes = ~isnan(obj.delta_densities_iterations);
297  weights = 1./obj.delta_densities_iterations(indexes);
298  if isempty(weights)
299  weights = 1 - weight_new;
300  else
301  weights = weights/sum(weights);
302  weights = weights/(sum(weights)+weight_new);
303  end
304 
305  end
306 
307 
308  %> determine new iteration input by weighting the previous results
309 
310  obj.density = weight_new*obj.density;
311  for iidx = 1:length(obj.densities_iterations)
312  if isempty( obj.densities_iterations{iidx} )
313  break
314  end
315 
316  obj.density = obj.density + weights(iidx)*obj.densities_iterations{iidx};
317  end
318 
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;
322 
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});
326  end
327 
328  %> calculating the current magnetization
329  if obj.Opt.Spin
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));
332  end
333 
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};
338  end
339  obj.densities_iterations{1} = obj.density;
340 
341  if obj.Opt.Spin
342  obj.magnetization_iterations(2:end) = obj.magnetization_iterations(1:end-1);
343  obj.magnetization_iterations(1) = obj.magnetization;
344  end
345 
346 
347 
348  end
349 
350 
351 %% ConvergenceTest
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 )
355 
356  if isnan(obj.delta_densities_iterations(1) )
357  ret = false;
358  return
359  end
360 
361  ret1 = obj.delta_densities_iterations(1) < obj.tolerance;
362 
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);
367  ret = ret1 & ret2;
368  else
369  ret = false;
370  end
371  return
372  else
373  ret = ret1;
374  return;
375  end
376 
377  end
378 
379 %% input parsing
380 %> @brief Parses the optional parameters for the class constructor.
381 %> @param varargin Cell array of optional parameters (https://www.mathworks.com/help/matlab/ref/varargin.html):
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 )
391 
392  p = inputParser;
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);
401 
402  p.parse(varargin{:});
403 
404 
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;
413 
414 
415  end
416 
417 
418 
419 end % methods private
420 
421 
422 end
function test(arg1, arg2)
Brief description of the function.
A class containing methodes for displaying several standard messages.
Definition: Messages.m:24
Structure Opt contains the basic computational parameters used in EQuUs.
Definition: structures.m:60
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.
function()
A class to calculate the onsite desnity useful for self-consistent calculations.
Definition: Density.m:26
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
A class providing interface to load variables from a file.
Definition: LoadFromFile.m:24
Structure junction_sites contains data to identify the individual sites of the leads,...
Definition: structures.m:176