fix fluid stability

This commit is contained in:
austin 2024-12-13 17:04:13 -05:00
parent 95adeb318a
commit ab5c556c4c
5 changed files with 120 additions and 103 deletions

View File

@ -15,7 +15,7 @@
/** /**
* The number of times to relax most solvers * The number of times to relax most solvers
*/ */
#define FLUID_GRID2_SOLVER_MULTIGRID_MAX_ITERATIONS 10 #define FLUID_GRID2_SOLVER_MULTIGRID_MAX_ITERATIONS 20
/** /**
* Tolerance to target for multigrid precomputing in projection * Tolerance to target for multigrid precomputing in projection

View File

@ -71,20 +71,20 @@ LIBRARY_API void fluid_grid2_solveDiffuseDensity(
//about ~40% faster than gauss seidel //about ~40% faster than gauss seidel
float residual = 1; float residual = 1;
int iterations = 0; int iterations = 0;
while(iterations < FLUID_GRID2_SOLVER_MULTIGRID_MAX_ITERATIONS && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){ // while(iterations < FLUID_GRID2_SOLVER_MULTIGRID_MAX_ITERATIONS && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){
residual = solver_multigrid_parallel_iterate(x,x0,a,c); // residual = solver_multigrid_parallel_iterate(x,x0,a,c);
fluid_grid2_set_bounds(environment,BOUND_SET_DENSITY_PHI,x);
iterations++;
}
// //about ~40% slower than multigrid
// for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){
// //iterate
// solver_gauss_seidel_iterate_parallel(x,x0,a,c,DIM);
// //set bounds
// fluid_grid2_set_bounds(environment,BOUND_SET_DENSITY_PHI,x); // fluid_grid2_set_bounds(environment,BOUND_SET_DENSITY_PHI,x);
// iterations++;
// } // }
//about ~40% slower than multigrid
for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){
//iterate
solver_gauss_seidel_iterate_parallel(x,x0,a,c,DIM);
//set bounds
fluid_grid2_set_bounds(environment,BOUND_SET_DENSITY_PHI,x);
}
} }
/** /**

View File

@ -69,16 +69,16 @@ void fluid_grid2_set_bounds_reflection(
//x-direction boundary planes //x-direction boundary planes
if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_U || vector_dir==BOUND_SET_VECTOR_U){ if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_U || vector_dir==BOUND_SET_VECTOR_U){
if(boundsArr[IX(0,x,y)] > 0){ // if(boundsArr[IX(0,x,y)] > 0){
target[IX(0,x,y)] = -target[IX(1,x,y)]; target[IX(0,x,y)] = -target[IX(1,x,y)];
} else { // } else {
target[IX(0,x,y)] = target[IX(1,x,y)]; // target[IX(0,x,y)] = target[IX(1,x,y)];
} // }
if(boundsArr[IX(DIM-1,x,y)] > 0){ // if(boundsArr[IX(DIM-1,x,y)] > 0){
target[IX(DIM-1,x,y)] = -target[IX(DIM-2,x,y)]; target[IX(DIM-1,x,y)] = -target[IX(DIM-2,x,y)];
} else { // } else {
target[IX(DIM-1,x,y)] = target[IX(DIM-2,x,y)]; // target[IX(DIM-1,x,y)] = target[IX(DIM-2,x,y)];
} // }
} else { } else {
target[IX(0,x,y)] = target[IX(1,x,y)]; target[IX(0,x,y)] = target[IX(1,x,y)];
target[IX(DIM-1,x,y)] = target[IX(DIM-2,x,y)]; target[IX(DIM-1,x,y)] = target[IX(DIM-2,x,y)];
@ -86,16 +86,16 @@ void fluid_grid2_set_bounds_reflection(
//y-direction boundary planes //y-direction boundary planes
if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_V || vector_dir==BOUND_SET_VECTOR_V){ if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_V || vector_dir==BOUND_SET_VECTOR_V){
if(boundsArr[IX(x,0,y)] > 0){ // if(boundsArr[IX(x,0,y)] > 0){
target[IX(x,0,y)] = -target[IX(x,1,y)]; target[IX(x,0,y)] = -target[IX(x,1,y)];
} else { // } else {
target[IX(x,0,y)] = target[IX(x,1,y)]; // target[IX(x,0,y)] = target[IX(x,1,y)];
} // }
if(boundsArr[IX(x,DIM-1,y)] > 0){ // if(boundsArr[IX(x,DIM-1,y)] > 0){
target[IX(x,DIM-1,y)] = -target[IX(x,DIM-2,y)]; target[IX(x,DIM-1,y)] = -target[IX(x,DIM-2,y)];
} else { // } else {
target[IX(x,DIM-1,y)] = target[IX(x,DIM-2,y)]; // target[IX(x,DIM-1,y)] = target[IX(x,DIM-2,y)];
} // }
} else { } else {
target[IX(x,0,y)] = target[IX(x,1,y)]; target[IX(x,0,y)] = target[IX(x,1,y)];
target[IX(x,DIM-1,y)] = target[IX(x,DIM-2,y)]; target[IX(x,DIM-1,y)] = target[IX(x,DIM-2,y)];
@ -103,16 +103,16 @@ void fluid_grid2_set_bounds_reflection(
//z-direction boundary planes //z-direction boundary planes
if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_W || vector_dir==BOUND_SET_VECTOR_W){ if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_W || vector_dir==BOUND_SET_VECTOR_W){
if(boundsArr[IX(x,y,0)] > 0){ // if(boundsArr[IX(x,y,0)] > 0){
target[IX(x,y,0)] = -target[IX(x,y,1)]; target[IX(x,y,0)] = -target[IX(x,y,1)];
} else { // } else {
target[IX(x,y,0)] = target[IX(x,y,1)]; // target[IX(x,y,0)] = target[IX(x,y,1)];
} // }
if(boundsArr[IX(x,y,DIM-1)] > 0){ // if(boundsArr[IX(x,y,DIM-1)] > 0){
target[IX(x,y,DIM-1)] = -target[IX(x,y,DIM-2)]; target[IX(x,y,DIM-1)] = -target[IX(x,y,DIM-2)];
} else { // } else {
target[IX(x,y,DIM-1)] = -target[IX(x,y,DIM-2)]; // target[IX(x,y,DIM-1)] = -target[IX(x,y,DIM-2)];
} // }
} else { } else {
target[IX(x,y,0)] = target[IX(x,y,1)]; target[IX(x,y,0)] = target[IX(x,y,1)];
target[IX(x,y,DIM-1)] = target[IX(x,y,DIM-2)]; target[IX(x,y,DIM-1)] = target[IX(x,y,DIM-2)];
@ -345,27 +345,44 @@ LIBRARY_API void fluid_grid2_set_bounds(
float * target float * target
){ ){
switch(vector_dir){ switch(vector_dir){
case BOUND_SET_PROJECTION_PHI:
case BOUND_SET_PROJECTION_PHI_0:
case BOUND_SET_VECTOR_DIFFUSE_PHI_U: case BOUND_SET_VECTOR_DIFFUSE_PHI_U:
case BOUND_SET_VECTOR_DIFFUSE_PHI_V: case BOUND_SET_VECTOR_DIFFUSE_PHI_V:
case BOUND_SET_VECTOR_DIFFUSE_PHI_W: { case BOUND_SET_VECTOR_DIFFUSE_PHI_W:
fluid_grid2_set_bounds_reflection(environment,vector_dir,target); case BOUND_SET_DENSITY_PHI:
} break;
case BOUND_SET_PROJECTION_PHI: {
fluid_grid2_set_bounds_continuity(environment,target);
} break;
case BOUND_SET_PROJECTION_PHI_0: {
fluid_grid2_set_bounds_continuity(environment,target);
} break;
case BOUND_SET_DENSITY_PHI: {
fluid_grid2_set_bounds_reflection(environment,vector_dir,target);
} break;
case BOUND_SET_VECTOR_U: case BOUND_SET_VECTOR_U:
case BOUND_SET_VECTOR_V: case BOUND_SET_VECTOR_V:
case BOUND_SET_VECTOR_W: case BOUND_SET_VECTOR_W:
case BOUND_SET_DENSITY: { case BOUND_SET_DENSITY:
fluid_grid2_set_bounds_reflection(environment,vector_dir,target); fluid_grid2_set_bounds_reflection(environment,vector_dir,target);
} break; break;
// case BOUND_SET_PROJECTION_PHI:
// case BOUND_SET_PROJECTION_PHI_0:
// case BOUND_SET_VECTOR_DIFFUSE_PHI_U:
// case BOUND_SET_VECTOR_DIFFUSE_PHI_V:
// case BOUND_SET_VECTOR_DIFFUSE_PHI_W:
// case BOUND_SET_DENSITY_PHI:
// case BOUND_SET_VECTOR_U:
// case BOUND_SET_VECTOR_V:
// case BOUND_SET_VECTOR_W:
// case BOUND_SET_DENSITY:
// fluid_grid2_set_bounds_continuity(environment,target);
// break;
// case BOUND_SET_PROJECTION_PHI:
// case BOUND_SET_PROJECTION_PHI_0:
// case BOUND_SET_VECTOR_DIFFUSE_PHI_U:
// case BOUND_SET_VECTOR_DIFFUSE_PHI_V:
// case BOUND_SET_VECTOR_DIFFUSE_PHI_W:
// case BOUND_SET_DENSITY_PHI:
// case BOUND_SET_VECTOR_U:
// case BOUND_SET_VECTOR_V:
// case BOUND_SET_VECTOR_W:
// case BOUND_SET_DENSITY:
// fluid_grid2_set_bounds_ghost_cell(environment,vector_dir,target);
// break;
// case BOUND_SET_PROJECTION_PHI: // case BOUND_SET_PROJECTION_PHI:
// case BOUND_SET_PROJECTION_PHI_0: // case BOUND_SET_PROJECTION_PHI_0:
@ -376,9 +393,9 @@ LIBRARY_API void fluid_grid2_set_bounds(
// case BOUND_SET_VECTOR_U: // case BOUND_SET_VECTOR_U:
// case BOUND_SET_VECTOR_V: // case BOUND_SET_VECTOR_V:
// case BOUND_SET_VECTOR_W: // case BOUND_SET_VECTOR_W:
// case BOUND_SET_DENSITY: { // case BOUND_SET_DENSITY:
// fluid_grid2_set_bounds_ghost_cell(environment,vector_dir,target); // fluid_grid2_set_bounds_zero(environment,target);
// } break; // break;
} }
} }

View File

@ -59,49 +59,49 @@ LIBRARY_API void fluid_grid2_solveVectorDiffuse(
float * v0 = GET_ARR_RAW(jrv0,CENTER_LOC); float * v0 = GET_ARR_RAW(jrv0,CENTER_LOC);
float * w0 = GET_ARR_RAW(jrw0,CENTER_LOC); float * w0 = GET_ARR_RAW(jrw0,CENTER_LOC);
// //about ~30% faster //about ~30% faster
// for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){ for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){
// //transform u direction //transform u direction
// solver_gauss_seidel_iterate_parallel(u,u0,a,c,DIM); solver_gauss_seidel_iterate_parallel(u,u0,a,c,DIM);
// //transform v direction //transform v direction
// solver_gauss_seidel_iterate_parallel(v,v0,a,c,DIM); solver_gauss_seidel_iterate_parallel(v,v0,a,c,DIM);
// //transform w direction //transform w direction
// solver_gauss_seidel_iterate_parallel(w,w0,a,c,DIM); solver_gauss_seidel_iterate_parallel(w,w0,a,c,DIM);
// //set bounds //set bounds
// fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_U,u); fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_U,u);
// fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_V,v); fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_V,v);
// fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_W,w); fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_W,w);
// } }
float residual; float residual;
int iterations; int iterations;
residual = 1; // residual = 1;
iterations = 0; // iterations = 0;
while(iterations < FLUID_GRID2_LINEARSOLVERTIMES && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){ // while(iterations < FLUID_GRID2_LINEARSOLVERTIMES && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){
residual = solver_multigrid_parallel_iterate(u,u0,a,c); // residual = solver_multigrid_parallel_iterate(u,u0,a,c);
fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_U,u); // fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_U,u);
iterations++; // iterations++;
} // }
residual = 1; // residual = 1;
iterations = 0; // iterations = 0;
while(iterations < FLUID_GRID2_LINEARSOLVERTIMES && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){ // while(iterations < FLUID_GRID2_LINEARSOLVERTIMES && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){
residual = solver_multigrid_parallel_iterate(v,v0,a,c); // residual = solver_multigrid_parallel_iterate(v,v0,a,c);
fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_V,v); // fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_V,v);
iterations++; // iterations++;
} // }
residual = 1; // residual = 1;
iterations = 0; // iterations = 0;
while(iterations < FLUID_GRID2_LINEARSOLVERTIMES && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){ // while(iterations < FLUID_GRID2_LINEARSOLVERTIMES && (residual > FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE || residual < -FLUID_GRID2_SOLVER_MULTIGRID_TOLERANCE)){
residual = solver_multigrid_parallel_iterate(w,w0,a,c); // residual = solver_multigrid_parallel_iterate(w,w0,a,c);
fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_W,w); // fluid_grid2_set_bounds(environment,BOUND_SET_VECTOR_DIFFUSE_PHI_W,w);
iterations++; // iterations++;
} // }
@ -268,17 +268,17 @@ LIBRARY_API void fluid_grid2_solveProjection(
// } // }
//init CG solver //init CG solver
solver_conjugate_gradient_init_serial(p,div); // solver_conjugate_gradient_init_serial(p,div);
chunk->projectionIterations = 0; // chunk->projectionIterations = 0;
//solve with CG // //solve with CG
while(chunk->projectionIterations < FLUID_GRID2_SOLVER_CG_MAX_ITERATIONS && (chunk->projectionResidual > FLUID_GRID2_SOLVER_CG_TOLERANCE || chunk->projectionResidual < -FLUID_GRID2_SOLVER_CG_TOLERANCE)){ // while(chunk->projectionIterations < FLUID_GRID2_SOLVER_CG_MAX_ITERATIONS && (chunk->projectionResidual > FLUID_GRID2_SOLVER_CG_TOLERANCE || chunk->projectionResidual < -FLUID_GRID2_SOLVER_CG_TOLERANCE)){
chunk->projectionResidual = solver_conjugate_gradient_iterate_parallel(p,div,a,c);; // chunk->projectionResidual = solver_conjugate_gradient_iterate_parallel(p,div,a,c);;
fluid_grid2_set_bounds(environment,BOUND_SET_PROJECTION_PHI,p); // fluid_grid2_set_bounds(environment,BOUND_SET_PROJECTION_PHI,p);
chunk->projectionIterations++; // chunk->projectionIterations++;
} // }
if(chunk->projectionResidual > FLUID_GRID2_SOLVER_CG_TOLERANCE || chunk->projectionResidual < -FLUID_GRID2_SOLVER_CG_TOLERANCE){ // if(chunk->projectionResidual > FLUID_GRID2_SOLVER_CG_TOLERANCE || chunk->projectionResidual < -FLUID_GRID2_SOLVER_CG_TOLERANCE){
// printf("Projection residual didn't converge! %f \n",chunk->projectionResidual); // // printf("Projection residual didn't converge! %f \n",chunk->projectionResidual);
} // }
//store scalar potential in cache //store scalar potential in cache
util_matrix_copy(p,chunk->scalarPotentialCache[CENTER_LOC],DIM); util_matrix_copy(p,chunk->scalarPotentialCache[CENTER_LOC],DIM);

View File

@ -256,9 +256,9 @@ int fluid_sim_grid2_speed_test3(){
int fluid_sim_grid2_speed_tests(){ int fluid_sim_grid2_speed_tests(){
int rVal = 0; int rVal = 0;
rVal += fluid_sim_grid2_speed_test1(); // rVal += fluid_sim_grid2_speed_test1();
rVal += fluid_sim_grid2_speed_test2(); // rVal += fluid_sim_grid2_speed_test2();
rVal += fluid_sim_grid2_speed_test3(); // rVal += fluid_sim_grid2_speed_test3();
return rVal; return rVal;
} }