简体   繁体   English

如何在C语言中方形障碍物的数值模拟中使高斯包运动

[英]How to make gaussian package move in numerical simulation of a square barrier in C

I am trying to use Gaussian packages to study the transmission probability via Trotter-Suzuki formula and fast Fourier transform (FFT) when confronted with a square barrier, just as done in this Quantum Python article . 我正在尝试使用高斯包来研究Trotter-Suzuki公式和快速傅立叶变换(FFT)在遇到正方形障碍时的传输概率,就像在Quantum Python文章中所做的那样。 But I need to realize it using C. In principle, the wave function will remain its shape before the collision with the square barrier. 但是我需要使用C来实现。原则上,波函数将在与方形势垒碰撞之前保持其形状。 But I found that the wave function becomes flat dramatically with time before colliding with the square barrier. 但是我发现波函数在与方形障碍物碰撞之前会随着时间急剧变平。 Anybody finds problems in the following codes? 有人在以下代码中发现问题吗?

Here, two files - result and psi.txt - are created to store the initial and evolved wave-function. 在这里,两个文件- 结果psi.txt -创建存储初始和演变波函数。 The first two data for each are x coordinates, the probability of the wave function at that x . 每个数据的前两个数据是x坐标,即在x处的波动函数的概率。 The third data for each line in file result is the square barrier distribution. 文件结果中每行的第三个数据是平方障碍分布。 The FFT I use is shown in this C program . 这个C程序显示我使用的FFT。

#include <stdio.h>
#include <math.h>

#define h_bar 1.0
#define pi 3.1415926535897932385E0
#define m0 1.0

typedef double real;
typedef struct { real Re; real Im; }  complex;

extern void fft(complex x[], int N, int flag);

complex complex_product(complex x, real y_power, real y_scale)
{//x*exp(i*y_power)*y_scale
    real Re, Im;

    Re = (x.Re*cos(y_power)-x.Im*sin(y_power))*y_scale;
    Im = (x.Re*sin(y_power)+x.Im*cos(y_power))*y_scale;

    x.Re = Re; x.Im = Im;
    return x;
}

real potential(real x, real a)
{
    return (x<0 || x>=a) ? 0 : 1;
}


void main()
{
    int t_steps=20, i, N=pow(2,10), m, n;
    complex psi[N];
    real x0=-2, p0=1, k0=p0/h_bar, x[N], k[N], V[N];
    real sigma=0.5, a=0.1, x_lower=-5, x_upper=5;
    real dt=1, dx=(x_upper-x_lower)/N, dk=2*pi/(dx*N);
    FILE  *file;

    file = fopen("result", "w");
    //initialize
    for (n=0; n<N; n++)
    {
        x[n] = x_lower+n*dx;
        k[n] = k0+(n-N*0.5)*dk;
        V[n] = potential(x[n], a);
        psi[n].Re = exp(-pow((x[n]-x0)/sigma, 2)/2)*cos(p0*(x[n]-x0)/h_bar);
        psi[n].Im = exp(-pow((x[n]-x0)/sigma, 2)/2)*sin(p0*(x[n]-x0)/h_bar);
    }

    for (m=0; m<N; m++)
        fprintf(file, "%g %g %g\n", x[m],     psi[m].Re*psi[m].Re+psi[m].Im*psi[m].Im, V[m]);
    fclose(file);

    for (i=0; i<t_steps; i++)
    {

        printf("t_steps=%d\n", i);
        for (n=0; n<N; n++)
        {
            psi[n]=complex_product(psi[n], -V[n]*dt/h_bar, 1);
            psi[n]=complex_product(psi[n], -k[0]*x[n], dx/sqrt(2*pi));//x--->x_mod
        }


        fft(psi, N, 1);//psi: x_mod--->k_mod

        for (m=0; m<N; m++)
        {
            psi[m]=complex_product(psi[m], -m*dk*x[0], 1);//k_mod--->k
            psi[m]=complex_product(psi[m], -h_bar*k[m]*k[m]*dt/(2*m0), 1./N);
            psi[m]=complex_product(psi[m], m*dk*x[0], 1);//k--->k_mod
        }

        fft(psi, N, -1);
        for (n=0; n<N; n++)
            psi[n] = complex_product(psi[n], k[0]*x[n], sqrt(2*pi)/dx);//x_mod--->x
    }

    file = fopen("psi.txt", "w");
    for (m=0; m<N; m++)
        fprintf(file, "%g %g 0\n", x[m], pow((psi[m]).Re, 2)+pow((psi[m]).Im, 2));
    fclose(file);   

}

I use the following Python code to plot the initial and final evolved wave functions: 我使用以下Python代码绘制初始和最终演化的wave函数:

call: `>>> python plot.py result psi.txt`
import matplotlib.pyplot as plt
from sys import argv

for filename in argv[1:]:
    print filename
    f = open(filename, 'r')
    lines = [line.strip(" \n").split(" ") for line in f]
    x = [float(line[0]) for line in lines]
    y = [float(line[2]) for line in lines]
    psi = [float(line[1]) for line in lines]
    print "x=%g, max=%g" % (x[psi.index(max(psi))], max(psi))

    plt.plot(x, y, x, psi)
#plt.xlim([-1.0e-10, 1.0e-10])
plt.ylim([0, 3])
plt.show()

变量i在这里未初始化:

 k[n] = k0+(i-N*0.5)*dk;

Your code is almost correct, sans the fact that you are missing the initial/final half-step in the real domain and some unnecessary operations (k mod -> k and back), but the main problem is that your initial conditions are really chosen badly. 您的代码几乎是正确的,没有在实际域中缺少初始/最终半步和一些不必要的操作(k mod- > k并返回)的事实,但是主要问题是您的初始条件是真正选择的不好 The time evolution of a Gaussian wavepacket results in the uncertainty spreading out quadratically in time: 高斯波包的时间演化导致不确定性在时间上呈二次方扩展:

波包宽度的时间演化

Given your choice of particle mass and initial wavepacket width, the term in the braces equals 1 + 4 t 2 . 给定您选择的粒子质量和初始波包宽度,括号中的项等于1 + 4 t 2 After one timestep, the wavepacket is already significantly wider than initially and after another timestep becomes wider than the entire simulation box. 在一个时间步长之后,波形包已经比最初的宽度明显宽,而在另一个时间步长之后,波形包的宽度变得比整个模拟盒都宽。 The periodicity implied by the use of FFT results in spatial and frequency aliasing, which together with the overly large timestep is why your final wavefunction looks that strange. 使用FFT隐含的周期性会导致空间和频率混叠,再加上过长的时间步长,这就是为什么最终波函数看起来如此奇怪的原因。

I would advise that you try to replicate exactly the conditions of the Python program, including the fact that the entire system is in a deep potential well (V border -> +oo). 我建议您尝试完全复制Python程序的条件,包括整个系统都位于深潜孔中(V 边界 -> + oo)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM