From e955c1f47930a8d79fd9e62752404870a883a052 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Sat, 2 Mar 2024 18:19:22 -0500 Subject: [PATCH] queueing logic without memleak allegedly --- src/main/c/includes/electrosphere_FluidSim.h | 120 +-- src/main/c/includes/libfluidsim.h | 4 - src/main/c/includes/threadpool.h | 30 + src/main/c/includes/utilities.h | 9 + src/main/c/src/threadpool.c | 118 ++- src/main/c/src/velocitystep.c | 2 +- src/main/java/electrosphere/FluidSim.java | 901 +++++++++---------- 7 files changed, 570 insertions(+), 614 deletions(-) diff --git a/src/main/c/includes/electrosphere_FluidSim.h b/src/main/c/includes/electrosphere_FluidSim.h index 067e495..ab43af0 100644 --- a/src/main/c/includes/electrosphere_FluidSim.h +++ b/src/main/c/includes/electrosphere_FluidSim.h @@ -17,110 +17,6 @@ extern "C" { #define electrosphere_FluidSim_LINEARSOLVERTIMES 20L #undef electrosphere_FluidSim_GRAVITY #define electrosphere_FluidSim_GRAVITY -100.0f -/* - * Class: electrosphere_FluidSim - * Method: simulate - * Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate - (JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: calculateChunkMask - * Signature: ([Ljava/nio/ByteBuffer;)I - */ -JNIEXPORT jint JNICALL Java_electrosphere_FluidSim_calculateChunkMask - (JNIEnv *, jobject, jobjectArray); - -/* - * Class: electrosphere_FluidSim - * Method: addSourceToVectors - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addSourceToVectors - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: solveVectorDiffuse - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveVectorDiffuse - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: setupProjection - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupProjection - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: solveProjection - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveProjection - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: finalizeProjection - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_finalizeProjection - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: advectVectors - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectVectors - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: addDensity - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;F)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addDensity - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: solveDiffuseDensity - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveDiffuseDensity - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: advectDensity - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectDensity - (JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); - -/* - * Class: electrosphere_FluidSim - * Method: setBoundsToNeighbors - * Signature: (III[Ljava/nio/ByteBuffer;)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setBoundsToNeighbors - (JNIEnv *, jobject, jint, jint, jint, jobjectArray); - -/* - * Class: electrosphere_FluidSim - * Method: copyNeighbors - * Signature: (IIII[Ljava/nio/ByteBuffer;)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_copyNeighbors - (JNIEnv *, jobject, jint, jint, jint, jint, jobjectArray); - /* * Class: electrosphere_FluidSim * Method: createThreadpool @@ -137,21 +33,29 @@ JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_unlockThreads (JNIEnv *, jclass, jlong); +/* + * Class: electrosphere_FluidSim + * Method: queueChunk + * Signature: (JII[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V + */ +JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk + (JNIEnv *, jclass, jlong, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat); + /* * Class: electrosphere_FluidSim * Method: submitWork - * Signature: ()V + * Signature: (J)V */ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_submitWork - (JNIEnv *, jclass); + (JNIEnv *, jclass, jlong); /* * Class: electrosphere_FluidSim * Method: fetchWork - * Signature: ()V + * Signature: (J)V */ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_fetchWork - (JNIEnv *, jclass); + (JNIEnv *, jclass, jlong); #ifdef __cplusplus } diff --git a/src/main/c/includes/libfluidsim.h b/src/main/c/includes/libfluidsim.h index 8e29b99..8ffa805 100644 --- a/src/main/c/includes/libfluidsim.h +++ b/src/main/c/includes/libfluidsim.h @@ -2,9 +2,5 @@ #ifndef LIB_FLUID_SIM #define LIB_FLUID_SIM -//include stb ds -#define STB_IMAGE_IMPLEMENTATION -#include "../lib/stb/stb_ds.h" - //close include guard #endif \ No newline at end of file diff --git a/src/main/c/includes/threadpool.h b/src/main/c/includes/threadpool.h index f38fe14..5691b6d 100644 --- a/src/main/c/includes/threadpool.h +++ b/src/main/c/includes/threadpool.h @@ -2,6 +2,9 @@ #define THREADPOOL +/** + * A threadpool used to distribute work +*/ typedef struct { int numThreads; pthread_t * threads; @@ -10,4 +13,31 @@ typedef struct { } ThreadPool; +/** + * A single chunk to have fluid simulated +*/ +typedef struct { + int chunkMask; + float * d; + float * u; + float * v; + float * w; + float * d0; + float * u0; + float * v0; + float * w0; +} Chunk; + + + +/** + * Overall state of the whole application +*/ +typedef struct { + ThreadPool * threadpool; + Chunk * chunks; + int numChunks; +} LibraryContext; + + #endif \ No newline at end of file diff --git a/src/main/c/includes/utilities.h b/src/main/c/includes/utilities.h index c20d38b..c10ba61 100644 --- a/src/main/c/includes/utilities.h +++ b/src/main/c/includes/utilities.h @@ -4,10 +4,19 @@ #ifndef UTILITIES_H #define UTILITIES_H +//swaps where two pointers are pointing #define SWAP(x0,x) {float *tmp=x0;x0=x;x=tmp;} + +//gets the index of a 3d point in an N^3 array #define IX(i,j,k) ((i)+(N)*(j)+(N*N)*(k)) + +//gets the index of a 3d point in a 3^3 array #define CK(m,n,o) ((m)+(n)*(3)+(o)*(3)*(3)) + +//gets the raw array of a java buffer #define GET_ARR(env,src,i) (*env)->GetDirectBufferAddress(env,(*env)->GetObjectArrayElement(env,src,i)) + +//returns true if the array exists, false otherwise #define ARR_EXISTS(chunk_mask,m,n,o) (chunk_mask & CHUNK_INDEX_ARR[CK(m,n,o)]) > 0 #endif \ No newline at end of file diff --git a/src/main/c/src/threadpool.c b/src/main/c/src/threadpool.c index 0aea6a7..cba4e4b 100644 --- a/src/main/c/src/threadpool.c +++ b/src/main/c/src/threadpool.c @@ -6,8 +6,15 @@ #include #include +//include stb ds +#define STB_DS_IMPLEMENTATION +#include "../lib/stb/stb_ds.h" + +//all other headers #include "../includes/libfluidsim.h" #include "../includes/threadpool.h" +#include "../includes/chunkmask.h" +#include "../includes/utilities.h" typedef struct { ThreadPool * threadPool; @@ -30,8 +37,12 @@ JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool jclass class, jint numThreads){ + LibraryContext * libraryContext = (LibraryContext *)malloc(sizeof(LibraryContext)); + libraryContext->numChunks = 0; + //init threadpool - ThreadPool * pool = (ThreadPool *)malloc(sizeof(ThreadPool)); + libraryContext->threadpool = (ThreadPool *)malloc(sizeof(ThreadPool)); + ThreadPool * pool = libraryContext->threadpool; pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * numThreads); pool->numThreads = numThreads; @@ -61,6 +72,7 @@ JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool //create data to be sent to thread ThreadData * threadData = (ThreadData *)malloc(sizeof(ThreadData)); threadData->threadPool = pool; + threadData->threadIndex = i; //create thread retCode = pthread_create(&pool->threads[i], NULL, mainThreadLoop, threadData); @@ -71,21 +83,106 @@ JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool printf("Finished creating threads\n"); - return (jlong)pool; + return (jlong)libraryContext; } /* - * Class: electrosphere_FluidSim - * Method: unlockThreads - * Signature: ()J + * Debug function */ -JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_unlockThreads - (JNIEnv * env, +JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_unlockThreads( + JNIEnv * env, jclass class, jlong threadPoolPtrRaw){ - ThreadPool * pool = (ThreadPool *)threadPoolPtrRaw; - pthread_barrier_wait(pool->barrierWithParentThread); + LibraryContext * libraryContext = (LibraryContext *)threadPoolPtrRaw; + pthread_barrier_wait(libraryContext->threadpool->barrierWithParentThread); +} + + +/* + * Queues a single chunk to do work + */ +JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk( + JNIEnv * env, + jclass class, + jlong libraryContextPtr, + jint DIM, + jint chunkMask, + jobjectArray dr, + jobjectArray d0r, + jobjectArray ur, + jobjectArray vr, + jobjectArray wr, + jobjectArray u0r, + jobjectArray v0r, + jobjectArray w0r, + jfloat DIFFUSION_CONSTANT, + jfloat VISCOSITY_CONSTANT, + jfloat timestep){ + LibraryContext * libraryContext = (LibraryContext *)libraryContextPtr; + + //if the array is full, malloc a new chunk, otherwise overwrite an existing one + int arrayCapacity = stbds_arrlen(libraryContext->chunks); + if(libraryContext->numChunks >= arrayCapacity){ + printf("%d > %d\n",libraryContext->numChunks,arrayCapacity); + Chunk * newChunk = (Chunk *)malloc(sizeof(Chunk)); + newChunk->chunkMask = chunkMask; + newChunk->u = GET_ARR(env,ur,CENTER_LOC); + newChunk->v = GET_ARR(env,vr,CENTER_LOC); + newChunk->w = GET_ARR(env,wr,CENTER_LOC); + newChunk->u0 = GET_ARR(env,u0r,CENTER_LOC); + newChunk->v0 = GET_ARR(env,v0r,CENTER_LOC); + newChunk->w0 = GET_ARR(env,w0r,CENTER_LOC); + newChunk->d = GET_ARR(env,dr,CENTER_LOC); + stbds_arrput(libraryContext->chunks,newChunk[0]); + newChunk->d0 = GET_ARR(env,d0r,CENTER_LOC); + } else { + Chunk * currentChunk = &libraryContext->chunks[libraryContext->numChunks]; + currentChunk->chunkMask = chunkMask; + currentChunk->u = GET_ARR(env,ur,CENTER_LOC); + currentChunk->v = GET_ARR(env,vr,CENTER_LOC); + currentChunk->w = GET_ARR(env,wr,CENTER_LOC); + currentChunk->u0 = GET_ARR(env,u0r,CENTER_LOC); + currentChunk->v0 = GET_ARR(env,v0r,CENTER_LOC); + currentChunk->w0 = GET_ARR(env,w0r,CENTER_LOC); + currentChunk->d = GET_ARR(env,dr,CENTER_LOC); + currentChunk->d0 = GET_ARR(env,d0r,CENTER_LOC); + } + + libraryContext->numChunks++; + // arrput(libraryContext->chunks,newChunk); +} + +/* + * Submits a request to the threadpool to do all the simulation + */ +JNIEXPORT void JNICALL Java_electrosphere_FluidSim_submitWork( + JNIEnv * env, + jclass class, + jlong contextPtr + ){ + LibraryContext * libraryContext = (LibraryContext *)contextPtr; + //begin work + //wait to begin work until parent signals its ready + pthread_barrier_wait(libraryContext->threadpool->barrierWithParentThread); +} + + +/* + * blocks until the simulation finishes, then grabs the results of the sim + */ +JNIEXPORT void JNICALL Java_electrosphere_FluidSim_fetchWork( + JNIEnv * env, + jclass class, + jlong contextPtr + ){ + LibraryContext * libraryContext = (LibraryContext *)contextPtr; + + //Roll threads over to the beginning of the workflow again, meanwhile do main thread cleanup work + pthread_barrier_wait(libraryContext->threadpool->barrierWithParentThread); + + //main thread does work to setup child chunks for receiving data here + libraryContext->numChunks = 0; } @@ -105,21 +202,18 @@ void * mainThreadLoop(void * dataRaw){ //begin work //wait to begin work until parent signals its ready - printf("call barrier 1\n"); pthread_barrier_wait(threadPool->barrierWithParentThread); //do main work //call this if the child threads need to wait on one another - printf("call barrier 2\n"); pthread_barrier_wait(threadPool->barrierMain); //finalize work //the parent thread needs to call the barrier as well with whatever method it uses to grab data from the sim back to java - printf("call barrier 3\n"); pthread_barrier_wait(threadPool->barrierWithParentThread); diff --git a/src/main/c/src/velocitystep.c b/src/main/c/src/velocitystep.c index 96e98aa..2939396 100644 --- a/src/main/c/src/velocitystep.c +++ b/src/main/c/src/velocitystep.c @@ -23,7 +23,7 @@ void advect(JNIEnv * env, uint32_t chunk_mask, int N, int b, jobjectArray jrd, j /* * Adds force to all vectors */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addSourceToVectors +void addSourceToVectors (JNIEnv * env, jobject this, jint N, diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index 9231778..c4d54f4 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -156,6 +156,7 @@ public class FluidSim { } } + static LinkedList simArrayList = new LinkedList(); public static void simChunks(FluidSim[][][] simArray, int step, float timestep){ // //init data for upcoming frame @@ -170,31 +171,45 @@ public class FluidSim { //Performs main fluid simulation logic // simArray[x][y][z].writeNewStateIntoBuffers(); + // + //flag this chunk as being simulated in the upcoming frame + simArrayList.add(simArray[x][y][z]); } } } - // - //Vector stage - solveChunkMask(simArray); - addVectorSources(simArray, timestep); - swapAllVectorFields(simArray, timestep); - solveVectorDiffusion(simArray, timestep); - solveProjection(simArray, step, timestep); - swapAllVectorFields(simArray, timestep); - advectVectorsAcrossBoundaries(simArray, timestep); - solveProjection(simArray, step, timestep); + //for each chunk, send them to C land + for(FluidSim chunk : simArrayList){ + queueChunkWrapper(threadpool, chunk, timestep); + } - // - //Density stage - addDensity(simArray, timestep); - swapAllDensityArrays(simArray, timestep); - diffuseDensity(simArray, timestep); - swapAllDensityArrays(simArray, timestep); - advectDensity(simArray, timestep); - // mirrorNeighborDensities(simArray, timestep); + //call for work to be done + submitWorkWrapper(threadpool); - + // // + // //Vector stage + // solveChunkMask(simArray); + // addVectorSources(simArray, timestep); + // swapAllVectorFields(simArray, timestep); + // solveVectorDiffusion(simArray, timestep); + // solveProjection(simArray, step, timestep); + // swapAllVectorFields(simArray, timestep); + // advectVectorsAcrossBoundaries(simArray, timestep); + // solveProjection(simArray, step, timestep); + + // // + // //Density stage + // addDensity(simArray, timestep); + // swapAllDensityArrays(simArray, timestep); + // diffuseDensity(simArray, timestep); + // swapAllDensityArrays(simArray, timestep); + // advectDensity(simArray, timestep); + // // mirrorNeighborDensities(simArray, timestep); + + //call for work to be done + fetchWorkWrapper(threadpool); + + simArrayList.clear(); // @@ -335,352 +350,352 @@ public class FluidSim { return rVal; } - private static void solveChunkMask(FluidSim[][][] simArray){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].calculateChunkMaskWrapper(); - } - } - } - } + // private static void solveChunkMask(FluidSim[][][] simArray){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].calculateChunkMaskWrapper(); + // } + // } + // } + // } - private static void addVectorSources(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ + // private static void addVectorSources(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ - //Add source to all 3 vectors - // add_source(N, u, u0, dt); - // add_source(N, v, v0, dt); - // add_source(N, w, w0, dt); - simArray[x][y][z].addSourceToVectorsWrapper(timestep); - } - } - } - //swap - //u <=> u0 etc for u, v, and w + // //Add source to all 3 vectors + // // add_source(N, u, u0, dt); + // // add_source(N, v, v0, dt); + // // add_source(N, w, w0, dt); + // simArray[x][y][z].addSourceToVectorsWrapper(timestep); + // } + // } + // } + // //swap + // //u <=> u0 etc for u, v, and w - } + // } - private static void solveVectorDiffusion(FluidSim[][][] simArray, float timestep){ - //samples u,v,w,u0,v0,w0 - //sets u,v,w - // for(int x = 0; x < simArray.length; x++){ - // for(int y = 0; y < simArray[0].length; y++){ - // for(int z = 0; z < simArray[0][0].length; z++){ - // simArray[x][y][z].copyNeighborsWrapper(1, simArray[x][y][z].uVector); - // simArray[x][y][z].copyNeighborsWrapper(2, simArray[x][y][z].vVector); - // simArray[x][y][z].copyNeighborsWrapper(3, simArray[x][y][z].wVector); - // simArray[x][y][z].copyNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); - // simArray[x][y][z].copyNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); - // simArray[x][y][z].copyNeighborsWrapper(3, simArray[x][y][z].wAdditionVector); - // } - // } - // } - for(int l = 0; l < LINEARSOLVERTIMES; l++){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - //lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a); - //+ - //set_bnd(env, chunk_mask, N, b, x); - //for u, v, and w all in 1 shot - simArray[x][y][z].solveVectorDiffuseWrapper(timestep); - } - } - } - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); - } - } - } - } - } + // private static void solveVectorDiffusion(FluidSim[][][] simArray, float timestep){ + // //samples u,v,w,u0,v0,w0 + // //sets u,v,w + // // for(int x = 0; x < simArray.length; x++){ + // // for(int y = 0; y < simArray[0].length; y++){ + // // for(int z = 0; z < simArray[0][0].length; z++){ + // // simArray[x][y][z].copyNeighborsWrapper(1, simArray[x][y][z].uVector); + // // simArray[x][y][z].copyNeighborsWrapper(2, simArray[x][y][z].vVector); + // // simArray[x][y][z].copyNeighborsWrapper(3, simArray[x][y][z].wVector); + // // simArray[x][y][z].copyNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); + // // simArray[x][y][z].copyNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); + // // simArray[x][y][z].copyNeighborsWrapper(3, simArray[x][y][z].wAdditionVector); + // // } + // // } + // // } + // for(int l = 0; l < LINEARSOLVERTIMES; l++){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // //lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a); + // //+ + // //set_bnd(env, chunk_mask, N, b, x); + // //for u, v, and w all in 1 shot + // simArray[x][y][z].solveVectorDiffuseWrapper(timestep); + // } + // } + // } + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); + // } + // } + // } + // } + // } - private static void solveProjection(FluidSim[][][] simArray, int step, float timestep){ - //samples u,v,w - //sets u0,v0 - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vAdditionVector); - } - } - } - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - // System.out.println("Setup " + x + " " + y + " " + z); - //setup projection across boundaries - //... - //set boundaries appropriately - //... - simArray[x][y][z].setupProjectionWrapper(timestep); - } - } - } - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].vAdditionVector); - } - } - } - //samples u0, v0 - //sets u0 - //these should have just been mirrored in the above - // - //Perform main projection solver - for(int l = 0; l < LINEARSOLVERTIMES; l++){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - //lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a); - //for u, v, and w all in 1 shot - simArray[x][y][z].solveProjectionWrapper(timestep); - } - } - } - //be sure to set boundaries to neighbor chunk values where appropriate - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].uAdditionVector); - } - } - } - } - //samples u,v,w,u0 - //sets u,v,w - //Finalize projection - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - //Subtract curl field from current vector field - //... - simArray[x][y][z].finalizeProjectionWrapper(timestep); - } - } - } - //set boundaries a final time for u,v,w - //... - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].wAdditionVector); - } - } - } - } + // private static void solveProjection(FluidSim[][][] simArray, int step, float timestep){ + // //samples u,v,w + // //sets u0,v0 + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vAdditionVector); + // } + // } + // } + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // // System.out.println("Setup " + x + " " + y + " " + z); + // //setup projection across boundaries + // //... + // //set boundaries appropriately + // //... + // simArray[x][y][z].setupProjectionWrapper(timestep); + // } + // } + // } + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].vAdditionVector); + // } + // } + // } + // //samples u0, v0 + // //sets u0 + // //these should have just been mirrored in the above + // // + // //Perform main projection solver + // for(int l = 0; l < LINEARSOLVERTIMES; l++){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // //lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a); + // //for u, v, and w all in 1 shot + // simArray[x][y][z].solveProjectionWrapper(timestep); + // } + // } + // } + // //be sure to set boundaries to neighbor chunk values where appropriate + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].uAdditionVector); + // } + // } + // } + // } + // //samples u,v,w,u0 + // //sets u,v,w + // //Finalize projection + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // //Subtract curl field from current vector field + // //... + // simArray[x][y][z].finalizeProjectionWrapper(timestep); + // } + // } + // } + // //set boundaries a final time for u,v,w + // //... + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].wAdditionVector); + // } + // } + // } + // } - private static void mirrorNeighborDensities(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].density); - } - } - } - } + // private static void mirrorNeighborDensities(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].density); + // } + // } + // } + // } - private static void swapAllVectorFields(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].swapVectorFields(); - } - } - } - //then need to mirror each array as relevant - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].wAdditionVector); - } - } - } - } + // private static void swapAllVectorFields(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].swapVectorFields(); + // } + // } + // } + // //then need to mirror each array as relevant + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].wAdditionVector); + // } + // } + // } + // } - private void swapVectorFields(){ - ByteBuffer tmp; - //swap x0 <-> x - // tmp = densityAddition; - // densityAddition = density[13]; - // density[13] = tmp; - //swap u0 <-> u - for(int i = 0; i < 27; i++){ - tmp = uAdditionVector[i]; - uAdditionVector[i] = uVector[i]; - uVector[i] = tmp; - //swap v0 <-> v - tmp = vAdditionVector[i]; - vAdditionVector[i] = vVector[i]; - vVector[i] = tmp; - //swap w0 <-> w - tmp = wAdditionVector[i]; - wAdditionVector[i] = wVector[i]; - wVector[i] = tmp; - } - //... - } + // private void swapVectorFields(){ + // ByteBuffer tmp; + // //swap x0 <-> x + // // tmp = densityAddition; + // // densityAddition = density[13]; + // // density[13] = tmp; + // //swap u0 <-> u + // for(int i = 0; i < 27; i++){ + // tmp = uAdditionVector[i]; + // uAdditionVector[i] = uVector[i]; + // uVector[i] = tmp; + // //swap v0 <-> v + // tmp = vAdditionVector[i]; + // vAdditionVector[i] = vVector[i]; + // vVector[i] = tmp; + // //swap w0 <-> w + // tmp = wAdditionVector[i]; + // wAdditionVector[i] = wVector[i]; + // wVector[i] = tmp; + // } + // //... + // } - private static void advectVectorsAcrossBoundaries(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vAdditionVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wAdditionVector); - } - } - } - //samples u,v,w,u0,v0,w0 - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - // advect(env, chunk_mask, N, 1, jru, u0, u0, v0, w0, dt); - // advect(env, chunk_mask, N, 2, jrv, v0, u0, v0, w0, dt); - // advect(env, chunk_mask, N, 3, jrw, w0, u0, v0, w0, dt); - //... - simArray[x][y][z].advectVectorsWrapper(timestep); - } - } - } - //mirror neighbor data - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); - simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); - simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); - simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); - simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); - } - } - } - } + // private static void advectVectorsAcrossBoundaries(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vAdditionVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wAdditionVector); + // } + // } + // } + // //samples u,v,w,u0,v0,w0 + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // // advect(env, chunk_mask, N, 1, jru, u0, u0, v0, w0, dt); + // // advect(env, chunk_mask, N, 2, jrv, v0, u0, v0, w0, dt); + // // advect(env, chunk_mask, N, 3, jrw, w0, u0, v0, w0, dt); + // //... + // simArray[x][y][z].advectVectorsWrapper(timestep); + // } + // } + // } + // //mirror neighbor data + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(1, simArray[x][y][z].uVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(2, simArray[x][y][z].vVector); + // simArray[x][y][z].setBoundsToNeighborsWrapper(3, simArray[x][y][z].wVector); + // simArray[x][y][z].copyNeighborsWrapper(1, x, simArray[x][y][z].uVector); + // simArray[x][y][z].copyNeighborsWrapper(2, x, simArray[x][y][z].vVector); + // simArray[x][y][z].copyNeighborsWrapper(3, x, simArray[x][y][z].wVector); + // } + // } + // } + // } - private static void addDensity(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - //add_source(N, x, x0, dt); - simArray[x][y][z].addDensityWrapper(timestep); - //swap x <=> x0 - //swap arrays in java side... - // simArray[x][y][z].swapDensityArrays(); - } - } - } - } + // private static void addDensity(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // //add_source(N, x, x0, dt); + // simArray[x][y][z].addDensityWrapper(timestep); + // //swap x <=> x0 + // //swap arrays in java side... + // // simArray[x][y][z].swapDensityArrays(); + // } + // } + // } + // } - private static void swapAllDensityArrays(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].swapDensityArrays(); - } - } - } - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].density); - simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].densityAddition); - } - } - } - } + // private static void swapAllDensityArrays(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].swapDensityArrays(); + // } + // } + // } + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].density); + // simArray[x][y][z].copyNeighborsWrapper(0, x, simArray[x][y][z].densityAddition); + // } + // } + // } + // } - private void swapDensityArrays(){ - for(int i = 0; i < 27; i++){ - ByteBuffer tmp = density[i]; - density[i] = densityAddition[i]; - densityAddition[i] = tmp; - } - } + // private void swapDensityArrays(){ + // for(int i = 0; i < 27; i++){ + // ByteBuffer tmp = density[i]; + // density[i] = densityAddition[i]; + // densityAddition[i] = tmp; + // } + // } - private static void diffuseDensity(FluidSim[][][] simArray, float timestep){ - for(int l = 0; l < LINEARSOLVERTIMES; l++){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - //lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a); - //+ - //set_bnd(env, chunk_mask, N, b, x); - simArray[x][y][z].solveDiffuseDensityWrapper(timestep); - } - } - } - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].density); - } - } - } - } - } + // private static void diffuseDensity(FluidSim[][][] simArray, float timestep){ + // for(int l = 0; l < LINEARSOLVERTIMES; l++){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // //lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a); + // //+ + // //set_bnd(env, chunk_mask, N, b, x); + // simArray[x][y][z].solveDiffuseDensityWrapper(timestep); + // } + // } + // } + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // simArray[x][y][z].setBoundsToNeighborsWrapper(0, simArray[x][y][z].density); + // } + // } + // } + // } + // } - private static void advectDensity(FluidSim[][][] simArray, float timestep){ - for(int x = 0; x < simArray.length; x++){ - for(int y = 0; y < simArray[0].length; y++){ - for(int z = 0; z < simArray[0][0].length; z++){ - //swap x <=> x0 again - // simArray[x][y][z].swapDensityArrays(); - //advect density - simArray[x][y][z].advectDensityWrapper(timestep); - } - } - } - } + // private static void advectDensity(FluidSim[][][] simArray, float timestep){ + // for(int x = 0; x < simArray.length; x++){ + // for(int y = 0; y < simArray[0].length; y++){ + // for(int z = 0; z < simArray[0][0].length; z++){ + // //swap x <=> x0 again + // // simArray[x][y][z].swapDensityArrays(); + // //advect density + // simArray[x][y][z].advectDensityWrapper(timestep); + // } + // } + // } + // } @@ -717,138 +732,6 @@ public class FluidSim { - /** - * The native function call to simulate a frame of fluid - * @param DIM_X - * @param DIM_Y - * @param DIM_Z - * @param x - * @param x0 - * @param u - * @param v - * @param w - * @param u0 - * @param v0 - * @param w0 - * @param DIFFUSION_CONSTANT - * @param VISCOSITY_CONSTANT - * @param timestep - */ - private native void simulate( - int DIM_X, - int chunkMask, - ByteBuffer[] x, - ByteBuffer x0, - ByteBuffer[] u, - ByteBuffer[] v, - ByteBuffer[] w, - ByteBuffer[] u0, - ByteBuffer[] v0, - ByteBuffer[] w0, - float DIFFUSION_CONSTANT, - float VISCOSITY_CONSTANT, - float timestep - ); - - private void calculateChunkMaskWrapper(){ - this.chunkMask = this.calculateChunkMask(density); - } - /** - * Calculates the mask of chunk neighbors - * @param densityBuffers The neighbor array - * @return The mask - */ - private native int calculateChunkMask(ByteBuffer[] densityBuffers); - - /** - * Add vector values to u, v, and w all at once - */ - private void addSourceToVectorsWrapper(float timestep){ - addSourceToVectors(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void addSourceToVectors(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0[], ByteBuffer v0[], ByteBuffer w0[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Solves u, v, and w diffusion systems of equations - */ - private void solveVectorDiffuseWrapper(float timestep){ - solveVectorDiffuse(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void solveVectorDiffuse(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0[], ByteBuffer v0[], ByteBuffer w0[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Setup projection system - */ - private void setupProjectionWrapper(float timestep){ - setupProjection(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void setupProjection(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0[], ByteBuffer v0[], ByteBuffer w0[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Solve projection system - */ - private void solveProjectionWrapper(float timestep){ - solveProjection(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void solveProjection(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0[], ByteBuffer v0[], ByteBuffer w0[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Does work like subtracting curl from vector field, setting boundaries, etc - */ - private void finalizeProjectionWrapper(float timestep){ - finalizeProjection(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void finalizeProjection(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0[], ByteBuffer v0[], ByteBuffer w0[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Advects vectors - */ - private void advectVectorsWrapper(float timestep){ - advectVectors(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void advectVectors(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0[], ByteBuffer v0[], ByteBuffer w0[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Adds density to the simulation - */ - private void addDensityWrapper(float timestep){ - addDensity(DIM, chunkMask, density, densityAddition, timestep); - } - private native void addDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer[] x0, float timestep); - - /** - * Solve density diffusion - */ - private void solveDiffuseDensityWrapper(float timestep){ - solveDiffuseDensity(DIM, chunkMask, density, densityAddition, uVector, vVector, wVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void solveDiffuseDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer[] x0, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - /** - * Solve density diffusion - */ - private void advectDensityWrapper(float timestep){ - advectDensity(DIM, chunkMask, density, densityAddition, uVector, vVector, wVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep); - } - private native void advectDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer[] x0, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep); - - - /** - * Sets the bounds of the neighbormap to neighbor values if available - */ - private void setBoundsToNeighborsWrapper(int vectorDir, ByteBuffer[] neighborMap){ - setBoundsToNeighbors(DIM, chunkMask, vectorDir, neighborMap); - } - private native void setBoundsToNeighbors(int DIM_X, int chunkMask, int vectorDir, ByteBuffer[] neighborMap); - - /** - * Sets the bounds of the neighbormap to neighbor values if available, otherwise doesn't mess with them. - * This is to make sure zeroing out doesn't mess up the sim - */ - private void copyNeighborsWrapper(int vectorDir, int x, ByteBuffer[] neighborMap){ - copyNeighbors(DIM, chunkMask, x, vectorDir, neighborMap); - } - private native void copyNeighbors(int DIM_X, int chunkMask, int x, int vectorDir, ByteBuffer[] neighborMap); /** @@ -869,21 +752,61 @@ public class FluidSim { private static native long unlockThreads(long threadPoolPtr); + /** + * Queues a single chunk to be simulated this frame + * @param chunk The chunk + * @param timestep The amount of time to simulate it for + */ + public static void queueChunkWrapper(long libraryContext, FluidSim chunk, float timestep){ + queueChunk( + libraryContext, + DIM, + chunk.chunkMask, + chunk.density, + chunk.densityAddition, + chunk.uVector, + chunk.vVector, + chunk.wVector, + chunk.uAdditionVector, + chunk.vAdditionVector, + chunk.wAdditionVector, + DIFFUSION_CONSTANT, + VISCOSITY_CONSTANT, + timestep + ); + } + public static native void queueChunk( + long libraryContext, + int DIM_X, + int chunkMask, + ByteBuffer[] d, + ByteBuffer[] d0, + ByteBuffer[] u, + ByteBuffer[] v, + ByteBuffer[] w, + ByteBuffer[] u0, + ByteBuffer[] v0, + ByteBuffer[] w0, + float DIFFUSION_CONSTANT, + float VISCOSITY_CONSTANT, + float timestep + ); + /** * Sends work to the threadpool */ - public static void submitWorkWrapper(){ - submitWork(); + public static void submitWorkWrapper(long contextPtr){ + submitWork(contextPtr); } - public static native void submitWork(); + public static native void submitWork(long contextPtr); /** * Fetches work from the threadpool */ - public static void fetchWorkWrapper(){ - fetchWork(); + public static void fetchWorkWrapper(long contextPtr){ + fetchWork(contextPtr); } - public static native void fetchWork(); + public static native void fetchWork(long contextPtr);