Skip to content

Commit d3e4a6f

Browse files
committed
A bunch of fluid-sim changes
1 parent e06e6dd commit d3e4a6f

File tree

6 files changed

+537
-264
lines changed

6 files changed

+537
-264
lines changed

package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
"@fortawesome/free-regular-svg-icons": "6.4.0",
1313
"@fortawesome/free-solid-svg-icons": "6.4.0",
1414
"@fortawesome/react-fontawesome": "0.2.0",
15-
"@vercel/analytics": "0.1.11",
15+
"@vercel/analytics": "1.0.1",
1616
"clsx": "1.2.1",
17-
"next": "latest",
17+
"next": "13.4.7",
1818
"react": "18.2.0",
1919
"react-dom": "18.2.0"
2020
},
@@ -23,19 +23,19 @@
2323
"@types/react": "18.0.15",
2424
"@types/react-dom": "18.0.6",
2525
"@webgpu/types": "0.1.32",
26-
"autoprefixer": "^10.4.7",
26+
"autoprefixer": "10.4.14",
2727
"eslint": "8.19.0",
2828
"eslint-config-next": "latest",
2929
"msdf-bmfont-xml": "2.7.0",
30-
"postcss": "^8.4.14",
30+
"postcss": "8.4.23",
3131
"postcss-comment": "2.0.0",
3232
"postcss-import": "15.1.0",
3333
"postcss-nesting": "11.2.1",
3434
"postcss-scss": "4.0.6",
3535
"sass": "1.59.3",
3636
"svg2ttf": "6.0.3",
3737
"svgicons2svgfont": "12.0.0",
38-
"tailwindcss": "3.2.7",
38+
"tailwindcss": "3.3.2",
3939
"typescript": "4.7.4"
4040
}
4141
}

postcss.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
plugins: {
33
'autoprefixer': {},
4+
'tailwindcss': {},
45
},
56
};

src/fluidsim/FluidSimMain.tsx

+40-16
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import { PerlinNoise2D } from './PerlinNoise';
44

55
export interface IFluidSimState {
6-
canvas: HTMLCanvasElement;
6+
running: boolean;
77
sim: IFluidSim;
8-
targetDefs: ICanvasTargetDef[];
8+
canvasTemp: HTMLCanvasElement;
99
}
1010

