Exemple #1
0
        /// <summary>
        /// Creates a Gaussian wavepacket with given properties.
        /// </summary>
        public static WaveFunction CreateGaussianWavePacket(
            int gridSizeX, int gridSizeY, float latticeSpacing, bool originAtLatticeCenter, float mass,
            Vec2 packetCenter, Vec2 packetWidth, Vec2 avgMomentum, bool multiThread = true)
        {
            WaveFunction wf = new WaveFunction(gridSizeX, gridSizeY, latticeSpacing);

            Complex I             = Complex.I;
            float   rootPi        = (float)Math.Sqrt(Math.PI);
            float   sigmaXSq      = packetWidth.X * packetWidth.X;
            float   sigmaYSq      = packetWidth.Y * packetWidth.Y;
            float   norm          = (float)Math.Sqrt((packetWidth.X / (rootPi * sigmaXSq)) * (packetWidth.Y / (rootPi * sigmaYSq)));
            int     halfGridSizeX = (gridSizeX - 1) / 2;
            int     halfGridSizeY = (gridSizeY - 1) / 2;

            TdseUtils.Misc.ForLoop(0, gridSizeY, (y) =>
            {
                float yf        = (originAtLatticeCenter) ? (y - halfGridSizeY) * latticeSpacing : (y * latticeSpacing);
                Complex expArgY = I * yf * avgMomentum.Y - (yf - packetCenter.Y) * (yf - packetCenter.Y) / (2 * sigmaYSq);

                float[] wfDataY = wf.Data[y];
                for (int x = 0; x < gridSizeX; x++)
                {
                    float xf = (originAtLatticeCenter) ? (x - halfGridSizeX) * latticeSpacing : (x * latticeSpacing);

                    Complex expArgYX = expArgY + I * xf * avgMomentum.X - (xf - packetCenter.X) * (xf - packetCenter.X) / (2 * sigmaXSq);
                    Complex wfVal    = norm * Complex.Exp(expArgYX);

                    wfDataY[2 * x]     = wfVal.Re;
                    wfDataY[2 * x + 1] = wfVal.Im;
                }
            }, multiThread);

            wf.Normalize();
            return(wf);
        }
