예제 #1
0
 /// <summary>
 /// Computes psi_k=psi_k*exp(-0.5*dt*1i*(hbar/m)*kˆ2).
 /// </summary>
 public void addPhaseMomentum()
 {
     for (int i = 0; i < psi.Length; i++)
     {
         psi[i] = psi[i] * ComplexNumber.Exp(-0.5 * ComplexNumber.ImaginaryOne * deltaT * PhysConst.hbar / mass * Math.Pow(K[i], 2));
     }
 }
예제 #2
0
 /// <summary>
 /// Computes psi=psi.*exp(-0.5*1i*dt*(V+(g1d/hbar)*abs(psi).ˆ2)).
 /// </summary>
 public void addPhaseSpatial()
 {
     for (int i = 0; i < psi.Length; i++)
     {
         psi[i] = psi[i] * ComplexNumber.Exp(-0.5 * ComplexNumber.ImaginaryOne * deltaT * (V[i] + g1D / PhysConst.hbar * Math.Pow(psi[i].Norm(), 2)));
     }
 }
예제 #3
0
파일: FFT.cs 프로젝트: bridgejohn/GPESolver
        /// <summary>
        /// The DFT calculates the discret Fourier transform of a complex array
        /// </summary>
        /// <returns>An array which is Fourier transformed</returns>
        /// <param name="f">Array to be Fourier transformed</param>
        public static ComplexNumber[] DFT(ComplexNumber[] f)
        {
            int N = f.Length;

            ComplexNumber[] F = new ComplexNumber[N];
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < N; i++)
                {
                    F[j] += ComplexNumber.Exp(-ComplexNumber.ImaginaryOne * 2 * Math.PI * j * i / N) * f[i];
                }
            }
            return(F);
        }
예제 #4
0
파일: FFT.cs 프로젝트: bridgejohn/GPESolver
        /// <summary>
        /// CT performs a FFT using the Cooley-Tukey algorithm, which requires an array of the power of two.
        /// The algorithm is recursively.
        /// </summary>
        /// <returns>Fourier transformed array</returns>
        /// <param name="f">Array to be Fourier transformed</param>
        public static ComplexNumber[] CT(ComplexNumber[] f)
        {
            int N = f.Length;

            ComplexNumber[] F = new ComplexNumber[N];


            if (N < 2)
            {
                F = f;   // breaks the recursion at its smallest array size of 1
            }
            else
            {
                // Creates to halfsize arrays for even and odd indices
                ComplexNumber[] even = new ComplexNumber[N / 2];
                ComplexNumber[] odd  = new ComplexNumber[N / 2];

                for (int i = 0; i < N / 2; i++)
                {
                    even[i] = f[2 * i];
                    odd[i]  = f[2 * i + 1];
                }

                // prepares arrays, in which the Fouriertrans formed version will be saved
                ComplexNumber[] EVEN = new ComplexNumber[N / 2];
                ComplexNumber[] ODD  = new ComplexNumber[N / 2];

                // Fourier transforms the smaller arrays by calling the function itself
                EVEN = CT(even);
                ODD  = CT(odd);

                // reassambles the values in the correct order
                for (int i = 0; i < N / 2; i++)
                {
                    F[i]         = EVEN[i] + ComplexNumber.Exp(-ComplexNumber.ImaginaryOne * 2 * Math.PI / N * i) * ODD[i];
                    F[i + N / 2] = EVEN[i] - ComplexNumber.Exp(-ComplexNumber.ImaginaryOne * 2 * Math.PI / N * i) * ODD[i];
                }
            }

            // returns the Fourier transformed array
            return(F);
        }
예제 #5
0
        /// <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)));
            }
        }
예제 #6
0
파일: FFT.cs 프로젝트: bridgejohn/GPESolver
        /// <summary>
        /// Transformation algorithm to perform a FFT using the Bit reversal structure.
        /// </summary>
        /// <remarks>
        /// The FT is performed by setting the <c>negativeTwidleFactor</c> to <c>true</c>, its inverse by setting it to <c>false</c>.
        /// </remarks>
        /// <returns>Transformed array</returns>
        /// <param name="negativeTwidleFactor">If set to <c>true</c> FT is performed, if <c>false</c> its inverse.</param>
        /// <param name="f">Array to be transformed</param>
        /// <param name="reversedBits">Reversed bit array, needs to be precalculated by <c>BitReverse</c></param>
        public static ComplexNumber[] Transform(bool negativeTwidleFactor, ComplexNumber[] f, uint[] reversedBits)
        {
            ComplexNumber[] workF = (ComplexNumber[])f.Clone();
            int             size  = f.Length;

            if (size != reversedBits.Length)
            {
                throw new Exception("The arrays dont have the same lenght");
            }
            int a     = 0;
            int findA = size;

            while (findA > 1)
            {
                findA = findA >> 1;
                a++;
            }

            // sets the prefactor for the twiddle factor to perform either FFT or IFFT
            int preFactor;

            if (negativeTwidleFactor)
            {
                preFactor = -1;
            }
            else
            {
                preFactor = 1;
            }

            // prepare necassary variables
            ComplexNumber even, odd, wM, w;
            int           shift, m;

            //orders the array according to the bit reversal
            for (int i = 0; i < f.Length; i++)
            {
                workF[i] = f[reversedBits[i]];
            }

            // three for loops to process the full FFT/IFFT
            // the result of the loops gives the FFT/IFFT in the normal ordered form
            for (int s = 1; s <= a; s++)
            {
                shift = 1 << (s - 1);                                                                // = 2^(s-1) via bitshift
                m     = 1 << s;                                                                      // = 2^s
                wM    = ComplexNumber.Exp(preFactor * ComplexNumber.ImaginaryOne * 2 * Math.PI / m); // twiddle factor, with prefactor for FFT/IFFT

                for (int i = 0; i < size; i += m)
                {
                    w = 1;
                    for (int j = 0; j < shift; j++)
                    {
                        // the call to the reverse bit structure accounts for the bitflipped order
                        even = workF[i + j];
                        odd  = w * workF[i + j + shift];

                        // joins together the desired even and odd parts, with the twidle factor multiplied to the odd part
                        workF[i + j]         = even + odd;
                        workF[i + j + shift] = even - odd;

                        // increase phase of twiddle factor
                        w = w * wM;
                    }
                }
            }
            return(workF);
        }