1111
export interface ICanvasTargetDef {
@@ -16,6 +16,7 @@ export interface ICanvasTargetDef {
1616
export interface IFluidSim {
1717
width: number;
1818
height: number;
19+
numPressureIterations: number;
1920
cells: Float32Array; // 2d array of floats, with values for (temperature, density, velocityX, velocityY)
2021

2122
cells2: Float32Array;
@@ -29,13 +30,15 @@ export interface IFluidSim {
2930
cellSize: number;
3031

3132
aggregates: ISimAggregates | null;
33+
34+
iterCount: number;
3235
}
3336

34-
export function initFluidSimState(canvas: HTMLCanvasElement): IFluidSimState {
37+
export function initFluidSimState(): IFluidSimState {
3538
return {
36-
canvas: canvas,
3739
sim: initFluidSim(64, 64),
38-
targetDefs: [],
40+
running: false,
41+
canvasTemp: document.createElement('canvas'),
3942
};
4043
}
4144

@@ -49,6 +52,7 @@ export function initFluidSim(w: number, h: number): IFluidSim {
4952
let sim: IFluidSim = {
5053
width,
5154
height,
55+
numPressureIterations: 1,
5256
cells: new Float32Array(width * height * 4),
5357
cells2: new Float32Array(width * height * 4),
5458
cells3: new Float32Array(width * height * 4),
@@ -58,13 +62,15 @@ export function initFluidSim(w: number, h: number): IFluidSim {
5862
divergence1: new Float32Array(width * height),
5963
cellSize,
6064
aggregates: null,
65+
iterCount: 0,
6166
};
6267

6368
let scaleX = 4 / width;
6469
let scaleY = 4 / height;
6570
let perlin = new PerlinNoise2D(4);
6671
let perlinVelX = new PerlinNoise2D(7);
6772
let perlinVelY = new PerlinNoise2D(8);
73+
let maxVelX = 0;
6874
for (let y = 0; y < height; y++) {
6975
for (let x = 0; x < width; x++) {
7076
sim.cells[(y * width + x) * 4 + 0] = perlin.octaveNoise((x + 10) * scaleX, (y + 10) * scaleY, 5, 0.8); // temperature
@@ -78,15 +84,18 @@ export function initFluidSim(w: number, h: number): IFluidSim {
7884
// units: m/s
7985
// a rectangular region of velocity, in the center of the screen, pointing up and to the right a bit
8086
if (x > width * 4 / 10 && x < width * 6 / 10 && y > height * 4 / 10 && y < height * 6 / 10) {
81-
velX = 1.5 / 100; // 1.5 m/s
82-
velY = 1.5 / 100;
87+
velX = 4 / 100; // 0.4 cm/s
88+
velY = 4 / 100;
89+
maxVelX = Math.max(maxVelX, velX);
8390
}
8491

8592
sim.cells[(y * width + x) * 4 + 2] = velX;
8693
sim.cells[(y * width + x) * 4 + 3] = velY;
8794
}
8895
}
8996

97+
console.log(`maxVelX: ${maxVelX}, cellSize: ${cellSize}, maxVelX / cellSize: ${maxVelX / cellSize}`);
98+
9099
fixBoundaries(sim);
91100
computeAggregateValues(sim);
92101

@@ -147,7 +156,9 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
147156

148157
// advection
149158

150-
if (false) {
159+
if (sim.iterCount > 0) {
160+
let maxDx = 0;
161+
let maxVx = 0;
151162
for (let y = 0; y < sim.height; y++) {
152163
for (let x = 0; x < sim.width; x++) {
153164
let vX = getCell(sim.cells, y, x, 2);
@@ -157,6 +168,9 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
157168
let x0 = x - vX * dt / sim.cellSize;
158169
let y0 = y - vY * dt / sim.cellSize;
159170

171+
maxDx = Math.max(maxDx, Math.abs(x0 - x));
172+
maxVx = Math.max(maxVx, Math.abs(vX));
173+
160174
// get all the state variables at that point
161175
let tempSrc = getCellBilinearClamped(sim.cells, y0, x0, 0);
162176
let densitySrc = getCellBilinearClamped(sim.cells, y0, x0, 1);
@@ -169,6 +183,8 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
169183
setCell(sim.cells2, y, x, 3, velYSrc);
170184
}
171185
}
186+
187+
// console.log(`maxDx: ${maxDx * 1000/20} (cells/s), maxVx: ${maxVx * 100} (cm/s)`);
172188
} else {
173189
sim.cells2.set(sim.cells);
174190
}
@@ -229,8 +245,8 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
229245
// (we've already got our tentative velocity field in arrFrom, and don't have things like gravity to worry about)
230246

231247
// solve pressure-poisson equation
232-
let pressureAlpha = -sim.cellSize * sim.cellSize / (4 * dt);
233-
let pressureBeta = 1;
248+
// let pressureAlpha = sim.cellSize * sim.cellSize;
249+
// let pressureBeta = 1;
234250

235251
let pressureFrom = sim.pressure0;
236252
let pressureTo = sim.pressure1;
@@ -276,7 +292,7 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
276292
let pressureRight = getCell0Clamped(pressureFrom, y, x + 1);
277293

278294
let pressureLaplace = pressureLeft + pressureRight + pressureUp + pressureDown;
279-
let pressureDst = (divergence + pressureAlpha * pressureLaplace) / pressureBeta;
295+
let pressureDst = (pressureLaplace - divergence * sim.cellSize * sim.cellSize) / 4;
280296
setCell0(pressureTo, y, x, pressureDst);
281297
}
282298
}
@@ -304,9 +320,12 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
304320
pressureFrom.fill(0);
305321

306322
calcDivergence(arrFrom, sim.divergence0);
323+
sim.divergence1.set(sim.divergence0);
324+
325+
let pressureIterCount = sim.iterCount === 0 ? 1024 : 200;
307326

308327
// iteratively calculate the pressure field
309-
for (let iter = 0; iter < 1000; iter++) {
328+
for (let iter = 0; iter < pressureIterCount; iter++) {
310329
calcPressureField(sim.divergence0, pressureFrom, pressureTo);
311330

312331
// swap arrays
@@ -315,16 +334,19 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
315334
pressureTo = tmp;
316335

317336
// check for convergence
318-
calcDivergenceFreeVelocityField(arrFrom, arrTo, pressureFrom);
319-
calcDivergence(arrTo, sim.divergence1);
320-
logDivergenceStats(sim.divergence1);
337+
// logDivergenceStats(sim.divergence1);
321338
}
339+
calcDivergenceFreeVelocityField(arrFrom, arrTo, pressureFrom);
340+
calcDivergence(arrTo, sim.divergence1);
322341

323342
// now we have the pressure field in pressureFrom
324343
// use it to calculate the final velocity field, which will be stored in arrFrom (which currently contains the tentative velocity field)
325344
calcDivergenceFreeVelocityField(arrFrom, arrFrom, pressureFrom);
326345
}
327346

347+
sim.pressure0 = pressureFrom;
348+
sim.pressure1 = pressureTo;
349+
328350
// woo, now we have the complete set of state variables for the next frame in arrFrom
329351
// so shuffle them around, ensuring arrFrom is stored to the main array (the others are just temporary)
330352
sim.cells = arrFrom;
@@ -334,6 +356,8 @@ export function stepFluidSim(sim: IFluidSim, dtMs: number) {
334356
fixBoundaries(sim);
335357
computeAggregateValues(sim);
336358

359+
sim.iterCount += 1;
360+
337361
console.log("step took " + (performance.now() - startTime) + "ms");
338362
}
339363

@@ -399,7 +423,7 @@ function computeAggregateValues(sim: IFluidSim): ISimAggregates {
399423

400424
sim.aggregates = aggs;
401425

402-
console.log(`aggregates: mass=${aggs.totalMass.toFixed(2)}, p_x=${aggs.totalMomentumX.toFixed(2)}, p_y=${aggs.totalMomentumY.toFixed(2)}, E_k=${aggs.totalKineticEnergy.toFixed(2)}, T=${aggs.averageTemperature.toFixed(2)}`);
426+
// console.log(`aggregates: mass=${aggs.totalMass.toFixed(2)}, p_x=${aggs.totalMomentumX.toFixed(2)}, p_y=${aggs.totalMomentumY.toFixed(2)}, E_k=${aggs.totalKineticEnergy.toFixed(2)}, T=${aggs.averageTemperature.toFixed(2)}`);
403427

404428
return aggs;
405429
}

0 commit comments

Comments
 (0)