Skip to content

Commit

Permalink
Updated the critical_* scripts, and added a simulate_* script for fer…
Browse files Browse the repository at this point in the history
…romagnets.
  • Loading branch information
Jabir Ali Ouassou committed Mar 4, 2015
1 parent 834011b commit 732b35b
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 184 deletions.
29 changes: 10 additions & 19 deletions Classes/Ferromagnet.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,7 @@

% Set the internal variables based on constructor arguments
self.exchange = exchange;
self.spinorbit = spinorbit;

% Add a triplet contribution to the initial state in order to
% improve the convergence of the differential equation solver
for n=1:length(positions)
for m=1:length(energies)
% triplet = (-1e-100 * exchange(1)) * SpinVector.Pauli.z ...
% + (1e-100i * exchange(2)) * eye(2) ...
% + (1e-100 * exchange(3)) * SpinVector.Pauli.x;
self.states(n,m).g = self.states(n,m).g;
self.states(n,m).gt = self.states(n,m).gt;
end
end
self.spinorbit = spinorbit;
end


Expand All @@ -55,8 +43,11 @@
% Define methods which are useful for working with ferromagnets
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function plot_comps(self)
% Calculate the singlet and triplet distributions
function plot_dist(self)
% Calculate the singlet and triplet distributions.
% NB: This implementation only *adds* the contribution from
% every energy, and does not perform a proper integral!

singlet = zeros(length(self.positions), 1);
triplet = zeros(length(self.positions), 1);
srtc = zeros(length(self.positions), 1);
Expand All @@ -78,7 +69,7 @@ function plot_comps(self)
positions, pchip(self.positions, triplet, positions));
legend('Singlet', 'Triplet');
else
% If there is an exchange field, distinguish SRT/LRT
% If there is an exchange field, do distinguish SRT/LRT
plot(positions, pchip(self.positions, singlet, positions), ...
positions, pchip(self.positions, srtc, positions), ...
positions, pchip(self.positions, lrtc, positions));
Expand Down Expand Up @@ -120,14 +111,14 @@ function update_coeff(self)
function update(self)
% This function updates the internal state of the ferromagnet
% by calling the other update methods. Always run this after
% updating the boundary conditions, exchange field, or
% spin-orbit field in the ferromagnet.
% updating the boundary conditions or fields in the ferromagnet,
% or after restoring from a backup.

% Update the state
self.update_coeff;
self.update_state;

% Plot the current DOS
% Plot the current density of states, if 'plot' is set to 'true'
if self.plot
self.plot_dos;
end
Expand Down
29 changes: 19 additions & 10 deletions Classes/Metal.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
% This defines a data structure that describes the physical state of a
% metal for a given range of positions and energies. The purpose of this
% class is mainly to be used as a base class for more interesting material
% classes, such as superconductors and ferromagnets.
% classes, such as those that describe superconductors and ferromagnets.
%
% Written by Jabir Ali Ouassou <[email protected]>
% Created 2015-02-23
Expand Down Expand Up @@ -58,7 +58,7 @@

% Initialize the internal state to a bulk superconductor with
% superconducting gap 1. This is useful as an initial guess
% when simulating strong proximity effects with energy units
% when simulating strong proximity effects in energy units
% where the zero-temperature gap is normalized to unity.
self.states(length(positions), length(energies)) = State;
for i=1:length(positions)
Expand Down Expand Up @@ -95,22 +95,22 @@ function update_boundary_left(self, other)
end

function update_boundary_right(self, other)
% This function updates the boundary condition to the left
% This function updates the boundary condition to the right
% based on the current state of another material.
self.boundary_right(:) = other.states(1,:);
end

function update_state(self)
% This function solves the Usadel equation numerically for the
% given position and energy range, and updates the current
% stored state of the system.
% estimate for the state of the system.

% Set the accuracy of the numerical solution
options = bvpset('AbsTol',self.error_abs,'RelTol',self.error_rel,'Nmax',self.grid_size);

% Partially evaluate the Jacobian matrix and boundary conditions
% for the different material energies, and store the resulting
% anonymous functions in a vector. These functions are passed on
% anonymous functions in an array. These functions are passed on
% to bvp6c when solving the equations.
jc = {};
bc = {};
Expand Down Expand Up @@ -140,7 +140,7 @@ function update_state(self)
self.states(n,m) = State(solution(:,n));
end

