Added functionality for real-time dynamics - quench of scattering length and rotation of dipoles.

This commit is contained in:
Karthik 2025-04-07 21:22:56 +02:00
parent 6566f53559
commit 178350bdc2
11 changed files with 443 additions and 118 deletions

View File

@ -1,4 +1,4 @@
function plotLive(psi,Params,Transf,Observ)
function plotLive(psi,Params,Transf,Observ,SimulationMode)
set(0,'defaulttextInterpreter','latex')
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
@ -14,6 +14,8 @@ function plotLive(psi,Params,Transf,Observ)
% Compute probability density |psi|^2
n = abs(psi).^2;
switch SimulationMode
case 'ImaginaryTimeEvolution'
%Plotting
figure(1);
clf
@ -73,4 +75,66 @@ function plotLive(psi,Params,Transf,Observ)
ylabel('$\mu$', 'FontSize', 14); xlabel('Time steps', 'FontSize', 14);
title('Chemical Potential', 'FontSize', 14);
grid on
case 'RealTimeEvolution'
%Plotting
figure(1);
clf
set(gcf,'Position', [100, 100, 1600, 900])
t = tiledlayout(2, 3, 'TileSpacing', 'compact', 'Padding', 'compact'); % 2x3 grid
nexttile;
nxz = squeeze(trapz(n*dy,2));
nyz = squeeze(trapz(n*dx,1));
nxy = squeeze(trapz(n*dz,3));
plotxz = pcolor(x,z,nxz');
set(plotxz, 'EdgeColor', 'none');
cbar1 = colorbar;
cbar1.Label.Interpreter = 'latex';
% cbar1.Ticks = []; % Disable the ticks
colormap(gca, Helper.Colormaps.plasma())
xlabel('$x$ ($\mu$m)', 'Interpreter', 'latex', 'FontSize', 14)
ylabel('$z$ ($\mu$m)', 'Interpreter', 'latex', 'FontSize', 14)
title('$|\Psi(x,z)|^2$', 'Interpreter', 'latex', 'FontSize', 14)
nexttile;
plotyz = pcolor(y,z,nyz');
set(plotyz, 'EdgeColor', 'none');
cbar1 = colorbar;
cbar1.Label.Interpreter = 'latex';
% cbar1.Ticks = []; % Disable the ticks
colormap(gca, Helper.Colormaps.plasma())
xlabel('$y$ ($\mu$m)', 'Interpreter', 'latex', 'FontSize', 14)
ylabel('$z$ ($\mu$m)', 'Interpreter', 'latex', 'FontSize', 14)
title('$|\Psi(y,z)|^2$', 'Interpreter', 'latex', 'FontSize', 14)
nexttile;
plotxy = pcolor(x,y,nxy');
set(plotxy, 'EdgeColor', 'none');
cbar1 = colorbar;
cbar1.Label.Interpreter = 'latex';
% cbar1.Ticks = []; % Disable the ticks
colormap(gca, Helper.Colormaps.plasma())
xlabel('$x$ ($\mu$m)', 'Interpreter', 'latex', 'FontSize', 14)
ylabel('$y$ ($\mu$m)', 'Interpreter', 'latex', 'FontSize', 14)
title('$|\Psi(x,y)|^2$', 'Interpreter', 'latex', 'FontSize', 14)
nexttile;
plot(Observ.tVecPlot,Observ.NormVec,'-b')
ylabel('$N$', 'FontSize', 14); xlabel('Time steps', 'FontSize', 14);
title('Normalization', 'FontSize', 14);
grid on
nexttile;
plot(Observ.tVecPlot,1-2*Observ.PCVec/pi,'-b')
ylabel('$C$', 'FontSize', 14); xlabel('Time steps', 'FontSize', 14);
title('Coherence', 'FontSize', 14);
grid on
nexttile;
plot(Observ.tVecPlot,Observ.EVec,'-b')
ylabel('$E_{tot}$', 'FontSize', 14); xlabel('Time steps', 'FontSize', 14);
title('Energy', 'FontSize', 14);
grid on
end

View File

@ -3,7 +3,7 @@
% Important: Run only sectionwise!!
%% - Create Simulator, Potential and Calculator object with specified options
% - Imaginary-Time
OptionsStruct = struct;
OptionsStruct.NumberOfAtoms = 40000;
@ -50,8 +50,79 @@ sim.Potential = pot.trap(); % + pot.repulsive_chopstick(
Plotter.visualizeTrapPotential(sim.Potential,Params,Transf)
%% - Plot initial wavefunction
Plotter.visualizeWavefunction(psi,Params,Transf)
%%
%% Imaginary-Time followed by Real-time
% - Imaginary-Time
OptionsStruct = struct;
OptionsStruct.NumberOfAtoms = 80000;
OptionsStruct.DipolarPolarAngle = deg2rad(0);
OptionsStruct.DipolarAzimuthAngle = 0;
OptionsStruct.ScatteringLength = 110;
OptionsStruct.TrapFrequencies = [50, 20, 150];
OptionsStruct.TrapPotentialType = 'Harmonic';
OptionsStruct.NumberOfGridPoints = [64, 128, 64];
OptionsStruct.Dimensions = [50, 50, 20];
OptionsStruct.UseApproximationForLHY = true;
OptionsStruct.IncludeDDICutOff = true;
OptionsStruct.CutoffType = 'CustomCylindrical';
OptionsStruct.CustomCylindricalCutOffRadius = 20.0;
OptionsStruct.CustomCylindricalCutOffHeight = 5.0;
OptionsStruct.SimulationMode = 'ImaginaryTimeEvolution'; % 'ImaginaryTimeEvolution' | 'RealTimeEvolution' | 'EnergyMinimization'
OptionsStruct.TimeStepSize = 5E-3; % in s
OptionsStruct.MinimumTimeStepSize = 1E-6; % in s
OptionsStruct.TimeCutOff = 1E5; % in s
OptionsStruct.EnergyTolerance = 5E-10;
OptionsStruct.ResidualTolerance = 1E-08;
OptionsStruct.NoiseScaleFactor = 0.010;
OptionsStruct.PlotLive = true;
OptionsStruct.JobNumber = 0;
OptionsStruct.RunOnGPU = false;
OptionsStruct.SaveData = false;
options = Helper.convertstruct2cell(OptionsStruct);
sim = Simulator.DipolarGas(options{:});
pot = Simulator.Potentials(options{:});
sim.Potential = pot.trap();
%-% Run Simulation %-%
[Params, Transf, psi, V, VDk] = sim.run();
SaveDirectory = './Results/Data_3D/RealTimeDynamics';
save(sprintf(strcat(SaveDirectory, '/psi_init.mat'),Params.njob),'psi','Transf','Params','VDk','V');
close all
clear
OptionsStruct.SimulationMode = 'RealTimeEvolution'; % 'ImaginaryTimeEvolution' | 'RealTimeEvolution' | 'EnergyMinimization'
OptionsStruct.EquilibrationTime = 20E-3;
OptionsStruct.QuenchTime = 30E-3;
OptionsStruct.HoldTime = 20E-3;
OptionsStruct.QuenchScatteringLength = true;
OptionsStruct.RotateDipoles = false;
OptionsStruct.FinalScatteringLength = 85;
OptionsStruct.FinalDipolarPolarAngle = deg2rad(90);
OptionsStruct.FinalDipolarAzimuthAngle = 0;
OptionsStruct.TimeStepSize = 1E-3; % in s
OptionsStruct.NoiseScaleFactor = 0.010;
OptionsStruct.PlotLive = true;
OptionsStruct.JobNumber = 0;
OptionsStruct.RunOnGPU = false;
OptionsStruct.SaveData = true;
OptionsStruct.SaveDirectory = SaveDirectory;
options = Helper.convertstruct2cell(OptionsStruct);
clear OptionsStruct
sim = Simulator.DipolarGas(options{:});
pot = Simulator.Potentials(options{:});
sim.Potential = pot.trap();
%-% Run Simulation %-%
[Params, Transf, psi, V, VDk] = sim.run();
%%
% To reproduce results from the Blair Blakie paper:
% (n*add^2, as/add)
% Critical point: (0.0978, 0.784); Triangular phase: (0.0959, 0.750); Stripe phase: (0.144, 0.765); Honeycomb phase: (0.192, 0.780)
@ -435,12 +506,16 @@ SaveDirectory = './Results/Data_3D/ApproximateLHY/BeyondSSD_Honeycomb';
JobNumber = 0;
Plotter.visualizeGSWavefunction(SaveDirectory, JobNumber)
%%
SaveDirectory = './Results/Data_3D/TiltedDipoles15';
SaveDirectory = './Results/Data_3D/TiltedDipoles0';
JobNumber = 0;
Plotter.visualizeGSWavefunction(SaveDirectory, JobNumber)
%%
SaveDirectory = './Results/Data_3D/TiltedDipoles15';
JobNumber = 1;
Plotter.visualizeGSWavefunction(SaveDirectory, JobNumber)
%%
SaveDirectory = './Results/Data_3D/TiltedDipoles30';
JobNumber = 0;
JobNumber = 1;
Plotter.visualizeGSWavefunction(SaveDirectory, JobNumber)
%%
SaveDirectory = './Results/Data_3D/TiltedDipoles45';

View File

@ -1,3 +1,4 @@
%{
theta = 0;
phi = 0;
@ -44,4 +45,52 @@ sim.Potential = pot.trap();
%-% Run Simulation %-%
[Params, Transf, psi, V, VDk] = sim.run();
%}
%% - Aspect Ratio: 2.5
theta = 45;
OptionsStruct = struct;
OptionsStruct.NumberOfAtoms = 1E5;
OptionsStruct.DipolarPolarAngle = deg2rad(theta);
OptionsStruct.DipolarAzimuthAngle = 0;
OptionsStruct.ScatteringLength = 85;
AspectRatio = 2.5;
HorizontalTrapFrequency = 125;
VerticalTrapFrequency = AspectRatio * HorizontalTrapFrequency;
OptionsStruct.TrapFrequencies = [HorizontalTrapFrequency, HorizontalTrapFrequency, VerticalTrapFrequency];
OptionsStruct.TrapPotentialType = 'Harmonic';
OptionsStruct.NumberOfGridPoints = [128, 128, 64];
OptionsStruct.Dimensions = [12, 12, 12];
OptionsStruct.UseApproximationForLHY = true;
OptionsStruct.IncludeDDICutOff = true;
OptionsStruct.CutoffType = 'CustomCylindrical';
OptionsStruct.CustomCylindricalCutOffRadius = 4.5;
OptionsStruct.CustomCylindricalCutOffHeight = 4.5;
OptionsStruct.SimulationMode = 'ImaginaryTimeEvolution'; % 'ImaginaryTimeEvolution' | 'RealTimeEvolution'
OptionsStruct.TimeStepSize = 1E-3; % in s
OptionsStruct.MinimumTimeStepSize = 2E-6; % in s
OptionsStruct.TimeCutOff = 2E6; % in s
OptionsStruct.EnergyTolerance = 5E-10;
OptionsStruct.ResidualTolerance = 1E-05;
OptionsStruct.NoiseScaleFactor = 0.01;
OptionsStruct.PlotLive = false;
OptionsStruct.JobNumber = 2;
OptionsStruct.RunOnGPU = true;
OptionsStruct.SaveData = true;
OptionsStruct.SaveDirectory = sprintf('./Results/Data_3D/TiltedDipoles%s', strrep(num2str(round(rad2deg(OptionsStruct.DipolarPolarAngle),2)), '.', '_'));
options = Helper.convertstruct2cell(OptionsStruct);
clear OptionsStruct
sim = Simulator.DipolarGas(options{:});
pot = Simulator.Potentials(options{:});
sim.Potential = pot.trap();
%-% Run Simulation %-%
[Params, Transf, psi, V, VDk] = sim.run();

View File

@ -36,7 +36,10 @@ classdef Calculator < handle & matlab.mixin.Copyable
p.KeepUnmatched = true;
addParameter(p, 'CutOffType', this.CalculatorDefaults.CutOffType,...
@(x) any(strcmpi(x,{'None', 'Cylindrical','CylindricalInfiniteZ', 'Spherical', 'CustomCylindrical'})));
addParameter(p, 'CustomCylindricalCutOffRadius', 1,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'CustomCylindricalCutOffHeight', 1,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
p.parse(varargin{:});
this.ChemicalPotential = this.CalculatorDefaults.ChemicalPotential;
@ -46,8 +49,8 @@ classdef Calculator < handle & matlab.mixin.Copyable
this.PhaseCoherence = this.CalculatorDefaults.PhaseCoherence;
this.TotalEnergy = this.CalculatorDefaults.TotalEnergy;
this.CutOffType = p.Results.CutOffType;
this.CustomCylindricalCutOffRadius = this.CalculatorDefaults.CustomCylindricalCutOffRadius;
this.CustomCylindricalCutOffHeight = this.CalculatorDefaults.CustomCylindricalCutOffHeight;
this.CustomCylindricalCutOffRadius = p.Results.CustomCylindricalCutOffRadius;
this.CustomCylindricalCutOffHeight = p.Results.CustomCylindricalCutOffHeight;
end
function restoreDefaults(this)

View File

@ -0,0 +1,19 @@
function [PhaseC] = calculatePhaseCoherence(~,psi,Transf)
norm = sum(sum(sum(abs(psi).^2,1),2),3)*Transf.dx*Transf.dy*Transf.dz;
psi = psi/sqrt(norm);
NumGlobalShifts = 800;
betas = []; phishift = [];
for jj = 1:NumGlobalShifts
phishift(jj) = -pi + 2*pi*(jj-1)/NumGlobalShifts;
betas(jj) = sum(sum(sum(abs(angle(psi*exp(-1i*phishift(jj)))).*abs(psi).^2)));
end
[~,minidx] = min(betas);
psi = psi*exp(-1i*phishift(minidx));
phi = angle(psi);
avgphi = sum(sum(sum(phi.*abs(psi).^2,1),2),3)*Transf.dx*Transf.dy*Transf.dz;
PhaseC = sum(sum(sum(abs(angle(psi)-avgphi).*abs(psi).^2)))*Transf.dx*Transf.dy*Transf.dz;
end

View File

@ -5,12 +5,20 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
DipolarPolarAngle;
DipolarAzimuthAngle
ScatteringLength;
FinalDipolarPolarAngle;
FinalDipolarAzimuthAngle
FinalScatteringLength;
EquilibrationTime;
QuenchTime;
HoldTime;
TrapFrequencies;
NumberOfGridPoints;
Dimensions;
Potential;
SimulationMode;
QuenchScatteringLength;
RotateDipoles;
TimeStepSize;
MinimumTimeStepSize;
TimeCutOff;
@ -23,6 +31,7 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
Calculator;
SimulationParameters;
QuenchSettings;
IncludeDDICutOff;
UseApproximationForLHY;
PlotLive;
@ -47,8 +56,14 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
@(x) assert(isnumeric(x) && isscalar(x) && (x > -2*pi) && (x < 2*pi)));
addParameter(p, 'DipolarAzimuthAngle', pi/2,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > -2*pi) && (x < 2*pi)));
addParameter(p, 'FinalDipolarPolarAngle', 0,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > -2*pi) && (x < 2*pi)));
addParameter(p, 'FinalDipolarAzimuthAngle', 0,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > -2*pi) && (x < 2*pi)));
addParameter(p, 'ScatteringLength', 120,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > -150) && (x < 150)));
addParameter(p, 'FinalScatteringLength', 88,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > -150) && (x < 150)));
addParameter(p, 'TrapFrequencies', 100 * ones(1,3),...
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
addParameter(p, 'NumberOfGridPoints', 128 * ones(1,3),...
@ -59,6 +74,12 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
@(x) assert(any(strcmpi(x,{'ImaginaryTimeEvolution','RealTimeEvolution', 'EnergyMinimization'}))));
addParameter(p, 'CutOffType', 'Cylindrical',...
@(x) assert(any(strcmpi(x,{'None', 'Cylindrical','CylindricalInfiniteZ', 'Spherical', 'CustomCylindrical'}))));
addParameter(p, 'EquilibrationTime', 20E-3,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'QuenchTime', 30E-3,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'HoldTime', 20E-3,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'TimeStepSize', 5E-4,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'MinimumTimeStepSize', 1e-6,...
@ -75,7 +96,10 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
@(x) assert(any(strcmpi(x,{'HeavyBall','NonLinearCGD'}))));
addParameter(p, 'MaxIterationsForGD', 100,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'QuenchScatteringLength', false,...
@islogical);
addParameter(p, 'RotateDipoles', false,...
@islogical);
addParameter(p, 'IncludeDDICutOff', true,...
@islogical);
addParameter(p, 'UseApproximationForLHY', false,...
@ -99,6 +123,12 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
this.DipolarPolarAngle = p.Results.DipolarPolarAngle;
this.DipolarAzimuthAngle = p.Results.DipolarAzimuthAngle;
this.ScatteringLength = p.Results.ScatteringLength;
this.FinalDipolarPolarAngle = p.Results.FinalDipolarPolarAngle;
this.FinalDipolarAzimuthAngle = p.Results.FinalDipolarAzimuthAngle;
this.FinalScatteringLength = p.Results.FinalScatteringLength;
this.EquilibrationTime = p.Results.EquilibrationTime;
this.QuenchTime = p.Results.QuenchTime;
this.HoldTime = p.Results.HoldTime;
this.TrapFrequencies = p.Results.TrapFrequencies;
this.NumberOfGridPoints = p.Results.NumberOfGridPoints;
this.Dimensions = p.Results.Dimensions;
@ -112,7 +142,8 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
this.NoiseScaleFactor = p.Results.NoiseScaleFactor;
this.GradientDescentMethod = p.Results.GradientDescentMethod;
this.MaxIterationsForGD = p.Results.MaxIterationsForGD;
this.QuenchScatteringLength = p.Results.QuenchScatteringLength;
this.RotateDipoles = p.Results.RotateDipoles;
this.IncludeDDICutOff = p.Results.IncludeDDICutOff;
this.UseApproximationForLHY = p.Results.UseApproximationForLHY;
this.PlotLive = p.Results.PlotLive;
@ -122,7 +153,7 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
this.DoSave = p.Results.SaveData;
this.SaveDirectory = p.Results.SaveDirectory;
this.Calculator = Simulator.Calculator('CutOffType', p.Results.CutOffType);
this.Calculator = Simulator.Calculator(varargin{:});
this.SimulationParameters = this.setupParameters();

View File

@ -15,7 +15,7 @@ function [psi,V,VDk] = initialize(this,Params,Transf,TransfRad)
[VDk, DDICutOffIncluded, CutOffType] = deal(loadedData.VDk, loadedData.DDICutOffIncluded, loadedData.CutOffType);
end
if isempty(VDk) || ~isequal(size(VDk), this.NumberOfGridPoints) || this.IncludeDDICutOff ~= DDICutOffIncluded
if isempty(VDk) || ~isequal(size(VDk), this.NumberOfGridPoints) || this.IncludeDDICutOff ~= DDICutOffIncluded || strcmp(this.Calculator.CutOffType, 'CustomCylindrical')
% Calculate VDk if necessary
VDk = this.Calculator.calculateVDk(Params, Transf, TransfRad, this.IncludeDDICutOff);
DDICutOffIncluded = this.IncludeDDICutOff;

View File

@ -3,7 +3,7 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
switch this.SimulationMode
case 'ImaginaryTimeEvolution'
dt = -1j*abs(this.TimeStepSize); % Imaginary Time
dt = -1j*abs(Params.dt); % Imaginary Time
KEop = 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
Observ.residual = 1;
@ -12,7 +12,7 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
if this.PlotLive
Plotter.plotLive(psi,Params,Transf,Observ)
Plotter.plotLive(psi,Params,Transf,Observ,this.SimulationMode)
drawnow
end
@ -59,11 +59,13 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
Observ.res_idx = Observ.res_idx + 1;
if this.PlotLive
Plotter.plotLive(psi,Params,Transf,Observ)
Plotter.plotLive(psi,Params,Transf,Observ,this.SimulationMode)
drawnow
end
if this.DoSave
save(sprintf(strcat(this.SaveDirectory, '/Run_%03i/psi_gs.mat'),Params.njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V');
end
%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);
@ -96,19 +98,40 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
Observ.res_idx = Observ.res_idx + 1;
disp('Run completed!');
if this.DoSave
disp('Saving data...');
save(sprintf(strcat(this.SaveDirectory, '/Run_%03i/psi_gs.mat'),Params.njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V');
disp('Save complete!');
end
case 'RealTimeEvolution'
dt = abs(this.TimeStepSize);
dt = abs(Params.dt);
KEop = 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
while t_idx < Params.sim_time_cut_off
if this.PlotLive
Plotter.plotLive(psi,Params,Transf,Observ,this.SimulationMode)
drawnow
end
while t_idx < this.QuenchSettings.tSteps
%Time
tVal = this.QuenchSettings.tVec(t_idx);
if this.QuenchScatteringLength
Params.gs = this.QuenchSettings.gs_vec(t_idx);
Params.gammaQF = this.QuenchSettings.gammaQF_vec(t_idx);
end
if this.RotateDipoles
Params.theta = this.QuenchSettings.theta_vec(t_idx);
Params.phi = this.QuenchSettings.phi_vec(t_idx);
VDk = this.Calculator.calculateVDk(Params, Transf, TransfRad, this.IncludeDDICutOff);
end
% Parameters at time t
@ -131,7 +154,7 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
if mod(t_idx,1000)==0
if mod(t_idx,this.QuenchSettings.saveinterval)==0
%Change in Normalization
Norm = sum(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; % normalisation
Observ.NormVec = [Observ.NormVec Norm];
@ -141,10 +164,21 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
E = E/Norm;
Observ.EVec = [Observ.EVec E];
% Phase coherence
[PhaseC] = this.Calculator.calculatePhaseCoherence(psi,Transf);
Observ.PCVec = [Observ.PCVec PhaseC];
Observ.tVecPlot = [Observ.tVecPlot tVal];
Observ.res_idx = Observ.res_idx + 1;
save(sprintf('./Data/Run_%03i/TimeEvolution/psi_%i.mat',Params.njob,Observ.res_idx),'psi','muchem','Observ','t_idx');
if this.PlotLive
Plotter.plotLive(psi,Params,Transf,Observ,this.SimulationMode)
drawnow
end
if this.DoSave
save(sprintf(strcat(this.SaveDirectory, '/Run_%03i/psi_%i.mat'), Params.njob, Observ.res_idx),'psi','muchem','Observ','t_idx');
end
end
if any(isnan(psi(:)))
disp('NaNs encountered!')
@ -170,12 +204,15 @@ function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ
Observ.res_idx = Observ.res_idx + 1;
disp('Run completed!');
if this.DoSave
disp('Saving data...');
save(sprintf('./Data/Run_%03i/TimeEvolution/psi_%i.mat',Params.njob,Observ.res_idx),'psi','muchem','Observ','t_idx');
save(sprintf(strcat(this.SaveDirectory, '/Run_%03i/psi_%i.mat'),Params.njob,Observ.res_idx),'psi','muchem','Observ','t_idx');
disp('Save complete!');
end
otherwise
disp('Choose a valid DDI cutoff type!')
disp('Choose a valid method!')
return
end
end

View File

@ -3,6 +3,10 @@ function [Params, Transf, psi,V,VDk] = run(this)
[Params] = this.setupParameters();
this.SimulationParameters = Params;
if strcmp(this.SimulationMode, 'RealTimeEvolution')
this.QuenchSettings = this.setupQuenchSettings(Params);
end
% --- Set up spatial grids and transforms ---
[Transf] = this.setupSpace(Params);
[TransfRad] = this.setupSpaceRadial(Params);

View File

@ -46,7 +46,7 @@ function [Params] = setupParameters(this)
Params.sim_time_cut_off = this.TimeCutOff; % sometimes the imaginary time gets a little stuck
% even though the solution is good, this just stops it going on forever
Params.mindt = this.MinimumTimeStepSize; % Minimum size for a time step using adaptive dt
Params.dt = this.TimeStepSize;
Params.nsf = this.NoiseScaleFactor;
Params.njob = this.JobNumber;

View File

@ -0,0 +1,43 @@
function Quench = setupQuenchSettings(this, Params)
Quench.eq_time = this.EquilibrationTime; % Equilibration time in s
Quench.quench_time = this.QuenchTime; % Quench time in s
Quench.hold_time = this.HoldTime; % Hold time in s
Quench.as_final = this.FinalScatteringLength*Params.a0; % Final scattering length in a0 (initial is Params.as)
Quench.theta_final = this.FinalDipolarPolarAngle; % pi/2 dipoles along x, theta=0 dipoles along z
Quench.phi_final = this.FinalDipolarAzimuthAngle;
% --- Save steps
Quench.saveinterval = 200;
% --- Constructing quench vectors
eq_time = Quench.eq_time*Params.w0;
quench_time = Quench.quench_time*Params.w0;
hold_time = Quench.hold_time*Params.w0;
tVec_Eq = 0:Params.dt:eq_time;
tVec_Q = (eq_time+Params.dt):Params.dt:(eq_time+quench_time);
tVec_H = (eq_time+quench_time+Params.dt):Params.dt:(eq_time+quench_time+hold_time);
Quench.tSteps = length(tVec_Eq) + length(tVec_Q) + length(tVec_H);
Quench.as_vec = [Params.as*ones(1, length(tVec_Eq)), linspace(Params.as,Quench.as_final,length(tVec_Q)), Quench.as_final*ones(1, length(tVec_H))];
Quench.gs_vec = 4*pi*Quench.as_vec/Params.l0;
Quench.theta_vec = [Params.theta*ones(1, length(tVec_Eq)), linspace(Params.theta,Quench.theta_final,length(tVec_Q)), Quench.theta_final*ones(1, length(tVec_H))];
Quench.phi_vec = [Params.phi*ones(1, length(tVec_Eq)), linspace(Params.phi,Quench.phi_final,length(tVec_Q)), Quench.phi_final*ones(1, length(tVec_H))];
Quench.tVec = [tVec_Eq, tVec_Q, tVec_H];
% Quantum fluctuations need to be calculated over the quench
eps_dd_vec = Params.add./Quench.as_vec;
if this.UseApproximationForLHY
Q5_vec = 1 + ((3*eps_dd_vec.^2)/2);
else
yeps_vec = (1-eps_dd_vec)./(3*eps_dd_vec);
Q5_vec = (3*eps_dd_vec).^(5/2).*( (8+26*yeps_vec+33*yeps_vec.^2).*sqrt(1+yeps_vec) + 15*yeps_vec.^3.*log((1+sqrt(1+yeps_vec))./sqrt(yeps_vec)) )/48;
Q5_vec = real(Q5_vec);
Q5_vec(eps_dd_vec == 0) = 1;
Q5_vec(eps_dd_vec == 1) = 3*sqrt(3)/2;
end
Quench.gammaQF_vec = 128/3*sqrt(pi*(Quench.as_vec/Params.l0).^5).*Q5_vec;
end