diff --git a/src/main/c/includes/fluid/queue/boundsolver.h b/src/main/c/includes/fluid/queue/boundsolver.h index 0994b32b..ab1ce3ee 100644 --- a/src/main/c/includes/fluid/queue/boundsolver.h +++ b/src/main/c/includes/fluid/queue/boundsolver.h @@ -7,6 +7,17 @@ +/** + * Should check the neighbor when filling + */ +#define fluid_solve_bounds_SKIP_NEIGHBOR 0 + +/** + * Should not check the neighbor when filling + */ +#define fluid_solve_bounds_CHECK_NEIGHBOR 1 + + /** * Sets the boundary values for each chunk * @param numReadIn The number of chunks @@ -16,6 +27,12 @@ LIBRARY_API void fluid_solve_bounds(int numReadIn, Chunk ** chunkViewC, Environment * environment); +/** + * Sets the bounds of an array to a provided value + * @param arrays The array to set + * @param fillVal The value to fill with + */ +LIBRARY_API void fluid_solve_bounds_set_bounds(float * arrays, float fillVal); #endif \ No newline at end of file diff --git a/src/main/c/includes/fluid/sim/grid2/mainFunctions.h b/src/main/c/includes/fluid/sim/grid2/mainFunctions.h index 6475aaa4..8d01b84a 100644 --- a/src/main/c/includes/fluid/sim/grid2/mainFunctions.h +++ b/src/main/c/includes/fluid/sim/grid2/mainFunctions.h @@ -4,6 +4,27 @@ #ifndef FLUID_GRID2_MAINFUNC #define FLUID_GRID2_MAINFUNC + + +#define FLUID_GRID2_BOUND_NO_DIR 0 +#define FLUID_GRID2_BOUND_DIR_U 1 +#define FLUID_GRID2_BOUND_DIR_V 2 +#define FLUID_GRID2_BOUND_DIR_W 3 + + + + + + + + + + + + +/** + * The main simulation function + */ void fluid_grid2_simulate( int numChunks, Chunk ** passedInChunks, @@ -11,6 +32,10 @@ void fluid_grid2_simulate( jfloat timestep ); + +/** + * Adds the sources to the destinations + */ void fluid_grid2_addSourceToVectors ( int chunk_mask, diff --git a/src/main/c/includes/fluid/sim/grid2/solver_consts.h b/src/main/c/includes/fluid/sim/grid2/solver_consts.h index 6b439e8c..1a9cf4d5 100644 --- a/src/main/c/includes/fluid/sim/grid2/solver_consts.h +++ b/src/main/c/includes/fluid/sim/grid2/solver_consts.h @@ -1,7 +1,8 @@ #ifndef FLUID_GRID2_SOLVER_CONSTS_H #define FLUID_GRID2_SOLVER_CONSTS_H -#define FLUID_GRID2_LINEARSOLVERTIMES 3 -#define FLUID_GRID2_VECTOR_DIFFUSE_TIMES 1 +#define FLUID_GRID2_LINEARSOLVERTIMES 20 +#define FLUID_GRID2_VECTOR_DIFFUSE_TIMES 20 +#define FLUID_GRID2_H (1) #endif \ No newline at end of file diff --git a/src/main/c/src/fluid/env/environment.c b/src/main/c/src/fluid/env/environment.c index 716d68bb..3012f91a 100644 --- a/src/main/c/src/fluid/env/environment.c +++ b/src/main/c/src/fluid/env/environment.c @@ -11,6 +11,7 @@ LIBRARY_API Environment * fluid_environment_create(){ Environment * rVal = (Environment *)calloc(1,sizeof(Environment)); rVal->queue.cellularQueue = NULL; rVal->queue.gridQueue = NULL; + rVal->queue.grid2Queue = NULL; return rVal; } diff --git a/src/main/c/src/fluid/queue/boundsolver.c b/src/main/c/src/fluid/queue/boundsolver.c index b55622f0..dbc9b977 100644 --- a/src/main/c/src/fluid/queue/boundsolver.c +++ b/src/main/c/src/fluid/queue/boundsolver.c @@ -372,3 +372,167 @@ LIBRARY_API void fluid_solve_bounds(int numReadIn, Chunk ** chunkViewC, Environm } } +/** + * Sets the bounds of an array to a provided value + * @param arrays The array to set + * @param fillVal The value to fill with + */ +LIBRARY_API void fluid_solve_bounds_set_bounds(float * arrays, float fillVal){ + int i, j; + //x+ face + for(i = 1; i < DIM; i++){ + for(j = 1; j < DIM; j++){ + arrays[IX(DIM-1, i, j)] = fillVal; + } + } + + //x- face + for(i = 1; i < DIM-1; i++){ + for(j = 1; j < DIM-1; j++){ + arrays[IX(0, i, j)] = fillVal; + } + } + + //y+ face + for(i = 1; i < DIM-1; i++){ + for(j = 1; j < DIM-1; j++){ + arrays[IX( i, DIM-1, j)] = fillVal; + } + } + + //y- face + for(i = 1; i < DIM-1; i++){ + for(j = 1; j < DIM-1; j++){ + arrays[IX(i, 0, j)] = fillVal; + } + } + + //z+ face + for(i = 1; i < DIM-1; i++){ + for(j = 1; j < DIM-1; j++){ + arrays[IX( i, j, DIM-1)] = fillVal; + } + } + + //z- face + for(i = 1; i < DIM-1; i++){ + for(j = 1; j < DIM-1; j++){ + arrays[IX(i, j, 0)] = fillVal; + } + } + + + // + // edges + // + + //x+ y+ edge + for(i = 1; i < DIM; i++){ + arrays[IX(DIM-1, DIM-1, i)] = fillVal; + } + + //x+ y- edge + for(i = 1; i < DIM; i++){ + arrays[IX(DIM-1, 0, i)] = fillVal; + } + + //x- y+ edge + for(i = 1; i < DIM; i++){ + arrays[IX( 0, DIM-1, i)] = fillVal; + } + + //x- y- edge + for(i = 1; i < DIM; i++){ + arrays[IX( 0, 0, i)] = fillVal; + } + + + + + + + + + + //x+ z+ edge + for(i = 1; i < DIM; i++){ + arrays[IX(DIM-1, i, DIM-1)] = fillVal; + } + + //x+ z- edge + for(i = 1; i < DIM; i++){ + arrays[IX(DIM-1, i, 0)] = fillVal; + } + + //x- z+ edge + for(i = 1; i < DIM; i++){ + arrays[IX( 0, i, DIM-1)] = fillVal; + } + + //x- z- edge + for(i = 1; i < DIM; i++){ + arrays[IX( 0, i, 0)] = fillVal; + } + + + + + + + + + //y+ z+ edge + for(i = 1; i < DIM; i++){ + arrays[IX( i, DIM-1, DIM-1)] = fillVal; + } + + //y+ z- edge + for(i = 1; i < DIM; i++){ + arrays[IX( i,DIM-1, 0)] = fillVal; + } + + //y- z+ edge + for(i = 1; i < DIM; i++){ + arrays[IX( i, 0, DIM-1)] = fillVal; + } + + //y- z- edge + for(i = 1; i < DIM; i++){ + arrays[IX( i, 0, 0)] = fillVal; + } + + + // + // CORNERS + // + + //x+ y+ z+ corner + arrays[IX(DIM-1, DIM-1, DIM-1)] = fillVal; + + //x+ y+ z- corner + arrays[IX(DIM-1, DIM-1, 0)] = fillVal; + + + + //x+ y- z+ corner + arrays[IX(DIM-1, 0, DIM-1)] = fillVal; + + //x+ y- z- corner + arrays[IX(DIM-1, 0, 0)] = fillVal; + + + + //x- y+ z+ corner + arrays[IX(0, DIM-1, DIM-1)] = fillVal; + + //x- y+ z- corner + arrays[IX(0, DIM-1, 0)] = fillVal; + + + + //x- y- z+ corner + arrays[IX(0, 0, DIM-1)] = fillVal; + + //x- y- z- corner + arrays[IX(0, 0, 0)] = fillVal; +} \ No newline at end of file diff --git a/src/main/c/src/fluid/sim/grid2/densitystep.c b/src/main/c/src/fluid/sim/grid2/densitystep.c index cae3e0dd..375c1ef8 100644 --- a/src/main/c/src/fluid/sim/grid2/densitystep.c +++ b/src/main/c/src/fluid/sim/grid2/densitystep.c @@ -7,6 +7,7 @@ #include "fluid/queue/chunkmask.h" #include "fluid/env/environment.h" #include "fluid/queue/chunk.h" +#include "fluid/sim/grid2/solver_consts.h" /** @@ -50,7 +51,8 @@ void fluid_grid2_solveDiffuseDensity( float VISCOSITY_CONST, float dt ){ - float a=dt*DIFFUSION_CONST*DIM*DIM*DIM; + float h = FLUID_GRID2_H; + float a=dt*DIFFUSION_CONST/(h*h); float c=1+6*a; int i, j, k, l, m; float * x = GET_ARR_RAW(d,CENTER_LOC); diff --git a/src/main/c/src/fluid/sim/grid2/fluidsim.c b/src/main/c/src/fluid/sim/grid2/fluidsim.c index 04fa48f5..ee2a07c6 100644 --- a/src/main/c/src/fluid/sim/grid2/fluidsim.c +++ b/src/main/c/src/fluid/sim/grid2/fluidsim.c @@ -1,5 +1,6 @@ #include #include +#include //native interfaces #include "native/electrosphere_server_fluid_simulator_FluidAcceleratedSimulator.h" @@ -25,11 +26,13 @@ static inline void fluid_grid2_saveStep(float * values, const char * name); static inline void fluid_grid2_applyGravity(Chunk * currentChunk, Environment * environment); static inline void fluid_grid2_clearArr(float ** d); +static inline void fluid_grid2_rewrite_bounds(Chunk * chunk); /** * A grid that stores a mask of the border locations */ -float * fluid_grid2_borderArr; +float * fluid_grid2_border_mask; +float * fluid_grid2_border_mask_inverted; /** * An array that stores values for the neighbor's arrays @@ -55,6 +58,13 @@ void fluid_grid2_simulate( //solve chunk mask for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; + + //update the bounds arrays + fluid_grid2_rewrite_bounds(currentChunk); + + + + //add velocity fluid_grid2_applyGravity(currentChunk,environment); fluid_grid2_addSourceToVectors( currentChunk->chunkMask, @@ -68,92 +78,40 @@ void fluid_grid2_simulate( FLUID_GRID2_VISCOSITY_CONSTANT, timestep ); - } - //swap all vector fields - { + //swap all vector fields //swap vector fields - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - float * tmpArr; - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->u[j]; - currentChunk->u[j] = currentChunk->u0[j]; - currentChunk->u0[j] = tmpArr; - } - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->v[j]; - currentChunk->v[j] = currentChunk->v0[j]; - currentChunk->v0[j] = tmpArr; - } - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->w[j]; - currentChunk->w[j] = currentChunk->w0[j]; - currentChunk->w0[j] = tmpArr; - } + float * tmpArr; + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->u[j]; + currentChunk->u[j] = currentChunk->u0[j]; + currentChunk->u0[j] = tmpArr; } - //copy neighbors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w0); + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->v[j]; + currentChunk->v[j] = currentChunk->v0[j]; + currentChunk->v0[j] = tmpArr; } - } - //solve vector diffusion - { + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->w[j]; + currentChunk->w[j] = currentChunk->w0[j]; + currentChunk->w0[j] = tmpArr; + } + //solve vector diffusion for(int l = 0; l < FLUID_GRID2_VECTOR_DIFFUSE_TIMES; l++){ //solve vector diffusion - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_solveVectorDiffuse(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } + fluid_grid2_solveVectorDiffuse(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); //update array for vectors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w); - // setBoundsToNeighborsRaw(DIM,chunkMask,1,currentChunk->u0); - // setBoundsToNeighborsRaw(DIM,chunkMask,2,currentChunk->v0); - // setBoundsToNeighborsRaw(DIM,chunkMask,3,currentChunk->w0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->w0); - } - } - } - //solve projection - { - //update array for vectors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_U,currentChunk->u); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_V,currentChunk->v); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_W,currentChunk->w); } //setup projection - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setupProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } + fluid_grid2_setupProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); //update array for vectors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,0,currentChunk->u0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,0,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->v0); - } + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_NO_DIR,currentChunk->u0); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_NO_DIR,currentChunk->v0); //samples u0, v0 //sets u0 @@ -161,179 +119,68 @@ void fluid_grid2_simulate( // //Perform main projection solver for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){ - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_solveProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,0,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->u0); - } + fluid_grid2_solveProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_NO_DIR,currentChunk->u0); } //samples u,v,w,u0 //sets u,v,w //Finalize projection - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_finalizeProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } + fluid_grid2_finalizeProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); //set boundaries a final time for u,v,w //... - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w0); - } - } - //swap all vector fields - { + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_U,currentChunk->u); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_V,currentChunk->v); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_W,currentChunk->w); + + //swap all vector fields //swap vector fields - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - float * tmpArr; - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->u[j]; - currentChunk->u[j] = currentChunk->u0[j]; - currentChunk->u0[j] = tmpArr; - } - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->v[j]; - currentChunk->v[j] = currentChunk->v0[j]; - currentChunk->v0[j] = tmpArr; - } - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->w[j]; - currentChunk->w[j] = currentChunk->w0[j]; - currentChunk->w0[j] = tmpArr; - } + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->u[j]; + currentChunk->u[j] = currentChunk->u0[j]; + currentChunk->u0[j] = tmpArr; } - //copy neighbors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w0); + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->v[j]; + currentChunk->v[j] = currentChunk->v0[j]; + currentChunk->v0[j] = tmpArr; } - } - //advect vectors across boundaries - { - //update border arrs - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w0); + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->w[j]; + currentChunk->w[j] = currentChunk->w0[j]; + currentChunk->w0[j] = tmpArr; } + //advect vectors across boundaries //advect - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_advectVectors(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } + fluid_grid2_advectVectors(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); //update neighbor arr - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - } - } - //solve projection - { - //update array for vectors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - } + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_U,currentChunk->u); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_V,currentChunk->v); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_W,currentChunk->w); //setup projection - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setupProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } + fluid_grid2_setupProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); //update array for vectors - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - } + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_U,currentChunk->u0); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_V,currentChunk->v0); //samples u0, v0 //sets u0 //these should have just been mirrored in the above // //Perform main projection solver for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){ - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_solveProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,0,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->u0); - } + fluid_grid2_solveProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_NO_DIR,currentChunk->u0); } //samples u,v,w,u0 //sets u,v,w //Finalize projection - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_finalizeProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } + fluid_grid2_finalizeProjection(currentChunk->chunkMask,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,currentChunk->w0,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); //set boundaries a final time for u,v,w //... - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,1,currentChunk->u0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,2,currentChunk->v0); - fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,3,currentChunk->w0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,1,currentChunk->u0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,2,currentChunk->v0); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,3,currentChunk->w0); - } + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_U,currentChunk->u); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_V,currentChunk->v); + fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,FLUID_GRID2_BOUND_DIR_W,currentChunk->w); } @@ -349,71 +196,35 @@ void fluid_grid2_simulate( //add density - { - double deltaDensity = 0; - environment->state.existingDensity = 0; - environment->state.newDensity = 0; - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_addDensity(environment,currentChunk->chunkMask,currentChunk->d,currentChunk->d0,timestep); - } - } - //swap all density arrays - { + double deltaDensity = 0; + environment->state.existingDensity = 0; + environment->state.newDensity = 0; + for(int i = 0; i < numChunks; i++){ + Chunk * currentChunk = chunks[i]; + fluid_grid2_addDensity(environment,currentChunk->chunkMask,currentChunk->d,currentChunk->d0,timestep); + //swap all density arrays //swap vector fields - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - float * tmpArr; - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->d[j]; - currentChunk->d[j] = currentChunk->d0[j]; - currentChunk->d0[j] = tmpArr; - } + float * tmpArr; + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->d[j]; + currentChunk->d[j] = currentChunk->d0[j]; + currentChunk->d0[j] = tmpArr; } - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->d); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->d0); - } - } - //diffuse density - { + //diffuse density for(int l = 0; l < FLUID_GRID2_LINEARSOLVERTIMES; l++){ - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; fluid_grid2_solveDiffuseDensity(currentChunk->chunkMask,currentChunk->d,currentChunk->d0,currentChunk->u,currentChunk->v,currentChunk->w,FLUID_GRID2_DIFFUSION_CONSTANT,FLUID_GRID2_VISCOSITY_CONSTANT,timestep); - } - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; fluid_grid2_setBoundsToNeighborsRaw(currentChunk->chunkMask,0,currentChunk->d); - } } - } - //swap all density arrays - { + //swap all density arrays //swap vector fields - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - float * tmpArr; - for(int j = 0; j < 27; j++){ - tmpArr = currentChunk->d[j]; - currentChunk->d[j] = currentChunk->d0[j]; - currentChunk->d0[j] = tmpArr; - } - } - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->d); - fluid_grid2_copyNeighborsRaw(currentChunk->chunkMask,0,0,currentChunk->d0); - } - } - //advect density - { - for(int i = 0; i < numChunks; i++){ - Chunk * currentChunk = chunks[i]; - fluid_grid2_advectDensity(currentChunk->chunkMask,currentChunk->d,currentChunk->d0,currentChunk->u,currentChunk->v,currentChunk->w,timestep); + for(int j = 0; j < 27; j++){ + tmpArr = currentChunk->d[j]; + currentChunk->d[j] = currentChunk->d0[j]; + currentChunk->d0[j] = tmpArr; } + //advect density + fluid_grid2_advectDensity(currentChunk->chunkMask,currentChunk->d,currentChunk->d0,currentChunk->u,currentChunk->v,currentChunk->w,timestep); } //mirror densities { @@ -511,14 +322,17 @@ static inline void fluid_grid2_clearArr(float ** d){ * Allocates the arrays necessary for grid2 simulation */ void fluid_grid2_allocate_arrays(){ - fluid_grid2_borderArr = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + fluid_grid2_border_mask = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + fluid_grid2_border_mask_inverted = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); for(int x = 0; x < DIM; x++){ for(int y = 0; y < DIM; y++){ for(int z = 0; z < DIM; z++){ if(x == 0 || x == DIM-1 || y == 0 || y == DIM-1 || z == 0 || z == DIM-1){ - fluid_grid2_borderArr[IX(x,y,z)] = 1; + fluid_grid2_border_mask[IX(x,y,z)] = 1; + fluid_grid2_border_mask_inverted[IX(x,y,z)] = 0; } else { - fluid_grid2_borderArr[IX(x,y,z)] = 0; + fluid_grid2_border_mask[IX(x,y,z)] = 0; + fluid_grid2_border_mask_inverted[IX(x,y,z)] = 1; } } } @@ -534,6 +348,94 @@ void fluid_grid2_allocate_arrays(){ fluid_grid2_neighborArr_bounds = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); } +/** + * Applies a bounds array to a source array + */ +static inline void fluid_grid2_apply_bounds_mask(float * realArr, float * boundsArr){ + __m256 maskedBounds, realVal, invertedMask, realPart, finalVec; + int x; + for(int z = 0; z < 18; z++){ + for(int y = 0; y < 18; y++){ + //lower part + x = 0; + //border part + maskedBounds = _mm256_loadu_ps(&fluid_grid2_border_mask[IX(x,y,z)]); + //real part + realVal = _mm256_loadu_ps(&realArr[IX(x,y,z)]); + invertedMask = _mm256_loadu_ps(&fluid_grid2_border_mask_inverted[IX(x,y,z)]); + realPart = _mm256_mul_ps(realVal,invertedMask); + finalVec = _mm256_add_ps(realPart,maskedBounds); + _mm256_storeu_ps(&realArr[IX(x,y,z)],finalVec); + + + //upper part + x = 2; + //border part + maskedBounds = _mm256_loadu_ps(&fluid_grid2_border_mask[IX(x,y,z)]); + //real part + realVal = _mm256_loadu_ps(&realArr[IX(x,y,z)]); + invertedMask = _mm256_loadu_ps(&fluid_grid2_border_mask_inverted[IX(x,y,z)]); + realPart = _mm256_mul_ps(realVal,invertedMask); + finalVec = _mm256_add_ps(realPart,maskedBounds); + _mm256_storeu_ps(&realArr[IX(x,y,z)],finalVec); + + } + } +} + +/** + * Applies the bounds mask to the current chunk + */ +static inline void fluid_grid2_set_bounds(Chunk * chunk){ + fluid_grid2_apply_bounds_mask(chunk->d[CENTER_LOC], fluid_grid2_neighborArr_d); + fluid_grid2_apply_bounds_mask(chunk->d0[CENTER_LOC], fluid_grid2_neighborArr_d0); + fluid_grid2_apply_bounds_mask(chunk->u[CENTER_LOC], fluid_grid2_neighborArr_u); + fluid_grid2_apply_bounds_mask(chunk->v[CENTER_LOC], fluid_grid2_neighborArr_v); + fluid_grid2_apply_bounds_mask(chunk->w[CENTER_LOC], fluid_grid2_neighborArr_w); + fluid_grid2_apply_bounds_mask(chunk->u0[CENTER_LOC], fluid_grid2_neighborArr_u0); + fluid_grid2_apply_bounds_mask(chunk->v0[CENTER_LOC], fluid_grid2_neighborArr_v0); + fluid_grid2_apply_bounds_mask(chunk->w0[CENTER_LOC], fluid_grid2_neighborArr_w0); + fluid_grid2_apply_bounds_mask(chunk->bounds[CENTER_LOC], fluid_grid2_neighborArr_bounds); +} + + +/** + * Quickly masks a chunk's arrays + */ +static inline void fluid_grid2_populate_masked_arr(float * sourceArr, float * workingArr){ + __m256 arrVal, maskVal, masked; + for(int z = 0; z < 18; z++){ + for(int y = 0; y < 18; y++){ + //lower part + arrVal = _mm256_loadu_ps(&sourceArr[IX(0,y,z)]); + maskVal = _mm256_loadu_ps(&fluid_grid2_border_mask[IX(0,y,z)]); + masked = _mm256_mul_ps(arrVal,maskVal); + _mm256_storeu_ps(&workingArr[IX(0,y,z)],masked); + + //upper part + arrVal = _mm256_loadu_ps(&sourceArr[IX(2,y,z)]); + maskVal = _mm256_loadu_ps(&fluid_grid2_border_mask[IX(0,y,z)]); + masked = _mm256_mul_ps(arrVal,maskVal); + _mm256_storeu_ps(&workingArr[IX(0,y,z)],masked); + } + } +} + +/** + * Rewrites the bounds arrays to contain the bounds of the current chunk + */ +static inline void fluid_grid2_rewrite_bounds(Chunk * chunk){ + fluid_grid2_populate_masked_arr(chunk->d[CENTER_LOC], fluid_grid2_neighborArr_d); + fluid_grid2_populate_masked_arr(chunk->d0[CENTER_LOC], fluid_grid2_neighborArr_d0); + fluid_grid2_populate_masked_arr(chunk->u[CENTER_LOC], fluid_grid2_neighborArr_u); + fluid_grid2_populate_masked_arr(chunk->v[CENTER_LOC], fluid_grid2_neighborArr_v); + fluid_grid2_populate_masked_arr(chunk->w[CENTER_LOC], fluid_grid2_neighborArr_w); + fluid_grid2_populate_masked_arr(chunk->u0[CENTER_LOC], fluid_grid2_neighborArr_u0); + fluid_grid2_populate_masked_arr(chunk->v0[CENTER_LOC], fluid_grid2_neighborArr_v0); + fluid_grid2_populate_masked_arr(chunk->w0[CENTER_LOC], fluid_grid2_neighborArr_w0); + fluid_grid2_populate_masked_arr(chunk->bounds[CENTER_LOC], fluid_grid2_neighborArr_bounds); +} + @@ -548,7 +450,3 @@ void fluid_grid2_allocate_arrays(){ - - - - diff --git a/src/main/c/src/fluid/sim/grid2/velocitystep.c b/src/main/c/src/fluid/sim/grid2/velocitystep.c index 225f53c9..d342e979 100644 --- a/src/main/c/src/fluid/sim/grid2/velocitystep.c +++ b/src/main/c/src/fluid/sim/grid2/velocitystep.c @@ -6,12 +6,7 @@ #include "fluid/queue/chunkmask.h" #include "fluid/queue/chunk.h" #include "fluid/sim/grid2/solver_consts.h" - - -#define BOUND_NO_DIR 0 -#define BOUND_DIR_U 1 -#define BOUND_DIR_V 2 -#define BOUND_DIR_W 3 +#include "fluid/sim/grid2/mainFunctions.h" #define SET_BOUND_IGNORE 0 #define SET_BOUND_USE_NEIGHBOR 1 @@ -66,7 +61,8 @@ void fluid_grid2_solveVectorDiffuse ( float VISCOSITY_CONST, float dt ){ - float a=dt*VISCOSITY_CONST*DIM*DIM*DIM; + float h = FLUID_GRID2_H; + float a=dt*VISCOSITY_CONST/(h*h); float c=1+6*a; int i, j, k, l, m; float * u = GET_ARR_RAW(jru,CENTER_LOC); @@ -184,8 +180,9 @@ void fluid_grid2_setupProjection( ){ int i, j, k; - __m256 nVector = _mm256_set1_ps(DIM); - __m256 constScalar = _mm256_set1_ps(-1.0/3.0); + float h = FLUID_GRID2_H; + __m256 nVector = _mm256_set1_ps(1); + __m256 constScalar = _mm256_set1_ps(-1.0/(2.0*h)); __m256 zeroVec = _mm256_set1_ps(0); __m256 vector, vector2, vector3; @@ -196,9 +193,6 @@ void fluid_grid2_setupProjection( float * p = GET_ARR_RAW(pr,CENTER_LOC); float * div = GET_ARR_RAW(divr,CENTER_LOC); - float scalar = 1.0/3.0; - float h = 1.0/DIM; - for(k=1; kqueue.gridQueue) + stbds_arrlen(env->queue.cellularQueue) diff --git a/src/test/c/fluid/sim/grid2/density_diffuse_tests.c b/src/test/c/fluid/sim/grid2/density_diffuse_tests.c new file mode 100644 index 00000000..ee4548fa --- /dev/null +++ b/src/test/c/fluid/sim/grid2/density_diffuse_tests.c @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + +int fluid_sim_grid2_density_diffuse_tests(int argc, char **argv){ + int rVal = 0; + + return rVal; +} \ No newline at end of file diff --git a/src/test/c/fluid/sim/grid2/grid2_tests.c b/src/test/c/fluid/sim/grid2/grid2_tests.c new file mode 100644 index 00000000..d4cfd6d7 --- /dev/null +++ b/src/test/c/fluid/sim/grid2/grid2_tests.c @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + +int fluid_sim_grid2_grid2_tests(int argc, char **argv){ + int rVal = 0; + + return rVal; +} \ No newline at end of file diff --git a/src/test/c/fluid/sim/simulator_tests.c b/src/test/c/fluid/sim/simulator_tests.c index 65fdf9cd..6197c50c 100644 --- a/src/test/c/fluid/sim/simulator_tests.c +++ b/src/test/c/fluid/sim/simulator_tests.c @@ -20,7 +20,7 @@ int fluid_sim_simulator_tests(int argc, char **argv){ int queueSize = 10; Chunk ** queue = chunk_create_queue(queueSize); - fluid_dispatch(queueSize,queue,env,FLUID_DISPATCHER_OVERRIDE_NONE); + fluid_dispatch(queueSize,queue,env,FLUID_DISPATCHER_OVERRIDE_CELLULAR); fluid_simulate(env);