/// <summary> /// <c>getGroundState</c> deteremines the Groundstate of a the wavefunction saved in <c>this.psi</c> /// with the imaginary time method /// </summary> public void getGroundState() { //ComplexNumber[] psi_0 = psi; double mu = 1; double mu_old; double mu_error = 1; ComplexNumber[] psi_old = new ComplexNumber[psi.Length]; double NormOfPsi = 0; for (int i = 0; i < psi.Length; i++) { NormOfPsi += Math.Pow(psi[i].Norm(), 2); } NormOfPsi = Math.Sqrt(NormOfPsi) * deltaX; int j = 0; while (mu_error > Math.Pow(10, -8)) { // creation of new wave function psi_old = (ComplexNumber[])psi.Clone(); for (int i = 0; i < psi.Length; i++) { psi[i] = psi[i] * Math.Exp(-0.5 * deltaT * (V[i] + g1D / PhysConst.hbar * Math.Pow(psi[i].Norm(), 2))); } //ComplexNumber[] psi_k = new ComplexNumber[psi.Length]; psi = FFT.BR(psi, reversedBits); // Fourier transformation of the wave function with the Cooley-Tukey algorithm psi = FFT.Shift(psi); // for (int i = 0; i < psi.Length; i++) { psi[i] = psi[i] / xSteps; } // psi = psi*exp((-0.5*deltaT*hbar*|k|^2)/m) for (int i = 0; i < psi.Length; i++) { psi[i] = psi[i] * Math.Exp(-0.5 * deltaT * (PhysConst.hbar / this.mass * Math.Pow(K[i], 2))); } psi = FFT.Shift(psi); psi = FFT.IBR(psi, reversedBits); //Inverse fourier transformation of the wave function with the bit reverse algorithm for (int i = 0; i < psi.Length; i++) { psi[i] = psi[i] * kSteps; } // psi = psi*exp(-0.5*deltaT*V(x)+g1D/hbar * |psi|^2) for (int i = 0; i < psi.Length; i++) { psi[i] = psi[i] * Math.Exp(-0.5 * deltaT * (V[i] + g1D / PhysConst.hbar * Math.Pow(psi[i].Norm(), 2))); } mu_old = mu; mu = Math.Log((psi_old[psi_old.Length / 2] / psi[psi.Length / 2]).Norm()) / deltaT; mu_error = Math.Abs(mu - mu_old) / mu; double currentNormOfPsi = 0; for (int i = 0; i < psi.Length; i++) { currentNormOfPsi += Math.Pow(psi[i].Norm(), 2); } currentNormOfPsi = Math.Sqrt(currentNormOfPsi) * deltaX; for (int i = 0; i < psi.Length; i++) { psi[i] = psi[i] * Math.Sqrt(NormOfPsi) / Math.Sqrt(currentNormOfPsi); } if (j > Math.Pow(10, 8)) { break; } j++; } }
/// <summary> /// Simulates on timestep of the time evolution by performing the splitstep fourier method only once. /// </summary> /// <param name="FT">Algorithm which will be used for the Fouriertransformation</param> public void splitStepFourier(string FT) { int size = this.psi.Length; // psi=psi.*exp(-0.5*1i*dt*(V+(g1d/hbar)*abs(psi).ˆ2)); for (int i = 0; i < size; i++) { psi[i] = psi[i] * ComplexNumber.Exp(-0.5 * ComplexNumber.ImaginaryOne * deltaT * (V[i] + g1D / PhysConst.hbar * Math.Pow(psi[i].Norm(), 2))); } // decides which algorithm will be used for the FT switch (FT) { case "DFT": psi = FFT.DFT(psi); break; case "CT": psi = FFT.CT(psi); break; case "BR": psi = FFT.BR(psi, reversedBits); break; default: break; } psi = FFT.Shift(psi); // shift the lower half with the upper one to restore normal order for (int i = 0; i < size; i++) { psi[i] = psi[i] / size; } // psi_k=psi_k*exp(-0.5*dt*1i*(hbar/m)*kˆ2) for (int i = 0; i < size; i++) { psi[i] = psi[i] * ComplexNumber.Exp(-0.5 * ComplexNumber.ImaginaryOne * deltaT * PhysConst.hbar / mass * Math.Pow(K[i], 2)); } psi = FFT.Shift(psi); // shifts again, so that the result of the IFT will be normal orderd // decides which algorithm will be used for the IFT switch (FT) { case "DFT": psi = FFT.IDFT(psi); break; case "CT": psi = FFT.ICT(psi); break; case "BR": psi = FFT.IBR(psi, reversedBits); break; default: break; } for (int i = 0; i < size; i++) { psi[i] = psi[i] * size; } //psi = psi.* exp(-0.5 * 1i * dt * (V + (g1d / hbar) * abs(psi).ˆ2)); for (int i = 0; i < size; i++) { psi[i] = psi[i] * ComplexNumber.Exp(-0.5 * ComplexNumber.ImaginaryOne * deltaT * (V[i] + g1D / PhysConst.hbar * Math.Pow(psi[i].Norm(), 2))); } }