queueing logic without memleak allegedly
All checks were successful
studiorailgun/fluid-sim/pipeline/head This commit looks good

This commit is contained in:
unknown 2024-03-02 18:19:22 -05:00
parent 0a15bf062c
commit e955c1f479
7 changed files with 570 additions and 614 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -6,8 +6,15 @@
#include <pthread.h>
#include <semaphore.h>
//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);

View File

@ -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,

View File

@ -156,6 +156,7 @@ public class FluidSim {
}
}
static LinkedList<FluidSim> simArrayList = new LinkedList<FluidSim>();
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();
}
}
}
//
//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);
//flag this chunk as being simulated in the upcoming frame
simArrayList.add(simArray[x][y][z]);
}
}
}
//
//Density stage
addDensity(simArray, timestep);
swapAllDensityArrays(simArray, timestep);
diffuseDensity(simArray, timestep);
swapAllDensityArrays(simArray, timestep);
advectDensity(simArray, timestep);
// mirrorNeighborDensities(simArray, timestep);
//for each chunk, send them to C land
for(FluidSim chunk : simArrayList){
queueChunkWrapper(threadpool, chunk, 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 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
}
private static void solveVectorDiffusion(FluidSim[][][] simArray, float timestep){
//samples u,v,w,u0,v0,w0
//sets u,v,w
// 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].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);
// simArray[x][y][z].calculateChunkMaskWrapper();
// }
// }
// }
// }
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 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 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);
}
}
}
}
// //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 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 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 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 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 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...
// 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 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 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);