work on pressurecell solver
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
eb845a3891
commit
a26ed3a001
@ -36,6 +36,27 @@
|
||||
*/
|
||||
#define CHUNK_SPACING 16
|
||||
|
||||
/**
|
||||
* The maximum level of the interest tree
|
||||
*/
|
||||
#define CHUNK_MAX_INTEREST_LEVEL 4
|
||||
|
||||
/**
|
||||
* The dimensions of the interest tree at each level
|
||||
*/
|
||||
static char INTEREST_MODIFIER_DIMS[CHUNK_MAX_INTEREST_LEVEL+1] = {
|
||||
16,
|
||||
8,
|
||||
4,
|
||||
2,
|
||||
1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the interest tree at a position and level
|
||||
*/
|
||||
#define INTEREST(tree,level,x,y,z) tree[level][x/INTEREST_MODIFIER_DIMS[level]*INTEREST_MODIFIER_DIMS[level]*INTEREST_MODIFIER_DIMS[level]+(y/INTEREST_MODIFIER_DIMS[level])*INTEREST_MODIFIER_DIMS[level]+(z/INTEREST_MODIFIER_DIMS[level])]
|
||||
|
||||
/**
|
||||
* A chunk
|
||||
*/
|
||||
@ -120,6 +141,11 @@ typedef struct {
|
||||
*/
|
||||
int simLOD;
|
||||
|
||||
/**
|
||||
* Octree that stores whether a location is of interest or not
|
||||
*/
|
||||
char ** interestTree;
|
||||
|
||||
/**
|
||||
* The convergence of this chunk
|
||||
*/
|
||||
|
||||
@ -6,9 +6,34 @@
|
||||
#include "fluid/queue/chunk.h"
|
||||
#include "fluid/queue/chunkmask.h"
|
||||
|
||||
/**
|
||||
* Used for signaling the bounds setting method to not use adjacent cells when evaluating borders
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_BOUND_NO_DIR 0
|
||||
|
||||
/**
|
||||
* Used for signaling the bounds setting method to use adjacent cells when evaluating x axis borders
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_DIRECTION_U 1
|
||||
|
||||
/**
|
||||
* Used for signaling the bounds setting method to use adjacent cells when evaluating y axis borders
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_DIRECTION_V 2
|
||||
|
||||
/**
|
||||
* Used for signaling the bounds setting method to use adjacent cells when evaluating z axis borders
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_DIRECTION_W 3
|
||||
|
||||
/**
|
||||
* Updates the bounds of the chunk based on its neighbors
|
||||
*/
|
||||
LIBRARY_API void pressurecell_update_bounds(Environment * environment, Chunk * chunk);
|
||||
|
||||
/**
|
||||
* Updates the interest tree for this chunk
|
||||
*/
|
||||
LIBRARY_API void pressurecell_update_interest(Environment * environment, Chunk * chunk);
|
||||
|
||||
#endif
|
||||
20
src/main/c/includes/fluid/sim/pressurecell/normalization.h
Normal file
20
src/main/c/includes/fluid/sim/pressurecell/normalization.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef FLUID_PRESSURECELL_NORMALIZATION_H
|
||||
#define FLUID_PRESSURECELL_NORMALIZATION_H
|
||||
|
||||
#include "public.h"
|
||||
#include "fluid/env/environment.h"
|
||||
#include "fluid/queue/chunk.h"
|
||||
#include "fluid/queue/chunkmask.h"
|
||||
|
||||
/**
|
||||
* Calculates the ratio to normalize the chunk by
|
||||
*/
|
||||
LIBRARY_API void fluid_pressurecell_calculate_normalization_ratio(Environment * env, Chunk * chunk);
|
||||
|
||||
/**
|
||||
* Normalizes the chunk
|
||||
*/
|
||||
LIBRARY_API void fluid_pressurecell_normalize_chunk(Environment * env, Chunk * chunk);
|
||||
|
||||
|
||||
#endif
|
||||
@ -7,6 +7,21 @@
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_SIM_STEP 0.01f
|
||||
|
||||
/**
|
||||
* Multiplier applied to advection to allow more mass/velocity to transfer per frame
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER 1.0f
|
||||
|
||||
/**
|
||||
* Spacing of cells
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_SPACING 1.0f
|
||||
|
||||
/**
|
||||
* Multiplier applied to pressure calculations to encourage advection
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_PRESSURE_MULTIPLIER 1.0f
|
||||
|
||||
/**
|
||||
* Maximum allowed velocity of the pressurecell simulator
|
||||
*/
|
||||
@ -15,17 +30,27 @@
|
||||
/**
|
||||
* Diffusion constant
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_DIFFUSION_CONSTANT 0.0001f
|
||||
#define FLUID_PRESSURECELL_DIFFUSION_CONSTANT 0.01f
|
||||
|
||||
/**
|
||||
* Viscosity constant
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_VISCOSITY_CONSTANT 0.0001f
|
||||
#define FLUID_PRESSURECELL_VISCOSITY_CONSTANT 0.01f
|
||||
|
||||
/**
|
||||
* Amount that density contributes to the pressure
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_DENSITY_CONST 0.001f
|
||||
|
||||
/**
|
||||
* Amount of the residual to add to the pressure field each frame
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_RESIDUAL_MULTIPLIER 0.1f
|
||||
|
||||
/**
|
||||
* Constant applied to divergence to get new pressure
|
||||
*/
|
||||
#define FLUID_PRESSURECELL_DIV_PRESSURE_CONST 5.0f
|
||||
|
||||
|
||||
#endif
|
||||
@ -28,6 +28,10 @@ LIBRARY_API void fluid_dispatch(int numReadIn, Chunk ** chunkViewC, Environment
|
||||
if(countCurrent > 0){
|
||||
arrdeln(environment->queue.grid2Queue,0,countCurrent);
|
||||
}
|
||||
countCurrent = arrlen(environment->queue.pressurecellQueue);
|
||||
if(countCurrent > 0){
|
||||
arrdeln(environment->queue.pressurecellQueue,0,countCurrent);
|
||||
}
|
||||
|
||||
|
||||
if(override == FLUID_DISPATCHER_OVERRIDE_CELLULAR){
|
||||
|
||||
@ -13,5 +13,22 @@ LIBRARY_API Chunk * chunk_create(){
|
||||
rVal->vTempCache = (float *)calloc(1,DIM*DIM*DIM*sizeof(float));
|
||||
rVal->wTempCache = (float *)calloc(1,DIM*DIM*DIM*sizeof(float));
|
||||
rVal->pressureTempCache = (float *)calloc(1,DIM*DIM*DIM*sizeof(float));
|
||||
|
||||
/**
|
||||
* Should store 5 tables:
|
||||
* 1x1x1
|
||||
* 2x2x2
|
||||
* 4x4x4
|
||||
* 8x8x8
|
||||
* 16x16x16
|
||||
*/
|
||||
rVal->interestTree = (char **)calloc(1,sizeof(char *) * 6);
|
||||
//allocating extra data for ghost cells even though we will not evaluate the ghost cells
|
||||
rVal->interestTree[0] = (char *)calloc(3*3*3,sizeof(char));
|
||||
rVal->interestTree[1] = (char *)calloc(4*4*4,sizeof(char));
|
||||
rVal->interestTree[2] = (char *)calloc(6*6*6,sizeof(char));
|
||||
rVal->interestTree[3] = (char *)calloc(10*10*10,sizeof(char));
|
||||
rVal->interestTree[4] = (char *)calloc(18*18*18,sizeof(char));
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -1,9 +1,147 @@
|
||||
|
||||
#include "fluid/sim/pressurecell/bounds.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets the bounds reflecting off hard borders and otherwise assuming continuity
|
||||
*/
|
||||
void fluid_pressurecell_set_bounds_legacy(
|
||||
Environment * environment,
|
||||
int vector_dir,
|
||||
float * target
|
||||
){
|
||||
//set the boundary planes
|
||||
for(int x = 1; x < DIM-1; x++){
|
||||
for(int y = 1; y < DIM-1; y++){
|
||||
|
||||
//x-direction boundary planes
|
||||
if(vector_dir == FLUID_PRESSURECELL_DIRECTION_U){
|
||||
target[IX(0,x,y)] = -target[IX(1,x,y)];
|
||||
target[IX(DIM-1,x,y)] = -target[IX(DIM-2,x,y)];
|
||||
} else {
|
||||
target[IX(0,x,y)] = target[IX(1,x,y)];
|
||||
target[IX(DIM-1,x,y)] = target[IX(DIM-2,x,y)];
|
||||
}
|
||||
|
||||
//y-direction boundary planes
|
||||
if(vector_dir == FLUID_PRESSURECELL_DIRECTION_V){
|
||||
target[IX(x,0,y)] = -target[IX(x,1,y)];
|
||||
target[IX(x,DIM-1,y)] = -target[IX(x,DIM-2,y)];
|
||||
} else {
|
||||
target[IX(x,0,y)] = target[IX(x,1,y)];
|
||||
target[IX(x,DIM-1,y)] = target[IX(x,DIM-2,y)];
|
||||
}
|
||||
|
||||
//z-direction boundary planes
|
||||
if(vector_dir == FLUID_PRESSURECELL_DIRECTION_W){
|
||||
target[IX(x,y,0)] = -target[IX(x,y,1)];
|
||||
target[IX(x,y,DIM-1)] = -target[IX(x,y,DIM-2)];
|
||||
} else {
|
||||
target[IX(x,y,0)] = target[IX(x,y,1)];
|
||||
target[IX(x,y,DIM-1)] = target[IX(x,y,DIM-2)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//sets the edges of the chunk
|
||||
//this should logically follow from how we're treating the boundary planes
|
||||
for(int x = 1; x < DIM-1; x++){
|
||||
target[IX(x,0,0)] = (float)(0.5f * (target[IX(x,1,0)] + target[IX(x,0,1)]));
|
||||
target[IX(x,DIM-1,0)] = (float)(0.5f * (target[IX(x,DIM-2,0)] + target[IX(x,DIM-1,1)]));
|
||||
target[IX(x,0,DIM-1)] = (float)(0.5f * (target[IX(x,1,DIM-1)] + target[IX(x,0,DIM-2)]));
|
||||
target[IX(x,DIM-1,DIM-1)] = (float)(0.5f * (target[IX(x,DIM-2,DIM-1)] + target[IX(x,DIM-1,DIM-2)]));
|
||||
|
||||
target[IX(0,x,0)] = (float)(0.5f * (target[IX(1,x,0)] + target[IX(0,x,1)]));
|
||||
target[IX(DIM-1,x,0)] = (float)(0.5f * (target[IX(DIM-2,x,0)] + target[IX(DIM-1,x,1)]));
|
||||
target[IX(0,x,DIM-1)] = (float)(0.5f * (target[IX(1,x,DIM-1)] + target[IX(0,x,DIM-2)]));
|
||||
target[IX(DIM-1,x,DIM-1)] = (float)(0.5f * (target[IX(DIM-2,x,DIM-1)] + target[IX(DIM-1,x,DIM-2)]));
|
||||
|
||||
|
||||
target[IX(0,0,x)] = (float)(0.5f * (target[IX(1,0,x)] + target[IX(0,1,x)]));
|
||||
target[IX(DIM-1,0,x)] = (float)(0.5f * (target[IX(DIM-2,0,x)] + target[IX(DIM-1,1,x)]));
|
||||
target[IX(0,DIM-1,x)] = (float)(0.5f * (target[IX(1,DIM-1,x)] + target[IX(0,DIM-2,x)]));
|
||||
target[IX(DIM-1,DIM-1,x)] = (float)(0.5f * (target[IX(DIM-2,DIM-1,x)] + target[IX(DIM-1,DIM-2,x)]));
|
||||
|
||||
}
|
||||
//sets the corners of the chunk
|
||||
//this should logically follow from how we're treating the boundary planes
|
||||
target[IX(0,0,0)] = (float)((target[IX(1,0,0)]+target[IX(0,1,0)]+target[IX(0,0,1)])/3.0);
|
||||
target[IX(DIM-1,0,0)] = (float)((target[IX(DIM-2,0,0)]+target[IX(DIM-1,1,0)]+target[IX(DIM-1,0,1)])/3.0);
|
||||
target[IX(0,DIM-1,0)] = (float)((target[IX(1,DIM-1,0)]+target[IX(0,DIM-2,0)]+target[IX(0,DIM-1,1)])/3.0);
|
||||
target[IX(0,0,DIM-1)] = (float)((target[IX(0,0,DIM-2)]+target[IX(1,0,DIM-1)]+target[IX(0,1,DIM-1)])/3.0);
|
||||
target[IX(DIM-1,DIM-1,0)] = (float)((target[IX(DIM-2,DIM-1,0)]+target[IX(DIM-1,DIM-2,0)]+target[IX(DIM-1,DIM-1,1)])/3.0);
|
||||
target[IX(0,DIM-1,DIM-1)] = (float)((target[IX(1,DIM-1,DIM-1)]+target[IX(0,DIM-2,DIM-1)]+target[IX(0,DIM-1,DIM-2)])/3.0);
|
||||
target[IX(DIM-1,0,DIM-1)] = (float)((target[IX(DIM-1,0,DIM-2)]+target[IX(DIM-2,0,DIM-1)]+target[IX(DIM-1,1,DIM-1)])/3.0);
|
||||
target[IX(DIM-1,DIM-1,DIM-1)] = (float)((target[IX(DIM-1,DIM-1,DIM-2)]+target[IX(DIM-1,DIM-2,DIM-1)]+target[IX(DIM-1,DIM-1,DIM-2)])/3.0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the bounds of the chunk based on its neighbors
|
||||
*/
|
||||
LIBRARY_API void pressurecell_update_bounds(Environment * environment, Chunk * chunk){
|
||||
// fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_BOUND_NO_DIR,chunk->d[CENTER_LOC]);
|
||||
// fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_BOUND_NO_DIR,chunk->d0[CENTER_LOC]);
|
||||
|
||||
}
|
||||
fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_DIRECTION_U,chunk->u[CENTER_LOC]);
|
||||
fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_DIRECTION_V,chunk->v[CENTER_LOC]);
|
||||
fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_DIRECTION_W,chunk->w[CENTER_LOC]);
|
||||
|
||||
// fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_DIRECTION_U,chunk->u0[CENTER_LOC]);
|
||||
// fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_DIRECTION_V,chunk->v0[CENTER_LOC]);
|
||||
// fluid_pressurecell_set_bounds_legacy(environment,FLUID_PRESSURECELL_DIRECTION_W,chunk->w0[CENTER_LOC]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the interest tree for this chunk
|
||||
*/
|
||||
LIBRARY_API void pressurecell_update_interest(Environment * environment, Chunk * chunk){
|
||||
int level, x, y, z;
|
||||
int dim;
|
||||
char ** interestTree = chunk->interestTree;
|
||||
float * densityArr = chunk->d[CENTER_LOC];
|
||||
float * densitSrcArr = chunk->d0[CENTER_LOC];
|
||||
// for(level = 0; level < CHUNK_MAX_INTEREST_LEVEL; level++){
|
||||
// dim = pow(2,level);
|
||||
// for(x = 0; x < dim; x++){
|
||||
// for(y = 0; y < dim; y++){
|
||||
// for(z = 0; z < dim; z++){
|
||||
// if(
|
||||
// densityArr[IX(x,y,z)] > 0 ||
|
||||
// densityArr[IX(x+1,y,z)] > 0 ||
|
||||
// densityArr[IX(x-1,y,z)] > 0 ||
|
||||
// densityArr[IX(x,y+1,z)] > 0 ||
|
||||
// densityArr[IX(x,y-1,z)] > 0 ||
|
||||
// densityArr[IX(x,y,z+1)] > 0 ||
|
||||
// densityArr[IX(x,y,z-1)] > 0
|
||||
// ){
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
if(
|
||||
densityArr[IX(x,y,z)] > MIN_FLUID_VALUE ||
|
||||
densityArr[IX(x+1,y,z)] > MIN_FLUID_VALUE ||
|
||||
densityArr[IX(x-1,y,z)] > MIN_FLUID_VALUE ||
|
||||
densityArr[IX(x,y+1,z)] > MIN_FLUID_VALUE ||
|
||||
densityArr[IX(x,y-1,z)] > MIN_FLUID_VALUE ||
|
||||
densityArr[IX(x,y,z+1)] > MIN_FLUID_VALUE ||
|
||||
densityArr[IX(x,y,z-1)] > MIN_FLUID_VALUE ||
|
||||
densitSrcArr[IX(x,y,z)] > MIN_FLUID_VALUE
|
||||
){
|
||||
INTEREST(interestTree,0,x,y,z) = 1;
|
||||
INTEREST(interestTree,1,x,y,z) = 1;
|
||||
INTEREST(interestTree,2,x,y,z) = 1;
|
||||
INTEREST(interestTree,3,x,y,z) = 1;
|
||||
INTEREST(interestTree,4,x,y,z) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "fluid/sim/pressurecell/density.h"
|
||||
#include "fluid/sim/pressurecell/solver_consts.h"
|
||||
@ -25,17 +26,18 @@ LIBRARY_API void pressurecell_diffuse_density(Environment * environment, Chunk *
|
||||
int x, y, z;
|
||||
float * densityArr = chunk->d[CENTER_LOC];
|
||||
float * densityTemp = chunk->dTempCache;
|
||||
float D = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * environment->consts.dt;
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
densityTemp[IX(x,y,z)] = densityArr[IX(x,y,z)] +
|
||||
densityArr[IX(x,y,z)] * -6 * FLUID_PRESSURECELL_DIFFUSION_CONSTANT +
|
||||
densityArr[IX(x-1,y,z)] * FLUID_PRESSURECELL_DIFFUSION_CONSTANT +
|
||||
densityArr[IX(x+1,y,z)] * FLUID_PRESSURECELL_DIFFUSION_CONSTANT +
|
||||
densityArr[IX(x,y-1,z)] * FLUID_PRESSURECELL_DIFFUSION_CONSTANT +
|
||||
densityArr[IX(x,y+1,z)] * FLUID_PRESSURECELL_DIFFUSION_CONSTANT +
|
||||
densityArr[IX(x,y,z-1)] * FLUID_PRESSURECELL_DIFFUSION_CONSTANT +
|
||||
densityArr[IX(x,y,z+1)] * FLUID_PRESSURECELL_DIFFUSION_CONSTANT
|
||||
densityArr[IX(x,y,z)] * -6 * D +
|
||||
densityArr[IX(x-1,y,z)] * D +
|
||||
densityArr[IX(x+1,y,z)] * D +
|
||||
densityArr[IX(x,y-1,z)] * D +
|
||||
densityArr[IX(x,y+1,z)] * D +
|
||||
densityArr[IX(x,y,z-1)] * D +
|
||||
densityArr[IX(x,y,z+1)] * D
|
||||
;
|
||||
}
|
||||
}
|
||||
@ -61,9 +63,9 @@ LIBRARY_API void pressurecell_advect_density(Environment * environment, Chunk *
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
//calculate the real (float) position we are at
|
||||
xp = x - u[IX(x,y,z)] * environment->consts.dt;
|
||||
yp = y - v[IX(x,y,z)] * environment->consts.dt;
|
||||
zp = z - w[IX(x,y,z)] * environment->consts.dt;
|
||||
xp = x - u[IX(x,y,z)] * environment->consts.dt * FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER;
|
||||
yp = y - v[IX(x,y,z)] * environment->consts.dt * FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER;
|
||||
zp = z - w[IX(x,y,z)] * environment->consts.dt * FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER;
|
||||
|
||||
//clamp to border
|
||||
x0 = xp;
|
||||
@ -91,7 +93,12 @@ LIBRARY_API void pressurecell_advect_density(Environment * environment, Chunk *
|
||||
x1 < 0 || y1 < 0 || z1 < 0 ||
|
||||
x1 > DIM-1 || y1 > DIM-1 || z1 > DIM-1
|
||||
){
|
||||
printf("advect dens: %d %d %d %d %d %d --- %f %f %f\n", x0, y0, z0, x1, y1, z1, x, y, z);
|
||||
printf("advect dens:\n");
|
||||
printf("%d %d %d\n", x0, y0, z0);
|
||||
printf("%d %d %d\n", x1, y1, z1);
|
||||
printf("%f %f %f\n", xp, yp, zp);
|
||||
printf("%f %f %f\n", u[IX(x,y,z)], v[IX(x,y,z)], w[IX(x,y,z)]);
|
||||
printf("%f\n", environment->consts.dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
@ -109,7 +116,7 @@ LIBRARY_API void pressurecell_advect_density(Environment * environment, Chunk *
|
||||
t1*u1*densityTemp[IX(x1,y1,z1)]
|
||||
);
|
||||
|
||||
densityArr[IX(x,y,z)] = interpolated;
|
||||
densityArr[IX(x,y,z)] = fmax(MIN_FLUID_VALUE,fmin(MAX_FLUID_VALUE,interpolated));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
src/main/c/src/fluid/sim/pressurecell/normalization.c
Normal file
29
src/main/c/src/fluid/sim/pressurecell/normalization.c
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
#include "fluid/sim/pressurecell/normalization.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the expected density and pressure
|
||||
*/
|
||||
LIBRARY_API void fluid_pressurecell_calculate_expected_intake(Environment * env, Chunk * chunk){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the ratio to normalize the chunk by
|
||||
*/
|
||||
LIBRARY_API void fluid_pressurecell_calculate_normalization_ratio(Environment * env, Chunk * chunk){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the chunk
|
||||
*/
|
||||
LIBRARY_API void fluid_pressurecell_normalize_chunk(Environment * env, Chunk * chunk){
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -13,21 +13,63 @@ LIBRARY_API void pressurecell_approximate_pressure(Environment * environment, Ch
|
||||
//values stored across frames
|
||||
float * presureCache = chunk->pressureCache[CENTER_LOC];
|
||||
float * divArr = chunk->divergenceCache[CENTER_LOC];
|
||||
// float * uArr = chunk->u[CENTER_LOC];
|
||||
// float * vArr = chunk->v[CENTER_LOC];
|
||||
// float * wArr = chunk->w[CENTER_LOC];
|
||||
float * uArr = chunk->uTempCache;
|
||||
float * vArr = chunk->vTempCache;
|
||||
float * wArr = chunk->wTempCache;
|
||||
//temporary caches
|
||||
float * pressureCache = chunk->pressureCache[CENTER_LOC];
|
||||
float * pressureTemp = chunk->pressureTempCache;
|
||||
float gridSpacing = 1;
|
||||
//consts/vars
|
||||
float gridSpacing = FLUID_PRESSURECELL_SPACING * FLUID_PRESSURECELL_SPACING;
|
||||
float du, dv, dw;
|
||||
float newPressure;
|
||||
float dt = environment->consts.dt;
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
//divergence part
|
||||
//positive value means inflow
|
||||
//negative value means outflow
|
||||
float newDiv =
|
||||
(
|
||||
uArr[IX(x+1,y,z)] - uArr[IX(x-1,y,z)] +
|
||||
vArr[IX(x+1,y,z)] - vArr[IX(x-1,y,z)] +
|
||||
wArr[IX(x+1,y,z)] - wArr[IX(x-1,y,z)]
|
||||
) / (2 * gridSpacing);
|
||||
float finalDiv = divArr[IX(x,y,z)];
|
||||
|
||||
|
||||
//poisson stencil
|
||||
float stencil = (
|
||||
-6 * pressureCache[IX(x,y,z)] +
|
||||
(
|
||||
pressureCache[IX(x+1,y,z)] +
|
||||
pressureCache[IX(x-1,y,z)] +
|
||||
pressureCache[IX(x,y+1,z)] +
|
||||
pressureCache[IX(x,y-1,z)] +
|
||||
pressureCache[IX(x,y,z+1)] +
|
||||
pressureCache[IX(x,y,z-1)]
|
||||
)
|
||||
) / gridSpacing;
|
||||
float residual = stencil - FLUID_PRESSURECELL_RESIDUAL_MULTIPLIER * finalDiv;
|
||||
// if(residual > 0){
|
||||
// printf("%f \n", finalDiv);
|
||||
// printf("%f \n", stencil);
|
||||
// printf("%f \n", residual);
|
||||
// }
|
||||
|
||||
//divergence caused by static outflow due to diffusion
|
||||
float outflowDiv = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * 6 * dt;
|
||||
|
||||
//compute the new pressure value
|
||||
newPressure =
|
||||
(divArr[IX(x+1,y,z)] - divArr[IX(x-1,y,z)]) / (2.0f * gridSpacing) +
|
||||
(divArr[IX(x+1,y,z)] - divArr[IX(x-1,y,z)]) / (2.0f * gridSpacing) +
|
||||
(divArr[IX(x+1,y,z)] - divArr[IX(x-1,y,z)]) / (2.0f * gridSpacing)
|
||||
;
|
||||
newPressure = newPressure / (gridSpacing * 2);
|
||||
newPressure = pressureCache[IX(x,y,z)] + residual;
|
||||
// newPressure = -FLUID_PRESSURECELL_DIV_PRESSURE_CONST * (newDiv + outflowDiv);
|
||||
// if(newPressure > 0){
|
||||
// printf("%f \n",newPressure);
|
||||
// }
|
||||
pressureTemp[IX(x,y,z)] = newPressure;
|
||||
}
|
||||
}
|
||||
@ -47,18 +89,38 @@ LIBRARY_API void pressurecell_approximate_divergence(Environment * environment,
|
||||
float * presureCache = chunk->pressureCache[CENTER_LOC];
|
||||
//temporary caches
|
||||
float * pressureTemp = chunk->pressureTempCache;
|
||||
float gridSpacing = 1;
|
||||
float gridSpacing = FLUID_PRESSURECELL_SPACING * FLUID_PRESSURECELL_SPACING;
|
||||
float du, dv, dw;
|
||||
float newDivergence;
|
||||
float dt = environment->consts.dt;
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
|
||||
//divergence caused by static outflow due to diffusion
|
||||
float outflowDiv = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * 6 * dt;
|
||||
|
||||
//compute divergence
|
||||
du = (uArr[IX(x+1,y,z)] - uArr[IX(x-1,y,z)]) / (2.0f * gridSpacing);
|
||||
dv = (vArr[IX(x+1,y,z)] - vArr[IX(x-1,y,z)]) / (2.0f * gridSpacing);
|
||||
dw = (wArr[IX(x+1,y,z)] - wArr[IX(x-1,y,z)]) / (2.0f * gridSpacing);
|
||||
dv = (vArr[IX(x,y+1,z)] - vArr[IX(x,y-1,z)]) / (2.0f * gridSpacing);
|
||||
dw = (wArr[IX(x,y,z+1)] - wArr[IX(x,y,z-1)]) / (2.0f * gridSpacing);
|
||||
// if(x == 1){
|
||||
// du = 0;
|
||||
// } else if(x == DIM-2){
|
||||
// du = 0;
|
||||
// }
|
||||
// if(y == 1){
|
||||
// dv = 0;
|
||||
// } else if(y == DIM-2){
|
||||
// dv = 0;
|
||||
// }
|
||||
// if(z == 1){
|
||||
// dw = 0;
|
||||
// } else if(z == DIM-2){
|
||||
// dw = 0;
|
||||
// }
|
||||
newDivergence = du+dv+dw;
|
||||
divArr[IX(x,y,z)] = newDivergence;
|
||||
divArr[IX(x,y,z)] = divArr[IX(x,y,z)] + newDivergence - FLUID_PRESSURECELL_RESIDUAL_MULTIPLIER * divArr[IX(x,y,z)] + outflowDiv;
|
||||
|
||||
//store pressure value from this frame
|
||||
presureCache[IX(x,y,z)] = pressureTemp[IX(x,y,z)];
|
||||
|
||||
@ -9,11 +9,18 @@
|
||||
#include "fluid/env/utilities.h"
|
||||
#include "fluid/queue/chunkmask.h"
|
||||
#include "fluid/queue/chunk.h"
|
||||
#include "fluid/sim/pressurecell/bounds.h"
|
||||
#include "fluid/sim/pressurecell/density.h"
|
||||
#include "fluid/sim/pressurecell/pressure.h"
|
||||
#include "fluid/sim/pressurecell/solver_consts.h"
|
||||
#include "fluid/sim/pressurecell/velocity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static inline void fluid_pressurecell_clearArr(float * d);
|
||||
|
||||
|
||||
/**
|
||||
* Used for storing timings
|
||||
*/
|
||||
@ -31,6 +38,16 @@ LIBRARY_API void fluid_pressurecell_simulate(
|
||||
//This is the section of non-parallel code
|
||||
//
|
||||
|
||||
for(int i = 0; i < numChunks; i++){
|
||||
Chunk * currentChunk = chunks[i];
|
||||
pressurecell_update_bounds(environment,currentChunk);
|
||||
// pressurecell_update_interest(environment,currentChunk);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//This is the section of parallel code
|
||||
//
|
||||
@ -96,6 +113,23 @@ LIBRARY_API void fluid_pressurecell_simulate(
|
||||
Chunk * currentChunk = chunks[i];
|
||||
pressurecell_advect_density(environment,currentChunk);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Setup for next iteration
|
||||
//
|
||||
for(int i = 0; i < numChunks; i++){
|
||||
Chunk * currentChunk = chunks[i];
|
||||
fluid_pressurecell_clearArr(currentChunk->d0[CENTER_LOC]);
|
||||
fluid_pressurecell_clearArr(currentChunk->u0[CENTER_LOC]);
|
||||
fluid_pressurecell_clearArr(currentChunk->v0[CENTER_LOC]);
|
||||
fluid_pressurecell_clearArr(currentChunk->w0[CENTER_LOC]);
|
||||
fluid_pressurecell_clearArr(currentChunk->pressureTempCache);
|
||||
fluid_pressurecell_clearArr(currentChunk->uTempCache);
|
||||
fluid_pressurecell_clearArr(currentChunk->vTempCache);
|
||||
fluid_pressurecell_clearArr(currentChunk->wTempCache);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -103,7 +137,14 @@ LIBRARY_API void fluid_pressurecell_simulate(
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clears an array
|
||||
*/
|
||||
static inline void fluid_pressurecell_clearArr(float * d){
|
||||
for(int j = 0; j < DIM * DIM * DIM; j++){
|
||||
d[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "fluid/queue/chunk.h"
|
||||
#include "fluid/sim/pressurecell/velocity.h"
|
||||
#include "fluid/sim/pressurecell/solver_consts.h"
|
||||
|
||||
@ -9,7 +11,6 @@
|
||||
LIBRARY_API void pressurecell_add_gravity(Environment * environment, Chunk * chunk){
|
||||
int x, y, z;
|
||||
float * dArr = chunk->d[CENTER_LOC];
|
||||
float * vArr = chunk->v[CENTER_LOC];
|
||||
float * vSourceArr = chunk->v0[CENTER_LOC];
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
@ -48,46 +49,57 @@ LIBRARY_API void pressurecell_add_velocity(Environment * environment, Chunk * ch
|
||||
*/
|
||||
LIBRARY_API void pressurecell_diffuse_velocity(Environment * environment, Chunk * chunk){
|
||||
int x, y, z;
|
||||
float * dArr = chunk->d[CENTER_LOC];
|
||||
float * uArr = chunk->u[CENTER_LOC];
|
||||
float * vArr = chunk->v[CENTER_LOC];
|
||||
float * wArr = chunk->w[CENTER_LOC];
|
||||
float * uTemp = chunk->uTempCache;
|
||||
float * vTemp = chunk->vTempCache;
|
||||
float * wTemp = chunk->wTempCache;
|
||||
float D = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * environment->consts.dt;
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
//diffuse u
|
||||
uTemp[IX(x,y,z)] = uArr[IX(x,y,z)] +
|
||||
uArr[IX(x,y,z)] * -6 * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
uArr[IX(x-1,y,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
uArr[IX(x+1,y,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
uArr[IX(x,y-1,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
uArr[IX(x,y+1,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
uArr[IX(x,y,z-1)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
uArr[IX(x,y,z+1)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT
|
||||
uArr[IX(x,y,z)] * -6 * D +
|
||||
uArr[IX(x-1,y,z)] * D +
|
||||
uArr[IX(x+1,y,z)] * D +
|
||||
uArr[IX(x,y-1,z)] * D +
|
||||
uArr[IX(x,y+1,z)] * D +
|
||||
uArr[IX(x,y,z-1)] * D +
|
||||
uArr[IX(x,y,z+1)] * D
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//diffuse v
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
vTemp[IX(x,y,z)] = vArr[IX(x,y,z)] +
|
||||
vArr[IX(x,y,z)] * -6 * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
vArr[IX(x-1,y,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
vArr[IX(x+1,y,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
vArr[IX(x,y-1,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
vArr[IX(x,y+1,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
vArr[IX(x,y,z-1)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
vArr[IX(x,y,z+1)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT
|
||||
vArr[IX(x,y,z)] * -6 * D +
|
||||
vArr[IX(x-1,y,z)] * D +
|
||||
vArr[IX(x+1,y,z)] * D +
|
||||
vArr[IX(x,y-1,z)] * D +
|
||||
vArr[IX(x,y+1,z)] * D +
|
||||
vArr[IX(x,y,z-1)] * D +
|
||||
vArr[IX(x,y,z+1)] * D
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//diffuse w
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
wTemp[IX(x,y,z)] = wArr[IX(x,y,z)] +
|
||||
wArr[IX(x,y,z)] * -6 * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
wArr[IX(x-1,y,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
wArr[IX(x+1,y,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
wArr[IX(x,y-1,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
wArr[IX(x,y+1,z)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
wArr[IX(x,y,z-1)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT +
|
||||
wArr[IX(x,y,z+1)] * FLUID_PRESSURECELL_VISCOSITY_CONSTANT
|
||||
wArr[IX(x,y,z)] * -6 * D +
|
||||
wArr[IX(x-1,y,z)] * D +
|
||||
wArr[IX(x+1,y,z)] * D +
|
||||
wArr[IX(x,y-1,z)] * D +
|
||||
wArr[IX(x,y+1,z)] * D +
|
||||
wArr[IX(x,y,z-1)] * D +
|
||||
wArr[IX(x,y,z+1)] * D
|
||||
;
|
||||
}
|
||||
}
|
||||
@ -108,15 +120,15 @@ LIBRARY_API void pressurecell_advect_velocity(Environment * environment, Chunk *
|
||||
int x0, x1, y0, y1, z0, z1;
|
||||
float xp, yp, zp;
|
||||
float s0, s1, t0, t1, u0, u1;
|
||||
float interpolated;
|
||||
float interpolatedU, interpolatedV, interpolatedW;
|
||||
float magnitude;
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
//TODO: eventually skip y levels if there is no density to advect
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
//calculate the real (float) position we are at
|
||||
xp = x - uTemp[IX(x,y,z)] * environment->consts.dt;
|
||||
yp = y - vTemp[IX(x,y,z)] * environment->consts.dt;
|
||||
zp = z - wTemp[IX(x,y,z)] * environment->consts.dt;
|
||||
xp = x - uTemp[IX(x,y,z)] * environment->consts.dt * FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER;
|
||||
yp = y - vTemp[IX(x,y,z)] * environment->consts.dt * FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER;
|
||||
zp = z - wTemp[IX(x,y,z)] * environment->consts.dt * FLUID_PRESSURECELL_TRANSFERENCE_MULTIPLIER;
|
||||
|
||||
//clamp to border
|
||||
x0 = xp;
|
||||
@ -138,21 +150,7 @@ LIBRARY_API void pressurecell_advect_velocity(Environment * environment, Chunk *
|
||||
u0 = 1-u1;
|
||||
|
||||
|
||||
if(
|
||||
x0 < 0 || y0 < 0 || z0 < 0 ||
|
||||
x0 > DIM-1 || y0 > DIM-1 || z0 > DIM-1 ||
|
||||
x1 < 0 || y1 < 0 || z1 < 0 ||
|
||||
x1 > DIM-1 || y1 > DIM-1 || z1 > DIM-1
|
||||
){
|
||||
printf("advect vel: out of bounds \n");
|
||||
printf("%d %d %d\n", x0, y0, z0);
|
||||
printf("%d %d %d\n ", x1, y1, z1);
|
||||
printf("%f %f %f\n", x, y, z);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
interpolated =
|
||||
interpolatedU =
|
||||
s0*(
|
||||
t0*u0*uTemp[IX(x0,y0,z0)]+
|
||||
t1*u0*uTemp[IX(x0,y1,z0)]+
|
||||
@ -165,9 +163,7 @@ LIBRARY_API void pressurecell_advect_velocity(Environment * environment, Chunk *
|
||||
t0*u1*uTemp[IX(x1,y0,z1)]+
|
||||
t1*u1*uTemp[IX(x1,y1,z1)]
|
||||
);
|
||||
uArr[IX(x,y,z)] = interpolated;
|
||||
|
||||
interpolated =
|
||||
interpolatedV =
|
||||
s0*(
|
||||
t0*u0*vTemp[IX(x0,y0,z0)]+
|
||||
t1*u0*vTemp[IX(x0,y1,z0)]+
|
||||
@ -180,9 +176,7 @@ LIBRARY_API void pressurecell_advect_velocity(Environment * environment, Chunk *
|
||||
t0*u1*vTemp[IX(x1,y0,z1)]+
|
||||
t1*u1*vTemp[IX(x1,y1,z1)]
|
||||
);
|
||||
vArr[IX(x,y,z)] = interpolated;
|
||||
|
||||
interpolated =
|
||||
interpolatedW =
|
||||
s0*(
|
||||
t0*u0*wTemp[IX(x0,y0,z0)]+
|
||||
t1*u0*wTemp[IX(x0,y1,z0)]+
|
||||
@ -195,7 +189,41 @@ LIBRARY_API void pressurecell_advect_velocity(Environment * environment, Chunk *
|
||||
t0*u1*wTemp[IX(x1,y0,z1)]+
|
||||
t1*u1*wTemp[IX(x1,y1,z1)]
|
||||
);
|
||||
wArr[IX(x,y,z)] = interpolated;
|
||||
|
||||
if(
|
||||
x0 < 0 || y0 < 0 || z0 < 0 ||
|
||||
x0 > DIM-1 || y0 > DIM-1 || z0 > DIM-1 ||
|
||||
x1 < 0 || y1 < 0 || z1 < 0 ||
|
||||
x1 > DIM-1 || y1 > DIM-1 || z1 > DIM-1
|
||||
){
|
||||
printf("advect vel: out of bounds \n");
|
||||
printf("%d %d %d\n", x, y, z);
|
||||
printf("%d %d %d\n", x0, y0, z0);
|
||||
printf("%d %d %d\n", x1, y1, z1);
|
||||
printf("percentages: \n");
|
||||
printf("%f %f %f\n", s0, t0, u0);
|
||||
printf("%f %f %f\n", s1, t1, u1);
|
||||
printf("%f %f %f\n", xp, yp, zp);
|
||||
printf("interpolated:\n");
|
||||
printf("%f %f %f\n", interpolatedU, interpolatedV, interpolatedW);
|
||||
printf("%f %f %f\n", uTemp[IX(x,y,z)], vTemp[IX(x,y,z)], wTemp[IX(x,y,z)]);
|
||||
printf("%f\n", environment->consts.dt);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
// magnitude = sqrt(interpolatedU * interpolatedU + interpolatedV * interpolatedV + interpolatedW * interpolatedW);
|
||||
|
||||
// if(magnitude > 1){
|
||||
// interpolatedU = interpolatedU / magnitude;
|
||||
// interpolatedV = interpolatedV / magnitude;
|
||||
// interpolatedW = interpolatedW / magnitude;
|
||||
// }
|
||||
|
||||
uArr[IX(x,y,z)] = interpolatedU;
|
||||
vArr[IX(x,y,z)] = interpolatedV;
|
||||
wArr[IX(x,y,z)] = interpolatedW;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,7 +234,7 @@ LIBRARY_API void pressurecell_advect_velocity(Environment * environment, Chunk *
|
||||
*/
|
||||
LIBRARY_API void pressurecell_interpolate_velocity(Environment * environment, Chunk * chunk){
|
||||
int x, y, z;
|
||||
float * presureCache = chunk->pressureCache[CENTER_LOC];
|
||||
float * presureCache = chunk->pressureTempCache;
|
||||
float * uArr = chunk->u[CENTER_LOC];
|
||||
float * vArr = chunk->v[CENTER_LOC];
|
||||
float * wArr = chunk->w[CENTER_LOC];
|
||||
@ -214,30 +242,49 @@ LIBRARY_API void pressurecell_interpolate_velocity(Environment * environment, Ch
|
||||
float * vTemp = chunk->vTempCache;
|
||||
float * wTemp = chunk->wTempCache;
|
||||
//temporary caches
|
||||
float * pressureTemp = chunk->pressureTempCache;
|
||||
float gridSpacing = 1;
|
||||
float gridSpacing = FLUID_PRESSURECELL_SPACING * FLUID_PRESSURECELL_SPACING;
|
||||
float du, dv, dw;
|
||||
float pressureDivergence;
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
float magnitude;
|
||||
for(y = 1; y < DIM-1; y++){
|
||||
for(z = 1; z < DIM-1; z++){
|
||||
for(x = 1; x < DIM-1; x++){
|
||||
//compute the new pressure value
|
||||
pressureDivergence =
|
||||
(presureCache[IX(x+1,y,z)] - presureCache[IX(x-1,y,z)]) / (2.0f * gridSpacing) +
|
||||
(presureCache[IX(x+1,y,z)] - presureCache[IX(x-1,y,z)]) / (2.0f * gridSpacing) +
|
||||
(presureCache[IX(x+1,y,z)] - presureCache[IX(x-1,y,z)]) / (2.0f * gridSpacing)
|
||||
;
|
||||
pressureDivergence = pressureDivergence / (gridSpacing * 2);
|
||||
|
||||
//project the pressure gradient onto the velocity field
|
||||
uTemp[IX(x,y,z)] = uTemp[IX(x,y,z)] - pressureDivergence;
|
||||
vTemp[IX(x,y,z)] = vTemp[IX(x,y,z)] - pressureDivergence;
|
||||
wTemp[IX(x,y,z)] = wTemp[IX(x,y,z)] - pressureDivergence;
|
||||
uTemp[IX(x,y,z)] = uTemp[IX(x,y,z)] - (presureCache[IX(x+1,y,z)] - presureCache[IX(x-1,y,z)]) / (gridSpacing * 2.0f);
|
||||
vTemp[IX(x,y,z)] = vTemp[IX(x,y,z)] - (presureCache[IX(x,y+1,z)] - presureCache[IX(x,y-1,z)]) / (gridSpacing * 2.0f);
|
||||
wTemp[IX(x,y,z)] = wTemp[IX(x,y,z)] - (presureCache[IX(x,y,z+1)] - presureCache[IX(x,y,z-1)]) / (gridSpacing * 2.0f);
|
||||
|
||||
// magnitude = sqrt(uTemp[IX(x,y,z)] * uTemp[IX(x,y,z)] + vTemp[IX(x,y,z)] * vTemp[IX(x,y,z)] + wTemp[IX(x,y,z)] * wTemp[IX(x,y,z)]);
|
||||
|
||||
//map the new velocity field onto the old one
|
||||
uArr[IX(x,y,z)] = uTemp[IX(x,y,z)];
|
||||
vArr[IX(x,y,z)] = vTemp[IX(x,y,z)];
|
||||
wArr[IX(x,y,z)] = wTemp[IX(x,y,z)];
|
||||
// if(magnitude > 1.0f){
|
||||
// uArr[IX(x,y,z)] = uTemp[IX(x,y,z)] / magnitude;
|
||||
// vArr[IX(x,y,z)] = vTemp[IX(x,y,z)] / magnitude;
|
||||
// wArr[IX(x,y,z)] = wTemp[IX(x,y,z)] / magnitude;
|
||||
// } else if(magnitude > 0.0f){
|
||||
// uArr[IX(x,y,z)] = uTemp[IX(x,y,z)];
|
||||
// vArr[IX(x,y,z)] = vTemp[IX(x,y,z)];
|
||||
// wArr[IX(x,y,z)] = wTemp[IX(x,y,z)];
|
||||
// } else {
|
||||
// uArr[IX(x,y,z)] = 0;
|
||||
// vArr[IX(x,y,z)] = 0;
|
||||
// wArr[IX(x,y,z)] = 0;
|
||||
// }
|
||||
|
||||
// if(
|
||||
// uTemp[x,y,z] < -100.0f || uTemp[x,y,z] > 100.0f ||
|
||||
// vTemp[x,y,z] < -100.0f || vTemp[x,y,z] > 100.0f ||
|
||||
// wTemp[x,y,z] < -100.0f || wTemp[x,y,z] > 100.0f ||
|
||||
// magnitude < -1000 || magnitude > 1000 ||
|
||||
// pressureDivergence < -1000 || pressureDivergence > 1000
|
||||
// ){
|
||||
// printf("pressure divergence thing is off!!\n");
|
||||
// printf("%f \n", magnitude);
|
||||
// printf("%f \n", pressureDivergence);
|
||||
// printf("%f %f %f \n", uTemp[IX(x,y,z)], vTemp[IX(x,y,z)], wTemp[IX(x,y,z)]);
|
||||
// printf("%f %f %f \n", uArr[IX(x,y,z)], vArr[IX(x,y,z)], wArr[IX(x,y,z)]);
|
||||
// printf("\n");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ public class ScriptClientVoxelUtils {
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||
Vector3d cursorPos = collisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||
if(cursorPos == null){
|
||||
cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE));
|
||||
cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).normalize().mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE));
|
||||
}
|
||||
cursorPos = cursorPos.add(cursorVerticalOffset);
|
||||
Vector3i worldPos = new Vector3i(
|
||||
|
||||
@ -106,6 +106,11 @@ public class ServerFluidChunk {
|
||||
*/
|
||||
FloatBuffer bounds;
|
||||
|
||||
/**
|
||||
* The pressure cache
|
||||
*/
|
||||
FloatBuffer pressureCache;
|
||||
|
||||
/**
|
||||
* The array of all adjacent weight buffers for the fluid sim
|
||||
*/
|
||||
@ -244,6 +249,7 @@ public class ServerFluidChunk {
|
||||
this.velocityY = this.bVelocityY[CENTER_BUFF].asFloatBuffer();
|
||||
this.velocityZ = this.bVelocityZ[CENTER_BUFF].asFloatBuffer();
|
||||
this.bounds = this.bBounds[CENTER_BUFF].asFloatBuffer();
|
||||
this.pressureCache = this.bPressureCache[CENTER_BUFF].asFloatBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -488,6 +494,17 @@ public class ServerFluidChunk {
|
||||
this.bounds.put(this.IX(x,y,z),bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pressure
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param z The z coordinate
|
||||
* @param pressure The pressure
|
||||
*/
|
||||
public void setPressure(int x, int y, int z, float pressure){
|
||||
pressureCache.put(this.IX(x,y,z),pressure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inddex into the buffer
|
||||
* @param x The x position
|
||||
|
||||
@ -275,6 +275,7 @@ public class ServerFluidManager {
|
||||
ServerFluidChunk fluidChunk = this.getChunk(worldPos.x, worldPos.y, worldPos.z);
|
||||
fluidChunk.setAsleep(false);
|
||||
fluidChunk.setWeight(voxelPos.x, voxelPos.y, voxelPos.z, weight);
|
||||
fluidChunk.setPressure(voxelPos.x, voxelPos.y, voxelPos.z, weight);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
|
||||
/**
|
||||
* The gravity constant
|
||||
*/
|
||||
public static final float GRAVITY_CONST = -1000f;
|
||||
public static final float GRAVITY_CONST = -100f;
|
||||
|
||||
/**
|
||||
* Load fluid sim library
|
||||
|
||||
@ -50,7 +50,7 @@ int fluid_sim_pressurecell_diffuse_test1(){
|
||||
//
|
||||
// cell that originall had values
|
||||
//
|
||||
expected = MAX_FLUID_VALUE - FLUID_PRESSURECELL_DIFFUSION_CONSTANT * 6 * MAX_FLUID_VALUE;
|
||||
expected = MAX_FLUID_VALUE - FLUID_PRESSURECELL_DIFFUSION_CONSTANT * 6 * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(4,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (4,4,4)! expected: %f actual: %f \n");
|
||||
@ -60,37 +60,37 @@ int fluid_sim_pressurecell_diffuse_test1(){
|
||||
//
|
||||
// neighbors
|
||||
//
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(3,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (3,4,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(5,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN * env->consts.dt){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (5,4,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(4,3,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (4,3,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(4,5,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (4,5,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(4,4,3)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (4,4,3)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->dTempCache[IX(4,4,5)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse density correctly (4,4,5)! expected: %f actual: %f \n");
|
||||
@ -126,7 +126,7 @@ int fluid_sim_pressurecell_diffuse_test2(){
|
||||
//
|
||||
// cell that originall had values
|
||||
//
|
||||
expected = MAX_FLUID_VALUE - FLUID_PRESSURECELL_DIFFUSION_CONSTANT * 6 * MAX_FLUID_VALUE;
|
||||
expected = MAX_FLUID_VALUE - FLUID_PRESSURECELL_DIFFUSION_CONSTANT * 6 * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(4,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (4,4,4)! expected: %f actual: %f \n");
|
||||
@ -136,37 +136,37 @@ int fluid_sim_pressurecell_diffuse_test2(){
|
||||
//
|
||||
// neighbors
|
||||
//
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(3,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (3,4,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(5,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (5,4,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(4,3,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (4,3,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(4,5,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (4,5,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(4,4,3)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (4,4,3)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE;
|
||||
expected = FLUID_PRESSURECELL_DIFFUSION_CONSTANT * MAX_FLUID_VALUE * env->consts.dt;
|
||||
actual = currentChunk->uTempCache[IX(4,4,5)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to diffuse velocity correctly (4,4,5)! expected: %f actual: %f \n");
|
||||
|
||||
78
src/test/c/fluid/sim/pressurecell/divergence_tests.c
Normal file
78
src/test/c/fluid/sim/pressurecell/divergence_tests.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "stb/stb_ds.h"
|
||||
|
||||
#include "fluid/queue/boundsolver.h"
|
||||
#include "fluid/queue/chunkmask.h"
|
||||
#include "fluid/queue/chunk.h"
|
||||
#include "fluid/env/environment.h"
|
||||
#include "fluid/env/utilities.h"
|
||||
#include "fluid/sim/pressurecell/pressure.h"
|
||||
#include "fluid/sim/pressurecell/solver_consts.h"
|
||||
#include "math/ode/multigrid.h"
|
||||
#include "../../../util/chunk_test_utils.h"
|
||||
#include "../../../util/test.h"
|
||||
|
||||
/**
|
||||
* Error margin for tests
|
||||
*/
|
||||
#define FLUID_PRESSURE_CELL_ERROR_MARGIN 0.00001f
|
||||
|
||||
/**
|
||||
* Number of chunks
|
||||
*/
|
||||
#define CHUNK_DIM 4
|
||||
|
||||
/**
|
||||
* Testing pressure values
|
||||
*/
|
||||
int fluid_sim_pressurecell_divergence_test1(){
|
||||
printf("fluid_sim_pressurecell_divergence_test1\n");
|
||||
int rVal = 0;
|
||||
Environment * env = fluid_environment_create();
|
||||
Chunk ** queue = NULL;
|
||||
queue = createChunkGrid(env,CHUNK_DIM,CHUNK_DIM,CHUNK_DIM);
|
||||
int chunkCount = arrlen(queue);
|
||||
|
||||
|
||||
|
||||
//setup chunk values
|
||||
float deltaDensity = 0.01f;
|
||||
Chunk * currentChunk = queue[0];
|
||||
currentChunk->divergenceCache[CENTER_LOC][IX(4,4,4)] = 0;
|
||||
|
||||
currentChunk->u[CENTER_LOC][IX(3,4,4)] = 1;
|
||||
currentChunk->u[CENTER_LOC][IX(5,4,4)] = -1;
|
||||
currentChunk->v[CENTER_LOC][IX(4,3,4)] = 1;
|
||||
currentChunk->v[CENTER_LOC][IX(4,5,4)] = -1;
|
||||
currentChunk->w[CENTER_LOC][IX(4,4,3)] = 1;
|
||||
currentChunk->w[CENTER_LOC][IX(4,4,5)] = -1;
|
||||
|
||||
//actually simulate
|
||||
pressurecell_approximate_divergence(env,currentChunk);
|
||||
|
||||
//test the result
|
||||
float expected, actual;
|
||||
|
||||
//
|
||||
// cell that originall had values
|
||||
//
|
||||
expected = -3 * env->consts.dt;
|
||||
actual = currentChunk->divergenceCache[CENTER_LOC][IX(4,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to calculate divergence correctly (4,4,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing pressure values
|
||||
*/
|
||||
int fluid_sim_pressurecell_divergence_tests(int argc, char **argv){
|
||||
int rVal = 0;
|
||||
|
||||
rVal += fluid_sim_pressurecell_divergence_test1();
|
||||
|
||||
return rVal;
|
||||
}
|
||||
@ -39,11 +39,14 @@ int fluid_sim_pressurecell_pressure_test1(){
|
||||
//setup chunk values
|
||||
float deltaDensity = 0.01f;
|
||||
Chunk * currentChunk = queue[0];
|
||||
currentChunk->d[CENTER_LOC][IX(4,4,4)] = MAX_FLUID_VALUE - deltaDensity;
|
||||
currentChunk->d0[CENTER_LOC][IX(4,4,4)] = deltaDensity;
|
||||
currentChunk->u0[CENTER_LOC][IX(4,4,4)] = FLUID_PRESSURECELL_MAX_VELOCITY;
|
||||
currentChunk->v0[CENTER_LOC][IX(4,4,4)] = FLUID_PRESSURECELL_MAX_VELOCITY;
|
||||
currentChunk->w0[CENTER_LOC][IX(4,4,4)] = FLUID_PRESSURECELL_MAX_VELOCITY;
|
||||
currentChunk->divergenceCache[CENTER_LOC][IX(4,4,4)] = 3;
|
||||
|
||||
currentChunk->pressureCache[CENTER_LOC][IX(3,4,4)] = 1;
|
||||
currentChunk->pressureCache[CENTER_LOC][IX(5,4,4)] = -1;
|
||||
currentChunk->pressureCache[CENTER_LOC][IX(4,3,4)] = 1;
|
||||
currentChunk->pressureCache[CENTER_LOC][IX(4,5,4)] = -1;
|
||||
currentChunk->pressureCache[CENTER_LOC][IX(4,4,3)] = 1;
|
||||
currentChunk->pressureCache[CENTER_LOC][IX(4,4,5)] = -1;
|
||||
|
||||
//actually simulate
|
||||
pressurecell_approximate_pressure(env,currentChunk);
|
||||
@ -54,11 +57,11 @@ int fluid_sim_pressurecell_pressure_test1(){
|
||||
//
|
||||
// cell that originall had values
|
||||
//
|
||||
// expected = MAX_FLUID_VALUE - FLUID_PRESSURECELL_MAX_VELOCITY * env->consts.dt * MAX_FLUID_VALUE;
|
||||
// actual = currentChunk->pressureCache[CENTER_LOC][IX(4,4,4)];
|
||||
// if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
// rVal += assertEqualsFloat(expected,actual,"Failed to advect density correctly (4,4,4)! expected: %f actual: %f \n");
|
||||
// }
|
||||
expected = -FLUID_PRESSURECELL_RESIDUAL_MULTIPLIER * currentChunk->divergenceCache[CENTER_LOC][IX(4,4,4)];
|
||||
actual = currentChunk->pressureTempCache[IX(4,4,4)];
|
||||
if(fabs(expected - actual) > FLUID_PRESSURE_CELL_ERROR_MARGIN){
|
||||
rVal += assertEqualsFloat(expected,actual,"Failed to advect density correctly (4,4,4)! expected: %f actual: %f \n");
|
||||
}
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user