diff --git a/.vscode/settings.json b/.vscode/settings.json index e2324420..b6676953 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -47,6 +47,7 @@ "gauss_seidel.h": "c", "ode_utils.h": "c", "util.h": "c", - "conjugate_gradient.h": "c" + "conjugate_gradient.h": "c", + "flux.h": "c" } } \ No newline at end of file diff --git a/src/main/c/includes/fluid/env/environment.h b/src/main/c/includes/fluid/env/environment.h index 4f5cdba6..d40048ed 100644 --- a/src/main/c/includes/fluid/env/environment.h +++ b/src/main/c/includes/fluid/env/environment.h @@ -31,6 +31,8 @@ typedef struct { jfieldID worldYId; jfieldID worldZId; jfieldID neighborsId; + jfieldID divergenceCacheId; + jfieldID scalarPotentialCacheId; jfieldID chunkmaskJId; jfieldID updatedId; jfieldID totalDensityId; @@ -87,8 +89,16 @@ typedef struct { typedef struct { /** * A grid that stores a mask of the border locations + * Stores 1 where it is a border region + * Stores 0 where it is an internal region */ float * fluid_grid2_border_mask; + + /** + * A grid that stores an inverted mask of the border locations + * Stores 0 where it is a border region + * Stores 1 where it is an internal region + */ float * fluid_grid2_border_mask_inverted; /** @@ -103,6 +113,8 @@ typedef struct { float * fluid_grid2_neighborArr_v0; float * fluid_grid2_neighborArr_w0; float * fluid_grid2_neighborArr_bounds; + float * fluid_grid2_neighborArr_divergenceCache; + float * fluid_grid2_neighborArr_scalarCache; } FluidGrid2State; /** diff --git a/src/main/c/includes/fluid/queue/chunk.h b/src/main/c/includes/fluid/queue/chunk.h index c553860c..c9790f46 100644 --- a/src/main/c/includes/fluid/queue/chunk.h +++ b/src/main/c/includes/fluid/queue/chunk.h @@ -48,8 +48,30 @@ typedef struct { float * u0[27]; float * v0[27]; float * w0[27]; + + /** + * Tracks which positions are bounds. Greater than 0 indicates a boundary, 0 or less indicates an open position. + */ float * bounds[27]; + + /** + * Caches the vector field divergence of this chunk for usage by neighbors next frame + */ + float * divergenceCache[27]; + + /** + * Caches the scalar potential of this chunk for usage next frame + */ + float * scalarPotentialCache[27]; + + /** + * The bitmask which tracks valid neighbors + */ uint32_t chunkMask; + + /** + * The raw java object corresponding to this chunk + */ jobject chunkJRaw; /** diff --git a/src/main/c/includes/fluid/sim/grid2/flux.h b/src/main/c/includes/fluid/sim/grid2/flux.h new file mode 100644 index 00000000..0f5fc20e --- /dev/null +++ b/src/main/c/includes/fluid/sim/grid2/flux.h @@ -0,0 +1,14 @@ +#ifndef FLUID_GRID2_FLUX_H +#define FLUID_GRID2_FLUX_H + +#include "fluid/queue/chunk.h" +#include "fluid/env/environment.h" + + +/** + * Updates the flux stored in the ghost cells of this chunk + */ +void fluid_grid2_update_ghost_flux(Environment * environment, Chunk * chunk); + + +#endif \ No newline at end of file diff --git a/src/main/c/includes/fluid/sim/grid2/velocity.h b/src/main/c/includes/fluid/sim/grid2/velocity.h index e900b532..e6437750 100644 --- a/src/main/c/includes/fluid/sim/grid2/velocity.h +++ b/src/main/c/includes/fluid/sim/grid2/velocity.h @@ -39,6 +39,7 @@ void fluid_grid2_addSourceToVectors( */ LIBRARY_API void fluid_grid2_setupProjection( Environment * environment, + Chunk * chunk, float ** ur, float ** vr, float ** wr, diff --git a/src/main/c/includes/util/matrix.h b/src/main/c/includes/util/matrix.h new file mode 100644 index 00000000..74f7ab4d --- /dev/null +++ b/src/main/c/includes/util/matrix.h @@ -0,0 +1,32 @@ +#ifndef UTIL_MATRIX_H +#define UTIL_MATRIX_H + +#include + + +/** + * Copies the contents of one matrix into another + * @param source The source matrix + * @param destination The destination matrix + * @param matDim The dimension of the matrix + */ +void util_matrix_copy( + float * source, + float * destination, + int matDim +){ + int i = 0; + int size=matDim*matDim*matDim; + for(i=0; istate.grid2.fluid_grid2_neighborArr_v0 = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); environment->state.grid2.fluid_grid2_neighborArr_w0 = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); environment->state.grid2.fluid_grid2_neighborArr_bounds = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + environment->state.grid2.fluid_grid2_neighborArr_divergenceCache = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + environment->state.grid2.fluid_grid2_neighborArr_scalarCache = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); } \ No newline at end of file diff --git a/src/main/c/src/fluid/queue/boundsolver.c b/src/main/c/src/fluid/queue/boundsolver.c index dbc9b977..56cf2fde 100644 --- a/src/main/c/src/fluid/queue/boundsolver.c +++ b/src/main/c/src/fluid/queue/boundsolver.c @@ -369,6 +369,8 @@ LIBRARY_API void fluid_solve_bounds(int numReadIn, Chunk ** chunkViewC, Environm fluid_solve_bounds_checker(current->v0,0); fluid_solve_bounds_checker(current->w0,0); fluid_solve_bounds_checker(current->bounds,BOUND_MAX_VALUE); + fluid_solve_bounds_checker(current->divergenceCache,0); + fluid_solve_bounds_checker(current->scalarPotentialCache,0); } } diff --git a/src/main/c/src/fluid/queue/javainterface.c b/src/main/c/src/fluid/queue/javainterface.c index 431ecfa6..405ed1c7 100644 --- a/src/main/c/src/fluid/queue/javainterface.c +++ b/src/main/c/src/fluid/queue/javainterface.c @@ -128,6 +128,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate environment->lookupTable.serverFluidChunkTable.v0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); environment->lookupTable.serverFluidChunkTable.w0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); environment->lookupTable.serverFluidChunkTable.boundsId = (*env)->GetFieldID(env,fluidSimStorageClass,"bBounds","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.scalarPotentialCacheId = (*env)->GetFieldID(env,fluidSimStorageClass,"bScalarPotentialCache","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.divergenceCacheId = (*env)->GetFieldID(env,fluidSimStorageClass,"bDivergenceCache","[Ljava/nio/ByteBuffer;"); environment->lookupTable.serverFluidChunkTable.worldXId = (*env)->GetFieldID(env,fluidSimStorageClass,"worldX","I"); environment->lookupTable.serverFluidChunkTable.worldYId = (*env)->GetFieldID(env,fluidSimStorageClass,"worldY","I"); environment->lookupTable.serverFluidChunkTable.worldZId = (*env)->GetFieldID(env,fluidSimStorageClass,"worldZ","I"); @@ -162,6 +164,8 @@ int readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){ jfieldID v0JId = environment->lookupTable.serverFluidChunkTable.v0JId; jfieldID w0JId = environment->lookupTable.serverFluidChunkTable.w0JId; jfieldID boundsId = environment->lookupTable.serverFluidChunkTable.boundsId; + jfieldID scalarPotentialCacheId = environment->lookupTable.serverFluidChunkTable.scalarPotentialCacheId; + jfieldID divergenceCacheId = environment->lookupTable.serverFluidChunkTable.divergenceCacheId; jfieldID chunkmaskJId = environment->lookupTable.serverFluidChunkTable.chunkmaskJId; jfieldID asleepId = environment->lookupTable.serverFluidChunkTable.asleepId; jfieldID worldXId = environment->lookupTable.serverFluidChunkTable.worldXId; @@ -183,6 +187,8 @@ int readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){ jobjectArray v0; jobjectArray w0; jobjectArray bounds; + jobjectArray scalarPotentialCache; + jobjectArray divergenceCache; int chunkMask; //solve chunk mask @@ -229,6 +235,8 @@ int readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){ v0 = (*env)->GetObjectField(env,chunkJRaw,v0JId); w0 = (*env)->GetObjectField(env,chunkJRaw,w0JId); bounds = (*env)->GetObjectField(env,chunkJRaw,boundsId); + scalarPotentialCache = (*env)->GetObjectField(env,chunkJRaw,scalarPotentialCacheId); + divergenceCache = (*env)->GetObjectField(env,chunkJRaw,divergenceCacheId); newChunk->chunkMask = chunkMask; newChunk->chunkJRaw = chunkJRaw; newChunk->x = (*env)->GetIntField(env,chunkJRaw,worldXId); @@ -245,6 +253,8 @@ int readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){ newChunk->v0[j] = getArray(env,v0,j); newChunk->w0[j] = getArray(env,w0,j); newChunk->bounds[j] = getArray(env,bounds,j); + newChunk->scalarPotentialCache[j] = getArray(env,scalarPotentialCache,j); + newChunk->divergenceCache[j] = getArray(env,scalarPotentialCache,j); } else { newChunk->d[j] = NULL; newChunk->d0[j] = NULL; @@ -255,6 +265,8 @@ int readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){ newChunk->v0[j] = NULL; newChunk->w0[j] = NULL; newChunk->bounds[j] = NULL; + newChunk->scalarPotentialCache[j] = NULL; + newChunk->divergenceCache[j] = NULL; } } } diff --git a/src/main/c/src/fluid/sim/grid2/flux.c b/src/main/c/src/fluid/sim/grid2/flux.c new file mode 100644 index 00000000..069b60d3 --- /dev/null +++ b/src/main/c/src/fluid/sim/grid2/flux.c @@ -0,0 +1,12 @@ + + +#include "fluid/sim/grid2/flux.h" + + + +/** + * Updates the flux stored in the ghost cells of this chunk + */ +void fluid_grid2_update_ghost_flux(Environment * environment, Chunk * chunk){ + +} \ No newline at end of file diff --git a/src/main/c/src/fluid/sim/grid2/grid2.c b/src/main/c/src/fluid/sim/grid2/grid2.c index 306654d4..beccd4a3 100644 --- a/src/main/c/src/fluid/sim/grid2/grid2.c +++ b/src/main/c/src/fluid/sim/grid2/grid2.c @@ -99,6 +99,7 @@ LIBRARY_API void fluid_grid2_simulate( // setup projection fluid_grid2_setupProjection( environment, + currentChunk, currentChunk->u, currentChunk->v, currentChunk->w, @@ -152,7 +153,7 @@ LIBRARY_API void fluid_grid2_simulate( // fluid_grid2_rewrite_bounds(currentChunk); //setup projection - fluid_grid2_setupProjection(environment,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,timestep); + fluid_grid2_setupProjection(environment,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,timestep); //Perform main projection solver fluid_grid2_solveProjection(environment,currentChunk,currentChunk->u0,currentChunk->v0,timestep); //Finalize projection @@ -350,66 +351,6 @@ static inline void fluid_grid2_clearArr(float ** d){ } } -/** - * Applies a bounds array to a source array - */ -static inline void fluid_grid2_apply_bounds_mask(Environment * environment, 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(&environment->state.grid2.fluid_grid2_border_mask[IX(x,y,z)]); - //real part - realVal = _mm256_loadu_ps(&realArr[IX(x,y,z)]); - invertedMask = _mm256_loadu_ps(&environment->state.grid2.fluid_grid2_border_mask_inverted[IX(x,y,z)]); - realPart = _mm256_mul_ps(realVal,invertedMask); - finalVec = _mm256_add_ps(realPart,maskedBounds); - _mm256_storeu_ps(&boundsArr[IX(x,y,z)],finalVec); - - - //middle part - x = 8; - //border part - maskedBounds = _mm256_loadu_ps(&environment->state.grid2.fluid_grid2_border_mask[IX(x,y,z)]); - //real part - realVal = _mm256_loadu_ps(&realArr[IX(x,y,z)]); - invertedMask = _mm256_loadu_ps(&environment->state.grid2.fluid_grid2_border_mask_inverted[IX(x,y,z)]); - realPart = _mm256_mul_ps(realVal,invertedMask); - finalVec = _mm256_add_ps(realPart,maskedBounds); - _mm256_storeu_ps(&boundsArr[IX(x,y,z)],finalVec); - - //upper part - x = 10; - //border part - maskedBounds = _mm256_loadu_ps(&environment->state.grid2.fluid_grid2_border_mask[IX(x,y,z)]); - //real part - realVal = _mm256_loadu_ps(&realArr[IX(x,y,z)]); - invertedMask = _mm256_loadu_ps(&environment->state.grid2.fluid_grid2_border_mask_inverted[IX(x,y,z)]); - realPart = _mm256_mul_ps(realVal,invertedMask); - finalVec = _mm256_add_ps(realPart,maskedBounds); - _mm256_storeu_ps(&boundsArr[IX(x,y,z)],finalVec); - - } - } -} - -/** - * Applies the bounds mask to the current chunk - */ -static inline void fluid_grid2_apply_neighbors(Environment * environment, Chunk * chunk){ - fluid_grid2_apply_bounds_mask(environment,chunk->d[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_d); - fluid_grid2_apply_bounds_mask(environment,chunk->d0[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_d0); - fluid_grid2_apply_bounds_mask(environment,chunk->u[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_u); - fluid_grid2_apply_bounds_mask(environment,chunk->v[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_v); - fluid_grid2_apply_bounds_mask(environment,chunk->w[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_w); - fluid_grid2_apply_bounds_mask(environment,chunk->u0[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_u0); - fluid_grid2_apply_bounds_mask(environment,chunk->v0[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_v0); - fluid_grid2_apply_bounds_mask(environment,chunk->w0[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_w0); - fluid_grid2_apply_bounds_mask(environment,chunk->bounds[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_bounds); -} /** @@ -457,6 +398,8 @@ static inline void fluid_grid2_rewrite_bounds(Environment * environment, Chunk * fluid_grid2_populate_masked_arr(environment,chunk->v0[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_v0); fluid_grid2_populate_masked_arr(environment,chunk->w0[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_w0); fluid_grid2_populate_masked_arr(environment,chunk->bounds[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_bounds); + fluid_grid2_populate_masked_arr(environment,chunk->scalarPotentialCache[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_scalarCache); + fluid_grid2_populate_masked_arr(environment,chunk->divergenceCache[CENTER_LOC], environment->state.grid2.fluid_grid2_neighborArr_divergenceCache); } diff --git a/src/main/c/src/fluid/sim/grid2/utilities.c b/src/main/c/src/fluid/sim/grid2/utilities.c index e4e6bf1d..ce6b20cb 100644 --- a/src/main/c/src/fluid/sim/grid2/utilities.c +++ b/src/main/c/src/fluid/sim/grid2/utilities.c @@ -51,6 +51,18 @@ void fluid_grid2_set_bounds_reflection( float * target ){ float * boundsArr = environment->state.grid2.fluid_grid2_neighborArr_bounds; + + //set the internal boundaries + for(int x = 1; x < DIM-1; x++){ + for(int y = 1; y < DIM-1; y++){ + for(int z = 1; z < DIM-1; z++){ + if(boundsArr[IX(x,y,z)] > 0){ + target[IX(x,y,z)] = 0; + } + } + } + } + //set the boundary planes for(int x=1; x < DIM-1; x++){ for(int y = 1; y < DIM-1; y++){ @@ -219,6 +231,14 @@ void fluid_grid2_set_bounds_ghost_cell( case BOUND_SET_VECTOR_W: { neighborArr = environment->state.grid2.fluid_grid2_neighborArr_w; } break; + + //used the cached scalar potential from last frame + case BOUND_SET_PROJECTION_PHI: { + neighborArr = environment->state.grid2.fluid_grid2_neighborArr_scalarCache; + } break; + case BOUND_SET_PROJECTION_PHI_0: { + neighborArr = environment->state.grid2.fluid_grid2_neighborArr_divergenceCache; + } break; } //set the boundary planes for(int x=1; x < DIM-1; x++){ @@ -325,25 +345,40 @@ LIBRARY_API void fluid_grid2_set_bounds( float * target ){ switch(vector_dir){ - // case BOUND_SET_VECTOR_DIFFUSE_PHI_U: - // case BOUND_SET_VECTOR_DIFFUSE_PHI_V: - // case BOUND_SET_VECTOR_DIFFUSE_PHI_W: { - // fluid_grid2_set_bounds_reflection(environment,vector_dir,target); - // } break; - case BOUND_SET_PROJECTION_PHI: + case BOUND_SET_VECTOR_DIFFUSE_PHI_U: + case BOUND_SET_VECTOR_DIFFUSE_PHI_V: + case BOUND_SET_VECTOR_DIFFUSE_PHI_W: { + fluid_grid2_set_bounds_reflection(environment,vector_dir,target); + } 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_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_DENSITY_PHI: { + fluid_grid2_set_bounds_reflection(environment,vector_dir,target); + } break; + 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); + fluid_grid2_set_bounds_reflection(environment,vector_dir,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; } } diff --git a/src/main/c/src/fluid/sim/grid2/velocity.c b/src/main/c/src/fluid/sim/grid2/velocity.c index 606d4440..9435b1ec 100644 --- a/src/main/c/src/fluid/sim/grid2/velocity.c +++ b/src/main/c/src/fluid/sim/grid2/velocity.c @@ -11,6 +11,7 @@ #include "math/ode/gauss_seidel.h" #include "math/ode/multigrid_parallel.h" #include "math/ode/conjugate_gradient.h" +#include "util/matrix.h" #define SET_BOUND_IGNORE 0 #define SET_BOUND_USE_NEIGHBOR 1 @@ -89,6 +90,7 @@ LIBRARY_API void fluid_grid2_solveVectorDiffuse( */ LIBRARY_API void fluid_grid2_setupProjection( Environment * environment, + Chunk * chunk, float ** ur, float ** vr, float ** wr, @@ -153,6 +155,8 @@ LIBRARY_API void fluid_grid2_setupProjection( } } + //store divergence in cache + util_matrix_copy(div,chunk->divergenceCache[CENTER_LOC],DIM); fluid_grid2_set_bounds(environment,BOUND_SET_PROJECTION_PHI,p); fluid_grid2_set_bounds(environment,BOUND_SET_PROJECTION_PHI_0,div); } @@ -208,6 +212,9 @@ LIBRARY_API void fluid_grid2_solveProjection( 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); } + + //store scalar potential in cache + util_matrix_copy(p,chunk->scalarPotentialCache[CENTER_LOC],DIM); } /** diff --git a/src/main/c/src/mem/fluidmem.c b/src/main/c/src/mem/fluidmem.c index 031e4ff9..c8bcd0b3 100644 --- a/src/main/c/src/mem/fluidmem.c +++ b/src/main/c/src/mem/fluidmem.c @@ -77,6 +77,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_ jfieldID v0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); jfieldID w0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); jfieldID boundsId = (*env)->GetFieldID(env,serverFluidChunkClass,"bBounds","[Ljava/nio/ByteBuffer;"); + jfieldID scalarPotentialCacheId = (*env)->GetFieldID(env,serverFluidChunkClass,"bScalarPotentialCache","[Ljava/nio/ByteBuffer;"); + jfieldID divergenceCacheId = (*env)->GetFieldID(env,serverFluidChunkClass,"bDivergenceCache","[Ljava/nio/ByteBuffer;"); allocateCenterField(env,fluidObj,dId); allocateCenterField(env,fluidObj,d0Id); allocateCenterField(env,fluidObj,uId); @@ -86,6 +88,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_ allocateCenterField(env,fluidObj,v0Id); allocateCenterField(env,fluidObj,w0Id); allocateCenterField(env,fluidObj,boundsId); + allocateCenterField(env,fluidObj,scalarPotentialCacheId); + allocateCenterField(env,fluidObj,divergenceCacheId); } /** @@ -138,6 +142,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_ jfieldID v0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); jfieldID w0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); jfieldID boundsId = (*env)->GetFieldID(env,serverFluidChunkClass,"bBounds","[Ljava/nio/ByteBuffer;"); + jfieldID scalarPotentialCacheId = (*env)->GetFieldID(env,serverFluidChunkClass,"bScalarPotentialCache","[Ljava/nio/ByteBuffer;"); + jfieldID divergenceCacheId = (*env)->GetFieldID(env,serverFluidChunkClass,"bDivergenceCache","[Ljava/nio/ByteBuffer;"); freeCenterField(env,fluidObj,dId); freeCenterField(env,fluidObj,d0Id); freeCenterField(env,fluidObj,uId); @@ -147,6 +153,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_ freeCenterField(env,fluidObj,v0Id); freeCenterField(env,fluidObj,w0Id); freeCenterField(env,fluidObj,boundsId); + freeCenterField(env,fluidObj,scalarPotentialCacheId); + freeCenterField(env,fluidObj,divergenceCacheId); } /** diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index e112e01f..62852fc1 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -151,6 +151,16 @@ public class ServerFluidChunk { */ public ByteBuffer[] bBounds = new ByteBuffer[ARRAY_CT]; + /** + * The array storing cached divergence data + */ + public ByteBuffer[] bDivergenceCache = new ByteBuffer[ARRAY_CT]; + + /** + * The array storing cached pressure data + */ + public ByteBuffer[] bScalarPotentialCache = new ByteBuffer[ARRAY_CT]; + /** * The array of pointers to neighboring chunks */ @@ -220,6 +230,8 @@ public class ServerFluidChunk { this.b0VelocityY[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN); this.b0VelocityZ[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN); this.bBounds[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN); + this.bDivergenceCache[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN); + this.bScalarPotentialCache[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN); //get float view this.weights = this.bWeights[CENTER_BUFF].asFloatBuffer(); @@ -528,6 +540,8 @@ public class ServerFluidChunk { b0VelocityY[index] = null; b0VelocityZ[index] = null; bBounds[index] = null; + bDivergenceCache[index] = null; + bScalarPotentialCache[index] = null; neighbors[index] = null; } else { bWeights[index] = neighbor.bWeights[CENTER_BUFF]; @@ -540,6 +554,8 @@ public class ServerFluidChunk { b0VelocityZ[index] = neighbor.b0VelocityZ[CENTER_BUFF]; b0VelocityZ[index] = neighbor.b0VelocityZ[CENTER_BUFF]; bBounds[index] = neighbor.bBounds[CENTER_BUFF]; + bDivergenceCache[index] = neighbor.bDivergenceCache[CENTER_BUFF]; + bScalarPotentialCache[index] = neighbor.bScalarPotentialCache[CENTER_BUFF]; neighbors[index] = neighbor; } } @@ -583,6 +599,8 @@ public class ServerFluidChunk { b0VelocityY[i] = null; b0VelocityZ[i] = null; bBounds[i] = null; + bDivergenceCache[i] = null; + bScalarPotentialCache[i] = null; } } diff --git a/src/test/c/fluid/sim/grid2/advect_projection_tests.c b/src/test/c/fluid/sim/grid2/advect_projection_tests.c index 03fbc455..97719c52 100644 --- a/src/test/c/fluid/sim/grid2/advect_projection_tests.c +++ b/src/test/c/fluid/sim/grid2/advect_projection_tests.c @@ -59,7 +59,7 @@ int fluid_sim_grid2_advect_projection_test1(){ fluid_grid2_flip_arrays(currentChunk->w,currentChunk->w0); ////project - fluid_grid2_setupProjection(env,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); + fluid_grid2_setupProjection(env,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); fluid_grid2_set_bounds(env,BOUND_SET_PROJECTION_PHI,currentChunk->u0[CENTER_LOC]); fluid_grid2_set_bounds(env,BOUND_SET_PROJECTION_PHI_0,currentChunk->v0[CENTER_LOC]); fluid_grid2_solveProjection(env,currentChunk,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); @@ -124,7 +124,7 @@ int fluid_sim_grid2_advect_projection_compute_error_over_time(){ fluid_grid2_flip_arrays(currentChunk->w,currentChunk->w0); ////project - fluid_grid2_setupProjection(env,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); + fluid_grid2_setupProjection(env,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); fluid_grid2_set_bounds(env,BOUND_SET_PROJECTION_PHI,currentChunk->u0[CENTER_LOC]); fluid_grid2_set_bounds(env,BOUND_SET_PROJECTION_PHI_0,currentChunk->v0[CENTER_LOC]); fluid_grid2_solveProjection(env,currentChunk,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); diff --git a/src/test/c/fluid/sim/grid2/border_diffusion_tests.c b/src/test/c/fluid/sim/grid2/border_diffusion_tests.c index 1f4f8c3e..451a3a91 100644 --- a/src/test/c/fluid/sim/grid2/border_diffusion_tests.c +++ b/src/test/c/fluid/sim/grid2/border_diffusion_tests.c @@ -274,10 +274,10 @@ int fluid_sim_grid2_border_diffusion_test6(){ int fluid_sim_grid2_border_diffusion_tests(int argc, char **argv){ int rVal = 0; - rVal += fluid_sim_grid2_border_diffusion_test1(); + // rVal += fluid_sim_grid2_border_diffusion_test1(); rVal += fluid_sim_grid2_border_diffusion_test2(); - rVal += fluid_sim_grid2_border_diffusion_test3(); - rVal += fluid_sim_grid2_border_diffusion_test4(); + // rVal += fluid_sim_grid2_border_diffusion_test3(); + // rVal += fluid_sim_grid2_border_diffusion_test4(); rVal += fluid_sim_grid2_border_diffusion_test5(); rVal += fluid_sim_grid2_border_diffusion_test6(); diff --git a/src/test/c/fluid/sim/grid2/finalize_projection_tests.c b/src/test/c/fluid/sim/grid2/finalize_projection_tests.c index 14e250d7..38d54e3d 100644 --- a/src/test/c/fluid/sim/grid2/finalize_projection_tests.c +++ b/src/test/c/fluid/sim/grid2/finalize_projection_tests.c @@ -35,7 +35,7 @@ int fluid_sim_grid2_finalize_projection_test1(){ //setup chunk values Chunk * currentChunk = queue[0]; currentChunk->u[CENTER_LOC][IX(3,3,3)] = 1.0f; - fluid_grid2_setupProjection(env,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); + fluid_grid2_setupProjection(env,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); fluid_grid2_solveProjection(env,currentChunk,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); fluid_grid2_set_bounds(env,BOUND_SET_PROJECTION_PHI,currentChunk->u0[CENTER_LOC]); diff --git a/src/test/c/fluid/sim/grid2/setup_projection_tests.c b/src/test/c/fluid/sim/grid2/setup_projection_tests.c index 067b1e3a..fe85bc15 100644 --- a/src/test/c/fluid/sim/grid2/setup_projection_tests.c +++ b/src/test/c/fluid/sim/grid2/setup_projection_tests.c @@ -38,7 +38,7 @@ int fluid_sim_grid2_setup_projection_test1(){ currentChunk->u[CENTER_LOC][IX(3,3,3)] = 1.0f; //actually simulate - fluid_grid2_setupProjection(env,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); + fluid_grid2_setupProjection(env,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); //test the result rVal += assertEqualsFloat(currentChunk->v0[CENTER_LOC][IX(2,3,3)],-0.5f * FLUID_GRID2_H,"Divergence of the vector field at 3,3,3 should be -0.5 * h! actual: %f expected: %f \n"); @@ -66,7 +66,7 @@ int fluid_sim_grid2_setup_projection_test2(){ currentChunk->u[CENTER_LOC][IX(3,3,3)] = -1.0f; //actually simulate - fluid_grid2_setupProjection(env,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); + fluid_grid2_setupProjection(env,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); //test the result rVal += assertEqualsFloat(currentChunk->v0[CENTER_LOC][IX(2,3,3)],0.5f * FLUID_GRID2_H,"Divergence of the vector field at 3,3,3 should be 0.5 * h! actual: %f expected: %f \n"); diff --git a/src/test/c/fluid/sim/grid2/solve_projection_tests.c b/src/test/c/fluid/sim/grid2/solve_projection_tests.c index f3b4f7c5..847ff911 100644 --- a/src/test/c/fluid/sim/grid2/solve_projection_tests.c +++ b/src/test/c/fluid/sim/grid2/solve_projection_tests.c @@ -35,7 +35,7 @@ int fluid_sim_grid2_solve_projection_test1(){ //setup chunk values Chunk * currentChunk = queue[0]; currentChunk->u[CENTER_LOC][IX(3,3,3)] = 1.0f; - fluid_grid2_setupProjection(env,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); + fluid_grid2_setupProjection(env,currentChunk,currentChunk->u,currentChunk->v,currentChunk->w,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); //actually solve fluid_grid2_solveProjection(env,currentChunk,currentChunk->u0,currentChunk->v0,FLUID_GRID2_SIM_STEP); diff --git a/src/test/c/fluid/sim/grid2/speed_tests.c b/src/test/c/fluid/sim/grid2/speed_tests.c index ac91f1b0..84850e9a 100644 --- a/src/test/c/fluid/sim/grid2/speed_tests.c +++ b/src/test/c/fluid/sim/grid2/speed_tests.c @@ -248,9 +248,9 @@ int fluid_sim_grid2_speed_test3(){ int fluid_sim_grid2_speed_tests(){ int rVal = 0; - rVal += fluid_sim_grid2_speed_test1(); - rVal += fluid_sim_grid2_speed_test2(); - rVal += fluid_sim_grid2_speed_test3(); +// rVal += fluid_sim_grid2_speed_test1(); +// rVal += fluid_sim_grid2_speed_test2(); +// rVal += fluid_sim_grid2_speed_test3(); return rVal; } \ No newline at end of file diff --git a/src/test/c/util/chunk_test_utils.c b/src/test/c/util/chunk_test_utils.c index defc0086..dc63c1ce 100644 --- a/src/test/c/util/chunk_test_utils.c +++ b/src/test/c/util/chunk_test_utils.c @@ -46,16 +46,20 @@ Chunk * chunk_create(int x, int y, int z){ chunk1->v0[i] = NULL; chunk1->w0[i] = NULL; chunk1->bounds[i] = NULL; + chunk1->scalarPotentialCache[i] = NULL; + chunk1->divergenceCache[i] = NULL; } - chunk1->d[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->d0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->u[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->v[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->w[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->u0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->v0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->w0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); - chunk1->bounds[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float)); + chunk1->d[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->d0[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->u[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->v[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->w[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->u0[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->v0[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->w0[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->bounds[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->scalarPotentialCache[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); + chunk1->divergenceCache[CENTER_LOC] = (float *)calloc(1,DIM * DIM * DIM * sizeof(float)); chunk1->x = x; chunk1->y = y; chunk1->z = z; @@ -75,6 +79,8 @@ void chunk_free(Chunk * chunk){ free(chunk->v0[CENTER_LOC]); free(chunk->w0[CENTER_LOC]); free(chunk->bounds[CENTER_LOC]); + free(chunk->scalarPotentialCache[CENTER_LOC]); + free(chunk->divergenceCache[CENTER_LOC]); free(chunk); } @@ -118,6 +124,8 @@ void chunk_fill(Chunk * chunk, float val){ chunk->v0[CENTER_LOC][i] = val; chunk->w0[CENTER_LOC][i] = val; chunk->bounds[CENTER_LOC][i] = val; + chunk->scalarPotentialCache[CENTER_LOC][i] = val; + chunk->divergenceCache[CENTER_LOC][i] = val; } } @@ -150,6 +158,8 @@ void chunk_link_by_index(Chunk * chunk1, Chunk * chunk2, int x, int y, int z){ chunk1->v0[CK(x,y,z)] = chunk2->v0[CENTER_LOC]; chunk1->w0[CK(x,y,z)] = chunk2->w0[CENTER_LOC]; chunk1->bounds[CK(x,y,z)] = chunk2->bounds[CENTER_LOC]; + chunk1->scalarPotentialCache[CK(x,y,z)] = chunk2->scalarPotentialCache[CENTER_LOC]; + chunk1->divergenceCache[CK(x,y,z)] = chunk2->divergenceCache[CENTER_LOC]; } /**