Latest working version.

This commit is contained in:
Karthik 2024-06-17 12:14:15 +02:00
parent 570995f3f5
commit 6bb354de7a
17 changed files with 605 additions and 591 deletions

View File

@ -28,11 +28,10 @@ options = Helper.convertstruct2cell(OptionsStruct)
clear OptionsStruct clear OptionsStruct
sim = Simulator.DipolarGas(options{:}); sim = Simulator.DipolarGas(options{:});
calc = Simulator.Calculator(options{:});
pot = Simulator.Potentials(options{:}); pot = Simulator.Potentials(options{:});
%-% Run Simulation %-% %-% Run Simulation %-%
[Params, Transf, psi, V, VDk] = sim.runSimulation(calc); [Params, Transf, psi, V, VDk] = sim.runSimulation();
%% - Plot numerical grid %% - Plot numerical grid
Plotter.visualizeSpace(Transf) Plotter.visualizeSpace(Transf)

View File

@ -27,13 +27,23 @@ classdef Calculator < handle & matlab.mixin.Copyable
methods methods
function this = Calculator(varargin) function this = Calculator(varargin)
p = inputParser;
p.KeepUnmatched = true;
addParameter(p, 'CutoffType', this.CalculatorDefaults.CutoffType,...
@(x) any(strcmpi(x,{'Cylindrical','CylindricalInfiniteZ', 'Spherical'})));
p.parse(varargin{:});
this.ChemicalPotential = this.CalculatorDefaults.ChemicalPotential; this.ChemicalPotential = this.CalculatorDefaults.ChemicalPotential;
this.EnergyComponents = this.CalculatorDefaults.EnergyComponents; this.EnergyComponents = this.CalculatorDefaults.EnergyComponents;
this.NormalizedResiduals = this.CalculatorDefaults.NormalizedResiduals; this.NormalizedResiduals = this.CalculatorDefaults.NormalizedResiduals;
this.OrderParameter = this.CalculatorDefaults.OrderParameter; this.OrderParameter = this.CalculatorDefaults.OrderParameter;
this.PhaseCoherence = this.CalculatorDefaults.PhaseCoherence; this.PhaseCoherence = this.CalculatorDefaults.PhaseCoherence;
this.TotalEnergy = this.CalculatorDefaults.TotalEnergy; this.TotalEnergy = this.CalculatorDefaults.TotalEnergy;
this.CutoffType = this.CalculatorDefaults.CutoffType; this.CutoffType = p.Results.CutoffType;
this.CalculatorDefaults.CutoffType = this.CutoffType;
end end
function restoreDefaults(this) function restoreDefaults(this)

View File

@ -1,28 +1,29 @@
function muchem = calculateChemicalPotential(psi,Params,Transf,VDk,V) function muchem = calculateChemicalPotential(~,psi,Params,Transf,VDk,V)
%Parameters %Parameters
normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi); normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi);
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
% DDIs % DDIs
frho=fftn(abs(psi).^2); frho=fftn(abs(psi).^2);
Phi=real(ifftn(frho.*VDk)); Phi=real(ifftn(frho.*VDk));
Eddi = (Params.gdd*Phi.*abs(psi).^2); Eddi = (Params.gdd*Phi.*abs(psi).^2);
%Kinetic energy %Kinetic energy
Ekin = KEop.*abs(fftn(psi)*normfac).^2; Ekin = KEop.*abs(fftn(psi)*normfac).^2;
Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3; Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3;
%Potential energy %Potential energy
Epot = V.*abs(psi).^2; Epot = V.*abs(psi).^2;
%Contact interactions %Contact interactions
Eint = Params.gs*abs(psi).^4; Eint = Params.gs*abs(psi).^4;
%Quantum fluctuations %Quantum fluctuations
Eqf = Params.gammaQF*abs(psi).^5; Eqf = Params.gammaQF*abs(psi).^5;
%Total energy %Total energy
muchem = Ekin + trapz(Epot(:) + Eint(:) + Eddi(:) + Eqf(:))*Transf.dx*Transf.dy*Transf.dz; % muchem = Ekin + trapz(Epot(:) + Eint(:) + Eddi(:) + Eqf(:))*Transf.dx*Transf.dy*Transf.dz; %
muchem = muchem / Params.N; muchem = muchem / Params.N;
end

View File

