Added Potentials class, removed in-plane trap
This commit is contained in:
parent
d3db12c84e
commit
e99f0170d9
@ -58,6 +58,7 @@ OptionsStruct.DipolarAzimuthAngle = 0;
|
|||||||
OptionsStruct.ScatteringLength = 98.0676; % Critical point: 102.515; Triangular phase: 98.0676; Stripe phase: 102.2518; Honeycomb phase: 102.6441
|
OptionsStruct.ScatteringLength = 98.0676; % Critical point: 102.515; Triangular phase: 98.0676; Stripe phase: 102.2518; Honeycomb phase: 102.6441
|
||||||
|
|
||||||
OptionsStruct.TrapFrequencies = [10, 10, 72.4];
|
OptionsStruct.TrapFrequencies = [10, 10, 72.4];
|
||||||
|
OptionsStruct.TrapPotentialType = 'None';
|
||||||
|
|
||||||
OptionsStruct.NumberOfGridPoints = [128, 128];
|
OptionsStruct.NumberOfGridPoints = [128, 128];
|
||||||
OptionsStruct.Dimensions = [7.5, 7.5]; % Critical point: 6.996; Triangular phase: 7.5; Stripe phase: 6.972; Honeycomb phase: 6.239 for both for Atom Number fixed to 1E5
|
OptionsStruct.Dimensions = [7.5, 7.5]; % Critical point: 6.996; Triangular phase: 7.5; Stripe phase: 6.972; Honeycomb phase: 6.239 for both for Atom Number fixed to 1E5
|
||||||
@ -74,9 +75,11 @@ options = Helper.convertstruct2cell(OptionsStruct)
|
|||||||
clear OptionsStruct
|
clear OptionsStruct
|
||||||
|
|
||||||
solver = VariationalSolver2D.DipolarGas(options{:});
|
solver = VariationalSolver2D.DipolarGas(options{:});
|
||||||
|
pot = VariationalSolver2D.Potentials(options{:});
|
||||||
|
solver.Potential = pot.trap();
|
||||||
|
|
||||||
%-% Run Solver %-%
|
%-% Run Solver %-%
|
||||||
[Params, Transf, psi, V, VDk] = solver.run();
|
[Params, Transf, psi, V, VDk] = solver.run();
|
||||||
|
|
||||||
%% - Plot numerical grid
|
%% - Plot numerical grid
|
||||||
% Plotter.visualizeSpace2D(Transf)
|
% Plotter.visualizeSpace2D(Transf)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function VDk = calculateVDkWithCutoff(~, rcut, Transf, Params, VParams)
|
function VDk = calculateVDkWithCutoff(~, Transf, Params, VParams)
|
||||||
% == Calculating the DDI potential in Fourier space with appropriate cutoff == %
|
% == Calculating the DDI potential in Fourier space with appropriate cutoff == %
|
||||||
|
|
||||||
% Interaction in K space
|
% Interaction in K space
|
||||||
@ -21,7 +21,7 @@ function VDk = calculateVDkWithCutoff(~, rcut, Transf, Params, VParams)
|
|||||||
% Implementing a cutoff:
|
% Implementing a cutoff:
|
||||||
VDr = ifftn(VDk);
|
VDr = ifftn(VDk);
|
||||||
VDr = fftshift(VDr);
|
VDr = fftshift(VDr);
|
||||||
|
rcut = min(Transf.Xmax,Transf.Ymax);
|
||||||
R = sqrt(Transf.X.^2+Transf.Y.^2) < 0.9*rcut;
|
R = sqrt(Transf.X.^2+Transf.Y.^2) < 0.9*rcut;
|
||||||
VDr = VDr.*double(R);
|
VDr = VDr.*double(R);
|
||||||
VDr = ifftshift(VDr);
|
VDr = ifftshift(VDr);
|
||||||
|
@ -8,6 +8,7 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
|
|||||||
TrapFrequencies;
|
TrapFrequencies;
|
||||||
NumberOfGridPoints;
|
NumberOfGridPoints;
|
||||||
Dimensions;
|
Dimensions;
|
||||||
|
Potential;
|
||||||
|
|
||||||
SimulationMode;
|
SimulationMode;
|
||||||
TimeStepSize;
|
TimeStepSize;
|
||||||
@ -79,6 +80,7 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
|
|||||||
this.TrapFrequencies = p.Results.TrapFrequencies;
|
this.TrapFrequencies = p.Results.TrapFrequencies;
|
||||||
this.NumberOfGridPoints = p.Results.NumberOfGridPoints;
|
this.NumberOfGridPoints = p.Results.NumberOfGridPoints;
|
||||||
this.Dimensions = p.Results.Dimensions;
|
this.Dimensions = p.Results.Dimensions;
|
||||||
|
this.Potential = NaN;
|
||||||
this.TimeStepSize = p.Results.TimeStepSize;
|
this.TimeStepSize = p.Results.TimeStepSize;
|
||||||
this.MinimumTimeStepSize = p.Results.MinimumTimeStepSize;
|
this.MinimumTimeStepSize = p.Results.MinimumTimeStepSize;
|
||||||
this.TimeCutOff = p.Results.TimeCutOff;
|
this.TimeCutOff = p.Results.TimeCutOff;
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
function [psi,V,VDk] = initialize(this,Params,VParams,Transf)
|
function [psi,V,VDk] = initialize(this,Params,VParams,Transf)
|
||||||
|
|
||||||
format long
|
% == User-defined potential == %
|
||||||
X = Transf.X; Y = Transf.Y;
|
V = this.Potential;
|
||||||
rcut = min(Transf.Xmax,Transf.Ymax);
|
assert(~anynan(V), 'Potential not defined! Specify as <SimulatorObject>.Potential = <PotentialsObject>.trap() + <AdditionalTerms>.');
|
||||||
|
|
||||||
% == Potential == %
|
|
||||||
V = 0.5*(Params.gx.*X.^2+Params.gy.*Y.^2);
|
|
||||||
|
|
||||||
% == Calculating the DDIs == %
|
% == Calculating the DDIs == %
|
||||||
if isfile(strcat(this.SaveDirectory, '/VDk_M.mat'))
|
if isfile(strcat(this.SaveDirectory, '/VDk_M.mat'))
|
||||||
VDk = load(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')));
|
VDk = load(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')));
|
||||||
VDk = VDk.VDk;
|
VDk = VDk.VDk;
|
||||||
else
|
else
|
||||||
VDk = this.Calculator.calculateVDkWithCutoff(rcut, Transf, Params, VParams);
|
VDk = this.Calculator.calculateVDkWithCutoff(Transf, Params, VParams);
|
||||||
save(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')),'VDk');
|
save(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')),'VDk');
|
||||||
fprintf('Computed and saved DDI potential in Fourier space with cutoff.\n')
|
fprintf('Computed and saved DDI potential in Fourier space with cutoff.\n')
|
||||||
end
|
end
|
||||||
|
@ -26,6 +26,9 @@ function [psi] = propagateWavefunction(this, psi, Params, VParams, Transf, VDk,
|
|||||||
gamma_eff = Params.gammaQF * (sqrt(2/5)/(pi^(3/4)*VParams.ell^(3/2)));
|
gamma_eff = Params.gammaQF * (sqrt(2/5)/(pi^(3/4)*VParams.ell^(3/2)));
|
||||||
Ez = (0.25*VParams.ell^2) + (0.25*Params.gz*VParams.ell^2);
|
Ez = (0.25*VParams.ell^2) + (0.25*Params.gz*VParams.ell^2);
|
||||||
|
|
||||||
|
pb = Helper.ProgressBar();
|
||||||
|
pb.run('Running simulation in imaginary time: ');
|
||||||
|
|
||||||
while t_idx < Params.sim_time_cut_off
|
while t_idx < Params.sim_time_cut_off
|
||||||
|
|
||||||
% kin
|
% kin
|
||||||
@ -68,12 +71,11 @@ function [psi] = propagateWavefunction(this, psi, Params, VParams, Transf, VDk,
|
|||||||
|
|
||||||
%Adaptive time step -- Careful, this can quickly get out of control
|
%Adaptive time step -- Careful, this can quickly get out of control
|
||||||
relres = abs(Observ.residual(Observ.res_idx)-Observ.residual(Observ.res_idx-1))/Observ.residual(Observ.res_idx);
|
relres = abs(Observ.residual(Observ.res_idx)-Observ.residual(Observ.res_idx-1))/Observ.residual(Observ.res_idx);
|
||||||
|
if relres <1e-5
|
||||||
if relres <1e-4
|
if AdaptIdx > 4 && abs(dt) > Params.mindt
|
||||||
if AdaptIdx > 3 && abs(dt) > Params.mindt
|
|
||||||
dt = dt / 2;
|
dt = dt / 2;
|
||||||
AdaptIdx = 0;
|
AdaptIdx = 0;
|
||||||
elseif AdaptIdx > 3 && abs(dt) < Params.mindt
|
elseif AdaptIdx > 4 && abs(dt) < Params.mindt
|
||||||
break
|
break
|
||||||
elseif Observ.residual(Observ.res_idx) < Params.rtol
|
elseif Observ.residual(Observ.res_idx) < Params.rtol
|
||||||
break
|
break
|
||||||
@ -84,11 +86,14 @@ function [psi] = propagateWavefunction(this, psi, Params, VParams, Transf, VDk,
|
|||||||
AdaptIdx = 0;
|
AdaptIdx = 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if any(isnan(psi(:)))
|
if any(isnan(psi(:)))
|
||||||
disp('NaNs encountered!')
|
disp('NaNs encountered!')
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
t_idx=t_idx+1;
|
t_idx=t_idx+1;
|
||||||
|
pb.run(100*t_idx/Params.sim_time_cut_off);
|
||||||
end
|
end
|
||||||
|
|
||||||
% Change in Energy
|
% Change in Energy
|
||||||
|
@ -6,8 +6,8 @@ function [psi] = setupWavefunction(~,Params,Transf)
|
|||||||
ellx = sqrt(Params.hbar/(Params.m*Params.wx))/Params.l0;
|
ellx = sqrt(Params.hbar/(Params.m*Params.wx))/Params.l0;
|
||||||
elly = sqrt(Params.hbar/(Params.m*Params.wy))/Params.l0;
|
elly = sqrt(Params.hbar/(Params.m*Params.wy))/Params.l0;
|
||||||
|
|
||||||
Rx = 6*sqrt(2)*ellx;
|
Rx = 4*sqrt(2)*ellx;
|
||||||
Ry = 6*sqrt(2)*elly;
|
Ry = 4*sqrt(2)*elly;
|
||||||
X0 = 0.0*Transf.Xmax;
|
X0 = 0.0*Transf.Xmax;
|
||||||
Y0 = 0.0*Transf.Ymax;
|
Y0 = 0.0*Transf.Ymax;
|
||||||
|
|
||||||
|
@ -0,0 +1,171 @@
|
|||||||
|
classdef Potentials < handle & matlab.mixin.Copyable
|
||||||
|
|
||||||
|
properties (Access = private)
|
||||||
|
|
||||||
|
PotentialDefaults = struct('TrapPotentialType', 'Harmonic', ...
|
||||||
|
'TrapFrequencies', 100 * ones(1,3), ...
|
||||||
|
'TrapDepth', 10, ...
|
||||||
|
'BoxSize', 5);
|
||||||
|
end
|
||||||
|
|
||||||
|
properties (Access = public)
|
||||||
|
TrapPotentialType;
|
||||||
|
TrapFrequencies;
|
||||||
|
TrapDepth;
|
||||||
|
BoxSize;
|
||||||
|
NumberOfGridPoints;
|
||||||
|
Dimensions;
|
||||||
|
SimulationParameters;
|
||||||
|
end
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%- Methods
|
||||||
|
|
||||||
|
methods
|
||||||
|
function this = Potentials(varargin)
|
||||||
|
|
||||||
|
p = inputParser;
|
||||||
|
p.KeepUnmatched = true;
|
||||||
|
|
||||||
|
addParameter(p, 'TrapPotentialType', this.PotentialDefaults.TrapPotentialType,...
|
||||||
|
@(x) assert(any(strcmpi(x,{'None','Harmonic','SquareBox','RoundBox'}))));
|
||||||
|
addParameter(p, 'TrapFrequencies', this.PotentialDefaults.TrapFrequencies,...
|
||||||
|
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
||||||
|
addParameter(p, 'TrapDepth', this.PotentialDefaults.TrapDepth,...
|
||||||
|
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
||||||
|
addParameter(p, 'BoxSize', this.PotentialDefaults.BoxSize,...
|
||||||
|
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
||||||
|
addParameter(p, 'NumberOfGridPoints', 128 * ones(1,3),...
|
||||||
|
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
||||||
|
addParameter(p, 'Dimensions', 10 * ones(1,3),...
|
||||||
|
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
||||||
|
|
||||||
|
p.parse(varargin{:});
|
||||||
|
|
||||||
|
this.TrapPotentialType = p.Results.TrapPotentialType;
|
||||||
|
this.TrapFrequencies = p.Results.TrapFrequencies;
|
||||||
|
this.TrapDepth = p.Results.TrapDepth;
|
||||||
|
this.BoxSize = p.Results.BoxSize;
|
||||||
|
this.NumberOfGridPoints = p.Results.NumberOfGridPoints;
|
||||||
|
this.Dimensions = p.Results.Dimensions;
|
||||||
|
|
||||||
|
this.SimulationParameters = this.setupParameters();
|
||||||
|
end
|
||||||
|
|
||||||
|
function [ret] = trap(this)
|
||||||
|
format long
|
||||||
|
switch this.TrapPotentialType
|
||||||
|
case 'None'
|
||||||
|
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
||||||
|
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
||||||
|
[X,Y] = ndgrid(x,y);
|
||||||
|
|
||||||
|
ret = 0.0 * (X+Y);
|
||||||
|
case 'Harmonic'
|
||||||
|
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
||||||
|
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
||||||
|
[X,Y] = ndgrid(x,y);
|
||||||
|
|
||||||
|
ret = 0.5*(this.SimulationParameters.gx.*X.^2+this.SimulationParameters.gy.*Y.^2);
|
||||||
|
case 'SquareBox'
|
||||||
|
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
||||||
|
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
||||||
|
[X,Y] = ndgrid(x,y);
|
||||||
|
|
||||||
|
heaviside_X = this.custom_heaviside(-abs(X) + this.SimulationParameters.boxsize/2);
|
||||||
|
heaviside_Y = this.custom_heaviside(-abs(Y) + this.SimulationParameters.boxsize/2);
|
||||||
|
|
||||||
|
ret = this.SimulationParameters.boxdepth * (1 - heaviside_X .* heaviside_Y);
|
||||||
|
case 'RoundBox'
|
||||||
|
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
||||||
|
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
||||||
|
[X,Y] = ndgrid(x,y);
|
||||||
|
|
||||||
|
ret = this.SimulationParameters.boxdepth * (1 - this.custom_heaviside((this.SimulationParameters.boxsize/2)^2 - X.^2 - Y.^2));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function restoreDefaults(this)
|
||||||
|
this.TrapPotentialType = this.PotentialDefaults.TrapPotentialType;
|
||||||
|
this.TrapFrequencies = this.PotentialDefaults.TrapFrequencies;
|
||||||
|
end
|
||||||
|
end %
|
||||||
|
|
||||||
|
methods
|
||||||
|
function set.TrapFrequencies(this, val)
|
||||||
|
assert(isnumeric(val) && isvector(val) && all(val > 0), 'Incorrectly defined trap frequencies!');
|
||||||
|
this.TrapFrequencies = val;
|
||||||
|
end
|
||||||
|
function ret = get.TrapFrequencies(this)
|
||||||
|
ret = this.TrapFrequencies;
|
||||||
|
end
|
||||||
|
function set.TrapPotentialType(this, val)
|
||||||
|
assert(any(strcmpi(val,{'None','Harmonic','SquareBox','RoundBox'})), 'Trap potential of the specified type cannot be generated!');
|
||||||
|
this.TrapPotentialType = val;
|
||||||
|
end
|
||||||
|
function ret = get.TrapPotentialType(this)
|
||||||
|
ret = this.TrapPotentialType;
|
||||||
|
end
|
||||||
|
function set.NumberOfGridPoints(this, val)
|
||||||
|
assert(isnumeric(val) && isvector(val) && all(val > 0), 'Incorrectly defined grid!');
|
||||||
|
this.NumberOfGridPoints = val;
|
||||||
|
end
|
||||||
|
function ret = get.NumberOfGridPoints(this)
|
||||||
|
ret = this.NumberOfGridPoints;
|
||||||
|
end
|
||||||
|
function set.Dimensions(this, val)
|
||||||
|
assert(isnumeric(val) && isvector(val) && all(val > 0), 'Incorrectly defined dimensions!');
|
||||||
|
this.Dimensions = val;
|
||||||
|
end
|
||||||
|
function ret = get.Dimensions(this)
|
||||||
|
ret = this.Dimensions;
|
||||||
|
end
|
||||||
|
end % - setters and getters
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%- Methods
|
||||||
|
|
||||||
|
methods(Access = protected)
|
||||||
|
function cp = copyElement(this)
|
||||||
|
% Shallow copy object
|
||||||
|
cp = copyElement@matlab.mixin.Copyable(this);
|
||||||
|
|
||||||
|
% Forces the setter to redefine the function handles to the new copied object
|
||||||
|
|
||||||
|
pl = properties(this);
|
||||||
|
for k = 1:length(pl)
|
||||||
|
sc = superclasses(this.(pl{k}));
|
||||||
|
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
||||||
|
cp.(pl{k}) = this.(pl{k}).copy();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
methods (Static)
|
||||||
|
|
||||||
|
function y = custom_heaviside(x)
|
||||||
|
% This function computes the Heaviside step function with a custom value for Heaviside(0).
|
||||||
|
% x: input array
|
||||||
|
% H0: value for Heaviside(0)
|
||||||
|
|
||||||
|
% Use MATLAB's built-in heaviside function
|
||||||
|
y = heaviside(x);
|
||||||
|
|
||||||
|
% Replace the default value for Heaviside(0) with the custom value H0
|
||||||
|
y(x == 0) = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Creates an Instance of Class, ensures singleton behaviour (that there
|
||||||
|
% can only be one Instance of this class
|
||||||
|
function singleObj = getInstance(varargin)
|
||||||
|
% Creates an Instance of Class, ensures singleton behaviour
|
||||||
|
persistent localObj;
|
||||||
|
if isempty(localObj) || ~isvalid(localObj)
|
||||||
|
localObj = Simulator.Potentials(varargin{:});
|
||||||
|
end
|
||||||
|
singleObj = localObj;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -0,0 +1,34 @@
|
|||||||
|
function [Params] = setupParameters(this)
|
||||||
|
CONSTANTS = Helper.PhysicsConstants;
|
||||||
|
hbar = CONSTANTS.PlanckConstantReduced; % [J.s]
|
||||||
|
w0 = 2*pi*61.6582; % Angular frequency unit [s^-1]
|
||||||
|
|
||||||
|
% Mass, length scale
|
||||||
|
Params.m = CONSTANTS.Dy164Mass;
|
||||||
|
l0 = sqrt(hbar/(Params.m*w0)); % Defining a harmonic oscillator length
|
||||||
|
|
||||||
|
% Number of points in each direction
|
||||||
|
Params.Nx = this.NumberOfGridPoints(1);
|
||||||
|
Params.Ny = this.NumberOfGridPoints(2);
|
||||||
|
|
||||||
|
% Dimensions (in units of l0)
|
||||||
|
Params.Lx = this.Dimensions(1);
|
||||||
|
Params.Ly = this.Dimensions(2);
|
||||||
|
|
||||||
|
% Trapping frequencies
|
||||||
|
Params.wx = 2*pi*this.TrapFrequencies(1);
|
||||||
|
Params.wy = 2*pi*this.TrapFrequencies(2);
|
||||||
|
Params.wz = 2*pi*this.TrapFrequencies(3);
|
||||||
|
|
||||||
|
% Trap depth and box size for box potentials
|
||||||
|
Params.boxdepth = this.TrapDepth; % The depth of the box
|
||||||
|
Params.boxsize = this.BoxSize; % The size of the box
|
||||||
|
|
||||||
|
% ================ Parameters defined by those above ================ %
|
||||||
|
|
||||||
|
% Trap gamma
|
||||||
|
Params.gx = (Params.wx/w0)^2;
|
||||||
|
Params.gy = (Params.wy/w0)^2;
|
||||||
|
Params.gz = (Params.wz/w0)^2;
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user