Setup hoisting step functions into javaland

This commit is contained in:
unknown 2023-07-23 13:44:01 -04:00
parent 2eeb45b1e9
commit e31b3643ba
7 changed files with 713 additions and 122 deletions

View File

@ -46,12 +46,27 @@ 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_FLAGS="-c -fPIC -m64 -mavx -mavx2 -O1"
INPUT_FILES="./densitystep.c"
OUTPUT_FILE="./densitystep.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="./velocitystep.c"
OUTPUT_FILE="./velocitystep.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="./chunkmask.c"
OUTPUT_FILE="./chunkmask.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="fluidsim.o"
INPUT_FILES="fluidsim.o densitystep.o velocitystep.o chunkmask.o"
gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE
#move to resources

47
src/main/c/densitystep.c Normal file
View File

@ -0,0 +1,47 @@
#include <jni.h>
#include <stdio.h>
#include <immintrin.h>
#include <stdint.h>
#include "includes/utilities.h"
#include "includes/chunkmask.h"
/*
* Class: electrosphere_FluidSim
* Method: addDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;F)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: setupDiffuseDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupDiffuseDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: solveDiffuseDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveDiffuseDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: advectDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat){
}

View File

@ -25,14 +25,6 @@ extern "C" {
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: linSolve
* Signature: (IIILjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_linSolve
(JNIEnv *, jobject, jint, jint, jint, jobject, jobject, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: calculateChunkMask
@ -41,6 +33,94 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_linSolve
JNIEXPORT jint JNICALL Java_electrosphere_FluidSim_calculateChunkMask
(JNIEnv *, jobject, jobjectArray);
/*
* Class: electrosphere_FluidSim
* Method: addSourceToVectors
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addSourceToVectors
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: setupVectorDiffuse
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupVectorDiffuse
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: solveVectorDiffuse
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveVectorDiffuse
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: setupProjection
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupProjection
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: solveProjection
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveProjection
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: finalizeProjection
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_finalizeProjection
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: advectVectors
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectVectors
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: addDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;F)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: setupDiffuseDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupDiffuseDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: solveDiffuseDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveDiffuseDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat);
/*
* Class: electrosphere_FluidSim
* Method: advectDensity
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectDensity
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jfloat, jfloat, jfloat);
#ifdef __cplusplus
}
#endif

View File

@ -10,6 +10,4 @@
#define GET_ARR(env,src,i) (*env)->GetDirectBufferAddress(env,(*env)->GetObjectArrayElement(env,src,i))
#define ARR_EXISTS(chunk_mask,m,n,o) (chunk_mask & CHUNK_INDEX_ARR[CK(m,n,o)]) > 0
void lin_solve(JNIEnv * env, uint32_t chunk_mask, int N, int b, float* x, float* x0, float a, float c);
#endif

View File

@ -1,59 +0,0 @@
#include <jni.h>
#include <immintrin.h>
#include <stdint.h>
#include "includes/utilities.h"
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_linSolve(
JNIEnv * env,
jobject this,
jint chunk_mask_raw,
jint DIM_X,
jint br,
jobject jrx,
jobject jrx0,
jfloat ar,
jfloat cr
){
//adapt object types
float * x = (*env)->GetDirectBufferAddress(env,jrx);
float * x0 = (*env)->GetDirectBufferAddress(env,jrx0);
//solve
lin_solve(env,chunk_mask_raw,DIM_X,br,x,x0,ar,cr);
}
/**
* Solves a linear system of equations in a vectorized manner
*/
void lin_solve(JNIEnv * env, uint32_t chunk_mask, int N, int b, float* x, float* x0, float a, float c){
int i, j, k, l, m;
__m256 aScalar = _mm256_set1_ps(a);
__m256 cScalar = _mm256_set1_ps(c);
// update for each cell
for(k=1; k<N-1; k++){
for(j=1; j<N-1; j++){
int n = 0;
//solve as much as possible vectorized
for(i = 1; i < N-1; i=i+8){
__m256 vector = _mm256_loadu_ps(&x[IX(i-1,j,k)]);
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i+1,j,k)]));
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j-1,k)]));
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j+1,k)]));
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j,k-1)]));
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j,k+1)]));
vector = _mm256_mul_ps(vector,aScalar);
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x0[IX(i,j,k)]));
vector = _mm256_div_ps(vector,cScalar);
_mm256_storeu_ps(&x[IX(i,j,k)],vector);
}
//If there is any leftover, perform manual solving
if(i>N-1){
for(i=i-8; i < N-1; i++){
x[IX(i,j,k)] = (x0[IX(i,j,k)] + a*(x[IX(i-1,j,k)]+x[IX(i+1,j,k)]+x[IX(i,j-1,k)]+x[IX(i,j+1,k)]+x[IX(i,j,k-1)]+x[IX(i,j,k+1)]))/c;
}
}
}
}
}

