/// <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); }
/// <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); }
/// <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); }