-
Notifications
You must be signed in to change notification settings - Fork 9
/
serial.cpp
65 lines (54 loc) · 1.74 KB
/
serial.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "common.h"
#include <cmath>
// Apply the force from neighbor to particle
void apply_force(particle_t& particle, particle_t& neighbor) {
// Calculate Distance
double dx = neighbor.x - particle.x;
double dy = neighbor.y - particle.y;
double r2 = dx * dx + dy * dy;
// Check if the two particles should interact
if (r2 > cutoff * cutoff)
return;
r2 = fmax(r2, min_r * min_r);
double r = sqrt(r2);
// Very simple short-range repulsive force
double coef = (1 - cutoff / r) / r2 / mass;
particle.ax += coef * dx;
particle.ay += coef * dy;
}
// Integrate the ODE
void move(particle_t& p, double size) {
// Slightly simplified Velocity Verlet integration
// Conserves energy better than explicit Euler method
p.vx += p.ax * dt;
p.vy += p.ay * dt;
p.x += p.vx * dt;
p.y += p.vy * dt;
// Bounce from walls
while (p.x < 0 || p.x > size) {
p.x = p.x < 0 ? -p.x : 2 * size - p.x;
p.vx = -p.vx;
}
while (p.y < 0 || p.y > size) {
p.y = p.y < 0 ? -p.y : 2 * size - p.y;
p.vy = -p.vy;
}
}
void init_simulation(particle_t* parts, int num_parts, double size) {
// You can use this space to initialize static, global data objects
// that you may need. This function will be called once before the
// algorithm begins. Do not do any particle simulation here
}
void simulate_one_step(particle_t* parts, int num_parts, double size) {
// Compute Forces
for (int i = 0; i < num_parts; ++i) {
parts[i].ax = parts[i].ay = 0;
for (int j = 0; j < num_parts; ++j) {
apply_force(parts[i], parts[j]);
}
}
// Move Particles
for (int i = 0; i < num_parts; ++i) {
move(parts[i], size);
}
}