Compare commits

...

2 Commits

Author SHA1 Message Date
unknown
9021125a74 All function calls on C side through wrappers 2024-03-10 15:47:43 -04:00
unknown
12dfd9e6b4 work to setup migration to c 2024-03-04 21:23:36 -05:00
5 changed files with 799 additions and 64 deletions

View File

@ -56,12 +56,17 @@ INPUT_FILES="./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="./fluidsim.c"
OUTPUT_FILE="./fluidsim.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 fluidsim.o"
gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE
#move to resources

700
src/main/c/fluidsim.c Normal file
View File

@ -0,0 +1,700 @@
#include <jni.h>
#include <stdint.h>
#include "includes/utilities.h"
#include "includes/chunkmask.h"
#include "includes/electrosphere_FluidSim.h"
#define DIM 18
#define LINEARSOLVERTIMES 20
#define DIFFUSION_CONSTANT 0.0
#define VISCOSITY_CONSTANT 0.0
typedef struct {
float * d;
float * u;
float * v;
float * w;
float * d0;
float * u0;
float * v0;
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");
//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);
}
}
}

View File

@ -17,14 +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
@ -121,6 +113,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: simulate
* Signature: (Ljava/util/List;F)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate
(JNIEnv *, jclass, jobject, jfloat);
#ifdef __cplusplus
}
#endif

View File

@ -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<FluidSim> chunksToSim = new LinkedList<FluidSim>();
//
//init data for upcoming frame
for(int x = 0; x < simArray.length; x++){
@ -168,29 +174,40 @@ public class FluidSim {
//Performs main fluid simulation logic
//
simArray[x][y][z].writeNewStateIntoBuffers();
//
// add to queue
//
chunksToSim.add(simArray[x][y][z]);
}
}
}
lastTime = GLFW.glfwGetTime();
//
//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);
simulateWrapper(chunksToSim,timestep);
// 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);
// 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);
}
@ -715,38 +732,38 @@ 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
);
// /**
// * 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);
@ -853,6 +870,19 @@ public class FluidSim {
/**
* Main simulation function
* @param timestep
*/
private static void simulateWrapper(List<FluidSim> chunks, float timestep){
simulate(chunks,timestep);
}
private static native void simulate(List<FluidSim> chunks, float timestep);

View File

@ -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();