示例#1
0
        /// <summary>
        /// Computes a 2D harmonic oscillator wavefunction with given quantum numbers.
        /// </summary>
        public static WaveFunction2D1P GetSHOWaveFunction(
            int gridSizeX, int gridSizeY, float latticeSpacing, float mass,
            Vec2 packetCenter, float sigma, int N, int Lz, bool multiThread = true)
        {
            // Check the input
            if ((N < 0) || (Lz > N) || (Lz < -N) || ((N + Lz) % 2) != 0)
            {
                throw new ArgumentException("Invalid (N,m) in WaveFunctionUtils.GetSHOWaveFunction.");
            }

            EigenSystem hamX   = Diagonalized1dShoHamiltonian(mass, sigma, packetCenter.X, latticeSpacing, gridSizeX);
            EigenSystem hamY   = Diagonalized1dShoHamiltonian(mass, sigma, packetCenter.Y, latticeSpacing, gridSizeY);
            Vector      eivcX0 = hamX.EigenVector(0);
            Vector      eivcY0 = hamY.EigenVector(0);

            WaveFunction2D1P result;

            if ((N == 0) && (Lz == 0))
            {
                result = DirectProduct(hamX.EigenVector(0), hamY.EigenVector(0), latticeSpacing);
            }
            else if ((N == 1) && (Lz == 1))
            {
                WaveFunction2D1P psi_10 = DirectProduct(hamX.EigenVector(1), hamY.EigenVector(0), latticeSpacing);
                WaveFunction2D1P psi_01 = DirectProduct(hamX.EigenVector(0), hamY.EigenVector(1), latticeSpacing);
                result = psi_10 + Complex.I * psi_01;
            }
            else if ((N == 2) && (Lz == 0))
            {
                WaveFunction2D1P psi_20 = DirectProduct(hamX.EigenVector(2), hamY.EigenVector(0), latticeSpacing);
                WaveFunction2D1P psi_02 = DirectProduct(hamX.EigenVector(0), hamY.EigenVector(2), latticeSpacing);
                result = psi_20 + psi_02;
            }
            else if ((N == 2) && (Lz == 2))
            {
                WaveFunction2D1P psi_11 = DirectProduct(hamX.EigenVector(1), hamY.EigenVector(1), latticeSpacing);
                WaveFunction2D1P psi_20 = DirectProduct(hamX.EigenVector(2), hamY.EigenVector(0), latticeSpacing);
                WaveFunction2D1P psi_02 = DirectProduct(hamX.EigenVector(0), hamY.EigenVector(2), latticeSpacing);
                result = psi_20 - psi_02 + (Math.Sqrt(2) * Complex.I) * psi_11;
            }
            else
            {
                throw new ArgumentException("Invalid (N,Lz) in WaveFunctionUtils.GetSHOWaveFunction.");
            }

            result.Normalize();
            return(result);
        }
示例#2
0
        /// <summary>
        /// Worker method.
        /// </summary>
        protected override void WorkerMethod()
        {
            // Reset counters
            m_currentTimeStepIndex = 0;
            m_lastSavedFrame       = -1;


            // Create a single-particle wf representing the incoming wavepacket
            WaveFunction2D1P initialWf1 = TdseSolver_2D1P.WaveFunctionUtils.CreateGaussianWavePacket(m_gridSizeX, m_gridSizeY, m_latticeSpacing,
                                                                                                     m_mass1, m_initialPosition1.ToPointF(), m_initialSize1.ToPointF(), m_initialMomentum1.ToPointF(), m_multiThread
                                                                                                     );

            // Create a single-particle wf representing the stationary bound state
            WaveFunction2D1P initialWf2 = WaveFunctionUtils.GetSHOWaveFunction(m_gridSizeX, m_gridSizeY, m_latticeSpacing,
                                                                               m_mass2, m_initialPosition2, m_sho_sigma, m_sho_N, m_sho_Lz, m_multiThread);

            // Precompute the potentials everywhere on the grid
            float[][] V1 = TdseUtils.Misc.Allocate2DArray(m_gridSizeY, m_gridSizeX);
            float[][] V2 = PrecomputeV2();

            // Create a VisscherWf from the direct product of the 1-particle wfs
            m_visscherWf = new VisscherWf(initialWf1, initialWf2, V1, V2, m_mass1, m_mass2, m_deltaT, m_multiThread);

            TimeStepCompleted();
            if (IsCancelled)
            {
                return;
            }

            float[][] Vrel = PrecomputeVrel();

            // Main loop: Evolve the relative wavefunction
            while (m_currentTimeStepIndex < m_totalNumTimeSteps)
            {
                // Evolve the wavefunction by one timestep
                EvolveByOneTimeStep(m_visscherWf, Vrel, V2);
                m_currentTimeStepIndex++;

                // Report progress to the client
                TimeStepCompleted();
                if (IsCancelled)
                {
                    return;
                }
            }
        }
