function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ) set(0,'defaulttextInterpreter','latex') set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex'); switch this.SimulationMode case 'ImaginaryTimeEvolution' dt=-1j*abs(this.TimeStepSize); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); Observ.residual = 1; Observ.res = 1; muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V); AdaptIdx = 0; pb = Helper.ProgressBar(); pb.run('Running simulation in imaginary time: '); while t_idx < Params.sim_time_cut_off %kin psi = fftn(psi); psi = psi.*exp(-0.5*1i*dt*KEop); psi = ifftn(psi); %DDI frho = fftn(abs(psi).^2); Phi = real(ifftn(frho.*VDk)); %Real-space psi = psi.*exp(-1i*dt*(V + Params.gs*abs(psi).^2 + Params.gdd*Phi + Params.gammaQF*abs(psi).^3 - muchem)); %kin psi = fftn(psi); psi = psi.*exp(-0.5*1i*dt*KEop); psi = ifftn(psi); %Renorm Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; psi = sqrt(Params.N)*psi/sqrt(Norm); muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V); if mod(t_idx,1000) == 0 %Change in Energy E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V); E = E/Norm; Observ.EVec = [Observ.EVec E]; %Chemical potential Observ.mucVec = [Observ.mucVec muchem]; %Normalized residuals res = this.Calculator.calculateNormalizedResiduals(psi,Params,Transf,VDk,V,muchem); Observ.residual = [Observ.residual res]; Observ.res_idx = Observ.res_idx + 1; save(sprintf('./Data/Run_%03i/psi_gs.mat',Params.njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V'); %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); if relres <1e-5 if AdaptIdx > 4 && abs(dt) > Params.mindt dt = dt / 2; fprintf('Time step changed to '); disp(dt); AdaptIdx = 0; elseif AdaptIdx > 4 && abs(dt) < Params.mindt break else AdaptIdx = AdaptIdx + 1; end else AdaptIdx = 0; end end if any(isnan(psi(:))) disp('NaNs encountered!') break end t_idx=t_idx+1; pb.run(100*t_idx/Params.sim_time_cut_off); end %Change in Energy E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V); E = E/Norm; Observ.EVec = [Observ.EVec E]; % Phase coherence [PhaseC] = this.Calculator.calculatePhaseCoherence(psi,Transf,Params); Observ.PCVec = [Observ.PCVec PhaseC]; Observ.res_idx = Observ.res_idx + 1; pb.run(' - Job Completed!'); disp('Saving data...'); save(sprintf('./Data/Run_%03i/psi_gs.mat',Params.njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V'); disp('Save complete!'); case 'RealTimeEvolution' dt = abs(this.TimeStepSize); KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2); muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V); pb = Helper.ProgressBar(); pb.run('Running simulation in real time: '); while t_idx < Params.sim_time_cut_off % Parameters at time t %kin psi = fftn(psi); psi = psi.*exp(-0.5*1i*dt*KEop); psi = ifftn(psi); %DDI frho = fftn(abs(psi).^2); Phi = real(ifftn(frho.*VDk)); %Real-space psi = psi.*exp(-1i*dt*(V + Params.gs*abs(psi).^2 + Params.gammaQF*abs(psi).^3 + Params.gdd*Phi - muchem)); %kin psi = fftn(psi); psi = psi.*exp(-0.5*1i*dt*KEop); psi = ifftn(psi); muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V); if mod(t_idx,1000)==0 %Change in Normalization Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; % normalisation Observ.NormVec = [Observ.NormVec Norm]; %Change in Energy E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V); 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'); end if any(isnan(psi(:))) disp('NaNs encountered!') break end t_idx=t_idx+1; pb.run(100*t_idx/Params.sim_time_cut_off); end %Change in Normalization Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; % normalisation Observ.NormVec = [Observ.NormVec Norm]; %Change in Energy E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V); 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; pb.run(' - Run Completed!'); disp('Saving data...'); save(sprintf('./Data/Run_%03i/TimeEvolution/psi_%i.mat',Params.njob,Observ.res_idx),'psi','muchem','Observ','t_idx'); disp('Save complete!'); otherwise disp('Choose a valid DDI cutoff type!') return end end