Thread Closed

NBody evaluation, is my model correct?

 
Share Thread Thread Tools
May25-05, 01:05 PM   #1
 
Unhappy

NBody evaluation, is my model correct?


Hello all,

I've written a very simple nbody solver in c. Basically, I just went through an array of particles and solved F = G(m1)(m2) / r ^2

The output is here: (sorry for the windows format)
http://www.crepinc.com/files/galax.wmv

As you can see, some of the particles don't do what one would expect....

So far the only possible reason I can come up for is that I'm solving the equations at a set dT. Thus if the dT is too large, "stuff happens" between the two different solves. But if dT is too small, the whole thing basically blows up.

Am I overlooking something, or is my math ok and my code is just bad?

Thanks a lot,

-Jack Carrozzo
http://www.crepinc.com/
 
PhysOrg.com
PhysOrg
science news on PhysOrg.com

>> Front-row seats to climate change
>> Attacking MRSA with metals from antibacterial clays
>> New formula invented for microscope viewing, substitutes for federally controlled drug
May25-05, 01:25 PM   #2
 
Recognitions:
Gold Membership Gold Member
Science Advisor Science Advisor
Quote by crepincdotcom
Am I overlooking something, or is my math ok and my code is just bad?
Can't tell without seeing the code, especially the lines that contain the time step variable.
 
May25-05, 02:01 PM   #3
 
Recognitions:
Gold Membership Gold Member
The time step can intrdouce such problems - you tend to find that energy isn't conserved. I would tend to put in energy conservation 'by hand'. However, there does seem to be another problem with your animation - it takes some time for all of the particles to start moving, and then some of them stop moving. I would guess that this is due to a problem with the code.
 
May25-05, 02:17 PM   #4
 

NBody evaluation, is my model correct?


OK, I will post the code at 8:00, sorry I can't get it before then.

As to the particles that stop, It usually doesn't do that. I think I've decreased dT too much or something.... I didn't make any hardcore code changes.

But, I don't want to bother you guys with code issues. In terms of theory, does evaluating F and then making a sum of all forces do the trick? Or do I need to find a way to use the differentia l equations and such?

-Jack Carrozzo
http://www.crepinc.com/
 
May26-05, 12:53 AM   #5
 
Hello,
Try to work with different DT. Best of Luck. Zaheer A
 
May26-05, 07:16 AM   #6
 
OK, at the bottom of this post is the code. I got the model to look FAIRLY accurate by playing with the dT. But if I go higher or lower, the whole system no longer works accuratly. IS there a logical explanation for this?

The other issue is that of the Y axis. You can see in the "MoveParticles" function that when taking the sum of all y-forces and adding them to the velocity, I multiply the acceleration by 25. I have no idea why this needs to happen. All I know is that, whithout that line, the simulation seems to "favor" the X axis, with the particles hardly moving in the Y.

Finally, one should notice that I removed some 0's from the constant G. This is because multiplying something X 10^ -11 with a number (Mass) like 10 ^ 6, there are a lot of extra spaces in there. I was told it was easier and more accurate in the evaluation of that code if I simply lopped off some zero's. So, any mass you see is actually large by a factor of 10^5.

Here's the code: (it will only let me post little bits, the whole thing is at crepinc.com/files/nbody.c)

Code:
#define NUMPARTS   100 //how many particles
#define GRID_X     640
#define GRID_Y     480
//known working values for these are 10, 100000, 0.004, 2
#define MASS       10 //plus 10 zeros
#define CENTERMASS 100000 //plus 10 zeros
#define TIMESTEP   0.004 //seconds per step
#define IMAGESTEP  2 //make bmp every n steps

#define rad(d)     (3.1415926 * d) / 180 //radians from degress
#define DEBUG      0 //0 off, 1 on

struct PartType
{
  int               x; //x coord for body
  int               y; //y coord
	unsigned long int m;
  double            vi;//i-hat of velocity vector
  double            vj;//j-hat "                "
};

struct ForceType
{
  double i;
  double j;
};