示例#3
0
        /// <summary>
        /// Forms the direct product of two wavefunctions
        /// </summary>
        private static WaveFunction2D1P DirectProduct(Vector wfx, Vector wfy, float latticeSpacing)
        {
            // Construct the 2D wavefunction
            int sx = wfx.Length;
            int sy = wfy.Length;
            WaveFunction2D1P wfdp = new WaveFunction2D1P(sx, sy, latticeSpacing);

            for (int y = 0; y < sy; y++)
            {
                double  wfyValue  = wfy[y];
                float[] wfdpDataY = wfdp.Data[y];

                for (int x = 0; x < sx; x++)
                {
                    double wfxValue = wfx[x];

                    wfdpDataY[2 * x]     = (float)(wfxValue * wfyValue);
                    wfdpDataY[2 * x + 1] = 0.0f;
                }
            }

            return(wfdp);
        }
示例#4
0
        /// <summary>
        /// Constructor. Initializes a Visscher wavefunction from a direct product of two ordinary wavefunctions.
        /// </summary>
        public VisscherWf(WaveFunction2D1P inputWf1, WaveFunction2D1P inputWf2, float[][] V1, float[][] V2, float mass1, float mass2, float dt, bool multiThread = true)
        {
            int sx = inputWf1.GridSizeX;
            int sy = inputWf1.GridSizeY;

            LatticeSpacing = inputWf1.LatticeSpacing;

            // Allocate the arrays
            RealPart  = TdseUtils.Misc.Allocate4DArray(sy, sx, sy, sx);
            ImagPartM = TdseUtils.Misc.Allocate4DArray(sy, sx, sy, sx);
            ImagPartP = TdseUtils.Misc.Allocate4DArray(sy, sx, sy, sx);

            // Get the real part of the total wf from the direct product of wf1*wf2, at time 0
            TdseUtils.Misc.ForLoop(0, sy, y2 =>
            {
                for (int x2 = 0; x2 < sx; x2++)
                {
                    float[][] RealPart_y2_x2 = RealPart[y2][x2];
                    float wf2_y2_x2r         = inputWf2.Data[y2][2 * x2];
                    float wf2_y2_x2i         = inputWf2.Data[y2][2 * x2 + 1];

                    for (int y1 = 0; y1 < sy; y1++)
                    {
                        float[] wf1_y1 = inputWf1.Data[y1];
                        for (int x1 = 0; x1 < sx; x1++)
                        {
                            RealPart_y2_x2[y1][x1] = wf1_y1[2 * x1] * wf2_y2_x2r - wf1_y1[2 * x1 + 1] * wf2_y2_x2i;
                        }
                    }
                }
            }, multiThread);


            // Get the imaginary parts of the total wf from the direct product of wf1*wf2, at time +/- dt.
            // To compute the latter, use a power series expansion of the time-evolution operator, accurate to 2nd order in H*dt
            if (V1 == null)
            {
                V1 = TdseUtils.Misc.Allocate2DArray(sy, sx);
            }                                                                // Set V1 to zero
            WaveFunction2D1P H_Wf1   = inputWf1.ApplyH(V1, mass1, multiThread);
            WaveFunction2D1P H2_Wf1  = H_Wf1.ApplyH(V1, mass1, multiThread);
            WaveFunction2D1P Wf1_Adv = inputWf1 + (dt / 2) * H_Wf1 + (dt * dt / 8) * H2_Wf1;
            WaveFunction2D1P Wf1_Ret = inputWf1 - (dt / 2) * H_Wf1 + (dt * dt / 8) * H2_Wf1;

            if (V2 == null)
            {
                V2 = TdseUtils.Misc.Allocate2DArray(sy, sx);
            }                                                                // Set V2 to zero
            WaveFunction2D1P H_Wf2   = inputWf2.ApplyH(V2, mass2, multiThread);
            WaveFunction2D1P H2_Wf2  = H_Wf2.ApplyH(V2, mass2, multiThread);
            WaveFunction2D1P Wf2_Adv = inputWf2 + (dt / 2) * H_Wf2 + (dt * dt / 8) * H2_Wf2;
            WaveFunction2D1P Wf2_Ret = inputWf2 - (dt / 2) * H_Wf2 + (dt * dt / 8) * H2_Wf2;

            TdseUtils.Misc.ForLoop(0, sy, y2 =>
            {
                for (int x2 = 0; x2 < sx; x2++)
                {
                    float[][] ImagPartP_y2_x2 = ImagPartP[y2][x2];
                    float[][] ImagPartM_y2_x2 = ImagPartM[y2][x2];

                    float wf2adv_y2_x2r = Wf2_Adv.Data[y2][2 * x2];
                    float wf2adv_y2_x2i = Wf2_Adv.Data[y2][2 * x2 + 1];

                    float wf2ret_y2_x2r = Wf2_Ret.Data[y2][2 * x2];
                    float wf2ret_y2_x2i = Wf2_Ret.Data[y2][2 * x2 + 1];

                    for (int y1 = 0; y1 < sy; y1++)
                    {
                        float[] wf1adv_y1 = Wf1_Adv.Data[y1];
                        float[] wf1ret_y1 = Wf1_Ret.Data[y1];

                        for (int x1 = 0; x1 < sx; x1++)
                        {
                            ImagPartP_y2_x2[y1][x1] = wf1adv_y1[2 * x1 + 1] * wf2adv_y2_x2r + wf1adv_y1[2 * x1] * wf2adv_y2_x2i;
                            ImagPartM_y2_x2[y1][x1] = wf1ret_y1[2 * x1 + 1] * wf2ret_y2_x2r + wf1ret_y1[2 * x1] * wf2ret_y2_x2i;
                        }
                    }
                }
            }, multiThread);
        }