#include #include #include "includes/utilities.h" #include "includes/chunkmask.h" #include "includes/electrosphere_FluidSim.h" #include "includes/mainFunctions.h" //include stb ds #define STB_DS_IMPLEMENTATION #include "./lib/stb/stb_ds.h" #define DIM 18 #define LINEARSOLVERTIMES 20 #define DIFFUSION_CONSTANT 0.0 #define VISCOSITY_CONSTANT 0.0 /** * A chunk */ typedef struct { jobject jchunk; float * d[27]; float * d0[27]; float * u[27]; float * v[27]; float * w[27]; float * u0[27]; float * v0[27]; float * w0[27]; jobjectArray jd; jobjectArray jd0; jobjectArray ju; jobjectArray jv; jobjectArray jw; jobjectArray ju0; jobjectArray jv0; jobjectArray jw0; int chunkMask; } Chunk; //all chunks Chunk ** chunks = NULL; #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 jd; jobjectArray jd0; 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); Chunk * newChunk; if(i >= stbds_arrlen(chunks)){ // printf("allocate chunk %d\n",i); // fflush(stdout); newChunk = (Chunk *)malloc(sizeof(Chunk)); // printf("new chunk %p\n",newChunk); // fflush(stdout); stbds_arrput(chunks,newChunk); // printf("new chunk %p\n",chunks[i]); // fflush(stdout); } else { newChunk = chunks[i]; // printf("get chunk %d: %p\n",i,newChunk); // fflush(stdout); } jd = (*env)->GetObjectField(env,chunkJRaw,dJId); jd0 = (*env)->GetObjectField(env,chunkJRaw,d0JId); u = (*env)->GetObjectField(env,chunkJRaw,uJId); v = (*env)->GetObjectField(env,chunkJRaw,vJId); w = (*env)->GetObjectField(env,chunkJRaw,wJId); u0 = (*env)->GetObjectField(env,chunkJRaw,u0JId); v0 = (*env)->GetObjectField(env,chunkJRaw,v0JId); w0 = (*env)->GetObjectField(env,chunkJRaw,w0JId); newChunk->jd = jd; newChunk->jd0 = jd0; newChunk->ju = u; newChunk->jv = v; newChunk->jw = w; newChunk->ju0 = u0; newChunk->jv0 = v0; newChunk->jw0 = w0; newChunk->jchunk = chunkJRaw; newChunk->chunkMask = chunkMask; for(int j = 0; j < 27; j++){ if((chunkMask & CHUNK_INDEX_ARR[j]) > 0){ newChunk->d[j] = GET_ARR(env,jd,j); newChunk->d0[j] = GET_ARR(env,jd0,j); newChunk->u[j] = GET_ARR(env,u,j); newChunk->v[j] = GET_ARR(env,v,j); newChunk->w[j] = GET_ARR(env,w,j); newChunk->u0[j] = GET_ARR(env,u0,j); newChunk->v0[j] = GET_ARR(env,v0,j); newChunk->w0[j] = GET_ARR(env,w0,j); } } // for(int j = 0; j < 27; j++){ // newChunk.d[j] = GET_ARR(env,d,j); // } // chunks[i].d0 = getBuffArr(d0JId); // chunks[i].u = getBuffArr(uJId); // chunks[i].v = getBuffArr(vJId); // chunks[i].w = getBuffArr(wJId); // chunks[i].u0 = getBuffArr(u0JId); // chunks[i].v0 = getBuffArr(v0JId); // chunks[i].w0 = getBuffArr(w0JId); } // printf("%p\n",chunks[0].d); //solve chunk mask for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; //old assignments // 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; setBuffArr(uJId,u0); setBuffArr(u0JId,u); setBuffArr(vJId,v0); setBuffArr(v0JId,v); setBuffArr(wJId,w0); setBuffArr(w0JId,w); jobject tmpObj; tmpObj = currentChunk->ju; currentChunk->ju = currentChunk->ju0; currentChunk->ju0 = u; tmpObj = currentChunk->jv; currentChunk->jv = currentChunk->jv0; currentChunk->jv0 = v; tmpObj = currentChunk->jw; currentChunk->jw = currentChunk->jw0; currentChunk->jw0 = w; } //copy neighbors for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; setBuffArr(uJId,u0); setBuffArr(u0JId,u); setBuffArr(vJId,v0); setBuffArr(v0JId,v); setBuffArr(wJId,w0); setBuffArr(w0JId,w); jobject tmpObj; tmpObj = currentChunk->ju; currentChunk->ju = currentChunk->ju0; currentChunk->ju0 = u; tmpObj = currentChunk->jv; currentChunk->jv = currentChunk->jv0; currentChunk->jv0 = v; tmpObj = currentChunk->jw; currentChunk->jw = currentChunk->jw0; currentChunk->jw0 = w; } //copy neighbors for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; 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++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; Java_electrosphere_FluidSim_addDensity(env,chunkJRaw,DIM,chunkMask,currentChunk->d,currentChunk->d0,timestep); } } //swap all density arrays { //swap vector fields for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; setBuffArr(dJId,jd0); setBuffArr(d0JId,jd); jobject tmpObj; tmpObj = currentChunk->jd; currentChunk->jd = currentChunk->jd0; currentChunk->jd0 = tmpObj; float * tmpArr; for(int j = 0; j < 27; j++){ tmpArr = currentChunk->d[j]; currentChunk->d[j] = currentChunk->d0[j]; currentChunk->d0[j] = tmpArr; } } for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,jd); Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,jd0); } } //diffuse density { for(int l = 0; l < LINEARSOLVERTIMES; l++){ for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; Java_electrosphere_FluidSim_solveDiffuseDensity(env,chunkJRaw,DIM,chunkMask,jd,jd0,u,v,w,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); } for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; Java_electrosphere_FluidSim_setBoundsToNeighbors(env,chunkJRaw,DIM,chunkMask,0,jd); } } } //swap all density arrays { //swap vector fields for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; setBuffArr(dJId,jd0); setBuffArr(d0JId,jd); jobject tmpObj; tmpObj = currentChunk->jd; currentChunk->jd = currentChunk->jd0; currentChunk->jd0 = tmpObj; float * tmpArr; for(int j = 0; j < 27; j++){ tmpArr = currentChunk->d[j]; currentChunk->d[j] = currentChunk->d0[j]; currentChunk->d0[j] = tmpArr; } } for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,jd); Java_electrosphere_FluidSim_copyNeighbors(env,chunkJRaw,DIM,chunkMask,0,0,jd0); } } //advect density { for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; Java_electrosphere_FluidSim_advectDensity(env,chunkJRaw,DIM,chunkMask,currentChunk->d,currentChunk->d0,u,v,w,DIFFUSION_CONSTANT,VISCOSITY_CONSTANT,timestep); } } //mirror densities { for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; chunkJRaw = currentChunk->jchunk; chunkMask = currentChunk->chunkMask; jd = currentChunk->jd; jd0 = currentChunk->jd0; u = currentChunk->ju; v = currentChunk->jv; w = currentChunk->jw; u0 = currentChunk->ju0; v0 = currentChunk->jv0; w0 = currentChunk->jw0; setBoundsToNeighborsRaw(env,chunkJRaw,DIM,chunkMask,0,currentChunk->d); } } }