C++ 在C++;

C++ 在C++;,c++,C++,我需要用Bulirsch-Stoer方法做一个N体模拟。我试着用C++中的这段代码为两个身体做这件事: void update(Body b){ initial_x=rx; initial_y=ry; initial_vx=vx; initial_vy=vy; dx=b.rx-initial_x; dy=b.ry-initial_y; dist = sqrt(dx*dx+dy*dy);

我需要用Bulirsch-Stoer方法做一个N体模拟。我试着用C++中的这段代码为两个身体做这件事:

void update(Body b){
        initial_x=rx;
        initial_y=ry;
        initial_vx=vx;
        initial_vy=vy;
        dx=b.rx-initial_x;
        dy=b.ry-initial_y;
        dist = sqrt(dx*dx+dy*dy);
        ax=G*b.mass*(b.rx-initial_x)/(dist*dist*dist);
        ay=G*b.mass*(b.ry-initial_y)/(dist*dist*dist);

        for(n=2;n<=8;n=n+2){
            h=H/n;
            vec_x[0]=initial_x+h*initial_vx;
            vec_y[0]=initial_y+h*initial_vy;
            vx=vx+h*ax;
            vy=vy+h*ay;
            dx=b.rx-vec_x[0];
            dy=b.ry-vec_y[0];
            dist = sqrt(dx*dx+dy*dy);
            ax=G*b.mass*(b.rx-vec_x[0])/(dist*dist*dist);
            ay=G*b.mass*(b.ry-vec_y[0])/(dist*dist*dist);
            vec_x[1]=initial_x+2*h*vx;
            vec_y[1]=initial_y+2*h*vy;
            vx=vx+h*ax;
            vy=vy+h*ay;
            dx=b.rx-vec_x[1];
            dy=b.ry-vec_y[1];
            dist = sqrt(dx*dx+dy*dy);
            ax=G*b.mass*(b.rx-vec_x[1])/(dist*dist*dist);
            ay=G*b.mass*(b.ry-vec_y[1])/(dist*dist*dist);
            if (n>2){
                for(int i=2;i<n;i++){
                    vec_x[i]=vec_x[i-2]+2*h*vx;
                    vec_y[i]=vec_y[i-2]+2*h*vy;
                    vx=vx+h*ax;
                    vy=vy+h*ay;
                    dx=b.rx-vec_x[i];
                    dy=b.ry-vec_y[i];
                    dist = sqrt(dx*dx+dy*dy);
                    ax=G*b.mass*(b.rx-vec_x[i])/(dist*dist*dist);
                    ay=G*b.mass*(b.ry-vec_y[i])/(dist*dist*dist);

                }
            }
            rx=0.5*(vec_x[n-2]+vec_x[n-1]+h*vx);
            ry=0.5*(vec_y[n-2]+vec_y[n-1]+h*vy);
            Rx[n/2-1]=rx;
            Ry[n/2-1]=ry;
        }

        rx=Rx[0]*(-H/4)*(-H/6)*(-H/8)/((H/2-H/4)*(H/2-H/6)*(H/2-H/8))+Rx[1]*(-H/2)*(-H/6)*(-H/8)/((H/4-H/2)*(H/4-H/6)*(H/4-H/8))+Rx[2]*(-H/2)*(-H/4)*(-H/8)/((H/6-H/2)*(H/6-H/4)*(H/6-H/8))+Rx[3]*(-H/2)*(-H/4)*(-H/6)/((H/8-H/2)*(H/8-H/4)*(H/8-H/6));
        ry=Ry[0]*(-H/4)*(-H/6)*(-H/8)/((H/2-H/4)*(H/2-H/6)*(H/2-H/8))+Ry[1]*(-H/2)*(-H/6)*(-H/8)/((H/4-H/2)*(H/4-H/6)*(H/4-H/8))+Ry[2]*(-H/2)*(-H/4)*(-H/8)/((H/6-H/2)*(H/6-H/4)*(H/6-H/8))+Ry[3]*(-H/2)*(-H/4)*(-H/6)/((H/8-H/2)*(H/8-H/4)*(H/8-H/6));
    }
无效更新(正文b){
初始_x=rx;
初始_y=ry;
初始_vx=vx;
初始值=vy;
dx=b.rx-初始值x;
dy=b.ry-初始值;
dist=sqrt(dx*dx+dy*dy);
ax=G*b.mass*(b.rx-initial_x)/(dist*dist*dist);
ay=G*b.mass*(b.ry-initial_y)/(dist*dist*dist);
对于(n=2;n2){

对于(int i=2;iIt看起来你有舍入误差,这会导致轨迹恶化。你需要在一个更合适的论坛上提问,你在数值模拟方面不会得到太多帮助。我的建议是不要自己实现Burlish Stoer(就像任何其他复杂的步进算法一样).相反,我会依赖数字配方的实现…或者忘记所有这些繁重的方法,根据我的经验,这些方法会给你一个常数(通常比运行它们的时间要短)@davidhigh该代码表明这是一个引力系统的模拟。这种问题因在较长时间内失去准确性而臭名昭著。我想最好的办法是用守恒量(总能量、角动量)来重新表述这个问题,并从那里开始(或至少监测它们的值).这不容易。我没有检查你的实现,但是轨道衰减得非常快(落在两个轨道下的恒星中)这一事实让我认为你没有给次级足够的速度来维持它的轨道。是的,除非你小心选择一个好的积分器,否则你会随着时间损失能量(但这通常超过数千个轨道,而不是两个)。对于圆形轨道,初始速度应为$v_x=0$,而$v_y=v_K$开普勒速度,即$v_K=\sqrt(GM_*/a)$,其中,$M_*$是中心天体的质量,$a$是轨道天体的半长轴。看起来你有舍入误差,这会导致轨道恶化。你需要在一个更合适的论坛上提问,你在这里不会得到太多的数值模拟帮助。我的建议是不要在y之前实现Burlish Stoer我们自己(和任何其他复杂的步进算法一样)。相反,我会依赖数字配方实现……或者忘记所有这些繁重的方法,根据我的经验,这些方法会给你一个常数(通常比运行它们的时间要短)@davidhigh该代码表明这是一个引力系统的模拟。这种问题因在较长时间内失去准确性而臭名昭著。我想最好的办法是用守恒量(总能量、角动量)来重新表述这个问题,并从那里开始(或至少监测它们的值).这不容易。我没有检查你的实现,但是轨道衰减得非常快(落在两个轨道下的恒星中)这一事实让我认为你没有给次级足够的速度来维持它的轨道。是的,除非你小心选择一个好的积分器,否则你会随着时间损失能量(但这通常超过数千个轨道,而不是两个)。对于圆形轨道,初始速度应该是$v_x=0$,并且$v_y=v_K$开普勒速度,即$v_K=\sqrt(GM_*/a)$,其中$M_*$是中心物体的质量,$a$是轨道物体的半长轴。