forked from jgbarbosa/3dfluid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
129 lines (109 loc) · 3.43 KB
/
main.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "EventManager.h"
#include "fluid_solver.h"
#include <iostream>
#include <vector>
#define SIZE 42
#define IX(i, j, k) ((i) + (M + 2) * (j) + (M + 2) * (N + 2) * (k))
// Globals for the grid size
static int M = SIZE;
static int N = SIZE;
static int O = SIZE;
static float dt = 0.1f; // Time delta
static float diff = 0.0001f; // Diffusion constant
static float visc = 0.0001f; // Viscosity constant
// Fluid simulation arrays
static float *u, *v, *w, *u_prev, *v_prev, *w_prev;
static float *dens, *dens_prev;
// Function to allocate simulation data
int allocate_data() {
int size = (M + 2) * (N + 2) * (O + 2);
u = new float[size];
v = new float[size];
w = new float[size];
u_prev = new float[size];
v_prev = new float[size];
w_prev = new float[size];
dens = new float[size];
dens_prev = new float[size];
if (!u || !v || !w || !u_prev || !v_prev || !w_prev || !dens || !dens_prev) {
std::cerr << "Cannot allocate memory" << std::endl;
return 0;
}
return 1;
}
// Function to clear the data (set all to zero)
void clear_data() {
int size = (M + 2) * (N + 2) * (O + 2);
for (int i = 0; i < size; i++) {
u[i] = v[i] = w[i] = u_prev[i] = v_prev[i] = w_prev[i] = dens[i] =
dens_prev[i] = 0.0f;
}
}
// Free allocated memory
void free_data() {
delete[] u;
delete[] v;
delete[] w;
delete[] u_prev;
delete[] v_prev;
delete[] w_prev;
delete[] dens;
delete[] dens_prev;
}
// Apply events (source or force) for the current timestep
void apply_events(const std::vector<Event> &events) {
for (const auto &event : events) {
if (event.type == ADD_SOURCE) {
// Apply density source at the center of the grid
int i = M / 2, j = N / 2, k = O / 2;
dens[IX(i, j, k)] = event.density;
} else if (event.type == APPLY_FORCE) {
// Apply forces based on the event's vector (fx, fy, fz)
int i = M / 2, j = N / 2, k = O / 2;
u[IX(i, j, k)] = event.force.x;
v[IX(i, j, k)] = event.force.y;
w[IX(i, j, k)] = event.force.z;
}
}
}
// Function to sum the total density
float sum_density() {
float total_density = 0.0f;
int size = (M + 2) * (N + 2) * (O + 2);
for (int i = 0; i < size; i++) {
total_density += dens[i];
}
return total_density;
}
// Simulation loop
void simulate(EventManager &eventManager, int timesteps) {
for (int t = 0; t < timesteps; t++) {
// Get the events for the current timestep
std::vector<Event> events = eventManager.get_events_at_timestamp(t);
// Apply events to the simulation
apply_events(events);
// Perform the simulation steps
vel_step(M, N, O, u, v, w, u_prev, v_prev, w_prev, visc, dt);
dens_step(M, N, O, dens, dens_prev, u, v, w, diff, dt);
}
}
int main() {
// Initialize EventManager
EventManager eventManager;
eventManager.read_events("events.txt");
// Get the total number of timesteps from the event file
int timesteps = eventManager.get_total_timesteps();
// Allocate and clear data
if (!allocate_data())
return -1;
clear_data();
// Run simulation with events
simulate(eventManager, timesteps);
// Print total density at the end of simulation
float total_density = sum_density();
std::cout << "Total density after " << timesteps
<< " timesteps: " << total_density << std::endl;
// Free memory
free_data();
return 0;
}