79
src/main/c/velocitystep.c Normal file
View File

@ -0,0 +1,79 @@
#include <jni.h>
#include <stdio.h>
#include <immintrin.h>
#include <stdint.h>
#include "includes/utilities.h"
#include "includes/chunkmask.h"
/*
* Class: electrosphere_FluidSim
* Method: addSourceToVectors
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addSourceToVectors
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: setupVectorDiffuse
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupVectorDiffuse
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: solveVectorDiffuse
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveVectorDiffuse
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: setupProjection
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_setupProjection
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: solveProjection
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_solveProjection
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: finalizeProjection
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_finalizeProjection
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}
/*
* Class: electrosphere_FluidSim
* Method: advectVectors
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
*/
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectVectors
(JNIEnv *, jobject, jint, jint, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat){
}

View File

@ -69,6 +69,8 @@ public class FluidSim {
float[] v0ArrayView = new float[DIM * DIM * DIM];
float[] w0ArrayView = new float[DIM * DIM * DIM];
int chunkMask = 0;
static final float DIFFUSION_CONSTANT = 0.00001f;
static final float VISCOSITY_CONSTANT = 0.00001f;
@ -129,10 +131,52 @@ public class FluidSim {
}
public static void simChunks(FluidSim[][][] simArray, int step, float timestep){
//
//init data for upcoming frame
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
simArray[x][y][z].simulate(step, timestep);
//
// Add forces and density here
//
simArray[x][y][z].addGravity();
//
//Performs main fluid simulation logic
//
simArray[x][y][z].writeNewStateIntoBuffers();
}
}
}
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
simArray[x][y][z].simulate(step,timestep);
}
}
}
solveChunkMask(simArray);
addVectorSources(simArray, timestep);
solveVectorDiffusion(simArray, timestep);
// setupProjection(simArray, timestep);
solveProjection(simArray, timestep);
swapAllVectorFields(simArray, timestep);
advectVectorsAcrossBoundaries(simArray, timestep);
// setupProjection(simArray, timestep);
solveProjection(simArray, timestep);
//
//Read out of buffers back into accessible arrays
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++){
//
//Reads out the results of the fluid sim
//
simArray[x][y][z].readDataIntoArrays();
}
}
}
@ -142,17 +186,6 @@ public class FluidSim {
* Runs a frame of the fluid simulation
*/
private void simulate(int step, float timestep){
//
// Add forces and density here
//
addGravity();
//
//Performs main fluid simulation logic
//
writeNewStateIntoBuffers();
simulate(
DIM,
0,
@ -168,13 +201,405 @@ public class FluidSim {
VISCOSITY_CONSTANT,
timestep
);
//
//Reads out the results of the fluid sim
//
readDataIntoArrays();
}
private static void solveChunkMask(FluidSim[][][] simArray){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
simArray[x][y][z].calculateChunkMaskWrapper();
}
}
}
}
private static void addVectorSources(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//Add source to all 3 vectors
// add_source(N, u, u0, dt);
// add_source(N, v, v0, dt);
// add_source(N, w, w0, dt);
simArray[x][y][z].addSourceToVectorsWrapper(timestep);
//swap
//u <=> u0 etc for u, v, and w
simArray[x][y][z].swapVectorFields();
//setup diffuse for all 3 vectors
simArray[x][y][z].setupVectorDiffuseWrapper(timestep);
}
}
}
}
private static void solveVectorDiffusion(FluidSim[][][] simArray, float timestep){
for(int l = 0; l < LINEARSOLVERTIMES; l++){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a);
//+
//set_bnd(env, chunk_mask, N, b, x);
//for u, v, and w all in 1 shot
simArray[x][y][z].solveVectorDiffuseWrapper(timestep);
}
}
}
}
}
private static void setupProjection(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//then
//setup vector projection
//...
simArray[x][y][z].setupProjectionWrapper(timestep);
}
}
}
}
private static void solveProjection(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//setup projection across boundaries
//...
//set boundaries appropriately
//...
simArray[x][y][z].setupProjectionWrapper(timestep);
}
}
}
for(int l = 0; l < LINEARSOLVERTIMES; l++){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a);
//+
//set_bnd(env, chunk_mask, N, b, x);
//for u, v, and w all in 1 shot
simArray[x][y][z].solveProjectionWrapper(timestep);
//be sure to set boundaries to neighbor chunk values where appropriate
}
}
}
}
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//Subtract curl field from current vector field
//...
//set boundaries a final time for u,v,w
//...
simArray[x][y][z].finalizeProjectionWrapper(timestep);
}
}
}
}
private static void swapAllVectorFields(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
simArray[x][y][z].swapVectorFields();
}
}
}
}
private void swapVectorFields(){
//swap u0 <-> u
//swap v0 <-> v
//swap w0 <-> w
//...
}
private static void advectVectorsAcrossBoundaries(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
// advect(env, chunk_mask, N, 1, jru, u0, u0, v0, w0, dt);
// advect(env, chunk_mask, N, 2, jrv, v0, u0, v0, w0, dt);
// advect(env, chunk_mask, N, 3, jrw, w0, u0, v0, w0, dt);
//...
simArray[x][y][z].advectVectorsWrapper(timestep);
}
}
}
}
private static void addDensity(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//add_source(N, x, x0, dt);
simArray[x][y][z].addDensityWrapper(timestep);
//swap x <=> x0
//swap arrays in java side...
simArray[x][y][z].swapDensityArrays();
//setup density diffusion
simArray[x][y][z].setupDiffuseDensityWrapper(timestep);
}
}
}
}
private void swapDensityArrays(){
ByteBuffer tmp = density[13];
density[13] = densityAddition;
densityAddition = tmp;
}
private static void diffuseDensity(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a);
//+
//set_bnd(env, chunk_mask, N, b, x);
simArray[x][y][z].solveDiffuseDensityWrapper(timestep);
}
}
}
}
private static void advectDensity(FluidSim[][][] simArray, float timestep){
for(int x = 0; x < simArray.length; x++){
for(int y = 0; y < simArray[0].length; y++){
for(int z = 0; z < simArray[0][0].length; z++){
//swap x <=> x0 again
simArray[x][y][z].swapDensityArrays();
//advect density
simArray[x][y][z].advectDensityWrapper(timestep);
}
}
}
}
/**
* The native function call to simulate a frame of fluid
* @param DIM_X
* @param DIM_Y
* @param DIM_Z
* @param x
* @param x0
* @param u
* @param v
* @param w
* @param u0
* @param v0
* @param w0
* @param DIFFUSION_CONSTANT
* @param VISCOSITY_CONSTANT
* @param timestep
*/
private native void simulate(
int DIM_X,
int chunkMask,
ByteBuffer[] x,
ByteBuffer x0,
ByteBuffer[] u,
ByteBuffer[] v,
ByteBuffer[] w,
ByteBuffer u0,
ByteBuffer v0,
ByteBuffer w0,
float DIFFUSION_CONSTANT,
float VISCOSITY_CONSTANT,
float timestep
);
private void calculateChunkMaskWrapper(){
this.chunkMask = this.calculateChunkMask(density);
}
/**
* Calculates the mask of chunk neighbors
* @param densityBuffers The neighbor array
* @return The mask
*/
private native int calculateChunkMask(ByteBuffer[] densityBuffers);
/**
* Add vector values to u, v, and w all at once
*/
private void addSourceToVectorsWrapper(float timestep){
addSourceToVectors(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void addSourceToVectors(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Setup u, v, and w to diffuse
*/
private void setupVectorDiffuseWrapper(float timestep){
setupVectorDiffuse(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void setupVectorDiffuse(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Solves u, v, and w diffusion systems of equations
*/
private void solveVectorDiffuseWrapper(float timestep){
solveVectorDiffuse(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void solveVectorDiffuse(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Setup projection system
*/
private void setupProjectionWrapper(float timestep){
setupProjection(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void setupProjection(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Solve projection system
*/
private void solveProjectionWrapper(float timestep){
solveProjection(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void solveProjection(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Does work like subtracting curl from vector field, setting boundaries, etc
*/
private void finalizeProjectionWrapper(float timestep){
finalizeProjection(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void finalizeProjection(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Advects vectors
*/
private void advectVectorsWrapper(float timestep){
advectVectors(DIM, chunkMask, uVector, vVector, wVector, uAdditionVector, vAdditionVector, wAdditionVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void advectVectors(int DIM_X, int chunkMask, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], ByteBuffer u0, ByteBuffer v0, ByteBuffer w0, float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Adds density to the simulation
*/
private void addDensityWrapper(float timestep){
addDensity(DIM, chunkMask, density, densityAddition, timestep);
}
private native void addDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer x0, float timestep);
/**
* Solve density diffusion
*/
private void setupDiffuseDensityWrapper(float timestep){
setupDiffuseDensity(DIM, chunkMask, density, densityAddition, uVector, vVector, wVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void setupDiffuseDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer x0, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Solve density diffusion
*/
private void solveDiffuseDensityWrapper(float timestep){
solveDiffuseDensity(DIM, chunkMask, density, densityAddition, uVector, vVector, wVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void solveDiffuseDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer x0, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
* Solve density diffusion
*/
private void advectDensityWrapper(float timestep){
advectDensity(DIM, chunkMask, density, densityAddition, uVector, vVector, wVector, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
}
private native void advectDensity(int DIM_X, int chunkMask, ByteBuffer[] x, ByteBuffer x0, ByteBuffer[] u, ByteBuffer v[], ByteBuffer w[], float DIFFUSION_CONSTANT, float VISCOSITY_CONSTANT, float timestep);
/**
@ -257,42 +682,48 @@ public class FluidSim {
}
}
/**
* The native function call to simulate a frame of fluid
* @param DIM_X
* @param DIM_Y
* @param DIM_Z
* @param x
* @param x0
* @param u
* @param v
* @param w
* @param u0
* @param v0
* @param w0
* @param DIFFUSION_CONSTANT
* @param VISCOSITY_CONSTANT
* @param timestep
*/
private native void simulate(
int DIM_X,
int chunkMask,
ByteBuffer[] x,
ByteBuffer x0,
ByteBuffer[] u,
ByteBuffer[] v,
ByteBuffer[] w,
ByteBuffer u0,
ByteBuffer v0,
ByteBuffer w0,
float DIFFUSION_CONSTANT,
float VISCOSITY_CONSTANT,
float timestep
);
private native void linSolve(int chunk_mask, int N, int b, ByteBuffer x, ByteBuffer x0, float a, float c);
private native int calculateChunkMask(ByteBuffer[] densityBuffers);
public float[] getData(){
return densityArrayView;