From 4bbc4883b60708bde0b13a35f2116c399eddb91e Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 29 Feb 2024 20:54:47 -0500 Subject: [PATCH 1/9] reorg + add stb dependency --- .gitignore | 3 ++- .gitmodules | 3 +++ src/main/c/compile.sh | 6 +++--- src/main/c/includes/libfluidsim.h | 10 ++++++++++ src/main/c/lib/stb | 1 + src/main/c/{ => src}/chunkmask.c | 5 +++-- src/main/c/{ => src}/densitystep.c | 18 ++++++++++-------- src/main/c/{ => src}/velocitystep.c | 5 +++-- src/main/java/electrosphere/Main.java | 6 +++--- 9 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 .gitmodules create mode 100644 src/main/c/includes/libfluidsim.h create mode 160000 src/main/c/lib/stb rename src/main/c/{ => src}/chunkmask.c (95%) rename src/main/c/{ => src}/densitystep.c (95%) rename src/main/c/{ => src}/velocitystep.c (99%) diff --git a/.gitignore b/.gitignore index 03cd192..87109a8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ /.project /.vscode /shared-folder -/shared-folder/** \ No newline at end of file +/shared-folder/** +/src/main/c/lib/** \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a8537d2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/main/c/lib/stb"] + path = src/main/c/lib/stb + url = https://github.com/nothings/stb.git diff --git a/src/main/c/compile.sh b/src/main/c/compile.sh index c02b26a..f210ea5 100644 --- a/src/main/c/compile.sh +++ b/src/main/c/compile.sh @@ -42,17 +42,17 @@ rm -f ./*.dll #compile object files COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -O1" -INPUT_FILES="./densitystep.c" +INPUT_FILES="./src/densitystep.c" OUTPUT_FILE="./densitystep.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -O1" -INPUT_FILES="./velocitystep.c" +INPUT_FILES="./src/velocitystep.c" OUTPUT_FILE="./velocitystep.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -O1" -INPUT_FILES="./chunkmask.c" +INPUT_FILES="./src/chunkmask.c" OUTPUT_FILE="./chunkmask.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE diff --git a/src/main/c/includes/libfluidsim.h b/src/main/c/includes/libfluidsim.h new file mode 100644 index 0000000..8e29b99 --- /dev/null +++ b/src/main/c/includes/libfluidsim.h @@ -0,0 +1,10 @@ +//include guard +#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/lib/stb b/src/main/c/lib/stb new file mode 160000 index 0000000..ae721c5 --- /dev/null +++ b/src/main/c/lib/stb @@ -0,0 +1 @@ +Subproject commit ae721c50eaf761660b4f90cc590453cdb0c2acd0 diff --git a/src/main/c/chunkmask.c b/src/main/c/src/chunkmask.c similarity index 95% rename from src/main/c/chunkmask.c rename to src/main/c/src/chunkmask.c index 06f879f..1e22832 100644 --- a/src/main/c/chunkmask.c +++ b/src/main/c/src/chunkmask.c @@ -1,7 +1,8 @@ #include #include -#include "includes/utilities.h" -#include "includes/chunkmask.h" +#include "../includes/libfluidsim.h" +#include "../includes/utilities.h" +#include "../includes/chunkmask.h" uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx); diff --git a/src/main/c/densitystep.c b/src/main/c/src/densitystep.c similarity index 95% rename from src/main/c/densitystep.c rename to src/main/c/src/densitystep.c index 787dc5b..b83af0d 100644 --- a/src/main/c/densitystep.c +++ b/src/main/c/src/densitystep.c @@ -2,9 +2,11 @@ #include #include #include +#include -#include "includes/utilities.h" -#include "includes/chunkmask.h" +#include "../includes/libfluidsim.h" +#include "../includes/utilities.h" +#include "../includes/chunkmask.h" void advectDensity(JNIEnv * env, uint32_t chunk_mask, int N, int b, jobjectArray jrd, jobjectArray d0, float * u, float * v, float * w, float dt); @@ -127,12 +129,12 @@ void advectDensity(JNIEnv * env, uint32_t chunk_mask, int N, int b, jobjectArray m = n = o = 1; - if(x < 1){ m -= 1; } - if(x >= N-1){ m += 1; } - if(y < 1){ n -= 1; } - if(y >= N-1){ n += 1; } - if(z < 1){ o -= 1; } - if(z >= N-1){ o += 1; } + // if(x < 1){ m -= 1; } + // if(x >= N-1){ m += 1; } + // if(y < 1){ n -= 1; } + // if(y >= N-1){ n += 1; } + // if(z < 1){ o -= 1; } + // if(z >= N-1){ o += 1; } //If the out of bounds coordinate is in bounds for a neighbor chunk, use that chunk as source instead // if(CK(m,n,o) != CENTER_LOC){ diff --git a/src/main/c/velocitystep.c b/src/main/c/src/velocitystep.c similarity index 99% rename from src/main/c/velocitystep.c rename to src/main/c/src/velocitystep.c index e731d2b..96e98aa 100644 --- a/src/main/c/velocitystep.c +++ b/src/main/c/src/velocitystep.c @@ -3,8 +3,9 @@ #include #include -#include "includes/utilities.h" -#include "includes/chunkmask.h" +#include "../includes/libfluidsim.h" +#include "../includes/utilities.h" +#include "../includes/chunkmask.h" #define BOUND_NO_DIR 0 diff --git a/src/main/java/electrosphere/Main.java b/src/main/java/electrosphere/Main.java index 0d7440b..ce8ce63 100644 --- a/src/main/java/electrosphere/Main.java +++ b/src/main/java/electrosphere/Main.java @@ -22,7 +22,7 @@ public class Main { public static void main(String args[]){ - int dim = 5; + int dim = 10; int i = 0; long time = 0; long lastTime = 0; @@ -36,9 +36,9 @@ public class Main { Mesh.initShaderProgram(); - FluidSim[][][] simArray = initFluidSim(dim,1,dim); + FluidSim[][][] simArray = initFluidSim(dim,1,1); - Mesh[][][] meshArray = initMeshes(dim,1,dim,simArray); + Mesh[][][] meshArray = initMeshes(dim,1,1,simArray); From 08c95a376a765bc427afeaf8f7e2e7a44954a2bb Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 29 Feb 2024 20:59:07 -0500 Subject: [PATCH 2/9] add jenkinsfile --- Jenkinsfile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..742f429 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,15 @@ +pipeline { + agent any + tools { + maven '3.9.6' + } + stages { + stage('Build') { + steps { + sh 'mvn --version' + sh 'java -version' + sh 'mvn clean generate-resources package' + } + } + } +} \ No newline at end of file From eae31e2ec3b6df438489c7a2f9eb3adc2db6d08b Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 29 Feb 2024 20:59:32 -0500 Subject: [PATCH 3/9] update jenkinsfile --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 742f429..79d7b79 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,6 +8,8 @@ pipeline { steps { sh 'mvn --version' sh 'java -version' + sh 'apt-get update' + sh 'apt-get install gcc' sh 'mvn clean generate-resources package' } } From 0794c889900bdc0f9d231259530a5e3d4892d8d5 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 29 Feb 2024 21:13:36 -0500 Subject: [PATCH 4/9] Jenkinsfile update --- Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 79d7b79..742f429 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,8 +8,6 @@ pipeline { steps { sh 'mvn --version' sh 'java -version' - sh 'apt-get update' - sh 'apt-get install gcc' sh 'mvn clean generate-resources package' } } From 1e16151860b452b9b80572cc3490e45278ca32e7 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 29 Feb 2024 21:20:59 -0500 Subject: [PATCH 5/9] properly init stb with jenkins --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 742f429..229b18c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,6 +8,8 @@ pipeline { steps { sh 'mvn --version' sh 'java -version' + sh 'git submodule init' + sh 'git submodule update' sh 'mvn clean generate-resources package' } } From 2dc54a81869d487490b72bf1e5789ee1e4485336 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 29 Feb 2024 22:22:50 -0500 Subject: [PATCH 6/9] Create threadpool in c land --- src/main/c/compile.sh | 7 ++- src/main/c/includes/electrosphere_FluidSim.h | 8 ++++ src/main/c/includes/threadpool.h | 11 +++++ src/main/c/src/densitystep.c | 1 - src/main/c/src/threadpool.c | 45 ++++++++++++++++++++ src/main/java/electrosphere/FluidSim.java | 8 ++++ src/main/java/electrosphere/Main.java | 2 + 7 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/main/c/includes/threadpool.h create mode 100644 src/main/c/src/threadpool.c diff --git a/src/main/c/compile.sh b/src/main/c/compile.sh index f210ea5..12cc9cf 100644 --- a/src/main/c/compile.sh +++ b/src/main/c/compile.sh @@ -56,12 +56,17 @@ INPUT_FILES="./src/chunkmask.c" OUTPUT_FILE="./chunkmask.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE +COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -O1" +INPUT_FILES="./src/threadpool.c" +OUTPUT_FILE="./threadpool.o" +gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE + #compile shared object file OUTPUT_FILE="libfluidsim$LIB_ENDING" COMPILE_FLAGS="-shared" -INPUT_FILES="densitystep.o velocitystep.o chunkmask.o" +INPUT_FILES="densitystep.o velocitystep.o chunkmask.o threadpool.o" gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE #move to resources diff --git a/src/main/c/includes/electrosphere_FluidSim.h b/src/main/c/includes/electrosphere_FluidSim.h index 4d2531b..c9fdbfa 100644 --- a/src/main/c/includes/electrosphere_FluidSim.h +++ b/src/main/c/includes/electrosphere_FluidSim.h @@ -121,6 +121,14 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setBoundsToNeighbors JNIEXPORT void JNICALL Java_electrosphere_FluidSim_copyNeighbors (JNIEnv *, jobject, jint, jint, jint, jint, jobjectArray); +/* + * Class: electrosphere_FluidSim + * Method: createThreadpool + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool + (JNIEnv *, jclass, jint); + #ifdef __cplusplus } #endif diff --git a/src/main/c/includes/threadpool.h b/src/main/c/includes/threadpool.h new file mode 100644 index 0000000..6698e65 --- /dev/null +++ b/src/main/c/includes/threadpool.h @@ -0,0 +1,11 @@ +#ifndef THREADPOOL +#define THREADPOOL + + +typedef struct { + int numThreads; + pthread_t * threads; +} ThreadPool; + + +#endif \ No newline at end of file diff --git a/src/main/c/src/densitystep.c b/src/main/c/src/densitystep.c index b83af0d..c318aa5 100644 --- a/src/main/c/src/densitystep.c +++ b/src/main/c/src/densitystep.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "../includes/libfluidsim.h" #include "../includes/utilities.h" diff --git a/src/main/c/src/threadpool.c b/src/main/c/src/threadpool.c new file mode 100644 index 0000000..c24eb0b --- /dev/null +++ b/src/main/c/src/threadpool.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include + +#include "../includes/libfluidsim.h" +#include "../includes/threadpool.h" + + +/** + * Main loops for the thread +*/ +void * main_thread_loop(void * data); + +/* + * Class: electrosphere_FluidSim + * Method: createThreadpool + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool + (JNIEnv * env, + jclass class, + jint numThreads){ + ThreadPool * pool = (ThreadPool *)malloc(sizeof(ThreadPool)); + pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * numThreads); + pool->numThreads = numThreads; + int retCode = 0; + for(int i = 0; i < pool->numThreads; i++){ + retCode = pthread_create(&pool->threads[i], NULL, main_thread_loop, NULL); + // printf("thread ret code %d\n",retCode); + } + + for(int i = 0; i < pool->numThreads; i++){ + pthread_join(pool->threads[i], NULL); + printf("resolve thread\n"); + } +} + + +void * main_thread_loop(void * data){ + printf("thread work\n"); + sleep(1); +} \ No newline at end of file diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index 862dfff..5d4c178 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -70,6 +70,8 @@ public class FluidSim { float[] w0ArrayView = new float[DIM * DIM * DIM]; int chunkMask = 0; + + public static long threadpool; static final float DIFFUSION_CONSTANT = 0.0f; @@ -849,6 +851,12 @@ public class FluidSim { private native void copyNeighbors(int DIM_X, int chunkMask, int x, int vectorDir, ByteBuffer[] neighborMap); + public static long createThreadpoolWrapper(int numThreads){ + return createThreadpool(numThreads); + } + private static native long createThreadpool(int numThreads); + + diff --git a/src/main/java/electrosphere/Main.java b/src/main/java/electrosphere/Main.java index ce8ce63..d6f8c35 100644 --- a/src/main/java/electrosphere/Main.java +++ b/src/main/java/electrosphere/Main.java @@ -83,6 +83,8 @@ public class Main { } private static FluidSim[][][] initFluidSim(int dimx, int dimy, int dimz){ + FluidSim.threadpool = FluidSim.createThreadpoolWrapper(5); + FluidSim[][][] simArray = new FluidSim[dimx][dimy][dimz]; for(int x = 0; x < simArray.length; x++){ for(int y = 0; y < simArray[0].length; y++){ From 0a15bf062c3068006f093ed2065ca0fc335e8999 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Fri, 1 Mar 2024 19:17:27 -0500 Subject: [PATCH 7/9] proper thread batching --- README.md | 5 + src/main/c/includes/electrosphere_FluidSim.h | 24 +++++ src/main/c/includes/threadpool.h | 2 + src/main/c/src/threadpool.c | 104 +++++++++++++++++-- src/main/java/electrosphere/FluidSim.java | 29 ++++++ src/main/java/electrosphere/Main.java | 3 +- 6 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..2d7c1b7 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ + + + +dependencies: + - pthread \ No newline at end of file diff --git a/src/main/c/includes/electrosphere_FluidSim.h b/src/main/c/includes/electrosphere_FluidSim.h index c9fdbfa..067e495 100644 --- a/src/main/c/includes/electrosphere_FluidSim.h +++ b/src/main/c/includes/electrosphere_FluidSim.h @@ -129,6 +129,30 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_copyNeighbors JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool (JNIEnv *, jclass, jint); +/* + * Class: electrosphere_FluidSim + * Method: unlockThreads + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_unlockThreads + (JNIEnv *, jclass, jlong); + +/* + * Class: electrosphere_FluidSim + * Method: submitWork + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_FluidSim_submitWork + (JNIEnv *, jclass); + +/* + * Class: electrosphere_FluidSim + * Method: fetchWork + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_FluidSim_fetchWork + (JNIEnv *, jclass); + #ifdef __cplusplus } #endif diff --git a/src/main/c/includes/threadpool.h b/src/main/c/includes/threadpool.h index 6698e65..f38fe14 100644 --- a/src/main/c/includes/threadpool.h +++ b/src/main/c/includes/threadpool.h @@ -5,6 +5,8 @@ typedef struct { int numThreads; pthread_t * threads; + pthread_barrier_t * barrierMain; + pthread_barrier_t * barrierWithParentThread; } ThreadPool; diff --git a/src/main/c/src/threadpool.c b/src/main/c/src/threadpool.c index c24eb0b..0aea6a7 100644 --- a/src/main/c/src/threadpool.c +++ b/src/main/c/src/threadpool.c @@ -4,15 +4,21 @@ #include #include #include +#include #include "../includes/libfluidsim.h" #include "../includes/threadpool.h" +typedef struct { + ThreadPool * threadPool; + int threadIndex; //the index for this thread in all threadpool objects +} ThreadData; + /** * Main loops for the thread */ -void * main_thread_loop(void * data); +void * mainThreadLoop(void * data); /* * Class: electrosphere_FluidSim @@ -23,23 +29,99 @@ JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool (JNIEnv * env, jclass class, jint numThreads){ + + //init threadpool ThreadPool * pool = (ThreadPool *)malloc(sizeof(ThreadPool)); pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * numThreads); pool->numThreads = numThreads; + + //used for storing return codes from pthread calls int retCode = 0; - for(int i = 0; i < pool->numThreads; i++){ - retCode = pthread_create(&pool->threads[i], NULL, main_thread_loop, NULL); - // printf("thread ret code %d\n",retCode); + + // + //create thread barriers + printf("Creating barrier for %d threads\n",pool->numThreads); + pool->barrierMain = (pthread_barrier_t *)malloc(sizeof(pthread_barrier_t)); + retCode = pthread_barrier_init(pool->barrierMain,NULL,pool->numThreads); + if(retCode != 0){ + printf("Failed to create main barrier! %d\n",retCode); } - - for(int i = 0; i < pool->numThreads; i++){ - pthread_join(pool->threads[i], NULL); - printf("resolve thread\n"); + + //+1 is for the main thread + printf("Creating barrier for %d threads\n",pool->numThreads+1); + pool->barrierWithParentThread = (pthread_barrier_t *)malloc(sizeof(pthread_barrier_t)); + retCode = pthread_barrier_init(pool->barrierWithParentThread,NULL,(pool->numThreads)+1); + if(retCode != 0){ + printf("Failed to create barrier with main thread! %d\n",retCode); } + + //start threads + for(int i = 0; i < pool->numThreads; i++){ + + //create data to be sent to thread + ThreadData * threadData = (ThreadData *)malloc(sizeof(ThreadData)); + threadData->threadPool = pool; + + //create thread + retCode = pthread_create(&pool->threads[i], NULL, mainThreadLoop, threadData); + if(retCode != 0){ + printf("Failed to create thread!~ %d\n",retCode); + } + } + + printf("Finished creating threads\n"); + + return (jlong)pool; } -void * main_thread_loop(void * data){ - printf("thread work\n"); - sleep(1); +/* + * Class: electrosphere_FluidSim + * Method: unlockThreads + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_unlockThreads + (JNIEnv * env, + jclass class, + jlong threadPoolPtrRaw){ + ThreadPool * pool = (ThreadPool *)threadPoolPtrRaw; + pthread_barrier_wait(pool->barrierWithParentThread); +} + + +/** + * Main loop for threads +*/ +void * mainThreadLoop(void * dataRaw){ + ThreadData * threadData = (ThreadData *)dataRaw; + ThreadPool * threadPool = threadData->threadPool; + int threadIndex = threadData->threadIndex; + + printf("thread work\n"); + + //main thread loop + int running = 1; + while(running){ + + //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); + + + } } \ No newline at end of file diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index 5d4c178..9231778 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -851,12 +851,41 @@ public class FluidSim { private native void copyNeighbors(int DIM_X, int chunkMask, int x, int vectorDir, ByteBuffer[] neighborMap); + /** + * Creates the thread pool for handling main work of the c lib + */ public static long createThreadpoolWrapper(int numThreads){ return createThreadpool(numThreads); } private static native long createThreadpool(int numThreads); + /** + * Unlocks the C threadpool + */ + public static long unlockThreadsWrapper(){ + return unlockThreads(threadpool); + } + private static native long unlockThreads(long threadPoolPtr); + + + /** + * Sends work to the threadpool + */ + public static void submitWorkWrapper(){ + submitWork(); + } + public static native void submitWork(); + + /** + * Fetches work from the threadpool + */ + public static void fetchWorkWrapper(){ + fetchWork(); + } + public static native void fetchWork(); + + diff --git a/src/main/java/electrosphere/Main.java b/src/main/java/electrosphere/Main.java index d6f8c35..e3c064c 100644 --- a/src/main/java/electrosphere/Main.java +++ b/src/main/java/electrosphere/Main.java @@ -55,7 +55,9 @@ public class Main { // //Simulate // + FluidSim.unlockThreadsWrapper(); FluidSim.simChunks(simArray,i,0.01f); + FluidSim.unlockThreadsWrapper(); time = time + (System.currentTimeMillis() - lastTime); // //Remesh @@ -84,7 +86,6 @@ public class Main { private static FluidSim[][][] initFluidSim(int dimx, int dimy, int dimz){ FluidSim.threadpool = FluidSim.createThreadpoolWrapper(5); - FluidSim[][][] simArray = new FluidSim[dimx][dimy][dimz]; for(int x = 0; x < simArray.length; x++){ for(int y = 0; y < simArray[0].length; y++){ From e955c1f47930a8d79fd9e62752404870a883a052 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Sat, 2 Mar 2024 18:19:22 -0500 Subject: [PATCH 8/9] 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); From 62373d266c2dc9f9a6e215bf86a214c52bbd588a Mon Sep 17 00:00:00 2001 From: unknown <> Date: Sat, 2 Mar 2024 21:51:47 -0500 Subject: [PATCH 9/9] density not crashing, but broken --- src/main/c/compile.sh | 7 +- src/main/c/includes/electrosphere_FluidSim.h | 2 +- src/main/c/includes/libfluidsim.h | 10 ++ src/main/c/includes/threadpool.h | 5 + src/main/c/src/densitystep.c | 84 +++------- src/main/c/src/libfluidsim.c | 77 +++++++++ src/main/c/src/threadpool.c | 29 ++-- src/main/java/electrosphere/FluidSim.java | 161 ++++++++++++++++++- src/main/java/electrosphere/Main.java | 2 +- 9 files changed, 296 insertions(+), 81 deletions(-) create mode 100644 src/main/c/src/libfluidsim.c diff --git a/src/main/c/compile.sh b/src/main/c/compile.sh index 12cc9cf..377e06d 100644 --- a/src/main/c/compile.sh +++ b/src/main/c/compile.sh @@ -61,12 +61,17 @@ INPUT_FILES="./src/threadpool.c" OUTPUT_FILE="./threadpool.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE +COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -O1" +INPUT_FILES="./src/libfluidsim.c" +OUTPUT_FILE="./libfluidsim.o" +gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE + #compile shared object file OUTPUT_FILE="libfluidsim$LIB_ENDING" COMPILE_FLAGS="-shared" -INPUT_FILES="densitystep.o velocitystep.o chunkmask.o threadpool.o" +INPUT_FILES="densitystep.o velocitystep.o chunkmask.o threadpool.o libfluidsim.o" gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE #move to resources diff --git a/src/main/c/includes/electrosphere_FluidSim.h b/src/main/c/includes/electrosphere_FluidSim.h index ab43af0..261b3e7 100644 --- a/src/main/c/includes/electrosphere_FluidSim.h +++ b/src/main/c/includes/electrosphere_FluidSim.h @@ -16,7 +16,7 @@ extern "C" { #undef electrosphere_FluidSim_LINEARSOLVERTIMES #define electrosphere_FluidSim_LINEARSOLVERTIMES 20L #undef electrosphere_FluidSim_GRAVITY -#define electrosphere_FluidSim_GRAVITY -100.0f +#define electrosphere_FluidSim_GRAVITY 0.0f /* * Class: electrosphere_FluidSim * Method: createThreadpool diff --git a/src/main/c/includes/libfluidsim.h b/src/main/c/includes/libfluidsim.h index 8ffa805..07baad8 100644 --- a/src/main/c/includes/libfluidsim.h +++ b/src/main/c/includes/libfluidsim.h @@ -2,5 +2,15 @@ #ifndef LIB_FLUID_SIM #define LIB_FLUID_SIM +#include "./threadpool.h" + +void simulate(LibraryContext * context, int threadIndex); + +void addDensity(int N, int chunk_mask, float * jrx, float * x0, float dt); + +void diffuseDensity(int N, int chunk_mask, float * jrx, float * jrx0, float DIFFUSION_CONST, float VISCOSITY_CONST, float dt); + +void advectDensity(uint32_t chunk_mask, int N, float * jrd, float * jrd0, float * u, float * v, float * w, float dt); + //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 5691b6d..73ae0a6 100644 --- a/src/main/c/includes/threadpool.h +++ b/src/main/c/includes/threadpool.h @@ -1,6 +1,8 @@ #ifndef THREADPOOL #define THREADPOOL +#include + /** * A threadpool used to distribute work @@ -18,6 +20,7 @@ typedef struct { */ typedef struct { int chunkMask; + float timestep; float * d; float * u; float * v; @@ -26,6 +29,8 @@ typedef struct { float * u0; float * v0; float * w0; + float diffuseConst; + float viscosityConst; } Chunk; diff --git a/src/main/c/src/densitystep.c b/src/main/c/src/densitystep.c index c318aa5..8216786 100644 --- a/src/main/c/src/densitystep.c +++ b/src/main/c/src/densitystep.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -7,53 +6,35 @@ #include "../includes/utilities.h" #include "../includes/chunkmask.h" -void advectDensity(JNIEnv * env, uint32_t chunk_mask, int N, int b, jobjectArray jrd, jobjectArray d0, float * u, float * v, float * w, float dt); -/* - * Class: electrosphere_FluidSim - * Method: addDensity - * Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;F)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addDensity - (JNIEnv * env, - jobject this, - jint N, - jint chunk_mask, - jobjectArray jrx, - jobjectArray x0, - jfloat dt){ +void addDensity( + int N, + int chunk_mask, + float * x, + float * s, + float dt){ int i; int size=N*N*N; - float * x = GET_ARR(env,jrx,CENTER_LOC); - float * s = GET_ARR(env,x0,CENTER_LOC); for(i=0; i +#include +#include +#include +#include +#include +#include + +//git libs +#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" + +#define DIM 18 +#define LINEARSOLVERTIMES 20 + + +//call this if the child threads need to wait on one another +void sync(LibraryContext * context){ + pthread_barrier_wait(context->threadpool->barrierMain); +} + +/** + * Main simulation function +*/ +void simulate(LibraryContext * context, int threadIndex){ + int numThreads = context->threadpool->numThreads; + int numChunks = context->numChunks; + + //add densities to chunks + for(int i = threadIndex; i < numChunks; i = i + numThreads){ + Chunk chunk = context->chunks[i]; + addDensity(DIM,chunk.chunkMask,chunk.d,chunk.d0,chunk.timestep); + } + sync(context); + + //diffuse density + for(int l = 0; l < LINEARSOLVERTIMES; l++){ + for(int i = threadIndex; i < numChunks; i = i + numThreads){ + Chunk chunk = context->chunks[i]; + SWAP(chunk.d,chunk.d0); + diffuseDensity( + DIM, + chunk.chunkMask, + chunk.d, + chunk.d0, + chunk.diffuseConst, + chunk.viscosityConst, + chunk.timestep + ); + SWAP(chunk.d,chunk.d0); + } + sync(context); + } + + //advect density + for(int i = threadIndex; i < numChunks; i = i + numThreads){ + Chunk chunk = context->chunks[i]; + advectDensity( + chunk.chunkMask, + DIM, + chunk.d, + chunk.d0, + chunk.u, + chunk.v, + chunk.w, + chunk.timestep + ); + } + + //call this if the child threads need to wait on one another + sync(context); +} \ No newline at end of file diff --git a/src/main/c/src/threadpool.c b/src/main/c/src/threadpool.c index cba4e4b..14ce791 100644 --- a/src/main/c/src/threadpool.c +++ b/src/main/c/src/threadpool.c @@ -17,7 +17,7 @@ #include "../includes/utilities.h" typedef struct { - ThreadPool * threadPool; + LibraryContext * libraryContext; int threadIndex; //the index for this thread in all threadpool objects } ThreadData; @@ -39,6 +39,7 @@ JNIEXPORT jlong JNICALL Java_electrosphere_FluidSim_createThreadpool LibraryContext * libraryContext = (LibraryContext *)malloc(sizeof(LibraryContext)); libraryContext->numChunks = 0; + libraryContext->chunks = NULL; //must be tied to NULL at the start //init threadpool libraryContext->threadpool = (ThreadPool *)malloc(sizeof(ThreadPool)); @@ -71,7 +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->libraryContext = libraryContext; threadData->threadIndex = i; //create thread @@ -124,7 +125,6 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk( //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); @@ -134,8 +134,11 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk( 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); + newChunk->timestep = timestep; + newChunk->diffuseConst = DIFFUSION_CONSTANT; + newChunk->viscosityConst = VISCOSITY_CONSTANT; + stbds_arrput(libraryContext->chunks,newChunk[0]); } else { Chunk * currentChunk = &libraryContext->chunks[libraryContext->numChunks]; currentChunk->chunkMask = chunkMask; @@ -147,10 +150,12 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk( currentChunk->w0 = GET_ARR(env,w0r,CENTER_LOC); currentChunk->d = GET_ARR(env,dr,CENTER_LOC); currentChunk->d0 = GET_ARR(env,d0r,CENTER_LOC); + currentChunk->timestep = timestep; + currentChunk->diffuseConst = DIFFUSION_CONSTANT; + currentChunk->viscosityConst = VISCOSITY_CONSTANT; } libraryContext->numChunks++; - // arrput(libraryContext->chunks,newChunk); } /* @@ -191,30 +196,26 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_fetchWork( */ void * mainThreadLoop(void * dataRaw){ ThreadData * threadData = (ThreadData *)dataRaw; - ThreadPool * threadPool = threadData->threadPool; + LibraryContext * libraryContext = threadData->libraryContext; int threadIndex = threadData->threadIndex; - printf("thread work\n"); //main thread loop int running = 1; - while(running){ + while(running==1){ //begin work //wait to begin work until parent signals its ready - pthread_barrier_wait(threadPool->barrierWithParentThread); + pthread_barrier_wait(libraryContext->threadpool->barrierWithParentThread); //do main work - - - //call this if the child threads need to wait on one another - pthread_barrier_wait(threadPool->barrierMain); + simulate(libraryContext,threadData->threadIndex); //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 - pthread_barrier_wait(threadPool->barrierWithParentThread); + pthread_barrier_wait(libraryContext->threadpool->barrierWithParentThread); } diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index c4d54f4..44fd007 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -79,7 +79,8 @@ public class FluidSim { static final int LINEARSOLVERTIMES = 20; - static final float GRAVITY = -100f; + static final float GRAVITY = 0.0f; + // static final float GRAVITY = -100f; //<-- original value public void setup(Vector3i offset){ //allocate buffers for this chunk @@ -713,6 +714,162 @@ public class FluidSim { + + /** + * OLD NATIVE DECLARATIONS + */ + + + + // /** + // * 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); + + + + + + + + + + + + + + + + + @@ -957,7 +1114,7 @@ public class FluidSim { for(int k = 0; k < DIM; k++){ index = ((i)+(DIM)*(j) + (DIM)*(DIM)*(k)); u0ArrayView[index] = 0; - v0ArrayView[index] = densityArrayView[index] * GRAVITY; + v0ArrayView[index] = 0; w0ArrayView[index] = 0; } } diff --git a/src/main/java/electrosphere/Main.java b/src/main/java/electrosphere/Main.java index e3c064c..c1dd9db 100644 --- a/src/main/java/electrosphere/Main.java +++ b/src/main/java/electrosphere/Main.java @@ -56,7 +56,7 @@ public class Main { //Simulate // FluidSim.unlockThreadsWrapper(); - FluidSim.simChunks(simArray,i,0.01f); + FluidSim.simChunks(simArray,i,0.0001f); FluidSim.unlockThreadsWrapper(); time = time + (System.currentTimeMillis() - lastTime); //