@ -1,35 +1,35 @@
function E = calculateEnergyComponents(psi,Params,Transf,VDk,V) function E = calculateEnergyComponents(~,psi,Params,Transf,VDk,V)
%Parameters %Parameters
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi); normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi);
% DDIs % DDIs
frho = fftn(abs(psi).^2); frho = fftn(abs(psi).^2);
Phi = real(ifftn(frho.*VDk)); Phi = real(ifftn(frho.*VDk));
Eddi = 0.5*Params.gdd*Phi.*abs(psi).^2; Eddi = 0.5*Params.gdd*Phi.*abs(psi).^2;
E.Eddi = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz; E.Eddi = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz;
% EddiTot = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz; % EddiTot = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz;
%Kinetic energy %Kinetic energy
% psik = ifftshift(fftn(fftshift(psi)))*normfac; % psik = ifftshift(fftn(fftshift(psi)))*normfac;
Ekin = KEop.*abs(fftn(psi)*normfac).^2; Ekin = KEop.*abs(fftn(psi)*normfac).^2;
E.Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3; E.Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3;
% Potential energy % Potential energy
Epot = V.*abs(psi).^2; Epot = V.*abs(psi).^2;
E.Epot = trapz(Epot(:))*Transf.dx*Transf.dy*Transf.dz; E.Epot = trapz(Epot(:))*Transf.dx*Transf.dy*Transf.dz;
%Contact interactions %Contact interactions
Eint = 0.5*Params.gs*abs(psi).^4; Eint = 0.5*Params.gs*abs(psi).^4;
E.Eint = trapz(Eint(:))*Transf.dx*Transf.dy*Transf.dz; E.Eint = trapz(Eint(:))*Transf.dx*Transf.dy*Transf.dz;
%Quantum fluctuations %Quantum fluctuations
Eqf = 0.4*Params.gammaQF*abs(psi).^5; Eqf = 0.4*Params.gammaQF*abs(psi).^5;
E.Eqf = trapz(Eqf(:))*Transf.dx*Transf.dy*Transf.dz; E.Eqf = trapz(Eqf(:))*Transf.dx*Transf.dy*Transf.dz;
% plot(Transf.x,abs(psi(:,end/2,end/2+1)).^2) end

View File

@ -1,24 +1,25 @@
function res = calculateNormalizedResiduals(psi,Params,Transf,VDk,V,muchem) function res = calculateNormalizedResiduals(~,psi,Params,Transf,VDk,V,muchem)
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
% DDIs % DDIs
frho=fftn(abs(psi).^2); frho=fftn(abs(psi).^2);
Phi=real(ifftn(frho.*VDk)); Phi=real(ifftn(frho.*VDk));
Eddi = Params.gdd*Phi.*psi; Eddi = Params.gdd*Phi.*psi;
%Kinetic energy %Kinetic energy
Ekin = ifftn(KEop.*fftn(psi)); Ekin = ifftn(KEop.*fftn(psi));
%Potential energy %Potential energy
Epot = V.*psi; Epot = V.*psi;
%Contact interactions %Contact interactions
Eint = Params.gs*abs(psi).^2.*psi; Eint = Params.gs*abs(psi).^2.*psi;
%Quantum fluctuations %Quantum fluctuations
Eqf = Params.gammaQF*abs(psi).^3.*psi; Eqf = Params.gammaQF*abs(psi).^3.*psi;
%Total energy %Total energy
res = trapz(abs(Ekin(:) + Epot(:) + Eint(:) + Eddi(:) + Eqf(:) - muchem*psi(:))*Transf.dx*Transf.dy*Transf.dz)/trapz(abs(muchem*psi(:))*Transf.dx*Transf.dy*Transf.dz); res = trapz(abs(Ekin(:) + Epot(:) + Eint(:) + Eddi(:) + Eqf(:) - muchem*psi(:))*Transf.dx*Transf.dy*Transf.dz)/trapz(abs(muchem*psi(:))*Transf.dx*Transf.dy*Transf.dz);
end

View File

@ -1,39 +1,39 @@
function VDkSemi = calculateNumericalHankelTransform(this,kr,kz,Rmax,Zmax,Nr) function VDkSemi = calculateNumericalHankelTransform(~,kr,kz,Rmax,Zmax,Nr)
% accuracy inputs for numerical integration % accuracy inputs for numerical integration
if(nargin==5) if(nargin==5)
Nr = 5e4; Nr = 5e4;
end end
Nz = 64; Nz = 64;
farRmultiple = 2000; farRmultiple = 2000;
% midpoint grids for the integration over 0<z<Zmax, Rmax<r<farRmultiple*Rmax (i.e. starts at Rmax) % midpoint grids for the integration over 0<z<Zmax, Rmax<r<farRmultiple*Rmax (i.e. starts at Rmax)
dr=(farRmultiple-1)*Rmax/Nr; dr=(farRmultiple-1)*Rmax/Nr;
r = ((1:Nr)'-0.5)*dr+Rmax; r = ((1:Nr)'-0.5)*dr+Rmax;
dz=Zmax/Nz; dz=Zmax/Nz;
z = ((1:Nz)-0.5)*dz; z = ((1:Nz)-0.5)*dz;
[R, Z] = ndgrid(r,z); [R, Z] = ndgrid(r,z);
Rsq = R.^2 + Z.^2; Rsq = R.^2 + Z.^2;
% real space interaction to be transformed % real space interaction to be transformed
igrandbase = (1 - 3*Z.^2./Rsq)./Rsq.^(3/2); igrandbase = (1 - 3*Z.^2./Rsq)./Rsq.^(3/2);
% do the Hankel/Fourier-Bessel transform numerically % do the Hankel/Fourier-Bessel transform numerically
% prestore to ensure each besselj is only calculated once % prestore to ensure each besselj is only calculated once
% cell is faster than (:,:,krn) slicing % cell is faster than (:,:,krn) slicing
Nkr = numel(kr); Nkr = numel(kr);
besselr = cell(Nkr,1); besselr = cell(Nkr,1);
for krn = 1:Nkr for krn = 1:Nkr
besselr{krn} = repmat(r.*besselj(0,kr(krn)*r),1,Nz); besselr{krn} = repmat(r.*besselj(0,kr(krn)*r),1,Nz);
end end
VDkSemi = zeros([Nkr,numel(kz)]); VDkSemi = zeros([Nkr,numel(kz)]);
for kzn = 1:numel(kz) for kzn = 1:numel(kz)
igrandbasez = repmat(cos(kz(kzn)*z),Nr,1) .* igrandbase; igrandbasez = repmat(cos(kz(kzn)*z),Nr,1) .* igrandbase;
for krn = 1:Nkr for krn = 1:Nkr
igrand = igrandbasez.*besselr{krn}; igrand = igrandbasez.*besselr{krn};
VDkSemi(krn,kzn) = VDkSemi(krn,kzn) - sum(igrand(:))*dz*dr; VDkSemi(krn,kzn) = VDkSemi(krn,kzn) - sum(igrand(:))*dz*dr;
end end
end
end end

