Use a vector math library
Find a suitable library that implements coordinate vectors, so you don't have to implement them as arrays of doubles. Ideally your struct Particle
should look like:
struct Particle {
double m; // mass
vec3 x; // position
vec3 v; // velocity
vec3 F; // force
vec3 F_old; // force past time step
};
And a suitable library will provide functions and operator overloads to make working with these types very easy. You should be able to write something like:
void Nbody::update_position(Particle *p) {
double a = dt * 0.5 / p->m;
p->x += dt * (p->v + a * p->F);
p->F_old = p->F;
}
There are many libraries available. I am partial to GLM myself. For a discussion of possible libraries, see https://stackoverflow.com/questions/1380371/what-are-the-most-widely-used-c-vector-matrix-math-linear-algebra-libraries-a.
Make function manipulating Particle
s member functions of Particle
You have a lot of functions that mainly manipulate a particle's state, but they are not part of struct Particle
itself. For example, update_position()
is something that apart from the timestep dt
only manipulates a Particle
's member variables. If you make it a member function of Particle
, it becomes a much cleaner looking function:
struct Particle {
...
void update_position(double dt);
};
void Particle::update_position(double dt) {
double a = dt * 0.5 / m;
x += dt * (v + a * F);
F_old = F;
}
And you call it like so:
void Nbody::comp_position() {
for (auto &p: particles) {
p.update_position(dt);
}
}
You can do the same for update_velocity()
, and even force()
.