This commit is contained in:
parent
da4e46daaf
commit
e6e469bec1
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -24,6 +24,11 @@
|
||||
"pool.h": "c",
|
||||
"mainfunctions.h": "c",
|
||||
"solver_consts.h": "c",
|
||||
"public.h": "c"
|
||||
"public.h": "c",
|
||||
"islandsolver.h": "c",
|
||||
"stb_ds.h": "c",
|
||||
"test.h": "c",
|
||||
"stdlib.h": "c",
|
||||
"chunk_test_utils.h": "c"
|
||||
}
|
||||
}
|
||||
@ -28,6 +28,22 @@ typedef struct {
|
||||
float * w0[27];
|
||||
int chunkMask;
|
||||
jobject chunkJRaw;
|
||||
|
||||
/**
|
||||
* The world x coordinate of this chunk
|
||||
*/
|
||||
int x;
|
||||
|
||||
/**
|
||||
* The world y coordinate of this chunk
|
||||
*/
|
||||
int y;
|
||||
|
||||
/**
|
||||
* The world z coordinate of this chunk
|
||||
*/
|
||||
int z;
|
||||
|
||||
} Chunk;
|
||||
|
||||
/**
|
||||
@ -40,25 +56,45 @@ typedef struct {
|
||||
*/
|
||||
#define SPARSE_ARRAY_CHUNK_DIM 7
|
||||
|
||||
/**
|
||||
* The number of chunks to place next to one another
|
||||
*/
|
||||
#define SPARSE_ARRAY_CHUNK_RADIUS 3
|
||||
|
||||
/**
|
||||
* The total number of chunks in the chunk tracking array
|
||||
*/
|
||||
#define SPARSE_ARRAY_TOTAL_CHUNKS SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM
|
||||
#define SPARSE_ARRAY_TOTAL_CHUNKS (SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM)
|
||||
|
||||
/**
|
||||
* The extra values at the edges of the sparse array (to allow pulling data from borders)
|
||||
*/
|
||||
#define SPARSE_ARRAY_BORDER_SIZE 2
|
||||
|
||||
/**
|
||||
* The size of the real data in the sparse array (not including bounds)
|
||||
*/
|
||||
#define SPARSE_ARRAY_REAL_DATA_SIZE (SPARSE_ARRAY_CHUNK_DIM * MAIN_ARRAY_DIM)
|
||||
|
||||
/**
|
||||
* The size of the dimension of the memory of the sparse array
|
||||
*/
|
||||
#define SPARSE_ARRAY_RAW_DIM ((SPARSE_ARRAY_CHUNK_DIM * MAIN_ARRAY_DIM) + SPARSE_ARRAY_BORDER_SIZE)
|
||||
#define SPARSE_ARRAY_RAW_DIM (SPARSE_ARRAY_REAL_DATA_SIZE + SPARSE_ARRAY_BORDER_SIZE)
|
||||
|
||||
/**
|
||||
* The size of a sparse array in number of elements
|
||||
*/
|
||||
#define SPARSE_ARRAY_FULL_SIZE SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM
|
||||
#define SPARSE_ARRAY_FULL_SIZE (SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM)
|
||||
|
||||
/**
|
||||
* The unit of spacial distance
|
||||
*/
|
||||
#define SPATIAL_UNIT 1
|
||||
|
||||
/**
|
||||
* The size of the sparse array in spatial units
|
||||
*/
|
||||
#define SPARSE_ARRAY_SPATIAL_SIZE (SPARSE_ARRAY_RAW_DIM * SPATIAL_UNIT)
|
||||
|
||||
/**
|
||||
* A set of sparse matricies for simulating fluids
|
||||
@ -138,4 +174,17 @@ LIBRARY_API void fluid_sparse_array_remove_chunk(SparseChunkArray * array, Chunk
|
||||
*/
|
||||
LIBRARY_API int fluid_sparse_array_get_index(SparseChunkArray * array, int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Cleans the sparse array
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_clean(SparseChunkArray * array);
|
||||
|
||||
/**
|
||||
* Gets the number of chunks in the sparse array
|
||||
*/
|
||||
LIBRARY_API int fluid_sparse_array_get_chunk_count(SparseChunkArray * array);
|
||||
|
||||
int GCI(int x, int y, int z);
|
||||
int GVI(int x, int y, int z);
|
||||
|
||||
#endif
|
||||
79
src/main/c/includes/fluid/islandsolver.h
Normal file
79
src/main/c/includes/fluid/islandsolver.h
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
|
||||
//Must be included for public functions to be imported/exported on windows
|
||||
#include "public.h"
|
||||
|
||||
#ifndef ISLANDSOLVER_H
|
||||
#define ISLANDSOLVER_H
|
||||
|
||||
#include "chunk.h"
|
||||
|
||||
/**
|
||||
* A set of sparse matricies for simulating fluids
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
/**
|
||||
* The chunks that still need to be solved
|
||||
*/
|
||||
Chunk ** remaining;
|
||||
|
||||
/**
|
||||
* The chunks that have already been solved for
|
||||
*/
|
||||
Chunk ** solved;
|
||||
|
||||
/**
|
||||
* The sparse array
|
||||
*/
|
||||
SparseChunkArray * sparseArray;
|
||||
|
||||
/**
|
||||
* The number of chunks in the currently solved island
|
||||
*/
|
||||
int currentChunks;
|
||||
|
||||
} FluidIslandSolver;
|
||||
|
||||
/**
|
||||
* Creates a fluid island solver
|
||||
*/
|
||||
LIBRARY_API FluidIslandSolver * fluid_island_solver_create();
|
||||
|
||||
/**
|
||||
* Frees a fluid island solver
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_free(FluidIslandSolver * solver);
|
||||
|
||||
/**
|
||||
* Adds a chunk to the fluid island solver
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_add_chunk(FluidIslandSolver * solver, Chunk * chunk);
|
||||
|
||||
/**
|
||||
* Adds a chunk to the fluid island solver
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_remove_chunk(FluidIslandSolver * solver, Chunk * chunk);
|
||||
|
||||
/**
|
||||
* Solves for the next available island
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_solve_island(FluidIslandSolver * solver);
|
||||
|
||||
/**
|
||||
* Gets the number of chunks in the current island
|
||||
*/
|
||||
LIBRARY_API int fluid_island_solver_get_chunk_count(FluidIslandSolver * solver);
|
||||
|
||||
/**
|
||||
* Gets the sparse array in the solver
|
||||
*/
|
||||
LIBRARY_API SparseChunkArray * fluid_island_solver_get_sparse_array(FluidIslandSolver * solver);
|
||||
|
||||
/**
|
||||
* Gets the number of chunks that still need to be solved for
|
||||
*/
|
||||
LIBRARY_API int fluid_island_solver_get_remaining(FluidIslandSolver * solver);
|
||||
|
||||
|
||||
#endif
|
||||
74
src/main/c/includes/fluid/sparsesimulator.h
Normal file
74
src/main/c/includes/fluid/sparsesimulator.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef SPARSESIMULATOR_H
|
||||
#define SPARSESIMULATOR_H
|
||||
|
||||
//Must be included for public functions to be imported/exported on windows
|
||||
#include "public.h"
|
||||
|
||||
#include "chunk.h"
|
||||
|
||||
/**
|
||||
* Simulates a sparse array
|
||||
*/
|
||||
LIBRARY_API int fluid_sparse_array_simulate(SparseChunkArray * array, float dt);
|
||||
|
||||
/**
|
||||
* Adds values from a source array to a current frame array (eg more density to the main density array)
|
||||
* @param x The array to store into
|
||||
* @param s The source array to pull from
|
||||
* @param dt The delta time of the simulation
|
||||
*/
|
||||
void fluid_sparse_array_add_source(float * x, float * s, float dt);
|
||||
|
||||
/**
|
||||
* Diffuses an array
|
||||
* @param b The axis to diffuse along
|
||||
* @param x The array to store the diffuse values
|
||||
* @param x0 The array that contains the first order derivatives
|
||||
* @param diff The diffuse constant
|
||||
* @param dt The delta time of the simulation
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_diffuse(int b, float * x, float * x0, float diff, float dt);
|
||||
|
||||
/**
|
||||
* Advects an array
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_advect(int N, int b, float * d, float * d0, float * u, float * v, float * w, float dt);
|
||||
|
||||
/**
|
||||
* Projects an array
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_project(int N, float * u, float * v, float * w, float * p, float * div);
|
||||
|
||||
/**
|
||||
* Sets the bounds of the simulation
|
||||
* @param b The axis to set bounds along
|
||||
* @param target The array to set the bounds of
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_set_bnd(int b, float * target);
|
||||
|
||||
/**
|
||||
* Performs the density step
|
||||
* @param x The density array
|
||||
* @param x0 The delta-density array
|
||||
* @param u The x velocity array
|
||||
* @param v The y velocity array
|
||||
* @param w THe z velocity array
|
||||
* @param diff The diffuse constant
|
||||
* @param dt The delta time for the simulation
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_dens_step(float * x, float * x0, float * u, float * v, float * w, float diff, float dt);
|
||||
|
||||
/**
|
||||
* Performs the velocity step
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_vel_step(int N, float * u, float * v, float * w, float * u0, float * v0, float * w0, float visc, float dt);
|
||||
|
||||
/**
|
||||
* Solves a linear system of equations in a vectorized manner
|
||||
* @param b The axis to set the bounds along
|
||||
* @param x The array that will contain the solved equations
|
||||
* @param x0 The array containing the first order derivatives
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_lin_solve(int b, float * x, float * x0);
|
||||
|
||||
#endif
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
# Find sources
|
||||
file(GLOB_RECURSE SOURCES "*.c")
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.c")
|
||||
|
||||
# include jni
|
||||
set(JAVA_AWT_LIBRARY NotNeeded)
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
|
||||
|
||||
|
||||
int GCI(int x, int y, int z);
|
||||
int GVI(int x, int y, int z);
|
||||
int solveOffset(int chunkPos);
|
||||
|
||||
/**
|
||||
@ -156,9 +154,10 @@ LIBRARY_API void fluid_sparse_array_remove_chunk(SparseChunkArray * array, Chunk
|
||||
int minPos = (SPARSE_ARRAY_BORDER_SIZE / 2);
|
||||
int i, j, k;
|
||||
|
||||
for(int m = 0; m < MAIN_ARRAY_DIM; m++){
|
||||
for(int n = 0; n < MAIN_ARRAY_DIM; n++){
|
||||
for(int o = 0; o < MAIN_ARRAY_DIM; o++){
|
||||
//we add +1 to the dimension to copy the neighbors into the chunk
|
||||
for(int m = 0; m < MAIN_ARRAY_DIM + 1; m++){
|
||||
for(int n = 0; n < MAIN_ARRAY_DIM + 1; n++){
|
||||
for(int o = 0; o < MAIN_ARRAY_DIM + 1; o++){
|
||||
i = m + 1;
|
||||
j = n + 1;
|
||||
k = o + 1;
|
||||
@ -223,6 +222,46 @@ LIBRARY_API int fluid_sparse_array_get_index(SparseChunkArray * array, int x, in
|
||||
return GVI(x,y,z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the sparse array
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_clean(SparseChunkArray * array){
|
||||
for(int x = 0; x < SPARSE_ARRAY_RAW_DIM; x++){
|
||||
for(int y = 0; y < SPARSE_ARRAY_RAW_DIM; y++){
|
||||
for(int z = 0; z < SPARSE_ARRAY_RAW_DIM; z++){
|
||||
array->d[GVI(x,y,z)] = 0;
|
||||
array->d0[GVI(x,y,z)] = 0;
|
||||
array->u[GVI(x,y,z)] = 0;
|
||||
array->v[GVI(x,y,z)] = 0;
|
||||
array->w[GVI(x,y,z)] = 0;
|
||||
array->u0[GVI(x,y,z)] = 0;
|
||||
array->v0[GVI(x,y,z)] = 0;
|
||||
array->w0[GVI(x,y,z)] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int x = 0; x < SPARSE_ARRAY_CHUNK_DIM; x++){
|
||||
for(int y = 0; y < SPARSE_ARRAY_CHUNK_DIM; y++){
|
||||
for(int z = 0; z < SPARSE_ARRAY_CHUNK_DIM; z++){
|
||||
array->chunks[GCI(x,y,z)] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of chunks in the sparse array
|
||||
*/
|
||||
LIBRARY_API int fluid_sparse_array_get_chunk_count(SparseChunkArray * array){
|
||||
int rVal = 0;
|
||||
for(int i = 0; i < SPARSE_ARRAY_TOTAL_CHUNKS; i++){
|
||||
if(array->chunks[i] != NULL){
|
||||
rVal++;
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the chunk at a given position within the sparse array
|
||||
*/
|
||||
|
||||
141
src/main/c/src/fluid/islandsolver.c
Normal file
141
src/main/c/src/fluid/islandsolver.c
Normal file
@ -0,0 +1,141 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../lib/stb/stb_ds.h"
|
||||
|
||||
#include "fluid/islandsolver.h"
|
||||
#include "fluid/chunk.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a fluid island solver
|
||||
*/
|
||||
LIBRARY_API FluidIslandSolver * fluid_island_solver_create(){
|
||||
FluidIslandSolver * rVal = (FluidIslandSolver *)malloc(sizeof(FluidIslandSolver));
|
||||
|
||||
rVal->sparseArray = fluid_sparse_array_create();
|
||||
rVal->remaining = NULL;
|
||||
rVal->solved = NULL;
|
||||
rVal->currentChunks = 0;
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a fluid island solver
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_free(FluidIslandSolver * solver){
|
||||
fluid_sparse_array_free(solver->sparseArray);
|
||||
free(solver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a chunk to the fluid island solver
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_add_chunk(FluidIslandSolver * solver, Chunk * chunk){
|
||||
stbds_arrput(solver->remaining,chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a chunk to the fluid island solver
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_remove_chunk(FluidIslandSolver * solver, Chunk * chunk){
|
||||
for(int i = 0; i < stbds_arrlen(solver->remaining); i++){
|
||||
if(solver->remaining[i] == chunk){
|
||||
stbds_arrdel(solver->remaining,i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < stbds_arrlen(solver->solved); i++){
|
||||
if(solver->solved[i] == chunk){
|
||||
stbds_arrdel(solver->solved,i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Solves for the next available island
|
||||
*/
|
||||
LIBRARY_API void fluid_island_solver_solve_island(FluidIslandSolver * solver){
|
||||
if(fluid_island_solver_get_remaining(solver) < 1){
|
||||
printf("Tried to solve a solver with 0 remaining! \n");
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
//clear the existing values
|
||||
fluid_sparse_array_clean(solver->sparseArray);
|
||||
|
||||
//fill in sparse array based on the first found chunk
|
||||
Chunk * target = stbds_arrpop(solver->remaining);
|
||||
fluid_sparse_array_add_chunk(
|
||||
solver->sparseArray,
|
||||
target,
|
||||
SPARSE_ARRAY_CHUNK_RADIUS,
|
||||
SPARSE_ARRAY_CHUNK_RADIUS,
|
||||
SPARSE_ARRAY_CHUNK_RADIUS
|
||||
);
|
||||
|
||||
//add neighbors of the target
|
||||
for(int i = 0; i < stbds_arrlen(solver->remaining); i++){
|
||||
Chunk * current = solver->remaining[i];
|
||||
// printf("%d %d %d %d %d\n",
|
||||
// abs(current->x - target->x) <= SPARSE_ARRAY_CHUNK_RADIUS,
|
||||
// abs(current->y - target->y) <= SPARSE_ARRAY_CHUNK_RADIUS,
|
||||
// abs(current->z - target->z) <= SPARSE_ARRAY_CHUNK_RADIUS,
|
||||
// target->x,
|
||||
// current->x
|
||||
// );
|
||||
if(
|
||||
abs(current->x - target->x) <= SPARSE_ARRAY_CHUNK_RADIUS &&
|
||||
abs(current->y - target->y) <= SPARSE_ARRAY_CHUNK_RADIUS &&
|
||||
abs(current->z - target->z) <= SPARSE_ARRAY_CHUNK_RADIUS
|
||||
){
|
||||
//remove this chunk from the remaining array
|
||||
stbds_arrdel(solver->remaining,i);
|
||||
i--;
|
||||
//add to sparse array
|
||||
int xPos = SPARSE_ARRAY_CHUNK_RADIUS + (current->x - target->x);
|
||||
int yPos = SPARSE_ARRAY_CHUNK_RADIUS + (current->y - target->y);
|
||||
int zPos = SPARSE_ARRAY_CHUNK_RADIUS + (current->z - target->z);
|
||||
if(
|
||||
xPos < 0 || xPos >= SPARSE_ARRAY_CHUNK_DIM ||
|
||||
yPos < 0 || yPos >= SPARSE_ARRAY_CHUNK_DIM ||
|
||||
zPos < 0 || zPos >= SPARSE_ARRAY_CHUNK_DIM
|
||||
){
|
||||
printf("Invalid insertion position! %d %d %d \n",xPos,yPos,zPos);
|
||||
fflush(stdout);
|
||||
}
|
||||
fluid_sparse_array_add_chunk(solver->sparseArray,current,xPos,yPos,zPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of chunks in the current island
|
||||
*/
|
||||
LIBRARY_API int fluid_island_solver_get_chunk_count(FluidIslandSolver * solver){
|
||||
return fluid_sparse_array_get_chunk_count(solver->sparseArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sparse array in the solver
|
||||
*/
|
||||
LIBRARY_API SparseChunkArray * fluid_island_solver_get_sparse_array(FluidIslandSolver * solver){
|
||||
return solver->sparseArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of chunks that still need to be solved for
|
||||
*/
|
||||
LIBRARY_API int fluid_island_solver_get_remaining(FluidIslandSolver * solver){
|
||||
return stbds_arrlen(solver->remaining);
|
||||
}
|
||||
|
||||
|
||||
192
src/main/c/src/fluid/sparsesimulator.c
Normal file
192
src/main/c/src/fluid/sparsesimulator.c
Normal file
@ -0,0 +1,192 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "../../lib/stb/stb_ds.h"
|
||||
|
||||
#include "fluid/chunk.h"
|
||||
#include "fluid/islandsolver.h"
|
||||
#include "fluid/sparsesimulator.h"
|
||||
#include "fluid/utilities.h"
|
||||
|
||||
#define LINEARSOLVERTIMES 10
|
||||
|
||||
/**
|
||||
* Simulates a sparse array
|
||||
*/
|
||||
LIBRARY_API int fluid_sparse_array_simulate(SparseChunkArray * array, float dt){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Adds values from a source array to a current frame array (eg more density to the main density array)
|
||||
* @param x The array to store into
|
||||
* @param s The source array to pull from
|
||||
* @param dt The delta time of the simulation
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_add_source(float * x, float * s, float dt){
|
||||
int i;
|
||||
int size=SPARSE_ARRAY_FULL_SIZE;
|
||||
for(i=0; i<size; i++){
|
||||
x[i] += dt*s[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Diffuses a given array by a diffusion constant
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_diffuse(int b, float * x, float * x0, float diff, float dt){
|
||||
float a=dt*diff*SPARSE_ARRAY_SPATIAL_SIZE*SPARSE_ARRAY_SPATIAL_SIZE*SPARSE_ARRAY_SPATIAL_SIZE;
|
||||
fluid_sparse_array_lin_solve(b, x, x0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advects a given array based on the force vectors in the simulation
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_advect(int N, int b, float * d, float * d0, float * u, float * v, float * w, float dt){
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the density step
|
||||
* @param x The density array
|
||||
* @param x0 The delta-density array
|
||||
* @param u The x velocity array
|
||||
* @param v The y velocity array
|
||||
* @param w THe z velocity array
|
||||
* @param diff The diffuse constant
|
||||
* @param dt The delta time for the simulation
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_dens_step(float * x, float * x0, float * u, float * v, float * w, float diff, float dt){
|
||||
fluid_sparse_array_add_source(x, x0, dt);
|
||||
SWAP(x0, x);
|
||||
fluid_sparse_array_diffuse(0, x, x0, diff, dt);
|
||||
// SWAP(x0, x);
|
||||
// fluid_sparse_array_advect(N, 0, x, x0, u, v, w, dt);
|
||||
}
|
||||
|
||||
/**
|
||||
* The main velocity step function
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_vel_step(int N, float * u, float * v, float * w, float * u0, float * v0, float * w0, float visc, float dt){
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects a given array based on force vectors
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_project(int N, float * u, float * v, float * w, float * p, float * div){
|
||||
}
|
||||
|
||||
/**
|
||||
* Solves a linear system of equations in a vectorized manner
|
||||
* @param b The axis to set the bounds along
|
||||
* @param x The array that will contain the solved equations
|
||||
* @param x0 The array containing the first order derivatives
|
||||
* @param a
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_lin_solve(int b, float * x, float * x0){
|
||||
int i, j, k, l, m;
|
||||
int a = 0;
|
||||
int c = 0;
|
||||
__m256 aScalar = _mm256_set1_ps(0);
|
||||
__m256 cScalar = _mm256_set1_ps(0);
|
||||
int vectorSize = 8;
|
||||
// iterate the solver
|
||||
for(l = 0; l < LINEARSOLVERTIMES; l++){
|
||||
// update for each cell
|
||||
for(k = (SPARSE_ARRAY_BORDER_SIZE / 2); k < SPARSE_ARRAY_RAW_DIM - (SPARSE_ARRAY_BORDER_SIZE / 2); k++){
|
||||
for(j = (SPARSE_ARRAY_BORDER_SIZE / 2); j < SPARSE_ARRAY_RAW_DIM - (SPARSE_ARRAY_BORDER_SIZE / 2); j++){
|
||||
int n = 0;
|
||||
//solve as much as possible vectorized
|
||||
for(i = (SPARSE_ARRAY_BORDER_SIZE / 2); i < SPARSE_ARRAY_RAW_DIM - (SPARSE_ARRAY_BORDER_SIZE / 2); i = i + vectorSize){
|
||||
__m256 vector = _mm256_loadu_ps(&x[GVI(i-1,j,k)]);
|
||||
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[GVI(i+1,j,k)]));
|
||||
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[GVI(i,j-1,k)]));
|
||||
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[GVI(i,j+1,k)]));
|
||||
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[GVI(i,j,k-1)]));
|
||||
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[GVI(i,j,k+1)]));
|
||||
vector = _mm256_mul_ps(vector,aScalar);
|
||||
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x0[GVI(i,j,k)]));
|
||||
vector = _mm256_div_ps(vector,cScalar);
|
||||
_mm256_storeu_ps(&x[GVI(i,j,k)],vector);
|
||||
}
|
||||
//If there is any leftover, perform manual solving
|
||||
if(i > SPARSE_ARRAY_RAW_DIM - (SPARSE_ARRAY_BORDER_SIZE / 2)){
|
||||
for(i = i - vectorSize; i < (SPARSE_ARRAY_RAW_DIM - (SPARSE_ARRAY_BORDER_SIZE / 2)); i++){
|
||||
/*
|
||||
want to solve the second derivative of the grid
|
||||
x0 stores the first derivative
|
||||
start with x being 0 in all locations
|
||||
then take the difference along x0 and store it in x
|
||||
this is approximating the derivative
|
||||
|
||||
equation looks something like
|
||||
|
||||
2nd deriv = x0 +
|
||||
|
||||
*/
|
||||
//phi is the scalar potential
|
||||
//want to solve the laplacian
|
||||
//laplacian is derivative of phi over the gid spacing squared along each dimension
|
||||
//the derivative of phi is just phi(x+1) - 2 * phi(x) + phi(x-1) along each axis "x"
|
||||
//we are grabbing phi from the x array
|
||||
x[GVI(i,j,k)] = (x0[GVI(i,j,k)] + a*(x[GVI(i-1,j,k)]+x[GVI(i+1,j,k)]+x[GVI(i,j-1,k)]+x[GVI(i,j+1,k)]+x[GVI(i,j,k-1)]+x[GVI(i,j,k+1)]))/c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fluid_sparse_array_set_bnd(b, x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bounds of the simulation
|
||||
* @param b The axis to set bounds along
|
||||
* @param target The array to set the bounds of
|
||||
*/
|
||||
LIBRARY_API void fluid_sparse_array_set_bnd(int b, float * target){
|
||||
for(int x=1; x < SPARSE_ARRAY_RAW_DIM-1; x++){
|
||||
for(int y = 1; y < SPARSE_ARRAY_RAW_DIM-1; y++){
|
||||
//((x)+(DIM)*(y) + (DIM)*(DIM)*(z))
|
||||
target[0 + SPARSE_ARRAY_RAW_DIM * x + SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM * y] =
|
||||
b==1 ?
|
||||
-target[1 + SPARSE_ARRAY_RAW_DIM * x + SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM * y]
|
||||
:
|
||||
target[1 + SPARSE_ARRAY_RAW_DIM * x + SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM * y]
|
||||
;
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,x,y)] = b==1 ? -target[IX(SPARSE_ARRAY_RAW_DIM-2,x,y)] : target[IX(SPARSE_ARRAY_RAW_DIM-2,x,y)];
|
||||
target[IX(x,0,y)] = b==2 ? -target[IX(x,1,y)] : target[IX(x,1,y)];
|
||||
target[IX(x,SPARSE_ARRAY_RAW_DIM-1,y)] = b==2 ? -target[IX(x,SPARSE_ARRAY_RAW_DIM-2,y)] : target[IX(x,SPARSE_ARRAY_RAW_DIM-2,y)];
|
||||
target[IX(x,y,0)] = b==3 ? -target[IX(x,y,1)] : target[IX(x,y,1)];
|
||||
target[IX(x,y,SPARSE_ARRAY_RAW_DIM-1)] = b==3 ? -target[IX(x,y,SPARSE_ARRAY_RAW_DIM-2)] : target[IX(x,y,SPARSE_ARRAY_RAW_DIM-2)];
|
||||
}
|
||||
}
|
||||
for(int x = 1; x < SPARSE_ARRAY_RAW_DIM-1; x++){
|
||||
target[IX(x,0,0)] = (float)(0.5f * (target[IX(x,1,0)] + target[IX(x,0,1)]));
|
||||
target[IX(x,SPARSE_ARRAY_RAW_DIM-1,0)] = (float)(0.5f * (target[IX(x,SPARSE_ARRAY_RAW_DIM-2,0)] + target[IX(x,SPARSE_ARRAY_RAW_DIM-1,1)]));
|
||||
target[IX(x,0,SPARSE_ARRAY_RAW_DIM-1)] = (float)(0.5f * (target[IX(x,1,SPARSE_ARRAY_RAW_DIM-1)] + target[IX(x,0,SPARSE_ARRAY_RAW_DIM-2)]));
|
||||
target[IX(x,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1)] = (float)(0.5f * (target[IX(x,SPARSE_ARRAY_RAW_DIM-2,SPARSE_ARRAY_RAW_DIM-1)] + target[IX(x,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2)]));
|
||||
|
||||
target[IX(0,x,0)] = (float)(0.5f * (target[IX(1,x,0)] + target[IX(0,x,1)]));
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,x,0)] = (float)(0.5f * (target[IX(SPARSE_ARRAY_RAW_DIM-2,x,0)] + target[IX(SPARSE_ARRAY_RAW_DIM-1,x,1)]));
|
||||
target[IX(0,x,SPARSE_ARRAY_RAW_DIM-1)] = (float)(0.5f * (target[IX(1,x,SPARSE_ARRAY_RAW_DIM-1)] + target[IX(0,x,SPARSE_ARRAY_RAW_DIM-2)]));
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,x,SPARSE_ARRAY_RAW_DIM-1)] = (float)(0.5f * (target[IX(SPARSE_ARRAY_RAW_DIM-2,x,SPARSE_ARRAY_RAW_DIM-1)] + target[IX(SPARSE_ARRAY_RAW_DIM-1,x,SPARSE_ARRAY_RAW_DIM-2)]));
|
||||
|
||||
|
||||
target[IX(0,0,x)] = (float)(0.5f * (target[IX(1,0,x)] + target[IX(0,1,x)]));
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,0,x)] = (float)(0.5f * (target[IX(SPARSE_ARRAY_RAW_DIM-2,0,x)] + target[IX(SPARSE_ARRAY_RAW_DIM-1,1,x)]));
|
||||
target[IX(0,SPARSE_ARRAY_RAW_DIM-1,x)] = (float)(0.5f * (target[IX(1,SPARSE_ARRAY_RAW_DIM-1,x)] + target[IX(0,SPARSE_ARRAY_RAW_DIM-2,x)]));
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1,x)] = (float)(0.5f * (target[IX(SPARSE_ARRAY_RAW_DIM-2,SPARSE_ARRAY_RAW_DIM-1,x)] + target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2,x)]));
|
||||
|
||||
}
|
||||
target[IX(0,0,0)] = (float)((target[IX(1,0,0)]+target[IX(0,1,0)]+target[IX(0,0,1)])/3.0);
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,0,0)] = (float)((target[IX(SPARSE_ARRAY_RAW_DIM-2,0,0)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,1,0)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,0,1)])/3.0);
|
||||
target[IX(0,SPARSE_ARRAY_RAW_DIM-1,0)] = (float)((target[IX(1,SPARSE_ARRAY_RAW_DIM-1,0)]+target[IX(0,SPARSE_ARRAY_RAW_DIM-2,0)]+target[IX(0,SPARSE_ARRAY_RAW_DIM-1,1)])/3.0);
|
||||
target[IX(0,0,SPARSE_ARRAY_RAW_DIM-1)] = (float)((target[IX(0,0,SPARSE_ARRAY_RAW_DIM-2)]+target[IX(1,0,SPARSE_ARRAY_RAW_DIM-1)]+target[IX(0,1,SPARSE_ARRAY_RAW_DIM-1)])/3.0);
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1,0)] = (float)((target[IX(SPARSE_ARRAY_RAW_DIM-2,SPARSE_ARRAY_RAW_DIM-1,0)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2,0)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1,1)])/3.0);
|
||||
target[IX(0,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1)] = (float)((target[IX(1,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1)]+target[IX(0,SPARSE_ARRAY_RAW_DIM-2,SPARSE_ARRAY_RAW_DIM-1)]+target[IX(0,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2)])/3.0);
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,0,SPARSE_ARRAY_RAW_DIM-1)] = (float)((target[IX(SPARSE_ARRAY_RAW_DIM-1,0,SPARSE_ARRAY_RAW_DIM-2)]+target[IX(SPARSE_ARRAY_RAW_DIM-2,0,SPARSE_ARRAY_RAW_DIM-1)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,1,SPARSE_ARRAY_RAW_DIM-1)])/3.0);
|
||||
target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1)] = (float)((target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2,SPARSE_ARRAY_RAW_DIM-1)]+target[IX(SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-1,SPARSE_ARRAY_RAW_DIM-2)])/3.0);
|
||||
}
|
||||
@ -9,7 +9,7 @@ else()
|
||||
endif()
|
||||
|
||||
# Grab test files
|
||||
file(GLOB_RECURSE TEST_FILES "*.c")
|
||||
file(GLOB_RECURSE TEST_FILES CONFIGURE_DEPENDS "*.c")
|
||||
set(TEST_DRIVER test_driver.c)
|
||||
|
||||
# include and enable testing
|
||||
|
||||
68
test/c/fluid/chunk_test_utils.h
Normal file
68
test/c/fluid/chunk_test_utils.h
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
#ifndef CHUNK_TEST_UTILS_H
|
||||
#define CHUNK_TEST_UTILS_H
|
||||
|
||||
#include "fluid/chunk.h"
|
||||
|
||||
|
||||
/**
|
||||
* Array id of the d array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_D 0
|
||||
|
||||
/**
|
||||
* Array id of the d0 array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_D0 1
|
||||
|
||||
/**
|
||||
* Array id of the u array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_U 2
|
||||
|
||||
/**
|
||||
* Array id of the v array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_V 3
|
||||
|
||||
/**
|
||||
* Array id of the w array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_W 4
|
||||
|
||||
/**
|
||||
* Array id of the u0 array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_U0 5
|
||||
|
||||
/**
|
||||
* Array id of the v0 array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_V0 6
|
||||
|
||||
/**
|
||||
* Array id of the w0 array for chunk_set_val
|
||||
*/
|
||||
#define ARR_ID_W0 7
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a chunk at a world position
|
||||
*/
|
||||
Chunk * chunk_create(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Frees a chunk
|
||||
*/
|
||||
void chunk_free(Chunk * chunk);
|
||||
|
||||
/**
|
||||
* Sets a chunk's value
|
||||
* @param chunk The chunk
|
||||
* @param i The value to set the array to
|
||||
* @param arr THe array to set
|
||||
*/
|
||||
void chunk_set_val(Chunk * chunk, int i, int arr);
|
||||
|
||||
#endif
|
||||
@ -65,6 +65,9 @@ int fluid_chunk_tests(int argc, char **argv){
|
||||
rVal += assertEquals(sparseArray->d[fluid_sparse_array_get_index(sparseArray,16,16,16)],chunk1->d[CENTER_LOC][IX(15,15,15)],"index 16,16,16 in the sparse array should be 15,15,15 of the chunk stored at 0,0,0 -- %d %d\n");
|
||||
rVal += assertEquals(sparseArray->d[fluid_sparse_array_get_index(sparseArray,17,1,1)],chunk2->d[CENTER_LOC][IX(1,1,1)],"index 17,1,1 in the sparse array should be 1,1,1 of the chunk stored at 1,0,0 -- %d %d\n");
|
||||
|
||||
//validate fluid_sparse_array_get_chunk_count
|
||||
rVal += assertEquals(fluid_sparse_array_get_chunk_count(sparseArray),2,"Sparse array not counting chunks correctly -- %d %d \n");
|
||||
|
||||
|
||||
//set some value in sparse array for future tests
|
||||
sparseArray->d[fluid_sparse_array_get_index(sparseArray,17,1,1)] = 6;
|
||||
@ -81,6 +84,10 @@ int fluid_chunk_tests(int argc, char **argv){
|
||||
fluid_sparse_array_remove_chunk(sparseArray,chunk1,0,0,0);
|
||||
rVal += assertNotEquals(chunk1->d[CENTER_LOC][IX(1,1,1)],6,"chunk should have received the value from the sparse array -- %d %d \n");
|
||||
|
||||
//clean the array and make sure it's clean
|
||||
fluid_sparse_array_clean(sparseArray);
|
||||
rVal += assertEquals(sparseArray->d[fluid_sparse_array_get_index(sparseArray,1,1,1)],0,"Array should have been cleaned -- %d %d \n");
|
||||
|
||||
|
||||
//free a sparse array
|
||||
fluid_sparse_array_free(sparseArray);
|
||||
|
||||
142
test/c/fluid/islandsolver_tests.c
Normal file
142
test/c/fluid/islandsolver_tests.c
Normal file
@ -0,0 +1,142 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fluid/chunk.h"
|
||||
#include "fluid/chunkmask.h"
|
||||
#include "fluid/utilities.h"
|
||||
#include "fluid/islandsolver.h"
|
||||
#include "../test.h"
|
||||
#include "chunk_test_utils.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a chunk at a world position
|
||||
*/
|
||||
Chunk * chunk_create(int x, int y, int z){
|
||||
Chunk * chunk1 = (Chunk *)malloc(sizeof(Chunk));
|
||||
chunk1->d[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->d0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->u[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->v[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->w[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->u0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->v0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->w0[CENTER_LOC] = (float *)malloc(DIM * DIM * DIM * sizeof(float));
|
||||
chunk1->x = x;
|
||||
chunk1->y = y;
|
||||
chunk1->z = z;
|
||||
return chunk1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a chunk
|
||||
*/
|
||||
void chunk_free(Chunk * chunk){
|
||||
free(chunk->d[CENTER_LOC]);
|
||||
free(chunk->d0[CENTER_LOC]);
|
||||
free(chunk->u[CENTER_LOC]);
|
||||
free(chunk->v[CENTER_LOC]);
|
||||
free(chunk->w[CENTER_LOC]);
|
||||
free(chunk->u0[CENTER_LOC]);
|
||||
free(chunk->v0[CENTER_LOC]);
|
||||
free(chunk->w0[CENTER_LOC]);
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a chunk's value
|
||||
* @param chunk The chunk
|
||||
* @param i The value to set the array to
|
||||
* @param arr THe array to set
|
||||
*/
|
||||
void chunk_set_val(Chunk * chunk, int i, int arr){
|
||||
for(int x = 0; x < DIM; x++){
|
||||
for(int y = 0; y < DIM; y++){
|
||||
for(int z = 0; z < DIM; z++){
|
||||
switch(arr){
|
||||
case ARR_ID_D: {
|
||||
chunk->d[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_D0: {
|
||||
chunk->d0[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_U: {
|
||||
chunk->u[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_V: {
|
||||
chunk->v[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_W: {
|
||||
chunk->w[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_U0: {
|
||||
chunk->u0[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_V0: {
|
||||
chunk->v0[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
case ARR_ID_W0: {
|
||||
chunk->w0[CENTER_LOC][x * DIM * DIM + y * DIM + z] = i;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int fluid_islandsolver_tests(int argc, char **argv){
|
||||
int rVal = 0;
|
||||
//allocate a sparse array
|
||||
FluidIslandSolver * islandSolver = fluid_island_solver_create();
|
||||
if(islandSolver == NULL){
|
||||
printf("Failed to allocate islandSolver!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//create chunks to add to the sparse array
|
||||
Chunk * chunk1 = chunk_create(0,0,0);
|
||||
Chunk * chunk2 = chunk_create(1,0,0);
|
||||
Chunk * chunk3 = chunk_create(7,0,0);
|
||||
|
||||
//test adding chunks
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk1);
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk2);
|
||||
rVal += assertEqualsPtr((void *)islandSolver->remaining[0],(void *)chunk1,"Failed to insert chunk1 \n");
|
||||
rVal += assertEqualsPtr((void *)islandSolver->remaining[1],(void *)chunk2,"Failed to insert chunk1 \n");
|
||||
rVal += assertNotEqualsPtr((void *)islandSolver->remaining[1],(void *)chunk1,"Failed to insert chunk1 \n");
|
||||
rVal += assertNotEqualsPtr((void *)islandSolver->remaining[0],(void *)chunk2,"Failed to insert chunk1 \n");
|
||||
|
||||
//test removing
|
||||
fluid_island_solver_remove_chunk(islandSolver,chunk1);
|
||||
rVal += assertEquals(fluid_island_solver_get_remaining(islandSolver),1,"remaining array should NOT be empty -- %d %d \n");
|
||||
fluid_island_solver_remove_chunk(islandSolver,chunk2);
|
||||
rVal += assertEquals(fluid_island_solver_get_remaining(islandSolver),0,"remaining array should be empty -- %d %d \n");
|
||||
|
||||
//solve an island
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk1);
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk2);
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk3);
|
||||
//this should solve for the lone chunk 3 island
|
||||
fluid_island_solver_solve_island(islandSolver);
|
||||
rVal += assertEquals(fluid_sparse_array_get_chunk_count(islandSolver->sparseArray),1,"sparse array should contain one element %d %d \n");
|
||||
//this should solve for the conjoined chunk1-chunk2 island
|
||||
fluid_island_solver_solve_island(islandSolver);
|
||||
rVal += assertEquals(fluid_sparse_array_get_chunk_count(islandSolver->sparseArray),2,"sparse array should contain two elements %d %d \n");
|
||||
rVal += assertEquals(fluid_island_solver_get_remaining(islandSolver),0,"there should be no remaining chunks %d %d \n");
|
||||
|
||||
//should be able to grab the sparse array from here still
|
||||
rVal += assertEqualsPtr(fluid_island_solver_get_sparse_array(islandSolver),islandSolver->sparseArray,"should be able to fetch the sparse array from the solver \n");
|
||||
|
||||
|
||||
|
||||
//free the test chunks
|
||||
chunk_free(chunk1);
|
||||
chunk_free(chunk2);
|
||||
chunk_free(chunk3);
|
||||
//free a sparse array
|
||||
fluid_island_solver_free(islandSolver);
|
||||
|
||||
return rVal;
|
||||
}
|
||||
137
test/c/fluid/sparsesimulator_tests.c
Normal file
137
test/c/fluid/sparsesimulator_tests.c
Normal file
@ -0,0 +1,137 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fluid/chunk.h"
|
||||
#include "fluid/chunkmask.h"
|
||||
#include "fluid/utilities.h"
|
||||
#include "fluid/islandsolver.h"
|
||||
#include "fluid/sparsesimulator.h"
|
||||
#include "../test.h"
|
||||
#include "chunk_test_utils.h"
|
||||
|
||||
#define TEST_DT 0.1
|
||||
#define TEST_DIFF_CONST 0.0001
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_fluid_sparse_array_add_source(){
|
||||
int rVal = 0;
|
||||
//allocate a sparse array
|
||||
FluidIslandSolver * islandSolver = fluid_island_solver_create();
|
||||
if(islandSolver == NULL){
|
||||
printf("Failed to allocate islandSolver!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
SparseChunkArray * sparseArray = islandSolver->sparseArray;
|
||||
|
||||
//create chunks to add to the sparse array
|
||||
Chunk * chunk1 = chunk_create(0,0,0);
|
||||
|
||||
int testVal = 1;
|
||||
|
||||
//add to island solver
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk1);
|
||||
chunk_set_val(chunk1,testVal,ARR_ID_D0);
|
||||
|
||||
//solve and simulate
|
||||
fluid_island_solver_solve_island(islandSolver);
|
||||
|
||||
//add source test
|
||||
fluid_sparse_array_add_source(sparseArray->d,sparseArray->d0, TEST_DT);
|
||||
//indices are weird because this chunk will be at the center of the sparse array
|
||||
int voxelIndex = MAIN_ARRAY_DIM + MAIN_ARRAY_DIM + MAIN_ARRAY_DIM + (SPARSE_ARRAY_BORDER_SIZE / 2);
|
||||
int index = fluid_sparse_array_get_index(sparseArray,voxelIndex,voxelIndex,voxelIndex);
|
||||
printf("voxelIndex: %d \n",voxelIndex);
|
||||
rVal += assertEqualsFloat(sparseArray->d[index],testVal * TEST_DT,"add source did not properly add the source to the array! %f %f \n");
|
||||
|
||||
|
||||
|
||||
//free the test chunks
|
||||
chunk_free(chunk1);
|
||||
//free a sparse array
|
||||
fluid_island_solver_free(islandSolver);
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_fluid_sparse_array_dens_step(){
|
||||
int rVal = 0;
|
||||
//allocate a sparse array
|
||||
FluidIslandSolver * islandSolver = fluid_island_solver_create();
|
||||
if(islandSolver == NULL){
|
||||
printf("Failed to allocate islandSolver!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
SparseChunkArray * sparseArray = islandSolver->sparseArray;
|
||||
|
||||
//create chunks to add to the sparse array
|
||||
Chunk * chunk1 = chunk_create(0,0,0);
|
||||
|
||||
int testVal = 1;
|
||||
|
||||
//add to island solver
|
||||
fluid_island_solver_add_chunk(islandSolver,chunk1);
|
||||
chunk_set_val(chunk1,testVal,ARR_ID_D0);
|
||||
|
||||
//solve and simulate
|
||||
fluid_island_solver_solve_island(islandSolver);
|
||||
|
||||
//add source test
|
||||
fluid_sparse_array_dens_step(sparseArray->d, sparseArray->d0, sparseArray->u, sparseArray->v, sparseArray->w, TEST_DIFF_CONST, TEST_DT);
|
||||
|
||||
|
||||
|
||||
//free the test chunks
|
||||
chunk_free(chunk1);
|
||||
//free a sparse array
|
||||
fluid_island_solver_free(islandSolver);
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int fluid_sparsesimulator_tests(int argc, char **argv){
|
||||
int rVal = 0;
|
||||
|
||||
rVal += test_fluid_sparse_array_add_source();
|
||||
rVal += test_fluid_sparse_array_dens_step();
|
||||
|
||||
return rVal;
|
||||
}
|
||||
@ -7,6 +7,25 @@ int assertEquals(int a, int b, char * msg){
|
||||
int rVal = (a != b);
|
||||
if(rVal){
|
||||
printf(msg, a, b);
|
||||
fflush(stdout);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
int assertEqualsPtr(void * a, void * b, char * msg){
|
||||
int rVal = (a != b);
|
||||
if(rVal){
|
||||
printf(msg, a, b);
|
||||
fflush(stdout);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
int assertEqualsFloat(float a, float b, char * msg){
|
||||
int rVal = (a != b);
|
||||
if(rVal){
|
||||
printf(msg, a, b);
|
||||
fflush(stdout);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
@ -15,6 +34,25 @@ int assertNotEquals(int a, int b, char * msg){
|
||||
int rVal = (a == b);
|
||||
if(rVal){
|
||||
printf(msg, a, b);
|
||||
fflush(stdout);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
int assertNotEqualsPtr(void * a, void * b, char * msg){
|
||||
int rVal = (a == b);
|
||||
if(rVal){
|
||||
printf(msg, a, b);
|
||||
fflush(stdout);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
int assertNotEqualsFloat(float a, float b, char * msg){
|
||||
int rVal = (a == b);
|
||||
if(rVal){
|
||||
printf(msg, a, b);
|
||||
fflush(stdout);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -5,4 +5,10 @@
|
||||
int assertEquals(int a, int b, char * msg);
|
||||
int assertNotEquals(int a, int b, char * msg);
|
||||
|
||||
int assertEqualsPtr(void * a, void * b, char * msg);
|
||||
int assertNotEqualsPtr(void * a, void * b, char * msg);
|
||||
|
||||
int assertEqualsFloat(float a, float b, char * msg);
|
||||
int assertNotEqualsFloat(float a, float b, char * msg);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user