View File

@ -1,4 +1,4 @@
function [m_Order] = calculateOrderParameter(psi,Transf,Params,VDk,V,T,muchem) function [m_Order] = calculateOrderParameter(~,psi,Transf,Params,VDk,V,T,muchem)
NumRealiz = 100; NumRealiz = 100;

View File

@ -1,18 +1,19 @@
function [PhaseC] = calculatePhaseCoherence(psi,Transf,Params) function [PhaseC] = calculatePhaseCoherence(~,psi,Transf,Params)
norm = sum(sum(sum(abs(psi).^2,1),2),3)*Transf.dx*Transf.dy*Transf.dz; norm = sum(sum(sum(abs(psi).^2,1),2),3)*Transf.dx*Transf.dy*Transf.dz;
psi = psi/sqrt(norm); psi = psi/sqrt(norm);
NumGlobalShifts = 800; NumGlobalShifts = 800;
betas = []; phishift = []; betas = []; phishift = [];
for jj = 1:NumGlobalShifts for jj = 1:NumGlobalShifts
phishift(jj) = -pi + 2*pi*(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))); betas(jj) = sum(sum(sum(abs(angle(psi*exp(-1i*phishift(jj)))).*abs(psi).^2)));
end
[minbeta,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 end
[minbeta,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;

View File

@ -1,31 +1,32 @@
function E = calculateTotalEnergy(psi,Params,Transf,VDk,V) function E = calculateTotalEnergy(~,psi,Params,Transf,VDk,V)
%Parameters %Parameters
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi); normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi);
% DDIs % DDIs
frho = fftn(abs(psi).^2); frho = fftn(abs(psi).^2);
Phi = real(ifftn(frho.*VDk)); Phi = real(ifftn(frho.*VDk));
Eddi = 0.5*Params.gdd*Phi.*abs(psi).^2; Eddi = 0.5*Params.gdd*Phi.*abs(psi).^2;
% EddiTot = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz; % EddiTot = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz;
%Kinetic energy %Kinetic energy
% psik = ifftshift(fftn(fftshift(psi)))*normfac; % psik = ifftshift(fftn(fftshift(psi)))*normfac;
Ekin = KEop.*abs(fftn(psi)*normfac).^2; Ekin = KEop.*abs(fftn(psi)*normfac).^2;
Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3; Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3;
% Potential energy % Potential energy
Epot = V.*abs(psi).^2; Epot = V.*abs(psi).^2;
%Contact interactions %Contact interactions
Eint = 0.5*Params.gs*abs(psi).^4; Eint = 0.5*Params.gs*abs(psi).^4;
%Quantum fluctuations %Quantum fluctuations
Eqf = 0.4*Params.gammaQF*abs(psi).^5; Eqf = 0.4*Params.gammaQF*abs(psi).^5;
E = Ekin + trapz(Epot(:) + Eint(:) + Eddi(:) + Eqf(:))*Transf.dx*Transf.dy*Transf.dz; E = Ekin + trapz(Epot(:) + Eint(:) + Eddi(:) + Eqf(:))*Transf.dx*Transf.dy*Transf.dz;
end

View File

