在使用包含所有实体的数组时,尝试编写代码来解决nbody问题时遇到问题。我的代码没有做正确的事情,我不知道它出错的地方虽然我怀疑它与传递数组作为参考有关。为了更容易发现我的错误,我将包含一个工作版本的代码,它不会以相同的方式使用包含所有实体的数组。以下是不起作用的代码(使用此代码计算物体轨道而不是椭圆时):
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#define h 10000.0 // size of the timestep
#define N 3 // number of bodies
#define G 6.67384*pow(10.0,-11) // gravitational constant
using namespace std;
class particle{
public:
double kx1,kx2,kx3,kx4, kv1, kv2, kv3, kv4;
double ky1, ky2, ky3, ky4, kvy1, kvy2, kvy3, kvy4;
double x,y,vx,vy,m;
double dist(particle body){
double dx = x - body.x;
double dy = y - body.y;
return sqrt(pow(dx,2.0)+pow(dy,2.0));
}
double g(double x1, double y1,particle body){
return G*body.m*(body.x-x1)/pow(dist(body),3.0);
}
double p(double x1, double y1, particle body){
return G*body.m*(body.y-y1)/pow(dist(body),3.0);
}
void update(){ //object advances 1 step
x = x + (1/6.0)*(kx1+2*kx2+2*kx3+kx4);
vx = vx + (1/6.0)*(kv1+2*kv2+2*kv3+kv4);
y = y + (1/6.0)*(ky1+2*ky2+2*ky3+ky4);
vy = vy + (1/6.0)*(kvy1+2*kvy2+2*kvy3+kvy4);
}
void create(double x1, double y1, double vx1, double vy1, double m1){ //choose the inital conditions for a new object
x = x1;
y = y1;
vx = vx1;
vy = vy1;
m =m1;
}
bool operator ==(particle &other){
if(x == other.x && y == other.y && vx == other.vx && vy == other.vy){
return true;
}
}
};
particle bodies[N];
void set(particle (&bodies)[N]){
bodies[0].create(1, 1, -2, 1, 2*pow(10.0,30));
bodies[1].create(2870671*pow(10.0,6), 0, 0, 6800, 8.6810*pow(10.0,25));
bodies[2].create(4498542*pow(10.0,6),0 ,0, 5430, 1.0243*pow(10.0,26));
}
double xforce(double x1, double y1, particle body, particle bodies[N]){ //force in the x- direction
double fx = 0;
for (int i = 0; i < N; i++){
if (bodies[i] == body ){;}
else{
fx += body.g(x1,y1,bodies[i]);
}
}
return fx;
}
double yforce(double x1, double y1, particle body, particle bodies[N]){ //force in the y- direction
double fy = 0;
for (int i = 0; i < N; i++){
if (bodies[i] == body) {;}
else{
fy += body.p(x1,y1,bodies[i]);
}
}
return fy;
}
void corr(double t, particle bodies[N]){ //runge kutta 4
for(int i =0; i <= N; i++){
bodies[i].kx1 = t*bodies[i].vx;
bodies[i].kv1 = t*xforce(bodies[i].x, bodies[i].y, bodies[i], bodies);
bodies[i].ky1 = t*bodies[i].vy;
bodies[i].kvy1 = t*yforce(bodies[i].x, bodies[i].y, bodies[i], bodies);
bodies[i].kx2 = t*(bodies[i].vx + 0.5*bodies[i].kv1);
bodies[i].kv2 = t*xforce(bodies[i].x + 0.5*bodies[i].kx1, bodies[i].y + 0.5*bodies[i].ky1, bodies[i], bodies);
bodies[i].ky2 = t*(bodies[i].vy + 0.5*bodies[i].kvy1);
bodies[i].kvy2 = t*yforce(bodies[i].x + 0.5*bodies[i].kx1, bodies[i].y + 0.5*bodies[i].ky1, bodies[i], bodies);
bodies[i].kx3 = t*(bodies[i].vx+ 0.5*bodies[i].kv2);
bodies[i].kv3 = t*xforce(bodies[i].x + 0.5*bodies[i].kx2, bodies[i].y + 0.5*bodies[i].ky2, bodies[i], bodies);
bodies[i].ky3 = t*(bodies[i].vy+ 0.5*bodies[i].kvy2);
bodies[i].kvy3 = t*yforce(bodies[i].x + 0.5*bodies[i].kx2, bodies[i].y + 0.5*bodies[i].ky2,bodies[i], bodies);
bodies[i].kx4 = t*(bodies[i].vx + bodies[i].kv3);
bodies[i].kv4 = t*xforce(bodies[i].x+ bodies[i].kx3, bodies[i].y + bodies[i].ky3, bodies[i], bodies);
bodies[i].ky4 = t*(bodies[i].vy + bodies[i].kvy3);
bodies[i].kvy4 = t*yforce(bodies[i].x + bodies[i].kx3, bodies[i].y + bodies[i].ky3, bodies[i], bodies);
}
}
void calculate(particle (&bodies)[N]){
set(bodies);
ofstream file;
file.open("tester.txt");
for(int i =0; i <=50000; i++){
corr(h, bodies);
for(int j = 0; j <= N; j++){
bodies[j].update();
}
if( i%1000 == 0){
file << i*h;
for(int j = 0; j <=N ; j++){
file <<" "<<bodies[j].x << " "<< bodies[j].y;
}
file <<" "<<"\n";
}
else{;}
}
file.close();
}
int main()
{
calculate(bodies);
system("pause");
return 0;
}
这是代码的工作版本,两者都应该解决同样的问题:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#define h 10000.0
#define N 3
#define G 6.67384*pow(10.0,-11)
using namespace std;
class particle{
public:
double kx1,kx2,kx3,kx4, kv1, kv2, kv3, kv4;
double ky1, ky2, ky3, ky4, kvy1, kvy2, kvy3, kvy4;
double x,y,vx,vy,m;
double dist(particle body){
double dx = x - body.x;
double dy = y - body.y;
return sqrt(pow(dx,2.0)+pow(dy,2.0));
}
double g(double x1, double y1,particle body){
return G*body.m*(body.x-x1)/pow(dist(body),3.0);
}
double p(double x1, double y1, particle body){
return G*body.m*(body.y-y1)/pow(dist(body),3.0);
}
void update(){
x = x + (1/6.0)*(kx1+2*kx2+2*kx3+kx4);
vx = vx + (1/6.0)*(kv1+2*kv2+2*kv3+kv4);
y = y + (1/6.0)*(ky1+2*ky2+2*ky3+ky4);
vy = vy + (1/6.0)*(kvy1+2*kvy2+2*kvy3+kvy4);
}
void create(double x1, double y1, double vx1, double vy1, double m1){
x = x1;
y = y1;
vx = vx1;
vy = vy1;
m =m1;
}
bool operator ==(particle &other){
if(x == other.x && y == other.y && vx == other.vx && vy == other.vy){
return true;
}
}
bool operator !=(particle &other){
if(x != other.x || y != other.y || vx != other.vx || vy != other.vy){
return true;
}
}
};
particle zon, uranus, neptunus;
particle closest[] = {uranus, neptunus};
void set(){
zon.create(1, 1, -2, 1, 2*pow(10.0,30));
uranus.create(2870671*pow(10.0,6), 0, 0, 6800, 8.6810*pow(10.0,25));
neptunus.create(4498542*pow(10.0,6),0 ,0, 5430, 1.0243*pow(10.0,26));
}
double xforce(double x1, double y1, particle body){
particle bodies[] = {zon, uranus, neptunus};
double fx = 0;
for (int i = 0; i < 3; i++){
if (bodies[i] == body ){;}
else{
fx += body.g(x1,y1,bodies[i]);
}
}
return fx;
}
double yforce(double x1, double y1, particle body){
particle bodies[] = {zon, uranus, neptunus};
double fy = 0;
for (int i = 0; i <= 3; i++){
if (bodies[i] == body) {;}
else{
fy += body.p(x1,y1,bodies[i]);
}
}
return fy;
}
void corr(particle& body, double t){
body.kx1 = t*body.vx;
body.kv1 = t*xforce(body.x, body.y, body);
body.ky1 = t*body.vy;
body.kvy1 = t*yforce(body.x, body.y, body);
body.kx2 = t*(body.vx + 0.5*body.kv1);
body.kv2 = t*xforce(body.x + 0.5*body.kx1, body.y + 0.5*body.ky1, body);
body.ky2 = t*(body.vy + 0.5*body.kvy1);
body.kvy2 = t*yforce(body.x + 0.5*body.kx1, body.y + 0.5*body.ky1, body);
body.kx3 = t*(body.vx+ 0.5*body.kv2);
body.kv3 = t*xforce(body.x + 0.5*body.kx2, body.y + 0.5*body.ky2, body);
body.ky3 = t*(body.vy+ 0.5*body.kvy2);
body.kvy3 = t*yforce(body.x + 0.5*body.kx2, body.y + 0.5*body.ky2,body);
body.kx4 = t*(body.vx+body.kv3);
body.kv4 = t*xforce(body.x+ body.kx3, body.y + body.ky3, body);
body.ky4 = t*(body.vy + body.kvy3);
body.kvy4 = t*yforce(body.x + body.kx3, body.y + body.ky3, body);
}
void bereken(){
set();
ofstream file;
file.open("tester.txt");
for(int i =0; i <=50000; i++){
corr(zon, h);
corr(uranus, h);
corr(neptunus, h);
zon.update();
uranus.update();
neptunus.update();
if( i%1000 == 0){
file << i*h <<" "<<zon.x << " "<< zon.y <<" "<<uranus.x<<" " <<uranus.y <<" "<< neptunus.x<<" "<<neptunus.y<<" "<<"\n";
}
else{;}
}
file.close();
}
int main()
{
bereken();
system("pause");
return 0;
}
答案 0 :(得分:0)
一个问题是你在3个地方溢出bodies[]
数组:
#define N 3
particle bodies[N];
for (int i = 0; i <= N; i++) {
bodies[i].x = ... // Oops, access bodies[3] which doesn't exist
您在两个地方使用的正确循环是:
for (int i = 0; i < N; i++) { // 0 to < N