All function calls on C side through wrappers

This commit is contained in:
unknown 2024-03-10 15:47:43 -04:00
parent 12dfd9e6b4
commit 9021125a74
4 changed files with 706 additions and 90 deletions

View File

@ -7,6 +7,9 @@
#define DIM 18 #define DIM 18
#define LINEARSOLVERTIMES 20 #define LINEARSOLVERTIMES 20
#define DIFFUSION_CONSTANT 0.0
#define VISCOSITY_CONSTANT 0.0
typedef struct { typedef struct {
float * d; float * d;
float * u; float * u;
@ -18,28 +21,680 @@ typedef struct {
float * w0; float * w0;
} Chunk; } 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( JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate(
JNIEnv * env, JNIEnv * env,
jclass class, jclass class,
jobject chunkList,
jfloat timestep 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);
} }
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_queueChunk( //solve chunk mask
JNIEnv * env, for(int i = 0; i < numChunks; i++){
jclass class, chunkJRaw = getChunk(i);
jint oldDim, chunkMask = (*env)->GetIntField(env,chunkJRaw,chunkmaskJId);
jint chunkmask, d = getBuffArr(dJId);
jobjectArray dr, d0 = getBuffArr(d0JId);
jobjectArray ur, u = getBuffArr(uJId);
jobjectArray vr, v = getBuffArr(vJId);
jobjectArray wr, w = getBuffArr(wJId);
jobjectArray d0r, u0 = getBuffArr(u0JId);
jobjectArray u0r, v0 = getBuffArr(v0JId);
jobjectArray v0r, w0 = getBuffArr(w0JId);
jobjectArray w0r, Java_electrosphere_FluidSim_addSourceToVectors(
jfloat DIFFUSION_CONSTANT, env,
jfloat VISCOSITY_CONSTANT 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

@ -113,21 +113,13 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setBoundsToNeighbors
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_copyNeighbors JNIEXPORT void JNICALL Java_electrosphere_FluidSim_copyNeighbors
(JNIEnv *, jobject, jint, jint, jint, jint, jobjectArray); (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 * Class: electrosphere_FluidSim
* Method: simulate * Method: simulate
* Signature: (F)V * Signature: (Ljava/util/List;F)V
*/ */
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate
(JNIEnv *, jclass, jfloat); (JNIEnv *, jclass, jobject, jfloat);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -15,6 +15,7 @@ import org.joml.Vector2i;
import org.joml.Vector3i; import org.joml.Vector3i;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.PointerBuffer; import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
/** /**
@ -40,21 +41,21 @@ public class FluidSim {
// +-------------+ (2,0,0) +---------------> X // +-------------+ (2,0,0) +---------------> X
//Buffers that contain density for current frame //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 //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 //Buffers that contain u vector directions
ByteBuffer[] uVector = new ByteBuffer[27]; public ByteBuffer[] uVector = new ByteBuffer[27];
//Buffers that contain v vector directions //Buffers that contain v vector directions
ByteBuffer[] vVector = new ByteBuffer[27]; public ByteBuffer[] vVector = new ByteBuffer[27];
//Buffers that contain w vector directions //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 //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 //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 //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 //The densities for every voxel for the current frame
float[] densityArrayView = new float[DIM * DIM * DIM]; float[] densityArrayView = new float[DIM * DIM * DIM];
@ -69,7 +70,7 @@ public class FluidSim {
public float[] v0ArrayView = new float[DIM * DIM * DIM]; public float[] v0ArrayView = new float[DIM * DIM * DIM];
float[] w0ArrayView = 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; 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){ public static void simChunks(FluidSim[][][] simArray, int step, float timestep){
List<FluidSim> chunksToSim = new LinkedList<FluidSim>();
// //
//init data for upcoming frame //init data for upcoming frame
for(int x = 0; x < simArray.length; x++){ for(int x = 0; x < simArray.length; x++){
@ -168,22 +174,18 @@ public class FluidSim {
//Performs main fluid simulation logic //Performs main fluid simulation logic
// //
simArray[x][y][z].writeNewStateIntoBuffers(); simArray[x][y][z].writeNewStateIntoBuffers();
//
// add to queue
//
chunksToSim.add(simArray[x][y][z]);
} }
} }
} }
//queue all chunks lastTime = GLFW.glfwGetTime();
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]);
}
}
}
// //
//Vector stage //Vector stage
simulateWrapper(timestep); simulateWrapper(chunksToSim,timestep);
// solveChunkMask(simArray); // solveChunkMask(simArray);
// addVectorSources(simArray, timestep); // addVectorSources(simArray, timestep);
// swapAllVectorFields(simArray, timestep); // swapAllVectorFields(simArray, timestep);
@ -193,14 +195,19 @@ public class FluidSim {
// advectVectorsAcrossBoundaries(simArray, timestep); // advectVectorsAcrossBoundaries(simArray, timestep);
// solveProjection(simArray, step, timestep); // solveProjection(simArray, step, timestep);
// // //
// //Density stage //Density stage
// addDensity(simArray, timestep); // addDensity(simArray, timestep);
// swapAllDensityArrays(simArray, timestep); // swapAllDensityArrays(simArray, timestep);
// diffuseDensity(simArray, timestep); // diffuseDensity(simArray, timestep);
// swapAllDensityArrays(simArray, timestep); // swapAllDensityArrays(simArray, timestep);
// advectDensity(simArray, timestep); // advectDensity(simArray, timestep);
// mirrorNeighborDensities(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 * Main simulation function
* @param timestep * @param timestep
*/ */
private static void simulateWrapper(float timestep){ private static void simulateWrapper(List<FluidSim> chunks, float timestep){
simulate(timestep); simulate(chunks,timestep);
} }
private static native void simulate(float timestep); private static native void simulate(List<FluidSim> chunks, float timestep);

View File

@ -71,7 +71,7 @@ public class Main {
GLFWContext.redraw(meshArray); GLFWContext.redraw(meshArray);
i++; i++;
if(i == 100){ if(i == 100){
System.out.println(time / 100.0); // System.out.println(time / 100.0);
} }
if(i > 3){ if(i > 3){
// scan.next(); // scan.next();