% Small time delay to prevent the interpreter from getting sluggish or killed by the system
% Time delay between iterations (reduces load on the system)
pause(self.delay);
end
end
Expand All @@ -154,7 +154,7 @@ function update(self)
self.update_coeff;
self.update_state;

% Plot the current DOS
% Plot the current density of states (if 'plot' is set to true)
if self.plot
self.plot_dos;
end
Expand All @@ -167,7 +167,10 @@ function update(self)

function print(self,varargin)
% This function is used to print messages, such as debug info
% and progress, if the 'debug' flag is set to 'true'.
% and progress, if the 'debug' flag is set to 'true'. The
% message is preceded by the name of the class, which lets you
% distinguish the output of 'Metal' instances from the output
% of instances of daughter classes.

if self.debug
fprintf(':: %s: %s\n', class(self), sprintf(varargin{:}));
Expand Down Expand Up @@ -202,7 +205,10 @@ function backup_load(self, backup)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function plot_dos(self)
% Calculate the density of states
% Calculate the density of states for the system.
% NB: This implementation only *adds* the contribution from
% every energy, and does not perform a proper integral!

dos = zeros(length(self.energies), 1);
for m=1:length(self.energies)
for n=1:length(self.positions)
Expand All @@ -218,7 +224,10 @@ function plot_dos(self)
end

function plot_dist(self)
% Calculate the singlet and triplet distributions
% Calculate the singlet and triplet distributions.
% NB: This implementation only *adds* the contribution from
% every energy, and does not perform a proper integral!

singlet = zeros(length(self.positions), 1);
triplet = zeros(length(self.positions), 1);
for m=1:length(self.energies)
Expand Down
2 changes: 1 addition & 1 deletion Classes/SpinVector.m
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function display(self)
% constants are given in polar coordinates, so that the Rashba constant
% is strength*sin(angle), and the Dresselhaus one strength*cos(angle).

% TODO: Add another argument to add SOC along z-axis.
% TODO: Add another argument which describes a SOC along the z-axis.

% Define the Rashba--Dresselhaus SU(2) field
result = SpinVector( strength*(cos(angle)*SpinVector.Pauli.x ...
Expand Down
34 changes: 21 additions & 13 deletions Classes/State.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
% solvers, and therefore provides the method 'vectorize' to pack the
% internal variables in a vector format, and constructor State(...)
% that is able to unpack this vector format. Alternatively, the
% vectorization can be performed without instantiating the class at all
% vectorization can be performed without instantiating the class at all,
% by calling the static methods 'pack' and 'unpack'.
%
% Written by Jabir Ali Ouassou <[email protected]>
Expand All @@ -34,8 +34,10 @@
methods
function self = State(varargin)
% This is the default constructor, which takes as its input either:
% (i) four 2x2 matrices, which should correspond to g, dg, gt, dgt;
% (ii) one 16-element complex vector, which should be produced by 'vectorize' method;
% (i) four 2x2 matrices, which should correspond to the
% matrices g, dg, gt, dgt, in that order;
% (ii) one 16-element complex vector, which should be produced
% by either the 'vectorize' metohd or the 'pack' method;
% (iii) no arguments, i.e. the empty constructor.
switch nargin
case 1
Expand Down Expand Up @@ -81,12 +83,14 @@ function display(self)
end

function g = eval_g(self)
% Return the Green's function matrix g (change from Riccati parametrization to normal Green's function)
% Return the Green's function matrix g, i.e. convert the
% Riccati parameter self.g to a normal Green's function.
g = ( eye(2) - self.g*self.gt ) \ ( eye(2) + self.g*self.gt );
end

function f = eval_f(self)
% Return the anomalous Green's function matrix f (change from Riccati parametrization to normal Green's function)
% Return the anomalous Green's function matrix f, i.e. convert
% the Riccati parameter self.g to a normal Green's function.
f = ( eye(2) - self.g*self.gt ) \ (2 * self.g);
end

Expand All @@ -95,29 +99,33 @@ function display(self)
end

function result = singlet(self)
% Calculate the singlet component of the Green's function (proportional to iσ^y)
% Calculate the singlet component of the Green's function,
% i.e. the component proportional to iσ^y.
f = self.eval_f;
result = (f(1,2) - f(2,1))/2;
end