Exemple #2
0
        /// <summary>
        /// Calculates the value of a (freely evolving) Gaussian wavepacket at a given location and time.
        /// </summary>
        public static Complex FreeGaussianWavePacketValue(float x, float y, float z, float t,
                                                          Vec3 initialCenter, Vec3 initialWidth, Vec3 avgMomentum, float mass)
        {
            Complex I = Complex.I;

            Complex effSigmaXSq = initialWidth.X * initialWidth.X + I * (t / mass);
            Complex effSigmaYSq = initialWidth.Y * initialWidth.Y + I * (t / mass);
            Complex effSigmaZSq = initialWidth.Z * initialWidth.Z + I * (t / mass);

            float xRel = x - initialCenter.X - avgMomentum.X * t / mass;
            float yRel = y - initialCenter.Y - avgMomentum.Y * t / mass;
            float zRel = z - initialCenter.Z - avgMomentum.Z * t / mass;

            float avgMomentumSq = avgMomentum.NormSq();

            Complex expArg = I * (x * avgMomentum.X + y * avgMomentum.Y + z * avgMomentum.Z) - I * t * avgMomentumSq / (2 * mass) -
                             (xRel * xRel) / (2 * effSigmaXSq) - (yRel * yRel) / (2 * effSigmaYSq) - (zRel * zRel) / (2 * effSigmaZSq);

            float   rootPi = (float)Math.Sqrt(Math.PI);
            Complex normX  = Complex.Sqrt(initialWidth.X / (rootPi * effSigmaXSq));
            Complex normY  = Complex.Sqrt(initialWidth.Y / (rootPi * effSigmaYSq));
            Complex normZ  = Complex.Sqrt(initialWidth.Z / (rootPi * effSigmaZSq));

            Complex wfVal = normX * normY * normZ * Complex.Exp(expArg);

            return(wfVal);
        }
        /// <summary>
        /// Creates a Gaussian wavepacket with given properties.
        /// </summary>
        public static WaveFunction CreateGaussianWavePacket(
            GridSpec gridSpec, float latticeSpacing, bool originAtLatticeCenter, float mass,
            Vec3 packetCenter, Vec3 packetWidth, Vec3 avgMomentum, bool multiThread = true)
        {
            WaveFunction wf = new WaveFunction(gridSpec, latticeSpacing);

            int sx = gridSpec.SizeX;
            int sy = gridSpec.SizeY;
            int sz = gridSpec.SizeZ;

            float[][][] wfData = wf.Data;


            Complex I             = Complex.I;
            float   rootPi        = (float)Math.Sqrt(Math.PI);
            float   sigmaXSq      = packetWidth.X * packetWidth.X;
            float   sigmaYSq      = packetWidth.Y * packetWidth.Y;
            float   sigmaZSq      = packetWidth.Z * packetWidth.Z;
            float   norm          = (float)Math.Sqrt(1.0 / (rootPi * packetWidth.X * rootPi * packetWidth.Y * rootPi * packetWidth.Z));
            int     halfGridSizeX = (sx - 1) / 2;
            int     halfGridSizeY = (sy - 1) / 2;
            int     halfGridSizeZ = (sz - 1) / 2;

            TdseUtils.Misc.ForLoop(0, sz, (z) =>
            {
                float zf        = (originAtLatticeCenter) ? (z - halfGridSizeZ) * latticeSpacing : (z * latticeSpacing);
                Complex expArgZ = I * zf * avgMomentum.Z - (zf - packetCenter.Z) * (zf - packetCenter.Z) / (2 * sigmaZSq);

                for (int y = 0; y < sy; y++)
                {
                    float yf         = (originAtLatticeCenter) ? (y - halfGridSizeY) * latticeSpacing : (y * latticeSpacing);
                    Complex expArgZY = expArgZ + I * yf * avgMomentum.Y - (yf - packetCenter.Y) * (yf - packetCenter.Y) / (2 * sigmaYSq);

                    float[] wfDataZY = wf.Data[z][y];
                    for (int x = 0; x < sx; x++)
                    {
                        float xf = (originAtLatticeCenter) ? (x - halfGridSizeX) * latticeSpacing : (x * latticeSpacing);

                        Complex expArgZYX = expArgZY + I * xf * avgMomentum.X - (xf - packetCenter.X) * (xf - packetCenter.X) / (2 * sigmaXSq);
                        Complex wfVal     = norm * Complex.Exp(expArgZYX);

                        wfDataZY[2 * x]     = wfVal.Re;
                        wfDataZY[2 * x + 1] = wfVal.Im;
                    }
                }
            }, multiThread);

            wf.Normalize();
            return(wf);
        }
Exemple #4
0
        /// <summary>
        /// Calculates the value of a (freely evolving) Gaussian wavepacket at a given location and time.
        /// </summary>
        public static Complex FreeGaussianWavePacketValue(float x, float y, float t,
                                                          PointF initialCenter, PointF initialWidth, PointF avgMomentum, float mass)
        {
            Complex I = Complex.I;

            Complex effSigmaXSq = initialWidth.X * initialWidth.X + I * (t / mass);
            Complex effSigmaYSq = initialWidth.Y * initialWidth.Y + I * (t / mass);

            float xRel = x - initialCenter.X - avgMomentum.X * t / mass;
            float yRel = y - initialCenter.Y - avgMomentum.Y * t / mass;

            float   avgMomentumSq = avgMomentum.X * avgMomentum.X + avgMomentum.Y * avgMomentum.Y;
            Complex expArg        = I * (x * avgMomentum.X + y * avgMomentum.Y) - I * t * avgMomentumSq / (2 * mass) - (xRel * xRel) / (2 * effSigmaXSq) - (yRel * yRel) / (2 * effSigmaYSq);

            float   rootPi = (float)Math.Sqrt(Math.PI);
            Complex normX  = Complex.Sqrt(initialWidth.X / (rootPi * effSigmaXSq));
            Complex normY  = Complex.Sqrt(initialWidth.Y / (rootPi * effSigmaYSq));

            Complex wfVal = normX * normY * Complex.Exp(expArg);

            return(wfVal);
        }