From 9021125a740e54c92d427ebdd65119c43097bb45 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Sun, 10 Mar 2024 15:47:43 -0400 Subject: [PATCH] All function calls on C side through wrappers --- src/main/c/fluidsim.c | 689 ++++++++++++++++++- src/main/c/includes/electrosphere_FluidSim.h | 12 +- src/main/java/electrosphere/FluidSim.java | 93 +-- src/main/java/electrosphere/Main.java | 2 +- 4 files changed, 706 insertions(+), 90 deletions(-) diff --git a/src/main/c/fluidsim.c b/src/main/c/fluidsim.c index 5095b19..00fa610 100644 --- a/src/main/c/fluidsim.c +++ b/src/main/c/fluidsim.c @@ -7,6 +7,9 @@ #define DIM 18 #define LINEARSOLVERTIMES 20 +#define DIFFUSION_CONSTANT 0.0 +#define VISCOSITY_CONSTANT 0.0 + typedef struct { float * d; float * u; @@ -18,28 +21,680 @@ typedef struct { float * w0; } Chunk; +#define getChunk(i) (*env)->CallObjectMethod(env,chunkList,jListGet,i) +#define getBuffArr(buffId) (*env)->GetObjectField(env,chunkJRaw,buffId) +#define setBuffArr(buffId,value) (*env)->SetObjectField(env,chunkJRaw,buffId,value) + +//jni help: +//https://stackoverflow.com/questions/39823375/clarification-about-getfieldid JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate( JNIEnv * env, jclass class, + jobject chunkList, jfloat timestep ){ -} + jclass listClass = (*env)->FindClass(env,"java/util/List"); + jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/FluidSim"); + //JNIEnv *env, jclass clazz, const char *name, const char *sig + jmethodID jListSize = (*env)->GetMethodID(env, listClass, "size", "()I"); + jmethodID jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;"); + jmethodID jListAdd = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk( - JNIEnv * env, - jclass class, - jint oldDim, - jint chunkmask, - jobjectArray dr, - jobjectArray ur, - jobjectArray vr, - jobjectArray wr, - jobjectArray d0r, - jobjectArray u0r, - jobjectArray v0r, - jobjectArray w0r, - jfloat DIFFUSION_CONSTANT, - jfloat VISCOSITY_CONSTANT -){ + //ByteBuffer[] + jfieldID dJId = (*env)->GetFieldID(env,fluidSimClass,"density","[Ljava/nio/ByteBuffer;"); + jfieldID d0JId = (*env)->GetFieldID(env,fluidSimClass,"densityAddition","[Ljava/nio/ByteBuffer;"); + jfieldID uJId = (*env)->GetFieldID(env,fluidSimClass,"uVector","[Ljava/nio/ByteBuffer;"); + jfieldID vJId = (*env)->GetFieldID(env,fluidSimClass,"vVector","[Ljava/nio/ByteBuffer;"); + jfieldID wJId = (*env)->GetFieldID(env,fluidSimClass,"wVector","[Ljava/nio/ByteBuffer;"); + jfieldID u0JId = (*env)->GetFieldID(env,fluidSimClass,"uAdditionVector","[Ljava/nio/ByteBuffer;"); + jfieldID v0JId = (*env)->GetFieldID(env,fluidSimClass,"vAdditionVector","[Ljava/nio/ByteBuffer;"); + jfieldID w0JId = (*env)->GetFieldID(env,fluidSimClass,"wAdditionVector","[Ljava/nio/ByteBuffer;"); + jfieldID chunkmaskJId = (*env)->GetFieldID(env,fluidSimClass,"chunkMask","I"); + + //the number of chunks + int numChunks = (*env)->CallIntMethod(env,chunkList,jListSize); + + //current chunk (this) + jobject chunkJRaw; + //current chunk fields + jobjectArray d; + jobjectArray d0; + jobjectArray u; + jobjectArray v; + jobjectArray w; + jobjectArray u0; + jobjectArray v0; + jobjectArray w0; + int chunkMask; + + //solve chunk mask + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = Java_electrosphere_FluidSim_calculateChunkMask(env,chunkJRaw,getBuffArr(dJId)); + (*env)->SetIntField(env,chunkJRaw,chunkmaskJId,chunkMask); + } + + //solve chunk mask + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_addSourceToVectors( + env, + chunkJRaw, + DIM, + chunkMask, + u, + v, + w, + u0, + v0, + w0, + DIFFUSION_CONSTANT, + VISCOSITY_CONSTANT, + timestep + ); + } + //swap all vector fields + { + //swap vector fields + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + setBuffArr(uJId,u0); + setBuffArr(u0JId,u); + + setBuffArr(vJId,v0); + setBuffArr(v0JId,v); + + setBuffArr(wJId,w0); + setBuffArr(w0JId,w); + } + //copy neighbors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w0); + } + } + //solve vector diffusion + { + for(int l = 0; l < LINEARSOLVERTIMES; l++){ + //solve vector diffusion + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_solveVectorDiffuse(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + //update array for vectors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + } + } + } + //solve projection + { + //update array for vectors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + } + //setup projection + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setupProjection(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + //update array for vectors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + } + //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 i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_solveProjection(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + } + } + //samples u,v,w,u0 + //sets u,v,w + //Finalize projection + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_finalizeProjection(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + //set boundaries a final time for u,v,w + //... + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w0); + } + } + //swap all vector fields + { + //swap vector fields + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + setBuffArr(uJId,u0); + setBuffArr(u0JId,u); + + setBuffArr(vJId,v0); + setBuffArr(v0JId,v); + + setBuffArr(wJId,w0); + setBuffArr(w0JId,w); + } + //copy neighbors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w0); + } + } + //advect vectors across boundaries + { + //update border arrs + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w0); + } + //advect + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_advectVectors(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + //update neighbor arr + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + } + } + //solve projection + { + //update array for vectors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + } + //setup projection + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setupProjection(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + //update array for vectors + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + } + //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 i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_solveProjection(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + } + } + //samples u,v,w,u0 + //sets u,v,w + //Finalize projection + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_finalizeProjection(env,chunkJRaw,DIM,chunkMask,u,v,w,u0,v0,w0,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + //set boundaries a final time for u,v,w + //... + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,1,u0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,2,v0); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,3,w0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,1,u0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,2,v0); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,3,w0); + } + } + //add density + { + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_addDensity(env,chunkJRaw,DIM,chunkMask,d,d0,timestep); + } + } + //swap all density arrays + { + //swap vector fields + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + setBuffArr(dJId,d0); + setBuffArr(d0JId,d); + } + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,d); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,d0); + } + } + //diffuse density + { + for(int l = 0; l < LINEARSOLVERTIMES; l++){ + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_solveDiffuseDensity(env,chunkJRaw,DIM,chunkMask,d,d0,u,v,w,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,0,d); + } + } + } + //swap all density arrays + { + //swap vector fields + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + setBuffArr(dJId,d0); + setBuffArr(d0JId,d); + } + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,d); + Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,d0); + } + } + //advect density + { + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_advectDensity(env,chunkJRaw,DIM,chunkMask,d,d0,u,v,w,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); + } + } + //mirror densities + { + for(int i = 0; i < numChunks; i++){ + chunkJRaw = getChunk(i); + chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId); + d = getBuffArr(dJId); + d0 = getBuffArr(d0JId); + u = getBuffArr(uJId); + v = getBuffArr(vJId); + w = getBuffArr(wJId); + u0 = getBuffArr(u0JId); + v0 = getBuffArr(v0JId); + w0 = getBuffArr(w0JId); + Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,0,d); + } + } } \ 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 ca84cd9..1ef8e24 100644 --- a/src/main/c/includes/electrosphere_FluidSim.h +++ b/src/main/c/includes/electrosphere_FluidSim.h @@ -113,21 +113,13 @@ 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: queueChunk - * 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;FF)V - */ -JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk - (JNIEnv *, jclass, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat); - /* * Class: electrosphere_FluidSim * Method: simulate - * Signature: (F)V + * Signature: (Ljava/util/List;F)V */ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate - (JNIEnv *, jclass, jfloat); + (JNIEnv *, jclass, jobject, jfloat); #ifdef __cplusplus } diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index ee61d5d..eca5910 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -15,6 +15,7 @@ import org.joml.Vector2i; import org.joml.Vector3i; import org.lwjgl.BufferUtils; import org.lwjgl.PointerBuffer; +import org.lwjgl.glfw.GLFW; import org.lwjgl.system.MemoryUtil; /** @@ -40,21 +41,21 @@ public class FluidSim { // +-------------+ (2,0,0) +---------------> X //Buffers that contain density for current frame - ByteBuffer[] density = new ByteBuffer[27]; + public ByteBuffer[] density = new ByteBuffer[27]; //Buffers that contain new density to add to the simulation - ByteBuffer[] densityAddition = new ByteBuffer[27]; + public ByteBuffer[] densityAddition = new ByteBuffer[27]; //Buffers that contain u vector directions - ByteBuffer[] uVector = new ByteBuffer[27]; + public ByteBuffer[] uVector = new ByteBuffer[27]; //Buffers that contain v vector directions - ByteBuffer[] vVector = new ByteBuffer[27]; + public ByteBuffer[] vVector = new ByteBuffer[27]; //Buffers that contain w vector directions - ByteBuffer[] wVector = new ByteBuffer[27]; + public ByteBuffer[] wVector = new ByteBuffer[27]; //Buffers that contain u vector directions to add to the simulation - ByteBuffer[] uAdditionVector = new ByteBuffer[27]; + public ByteBuffer[] uAdditionVector = new ByteBuffer[27]; //Buffers that contain v vector directions to add to the simulation - ByteBuffer[] vAdditionVector = new ByteBuffer[27]; + public ByteBuffer[] vAdditionVector = new ByteBuffer[27]; //Buffers that contain w vector directions to add to the simulation - ByteBuffer[] wAdditionVector = new ByteBuffer[27]; + public ByteBuffer[] wAdditionVector = new ByteBuffer[27]; //The densities for every voxel for the current frame float[] densityArrayView = new float[DIM * DIM * DIM]; @@ -69,7 +70,7 @@ public class FluidSim { public float[] v0ArrayView = new float[DIM * DIM * DIM]; float[] w0ArrayView = new float[DIM * DIM * DIM]; - int chunkMask = 0; + public int chunkMask = 0; static final float DIFFUSION_CONSTANT = 0.0f; @@ -154,7 +155,12 @@ public class FluidSim { } } + static int i = 0; + static double time = 0; + static double lastTime = 0; public static void simChunks(FluidSim[][][] simArray, int step, float timestep){ + + List chunksToSim = new LinkedList(); // //init data for upcoming frame for(int x = 0; x < simArray.length; x++){ @@ -168,22 +174,18 @@ public class FluidSim { //Performs main fluid simulation logic // simArray[x][y][z].writeNewStateIntoBuffers(); + // + // add to queue + // + chunksToSim.add(simArray[x][y][z]); } } } - //queue all chunks - 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++){ - queueChunkWrapper(simArray[x][y][z]); - } - } - } - + lastTime = GLFW.glfwGetTime(); // //Vector stage - simulateWrapper(timestep); + simulateWrapper(chunksToSim,timestep); // solveChunkMask(simArray); // addVectorSources(simArray, timestep); // swapAllVectorFields(simArray, timestep); @@ -193,14 +195,19 @@ public class FluidSim { // advectVectorsAcrossBoundaries(simArray, timestep); // solveProjection(simArray, step, timestep); - // // - // //Density stage + // + //Density stage // addDensity(simArray, timestep); // swapAllDensityArrays(simArray, timestep); // diffuseDensity(simArray, timestep); // swapAllDensityArrays(simArray, timestep); // advectDensity(simArray, timestep); // mirrorNeighborDensities(simArray, timestep); + time = time + (GLFW.glfwGetTime() - lastTime); + i++; + if(i == 100){ + System.out.println(time / 100.0 * 1000.0); + } @@ -862,53 +869,15 @@ public class FluidSim { - /** - * Queues a chunk - * @param chunk the chunk - */ - private static void queueChunkWrapper(FluidSim chunk){ - queueChunk( - DIM, - chunk.chunkMask, - chunk.density, - chunk.uVector, - chunk.vVector, - chunk.wVector, - chunk.densityAddition, - chunk.uAdditionVector, - chunk.vAdditionVector, - chunk.wAdditionVector, - DIFFUSION_CONSTANT, - VISCOSITY_CONSTANT - ); - } - - private static native void queueChunk( - int DIM_X, - int chunkMask, - ByteBuffer d[], - ByteBuffer u[], - ByteBuffer v[], - ByteBuffer w[], - ByteBuffer d0[], - ByteBuffer u0[], - ByteBuffer v0[], - ByteBuffer w0[], - float DIFFUSION_CONSTANT, - float VISCOSITY_CONSTANT - ); - - - /** * Main simulation function * @param timestep */ - private static void simulateWrapper(float timestep){ - simulate(timestep); + private static void simulateWrapper(List chunks, float timestep){ + simulate(chunks,timestep); } - private static native void simulate(float timestep); + private static native void simulate(List chunks, float timestep); diff --git a/src/main/java/electrosphere/Main.java b/src/main/java/electrosphere/Main.java index 0d7440b..eba11cb 100644 --- a/src/main/java/electrosphere/Main.java +++ b/src/main/java/electrosphere/Main.java @@ -71,7 +71,7 @@ public class Main { GLFWContext.redraw(meshArray); i++; if(i == 100){ - System.out.println(time / 100.0); + // System.out.println(time / 100.0); } if(i > 3){ // scan.next();