function result = triplet(self)
% Calculate the triplet component of the Green's function (proportional to [σ^x,σ^y,σ^z]iσ^y)
% Calculate the triplet component of the Green's function,
% i.e. the component proportional to [σ^x,σ^y,σ^z] iσ^y.
f = self.eval_f;
result = [(f(2,2) - f(1,1))/2, ...
(f(1,1) + f(2,2))/2i, ...
(f(1,2) + f(2,1))/2];
end

function result = srtc(self, exchange)
% This method returns the short-range triplet component
% (along the exchange-field provided as an argument)
% This method returns the short-range triplet component, i.e.
% the triplet component *along* the exchange field, where the
% exchange field should be provided as an argument.
unitvec = exchange/norm(exchange);
result = dot(unitvec,self.triplet) .* unitvec;
end

function result = lrtc(self, exchange)
% This method returns the long-range triplet component
% (perpendicular to the exchange-field provided as argument)
% This method returns the long-range triplet component, i.e.
% the triplet component *perpendicular* to the exchange field,
% where the exchange field should be provided as argument.
result = self.triplet - self.srtc(exchange);
end
end
Expand All @@ -130,7 +138,7 @@ function display(self)
methods (Static)
function [g,dg,gt,dgt] = unpack(vector)
% This method is used to unpack a 16 element state vector into
% the Riccati parametrized Green's function it represents.
% the Riccati parametrized Green's function that it represents.
args = reshape(vector, 2, 8);
g = args(:,1:2);
dg = args(:,3:4);
Expand All @@ -140,7 +148,7 @@ function display(self)

function vector = pack(g,dg,gt,dgt)
% This method is used to pack Riccati parametrized Green's
% functions into a 1x16 state vector.
% functions into a 16 element complex state vector.
vector = reshape([g dg gt dgt], 16, 1);
end
end
Expand Down
31 changes: 21 additions & 10 deletions Classes/Superconductor.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

temperature = 0; % Temperature of the system (relative to the critical temperature of a bulk superconductor)
strength = 1; % Strength of the superconductor (the material constant N0V which appears in the gap equation)
strength = 0.2; % Strength of the superconductor (the material constant N0V which appears in the gap equation)
gap = griddedInterpolant([0,1],[1,1]); % Superconducting gap as a function of position (relative to the zero-temperature gap of a bulk superconductor)

end
Expand Down Expand Up @@ -58,19 +58,31 @@ function gap_reduce(self)
function result = gap_left(self)
% This function returns the left superconducting gap.

result = self.gap.Values(1);
result = abs(self.gap.Values(1));
end

function result = gap_right(self)
% This function returns the right superconducting gap.

result = self.gap.Values(end);
result = abs(self.gap.Values(end));
end

function result = gap_mean(self)
% This function returns the mean superconducting gap.

result = mean(self.gap.Values);
result = mean(abs(self.gap.Values));
end

function result = gap_max(self)
% This function returns the maximal superconducting gap.

result = max(abs(self.gap.Values));
end

function result = gap_min(self)
% This function returns the minimal superconducting gap.

result = min(abs(self.gap.Values));
end

function plot_gap(self)
Expand All @@ -91,7 +103,7 @@ function update_gap(self)
% This function updates the gap function, which contains the
% current estimate of the superconducting gap in the material.

% Calculate the gap at the positions in the system
% Calculate the gap at every position in the system
gaps = [];
for n=1:length(self.positions)
gaps(n) = self.calculate_gap(self, self.positions(n));
Expand All @@ -118,7 +130,7 @@ function update(self)
% This function updates the internal state of the superconductor
% by calling the other update methods. Always run this after
% updating the boundary conditions or physical properties of
% the superconductor.
% the superconductor, or after restoring from a backup.

% Update the state
self.update_gap;
Expand Down Expand Up @@ -239,10 +251,9 @@ function update(self)
end

function result = Bulk(energy, gap)
% This function takes as its input an energy and a superconducting gap,
% and returns a State object with Riccati parametrized Green's functions
% that corresponds to a BCS superconductor bulk state. We also
% include an infinitesimal triplet contribution.
% This function takes as its input an energy and a superconducting
% gap, and returns a State object with Riccati parametrized Green's
% functions that correspond to a BCS superconductor bulk state.
theta = atanh(gap/(energy+1e-3i));
c = cosh(theta);
s = sinh(theta);
Expand Down
Loading

0 comments on commit 732b35b

Please sign in to comment.