@ -15,6 +15,8 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
EnergyTolerance; EnergyTolerance;
MinimumTimeStep; MinimumTimeStep;
Calculator;
%Flags %Flags
DebugMode; DebugMode;
@ -46,6 +48,8 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0))); @(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
addParameter(p, 'SimulationMode', 'ImaginaryTimeEvolution',... addParameter(p, 'SimulationMode', 'ImaginaryTimeEvolution',...
@(x) any(strcmpi(x,{'ImaginaryTimeEvolution','RealTimeEvolution'}))); @(x) any(strcmpi(x,{'ImaginaryTimeEvolution','RealTimeEvolution'})));
addParameter(p, 'CutoffType', 'Cylindrical',...
@(x) any(strcmpi(x,{'Cylindrical','CylindricalInfiniteZ', 'Spherical'})));
addParameter(p, 'TimeStep', 5E-4,... addParameter(p, 'TimeStep', 5E-4,...
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0))); @(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
addParameter(p, 'SimulationTime', 2e6,... addParameter(p, 'SimulationTime', 2e6,...
@ -81,6 +85,8 @@ classdef DipolarGas < handle & matlab.mixin.Copyable
this.DoSave = p.Results.SaveData; this.DoSave = p.Results.SaveData;
this.SaveDirectory = p.Results.SaveDirectory; this.SaveDirectory = p.Results.SaveDirectory;
this.Calculator = Simulator.Calculator('CutoffType', p.Results.CutoffType);
switch this.SimulationMode switch this.SimulationMode
case "ImaginaryTimeEvolution" case "ImaginaryTimeEvolution"
% Development In progress % Development In progress

View File

@ -1,22 +1,20 @@
function [psi,V,VDk] = initialize(this,calcObj,Params,Transf,TransfRad) function [psi,V,VDk] = initialize(this,Params,Transf,TransfRad)
format long
X = Transf.X; Y = Transf.Y; Z = Transf.Z;
format long % == Trap potential == %
X = Transf.X; Y = Transf.Y; Z = Transf.Z; V = 0.5*(Params.gx.*X.^2+Params.gy.*Y.^2+Params.gz*Z.^2);
% == Trap potential == % % == Calculating the DDIs == %
V = 0.5*(Params.gx.*X.^2+Params.gy.*Y.^2+Params.gz*Z.^2); if isfile(strcat(this.SaveDirectory, '/VDk_M.mat'))
% == Calculating the DDIs == %
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 = calcObj.calculateVDCutoff(Params,Transf,TransfRad); VDk = this.Calculator.calculateVDCutoff(Params,Transf,TransfRad);
save(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')),'VDk'); save(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')),'VDk');
end end
fprintf('Computed and saved DDI potential in Fourier space with %s cutoff.', calcObj.CutoffType) fprintf('Computed and saved DDI potential in Fourier space with %s cutoff.', this.Calculator.CutoffType)
% == Setting up the initial wavefunction == %
psi = this.setupWavefunction(Params,Transf);
% == Setting up the initial wavefunction == %
psi = this.setupWavefunction(Params,Transf);
end end

View File

@ -1,4 +1,4 @@
function [Params, Transf, psi,V,VDk] = runSimulation(this,calcObj) function [Params, Transf, psi,V,VDk] = runSimulation(this)
% --- Obtain simulation parameters --- % --- Obtain simulation parameters ---
[Params] = this.setupParameters(); [Params] = this.setupParameters();
@ -9,15 +9,15 @@ function [Params, Transf, psi,V,VDk] = runSimulation(this,calcObj)
% --- Initialize --- % --- Initialize ---
mkdir(sprintf(this.SaveDirectory)) mkdir(sprintf(this.SaveDirectory))
[psi,V,VDk] = this.initialize(calcObj,Params,Transf,TransfRad); [psi,V,VDk] = this.initialize(Params,Transf,TransfRad);
Observ.EVec = []; Observ.NormVec = []; Observ.PCVec = []; Observ.tVecPlot = []; Observ.mucVec = []; Observ.EVec = []; Observ.NormVec = []; Observ.PCVec = []; Observ.tVecPlot = []; Observ.mucVec = [];
t_idx = 1; %Start at t = 0; t_idx = 1; %Start at t = 0;
Observ.res_idx = 1; Observ.res_idx = 1;
% --- Job Settings --- % --- Job Settings ---
% njob = 6; njob = 6;
% mkdir(sprintf('./Data/Run_%03i',njob)) mkdir(sprintf('./Data/Run_%03i',njob))
% --- Run Simulation --- % --- Run Simulation ---
% [psi] = this.solver(psi,Params,Transf,VDk,V,njob,t_idx,Observ); % [psi] = this.solver(psi,Params,Transf,VDk,V,njob,t_idx,Observ);

View File

@ -1,92 +1,91 @@
function [Params] = setupParameters(this) function [Params] = setupParameters(this)
CONSTANTS = Helper.PhysicsConstants;
CONSTANTS = Helper.PhysicsConstants; hbar = CONSTANTS.PlanckConstantReduced; % [J.s]
hbar = CONSTANTS.PlanckConstantReduced; % [J.s] kbol = CONSTANTS.BoltzmannConstant; % [J/K]
kbol = CONSTANTS.BoltzmannConstant; % [J/K] mu0 = CONSTANTS.VacuumPermeability; % [N/A^2]
mu0 = CONSTANTS.VacuumPermeability; % [N/A^2] muB = CONSTANTS.BohrMagneton; % [J/T]
muB = CONSTANTS.BohrMagneton; % [J/T] a0 = CONSTANTS.BohrRadius; % [m]
a0 = CONSTANTS.BohrRadius; % [m] m0 = CONSTANTS.AtomicMassUnit; % [kg]
m0 = CONSTANTS.AtomicMassUnit; % [kg] w0 = 2*pi*100; % Angular frequency unit [s^-1]
w0 = 2*pi*100; % Angular frequency unit [s^-1] mu0factor = 0.3049584233607396; % =(m0/me)*pi*alpha^2 -- me=mass of electron, alpha=fine struct. const.
mu0factor = 0.3049584233607396; % =(m0/me)*pi*alpha^2 -- me=mass of electron, alpha=fine struct. const.
% mu0=mu0factor *hbar^2*a0/(m0*muB^2) % mu0=mu0factor *hbar^2*a0/(m0*muB^2)
% Number of points in each direction % Number of points in each direction
Params.Nx = this.NumberOfGridPoints(1); Params.Nx = this.NumberOfGridPoints(1);
Params.Ny = this.NumberOfGridPoints(2); Params.Ny = this.NumberOfGridPoints(2);
Params.Nz = this.NumberOfGridPoints(3); Params.Nz = this.NumberOfGridPoints(3);
% Dimensions (in units of l0) % Dimensions (in units of l0)
Params.Lx = this.Dimensions(1); Params.Lx = this.Dimensions(1);
Params.Ly = this.Dimensions(2); Params.Ly = this.Dimensions(2);
Params.Lz = this.Dimensions(3); Params.Lz = this.Dimensions(3);
% Masses % Masses
Params.m = CONSTANTS.Dy164Mass; Params.m = CONSTANTS.Dy164Mass;
l0 = sqrt(hbar/(Params.m*w0)); % Defining a harmonic oscillator length l0 = sqrt(hbar/(Params.m*w0)); % Defining a harmonic oscillator length
% Atom numbers % Atom numbers
Params.N = this.NumberOfAtoms; Params.N = this.NumberOfAtoms;
% Dipole angle % Dipole angle
Params.theta = this.DipolarPolarAngle; % pi/2 dipoles along x, theta=0 dipoles along z Params.theta = this.DipolarPolarAngle; % pi/2 dipoles along x, theta=0 dipoles along z
Params.phi = this.DipolarAzimuthAngle; Params.phi = this.DipolarAzimuthAngle;
% Dipole lengths (units of muB) % Dipole lengths (units of muB)
Params.mu = CONSTANTS.DyMagneticMoment; Params.mu = CONSTANTS.DyMagneticMoment;
% Scattering lengths % Scattering lengths
Params.as = this.ScatteringLength*a0; Params.as = this.ScatteringLength*a0;
% Trapping frequencies % Trapping frequencies
Params.wx = 2*pi*this.TrapFrequencies(1); Params.wx = 2*pi*this.TrapFrequencies(1);
Params.wy = 2*pi*this.TrapFrequencies(2); Params.wy = 2*pi*this.TrapFrequencies(2);
Params.wz = 2*pi*this.TrapFrequencies(3); Params.wz = 2*pi*this.TrapFrequencies(3);
% Stochastic GPE % Stochastic GPE
Params.gamma_S = 7.5*10^(-3); % gamma for the stochastic GPE Params.gamma_S = 7.5*10^(-3); % gamma for the stochastic GPE
Params.muchem = 12.64*Params.wz/w0; % fixing the chemical potential for the stochastic GPE Params.muchem = 12.64*Params.wz/w0; % fixing the chemical potential for the stochastic GPE
Params.Etol = this.EnergyTolerance; % Tolerances Params.Etol = this.EnergyTolerance; % Tolerances
Params.cut_off = this.SimulationTime; % sometimes the imaginary time gets a little stuck Params.cut_off = this.SimulationTime; % sometimes the imaginary time gets a little stuck
% even though the solution is good, this just stops it going on forever % even though the solution is good, this just stops it going on forever
Params.mindt = this.MinimumTimeStep; % Minimum size for a time step using adaptive dt Params.mindt = this.MinimumTimeStep; % Minimum size for a time step using adaptive dt
% ================ Parameters defined by those above ================ % % ================ Parameters defined by those above ================ %
% Contact interaction strength (units of l0/m) % Contact interaction strength (units of l0/m)
Params.gs = 4*pi*Params.as/l0; Params.gs = 4*pi*Params.as/l0;
% Dipole lengths % Dipole lengths
Params.add = mu0*Params.mu^2*Params.m/(12*pi*hbar^2); Params.add = mu0*Params.mu^2*Params.m/(12*pi*hbar^2);
% DDI strength % DDI strength
Params.gdd = 12*pi*Params.add/l0; %sometimes the 12 is a 4 --> depends on how Vdk (DDI) is defined Params.gdd = 12*pi*Params.add/l0; %sometimes the 12 is a 4 --> depends on how Vdk (DDI) is defined
% Trap gamma % Trap gamma
Params.gx = (Params.wx/w0)^2; Params.gx = (Params.wx/w0)^2;
Params.gy = (Params.wy/w0)^2; Params.gy = (Params.wy/w0)^2;
Params.gz = (Params.wz/w0)^2; Params.gz = (Params.wz/w0)^2;
% == Calculate LHY correction == % % == Calculate LHY correction == %
eps_dd = Params.add/Params.as; eps_dd = Params.add/Params.as;
if eps_dd == 0 if eps_dd == 0
Q5 = 1; Q5 = 1;
elseif eps_dd == 1 elseif eps_dd == 1
Q5 = 3*sqrt(3)/2; Q5 = 3*sqrt(3)/2;
else else
yeps = (1-eps_dd)/(3*eps_dd); yeps = (1-eps_dd)/(3*eps_dd);
Q5 = (3*eps_dd)^(5/2)*( (8+26*yeps+33*yeps^2)*sqrt(1+yeps) + 15*yeps^3*log((1+sqrt(1+yeps))/sqrt(yeps)) )/48; Q5 = (3*eps_dd)^(5/2)*( (8+26*yeps+33*yeps^2)*sqrt(1+yeps) + 15*yeps^3*log((1+sqrt(1+yeps))/sqrt(yeps)) )/48;
Q5 = real(Q5); Q5 = real(Q5);
end end
Params.gammaQF = 128/3*sqrt(pi*(Params.as/l0)^5)*Q5; Params.gammaQF = 128/3*sqrt(pi*(Params.as/l0)^5)*Q5;
% Loading the rest into Params % Loading the rest into Params
Params.hbar = hbar; Params.hbar = hbar;
Params.kbol = kbol; Params.kbol = kbol;
Params.mu0 = mu0; Params.mu0 = mu0;
Params.muB = muB; Params.muB = muB;
Params.a0 = a0; Params.a0 = a0;
Params.w0 = w0; Params.w0 = w0;
Params.l0 = l0; Params.l0 = l0;
end end

View File

@ -1,33 +1,33 @@
function [Transf] = setupSpace(this,Params) function [Transf] = setupSpace(this,Params)
Transf.Xmax = 0.5*Params.Lx; Transf.Xmax = 0.5*Params.Lx;
Transf.Ymax = 0.5*Params.Ly; Transf.Ymax = 0.5*Params.Ly;
Transf.Zmax = 0.5*Params.Lz; Transf.Zmax = 0.5*Params.Lz;
Nz = Params.Nz; Nx = Params.Nx; Ny = Params.Ny; Nz = Params.Nz; Nx = Params.Nx; Ny = Params.Ny;
% Fourier grids % Fourier grids
x = linspace(-0.5*Params.Lx,0.5*Params.Lx-Params.Lx/Params.Nx,Params.Nx); x = linspace(-0.5*Params.Lx,0.5*Params.Lx-Params.Lx/Params.Nx,Params.Nx);
Kmax = pi*Params.Nx/Params.Lx; Kmax = pi*Params.Nx/Params.Lx;
kx = linspace(-Kmax,Kmax,Nx+1); kx = linspace(-Kmax,Kmax,Nx+1);
kx = kx(1:end-1); dkx = kx(2)-kx(1); kx = kx(1:end-1); dkx = kx(2)-kx(1);
kx = fftshift(kx); kx = fftshift(kx);
y = linspace(-0.5*Params.Ly,0.5*Params.Ly-Params.Ly/Params.Ny,Params.Ny); y = linspace(-0.5*Params.Ly,0.5*Params.Ly-Params.Ly/Params.Ny,Params.Ny);
Kmax = pi*Params.Ny/Params.Ly; Kmax = pi*Params.Ny/Params.Ly;
ky = linspace(-Kmax,Kmax,Ny+1); ky = linspace(-Kmax,Kmax,Ny+1);
ky = ky(1:end-1); dky = ky(2)-ky(1); ky = ky(1:end-1); dky = ky(2)-ky(1);
ky = fftshift(ky); ky = fftshift(ky);
z = linspace(-0.5*Params.Lz,0.5*Params.Lz-Params.Lz/Params.Nz,Params.Nz); z = linspace(-0.5*Params.Lz,0.5*Params.Lz-Params.Lz/Params.Nz,Params.Nz);
Kmax = pi*Params.Nz/Params.Lz; Kmax = pi*Params.Nz/Params.Lz;
kz = linspace(-Kmax,Kmax,Nz+1); kz = linspace(-Kmax,Kmax,Nz+1);
kz = kz(1:end-1); dkz = kz(2)-kz(1); kz = kz(1:end-1); dkz = kz(2)-kz(1);
kz = fftshift(kz); kz = fftshift(kz);
[Transf.X,Transf.Y,Transf.Z]=ndgrid(x,y,z); [Transf.X,Transf.Y,Transf.Z]=ndgrid(x,y,z);
[Transf.KX,Transf.KY,Transf.KZ]=ndgrid(kx,ky,kz); [Transf.KX,Transf.KY,Transf.KZ]=ndgrid(kx,ky,kz);
Transf.x = x; Transf.y = y; Transf.z = z; Transf.x = x; Transf.y = y; Transf.z = z;
Transf.kx = kx; Transf.ky = ky; Transf.kz = kz; Transf.kx = kx; Transf.ky = ky; Transf.kz = kz;
Transf.dx = x(2)-x(1); Transf.dy = y(2)-y(1); Transf.dz = z(2)-z(1); Transf.dx = x(2)-x(1); Transf.dy = y(2)-y(1); Transf.dz = z(2)-z(1);
Transf.dkx = dkx; Transf.dky = dky; Transf.dkz = dkz; Transf.dkx = dkx; Transf.dky = dky; Transf.dkz = dkz;
end end

View File

@ -1,50 +1,49 @@
function [Transf] = setupSpaceRadial(this,Params,morder) function [Transf] = setupSpaceRadial(~,Params,morder)
Params.Lr = 0.5*min(Params.Lx,Params.Ly); Params.Lr = 0.5*min(Params.Lx,Params.Ly);
Params.Nr = max(Params.Nx,Params.Ny); Params.Nr = max(Params.Nx,Params.Ny);
Zmax = 0.5*Params.Lz; Zmax = 0.5*Params.Lz;
Rmax = Params.Lr; Rmax = Params.Lr;
Nz = Params.Nz; Nz = Params.Nz;
Nr = Params.Nr; Nr = Params.Nr;
if(nargin==2) if(nargin==2)
morder=0; %only do Bessel J0 morder=0; %only do Bessel J0
end end
% Fourier grids % Fourier grids
z=linspace(-Zmax,Zmax,Nz+1); z=linspace(-Zmax,Zmax,Nz+1);
z=z(1:end-1); z=z(1:end-1);
dz=z(2)-z(1); dz=z(2)-z(1);
Kmax=Nz*2*pi/(4*Zmax); Kmax=Nz*2*pi/(4*Zmax);
kz=linspace(-Kmax,Kmax,Nz+1); kz=linspace(-Kmax,Kmax,Nz+1);
kz=kz(1:end-1); kz=kz(1:end-1);
% Hankel grids and transform % Hankel grids and transform
H = hankelmatrix(morder,Rmax,Nr); H = hankelmatrix(morder,Rmax,Nr);
r=H.r(:); r=H.r(:);
kr=H.kr(:); kr=H.kr(:);
T = diag(H.J/H.kmax)*H.T*diag(Rmax./H.J)*dz*(2*pi); T = diag(H.J/H.kmax)*H.T*diag(Rmax./H.J)*dz*(2*pi);
Tinv = diag(H.J./Rmax)*H.T'*diag(H.kmax./H.J)/dz/(2*pi); Tinv = diag(H.J./Rmax)*H.T'*diag(H.kmax./H.J)/dz/(2*pi);
wr=H.wr; wr=H.wr;
wk=H.wk; wk=H.wk;
% H.T'*diag(H.J/H.vmax)*H.T*diag(Rmax./H.J) % H.T'*diag(H.J/H.vmax)*H.T*diag(Rmax./H.J)
[Transf.R,Transf.Z]=ndgrid(r,z); [Transf.R,Transf.Z]=ndgrid(r,z);
[Transf.KR,Transf.KZ]=ndgrid(kr,kz); [Transf.KR,Transf.KZ]=ndgrid(kr,kz);
Transf.T=T; Transf.T=T;
Transf.Tinv=Tinv; Transf.Tinv=Tinv;
Transf.r=r; Transf.r=r;
Transf.kr=kr; Transf.kr=kr;
Transf.z=z; Transf.z=z;
Transf.kz=kz; Transf.kz=kz;
Transf.wr=wr; Transf.wr=wr;
Transf.wk=wk; Transf.wk=wk;
Transf.Rmax=Rmax; Transf.Rmax=Rmax;
Transf.Zmax=Zmax; Transf.Zmax=Zmax;
Transf.dz=z(2)-z(1); Transf.dz=z(2)-z(1);
Transf.dkz=kz(2)-kz(1); Transf.dkz=kz(2)-kz(1);
%b1=Transf;
function s_HT = hankelmatrix(order,rmax,Nr,eps_roots) function s_HT = hankelmatrix(order,rmax,Nr,eps_roots)
%HANKEL_MATRIX: Generates data to use for Hankel Transforms %HANKEL_MATRIX: Generates data to use for Hankel Transforms

View File

@ -1,25 +1,25 @@
function [psi] = setupWavefunction(this,Params,Transf) function [psi] = setupWavefunction(~,Params,Transf)
X = Transf.X; Y = Transf.Y; Z = Transf.Z; X = Transf.X; Y = Transf.Y; Z = Transf.Z;
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;
ellz = sqrt(Params.hbar/(Params.m*Params.wz))/Params.l0; ellz = sqrt(Params.hbar/(Params.m*Params.wz))/Params.l0;
Rx = 8*ellx; Ry = 8*elly; Rz = 8*ellz; Rx = 8*ellx; Ry = 8*elly; Rz = 8*ellz;
X0 = 0.0*Transf.Xmax; Y0 = 0.0*Transf.Ymax; Z0 = 0*Transf.Zmax; X0 = 0.0*Transf.Xmax; Y0 = 0.0*Transf.Ymax; Z0 = 0*Transf.Zmax;
psi = exp(-(X-X0).^2/Rx^2-(Y-Y0).^2/Ry^2-(Z-Z0).^2/Rz^2); psi = exp(-(X-X0).^2/Rx^2-(Y-Y0).^2/Ry^2-(Z-Z0).^2/Rz^2);
cur_norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; cur_norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz;
psi = psi/sqrt(cur_norm); psi = psi/sqrt(cur_norm);
% add some noise % add some noise
r = normrnd(0,1,size(X)); r = normrnd(0,1,size(X));
theta = rand(size(X)); theta = rand(size(X));
noise = r.*exp(2*pi*1i*theta); noise = r.*exp(2*pi*1i*theta);
psi = psi + 0.01*noise; psi = psi + 0.01*noise;
Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz;
psi = sqrt(Params.N)*psi/sqrt(Norm); psi = sqrt(Params.N)*psi/sqrt(Norm);
end end

View File

@ -1,17 +1,16 @@
function [psi] = solver(this,psi,Params,Transf,VDk,V,njob,t_idx,Observ) function [psi] = propagate(this,psi,Params,Transf,VDk,V,njob,t_idx,Observ)
set(0,'defaulttextInterpreter','latex')
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
set(0,'defaulttextInterpreter','latex') dt=-1j*abs(this.TimeStep);
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
dt=-1j*abs(this.TimeStep); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
Observ.residual = 1; Observ.res = 1;
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); muchem = this.Calculator.ChemicalPotential(psi,Params,Transf,VDk,V);
Observ.residual = 1; Observ.res = 1; AdaptIdx = 0;
muchem = Simulator.ChemicalPotential(psi,Params,Transf,VDk,V); while t_idx < Params.cut_off
AdaptIdx = 0;
while t_idx < Params.cut_off
%kin %kin
psi = fftn(psi); psi = fftn(psi);
psi = psi.*exp(-0.5*1i*dt*KEop); psi = psi.*exp(-0.5*1i*dt*KEop);
@ -22,7 +21,7 @@ while t_idx < Params.cut_off
Phi = real(ifftn(frho.*VDk)); Phi = real(ifftn(frho.*VDk));
%Real-space %Real-space
psi = psi.*exp(-1i*dt*(V + Params.gs*abs(psi).^2 + Params.gammaQF*abs(psi).^3 + Params.gdd*Phi - muchem)); psi = psi.*exp(-1i*dt*(V + Params.gs*abs(psi).^2 + Params.gdd*Phi + Params.gammaQF*abs(psi).^3 - muchem));
%kin %kin
psi = fftn(psi); psi = fftn(psi);
@ -33,12 +32,12 @@ while t_idx < Params.cut_off
Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz;
psi = sqrt(Params.N)*psi/sqrt(Norm); psi = sqrt(Params.N)*psi/sqrt(Norm);
muchem = Simulator.ChemicalPotential(psi,Params,Transf,VDk,V); muchem = this.Calculator.ChemicalPotential(psi,Params,Transf,VDk,V);
if mod(t_idx,1000) == 0 if mod(t_idx,1000) == 0
%Change in Energy %Change in Energy
E = Simulator.TotalEnergy(psi,Params,Transf,VDk,V); E = this.Calculator.TotalEnergy(psi,Params,Transf,VDk,V);
E = E/Norm; E = E/Norm;
Observ.EVec = [Observ.EVec E]; Observ.EVec = [Observ.EVec E];
@ -46,7 +45,7 @@ while t_idx < Params.cut_off
Observ.mucVec = [Observ.mucVec muchem]; Observ.mucVec = [Observ.mucVec muchem];
%Normalized residuals %Normalized residuals
res = Simulator.NormalizedResiduals(psi,Params,Transf,VDk,V,muchem); res = this.Calculator.NormalizedResiduals(psi,Params,Transf,VDk,V,muchem);
Observ.residual = [Observ.residual res]; Observ.residual = [Observ.residual res];
Observ.res_idx = Observ.res_idx + 1; Observ.res_idx = Observ.res_idx + 1;
@ -74,17 +73,17 @@ while t_idx < Params.cut_off
break break
end end
t_idx=t_idx+1; t_idx=t_idx+1;
end end
%Change in Energy %Change in Energy
E = Simulator.TotalEnergy(psi,Params,Transf,VDk,V); E = this.Calculator.TotalEnergy(psi,Params,Transf,VDk,V);
E = E/Norm; E = E/Norm;
Observ.EVec = [Observ.EVec E]; Observ.EVec = [Observ.EVec E];
% Phase coherence % Phase coherence
[PhaseC] = Simulator.PhaseCoherence(psi,Transf,Params); [PhaseC] = this.Calculator.PhaseCoherence(psi,Transf,Params);
Observ.PCVec = [Observ.PCVec PhaseC]; Observ.PCVec = [Observ.PCVec PhaseC];
Observ.res_idx = Observ.res_idx + 1; Observ.res_idx = Observ.res_idx + 1;
save(sprintf('./Data/Run_%03i/psi_gs.mat',njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V'); save(sprintf('./Data/Run_%03i/psi_gs.mat',njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V');
end end