struct PartType Particles[NUMPARTS];
struct ForceType ForceSum;
struct ForceType MoveForce[NUMPARTS]; //where forces are stored until move()
int ImageGrid[GRID_X][GRID_Y];
int Steps,ERR;
int ImgSteps=0;
Code:
void InitParticles( void )
{
  int i,j;

	srand(time()*getpid());
	Particles[0].x = (int)(GRID_X / 2);
  Particles[0].y = (int)(GRID_Y / 2);
  Particles[0].m = CENTERMASS;
  Particles[0].vi = 0;
  Particles[0].vj = 0;

	for (i=1;i<NUMPARTS;i++) //starts at 1, not 0
  {
    Particles[i].x = ((double)rand()/((double)pow(2,31))) * GRID_X;
    Particles[i].y = ((double)rand()/((double)pow(2,31))) * GRID_Y;
    Particles[i].m = MASS;
    Particles[i].vi = 0;
    Particles[i].vj = 0;
  }

	for (i=0;i<GRID_X;i++)
	{
		for (j=0;j<GRID_Y;j++)
		{
			ImageGrid[i][j]=0;
		}
	}
}
Code:
void ComputeForces( void )
{
  int i,j,fxsign,fysign; //signs: 0 +, 1 -
  double r,F,theta,dx,dy,fx,fy;
  double G=0.667; //has 10 zeros taken off

  for (i=0;i<NUMPARTS;i++)
  {
		ForceSum.i=0;
  	ForceSum.j=0;
    for (j=0;j<NUMPARTS;j++)
    {
      if (j!=i)
      {
				fxsign=0;
				fysign=0;
				if ((Particles[j].x - Particles[i].x) < 0) fxsign++;
				if ((Particles[j].y - Particles[i].y) < 0) fysign++;
				dx = abs(Particles[i].x - Particles[j].x);
        dy = abs(Particles[i].y - Particles[j].y);
        theta = atan(dy/dx); //theta in radians
        r = sqrt((dx * dx) + (dy * dy)); //distance
				F = ((G * (double)(Particles[i].m) * (double)(Particles[j].m)) / (r * r));
				if (DEBUG) printf("F= %e, G= %e m1= %d, m2= %d, r= %f\n",F,G,Particles[i].m,Particles[j].m,r);
				fx = cos(rad(theta)) * F;
        fy = sin(rad(theta)) * F;
				if (DEBUG) if (i==2) printf("compareing to %d, r - %f, force x %f, force y %f, theta %f\n",j,r,fx,fy,theta);
				if (fxsign==0)
					ForceSum.i += fx;
				else
					ForceSum.i -= fx;

				if (fysign==0)
        	ForceSum.j += fy;
				else
					ForceSum.j -= fy;
      }
    }
    MoveForce[i].i = ForceSum.i;
    MoveForce[i].j = ForceSum.j;
  }
}
Code:
void MoveParticles( void )
{
  int i;
  double A; //acceleration

  for (i=0;i<NUMPARTS;i++)
  {
    //F=MA, A=F/M
    A = (MoveForce[i].i / (Particles[i].m));
    Particles[i].vi += (A * TIMESTEP);
    A = (MoveForce[i].j / (Particles[i].m));
		A *= 25; //don't know why, but need this
    Particles[i].vj += (A * TIMESTEP);

		Particles[i].x += (int)(Particles[i].vi);
		Particles[i].y += (int)(Particles[i].vj);

		if (DEBUG) if (i==2) printf("part 2, y %f, f %f, %f.\n",Particles[i].vj,MoveForce[i].i,MoveForce[i].j);
  }
  Steps++;
}
("DataOut and bitmap functions left out)
Code:
int main( int argc, char *argv[] )
{
	int i, frames;

	printf("Simple NBODY solver by Jack Carrozzo.\n");

	if (argc!=2)
	{
		printf("Usage: ./nbody <frames>\n");
		exit(1);
	}

	frames = atoi(argv[1]);

	printf("Will go for %d iterations, writing %d frames.\n",(int)(frames*IMAGESTEP),frames);

	InitParticles();

	if (DEBUG)
	{
			printf("\n   [+] Time: %d [+]\n",Steps);
			for (i=0;i<NUMPARTS;i++)
			{
				printf("----------------------\n");
				printf("Particle Num     : %d\n",i);
				printf("Particle Position: (%d,%d)\n",Particles[i].x,Particles[i].y);
				printf("Particle Velocity: (%f,%f)\n",Particles[i].vi,Particles[i].vj);
				printf("----------------------\n");
		}
	}
	DataOut();

	for (i=0;i<(frames*IMAGESTEP);i++)
	{
		ComputeForces();
		MoveParticles();
		DataOut();
	}

	if (DEBUG)
	{
		printf("\n   [+] Time: %d [+]\n",Steps);
		for (i=0;i<NUMPARTS;i++)
		{
			printf("----------------------\n");
			printf("Particle Num     : %d\n",i);
			printf("Particle Position: (%d,%d)\n",Particles[i].x,Particles[i].y);
			printf("Particle Velocity: (%f,%f)\n",Particles[i].vi,Particles[i].vj);
			printf("----------------------\n");
		}
	}
	printf("Done.\n");

  return 0;
}
Thanks a lot,

-Jack Carrozzo
http://www.crepinc.com/
 
May26-05, 07:23 AM   #7
 
OK the source above can by found fully at: crepinc.com/files/nbody.c
The movie it put out is at: crepinc.com/files/galax2.wmv (sorry for WMV)
Notice how it's better than the first movie (crepinc.com/files/galax.wmv), but how some particles still stop. I can find no reason for this. All the particles are evaluated exactly the same way, why are some treated differently?

FYI to compile the code: gcc -O3 -lm -onbody nbody.c

Thanks

-Jack Carrozzo
http://www.crepinc.com/
 
May26-05, 10:31 AM   #8
 
Recognitions:
Gold Membership Gold Member
Science Advisor Science Advisor
Does the code work properly when TIMESTEP = 1?
 
May26-05, 01:14 PM   #9
 
It DID work, though everything went so fast it was a little hard to tell.

That's a good point, I'll check it out tomorrow when I can get to my other comp.

Thanks

-Jack Carrozzo
http://www.crepinc.com/
 
May26-05, 01:41 PM   #10
 
Recognitions:
Gold Membership Gold Member
In fx = cos(rad(theta)) * F; theta is already in radians, so multiplying it by pi/180 is an error
 
May26-05, 04:00 PM   #11
 
Aha! I'm an idiot , quite sorry for that. I suppose that would account for the X-favouring issue. I'm not sure why it would have worked before and not not, but tomorrow I'll fix this and see what I get.

Thanks a lot,

-Jack Carrozzo
http://www.crepinc.com/
 
May27-05, 01:07 PM   #12
 
OK, I fixed the Radians problem. It seems to be working now. The only issue seems to be the singularity issue. I would imagine that this is an inherant issue in every code of this sort, am I right?

The pretty-much ok video is at: http://creponc.com/files/galax3.wmv
A funny mess up: http://crepinc.com/files/blowup.wmv

Thanks.

-Jack Carrozzo
http://www.crepinc.com/
 
Jun10-05, 03:45 PM   #13
 
Check out the NEMO site at the University of Maryland:

http://bima.astro.umd.edu/nemo/

In addition to posting information about their own work, they also list several sites/resources/software packages relating to N-Body work.

Regards,


DuncanM
http://www.rocketscientists.ca/
 
Thread Closed
Thread Tools


Similar Threads for: NBody evaluation, is my model correct?
Thread Forum Replies
is Free-electron model := Drude Model (of metals) ? Atomic, Solid State, Comp. Physics 2
What if the Bohmian model turned out to be correct? Quantum Physics 144
Creating an Optimizer - What is the correct Math Model or formula to use ? Linear & Abstract Algebra 1
question on Lotka-Volterra model and Lanchaster combat model Differential Equations 6
time dilation(correct/not correct) Introductory Physics Homework 1