From 2fda30c8c102310cbe49e5f5bf8a134014b1ce40 Mon Sep 17 00:00:00 2001 From: austin Date: Fri, 13 Dec 2024 19:54:09 -0500 Subject: [PATCH] grid2 work --- src/main/c/includes/fluid/env/environment.h | 1 + src/main/c/includes/fluid/sim/grid2/density.h | 4 + src/main/c/src/fluid/queue/javainterface.c | 1 + src/main/c/src/fluid/queue/metadatacalc.c | 15 ++- src/main/c/src/fluid/sim/grid2/density.c | 36 +++++- src/main/c/src/fluid/sim/grid2/grid2.c | 2 +- src/main/c/src/fluid/sim/grid2/utilities.c | 111 ++++++++++++++++-- .../ui/menu/debug/ImGuiFluidMonitor.java | 1 + .../fluid/manager/ServerFluidChunk.java | 13 ++ src/test/c/fluid/sim/grid2/full_sim_tests.c | 50 +++++--- 10 files changed, 202 insertions(+), 32 deletions(-) diff --git a/src/main/c/includes/fluid/env/environment.h b/src/main/c/includes/fluid/env/environment.h index 67be4901..9b735681 100644 --- a/src/main/c/includes/fluid/env/environment.h +++ b/src/main/c/includes/fluid/env/environment.h @@ -40,6 +40,7 @@ typedef struct { jfieldID asleepId; jfieldID homogenousId; jfieldID normalizationRatioId; + jfieldID massCountId; } ServerFluidChunkLookupTable; /** diff --git a/src/main/c/includes/fluid/sim/grid2/density.h b/src/main/c/includes/fluid/sim/grid2/density.h index bd2be3f9..56006acc 100644 --- a/src/main/c/includes/fluid/sim/grid2/density.h +++ b/src/main/c/includes/fluid/sim/grid2/density.h @@ -55,6 +55,10 @@ LIBRARY_API void fluid_grid2_advectDensity(Environment * environment, float ** d void fluid_grid2_normalizeDensity(Environment * environment, float ** d, float ratio); +/** + * Calculates the current sum of the chunk for normalization purposes + */ +double fluid_grid2_sum_for_normalization(Environment * environment, Chunk * chunk); diff --git a/src/main/c/src/fluid/queue/javainterface.c b/src/main/c/src/fluid/queue/javainterface.c index 405ed1c7..3a32e3b0 100644 --- a/src/main/c/src/fluid/queue/javainterface.c +++ b/src/main/c/src/fluid/queue/javainterface.c @@ -140,6 +140,7 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate environment->lookupTable.serverFluidChunkTable.asleepId = (*env)->GetFieldID(env,fluidSimStorageClass,"asleep","Z"); environment->lookupTable.serverFluidChunkTable.homogenousId = (*env)->GetFieldID(env,fluidSimStorageClass,"isHomogenous","Z"); environment->lookupTable.serverFluidChunkTable.normalizationRatioId = (*env)->GetStaticFieldID(env,fluidSimStorageClass,"normalizationRatio","F"); + environment->lookupTable.serverFluidChunkTable.massCountId = (*env)->GetStaticFieldID(env,fluidSimStorageClass,"massCount","F"); } /** diff --git a/src/main/c/src/fluid/queue/metadatacalc.c b/src/main/c/src/fluid/queue/metadatacalc.c index 27fbe72d..c27a6da3 100644 --- a/src/main/c/src/fluid/queue/metadatacalc.c +++ b/src/main/c/src/fluid/queue/metadatacalc.c @@ -90,7 +90,20 @@ void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Enviro //alert java side to updated static values float normalizationRatio = environment->state.normalizationRatio; - (*env)->SetStaticFloatField(env,environment->lookupTable.serverFluidChunkClass,environment->lookupTable.serverFluidChunkTable.normalizationRatioId,normalizationRatio); + (*env)->SetStaticFloatField( + env, + environment->lookupTable.serverFluidChunkClass, + environment->lookupTable.serverFluidChunkTable.normalizationRatioId, + normalizationRatio + ); + //mass + float massCount = (float)environment->state.existingDensity; + (*env)->SetStaticFloatField( + env, + environment->lookupTable.serverFluidChunkClass, + environment->lookupTable.serverFluidChunkTable.massCountId, + massCount + ); //update frame state diff --git a/src/main/c/src/fluid/sim/grid2/density.c b/src/main/c/src/fluid/sim/grid2/density.c index f0272e75..df6492ae 100644 --- a/src/main/c/src/fluid/sim/grid2/density.c +++ b/src/main/c/src/fluid/sim/grid2/density.c @@ -1,11 +1,13 @@ #include #include #include +#include #include "fluid/env/utilities.h" #include "fluid/queue/chunkmask.h" #include "fluid/env/environment.h" #include "fluid/queue/chunk.h" +#include "fluid/sim/grid2/density.h" #include "fluid/sim/grid2/solver_consts.h" #include "fluid/sim/grid2/utilities.h" #include "math/ode/multigrid.h" @@ -247,9 +249,39 @@ void fluid_grid2_normalizeDensity(Environment * environment, float ** d, float r int j; int size=DIM*DIM*DIM; float * x = GET_ARR_RAW(d,CENTER_LOC); + //apply a n ease in-out quart function to weight mass normalization to places with already larger masses for(j=0; j NORMALIZATION_CUTOFF){ + // value = fmax(value,NORMALIZATION_CLAMP_VAL) * ratio; + // x[j] = value; + // } else { + // x[j] = 0; + // } } } + + +/** + * Normalizes the density array with a given ratio + */ +double fluid_grid2_sum_for_normalization(Environment * environment, Chunk * chunk){ + int j; + int size=DIM*DIM*DIM; + float * x = chunk->d[CENTER_LOC]; + double rVal = 0; + for(int i = 1; i < DIM - 1; i++){ + for(int j = 1; j < DIM - 1; j++){ + for(int k = 1; k < DIM - 1; k++){ + float val = x[IX(i,j,k)]; + rVal = rVal + val; + // if(val > NORMALIZATION_CUTOFF){ + // rVal = rVal + fmax(val,NORMALIZATION_CLAMP_VAL); + // } + } + } + } + return rVal; +} diff --git a/src/main/c/src/fluid/sim/grid2/grid2.c b/src/main/c/src/fluid/sim/grid2/grid2.c index 9d9aebe5..95b75134 100644 --- a/src/main/c/src/fluid/sim/grid2/grid2.c +++ b/src/main/c/src/fluid/sim/grid2/grid2.c @@ -307,7 +307,7 @@ LIBRARY_API void fluid_grid2_simulate( double transformedDensity = 0; for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; - transformedDensity = transformedDensity + fluid_grid2_calculateSum(currentChunk->d); + transformedDensity = transformedDensity + fluid_grid2_sum_for_normalization(environment,currentChunk); } double normalizationRatio = 0; if(transformedDensity != 0){ diff --git a/src/main/c/src/fluid/sim/grid2/utilities.c b/src/main/c/src/fluid/sim/grid2/utilities.c index 0e8ba2a0..93a26911 100644 --- a/src/main/c/src/fluid/sim/grid2/utilities.c +++ b/src/main/c/src/fluid/sim/grid2/utilities.c @@ -42,6 +42,79 @@ void fluid_grid2_add_source(float * x, float * s, float dt){ } +/** + * Sets the bounds reflecting off hard borders and otherwise assuming continuity + */ +void fluid_grid2_set_bounds_legacy( + Environment * environment, + int vector_dir, + float * target +){ + //set the boundary planes + for(int x = 1; x < DIM-1; x++){ + for(int y = 1; y < DIM-1; y++){ + + //x-direction boundary planes + if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_U || vector_dir==BOUND_SET_VECTOR_U){ + target[IX(0,x,y)] = -target[IX(1,x,y)]; + target[IX(DIM-1,x,y)] = -target[IX(DIM-2,x,y)]; + } else { + target[IX(0,x,y)] = target[IX(1,x,y)]; + target[IX(DIM-1,x,y)] = target[IX(DIM-2,x,y)]; + } + + //y-direction boundary planes + if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_V || vector_dir==BOUND_SET_VECTOR_V){ + target[IX(x,0,y)] = -target[IX(x,1,y)]; + target[IX(x,DIM-1,y)] = -target[IX(x,DIM-2,y)]; + } else { + target[IX(x,0,y)] = target[IX(x,1,y)]; + target[IX(x,DIM-1,y)] = target[IX(x,DIM-2,y)]; + } + + //z-direction boundary planes + if(vector_dir==BOUND_SET_VECTOR_DIFFUSE_PHI_W || vector_dir==BOUND_SET_VECTOR_W){ + target[IX(x,y,0)] = -target[IX(x,y,1)]; + target[IX(x,y,DIM-1)] = -target[IX(x,y,DIM-2)]; + } else { + target[IX(x,y,0)] = target[IX(x,y,1)]; + target[IX(x,y,DIM-1)] = target[IX(x,y,DIM-2)]; + } + } + } + + //sets the edges of the chunk + //this should logically follow from how we're treating the boundary planes + for(int x = 1; x < DIM-1; x++){ + target[IX(x,0,0)] = (float)(0.5f * (target[IX(x,1,0)] + target[IX(x,0,1)])); + target[IX(x,DIM-1,0)] = (float)(0.5f * (target[IX(x,DIM-2,0)] + target[IX(x,DIM-1,1)])); + target[IX(x,0,DIM-1)] = (float)(0.5f * (target[IX(x,1,DIM-1)] + target[IX(x,0,DIM-2)])); + target[IX(x,DIM-1,DIM-1)] = (float)(0.5f * (target[IX(x,DIM-2,DIM-1)] + target[IX(x,DIM-1,DIM-2)])); + + target[IX(0,x,0)] = (float)(0.5f * (target[IX(1,x,0)] + target[IX(0,x,1)])); + target[IX(DIM-1,x,0)] = (float)(0.5f * (target[IX(DIM-2,x,0)] + target[IX(DIM-1,x,1)])); + target[IX(0,x,DIM-1)] = (float)(0.5f * (target[IX(1,x,DIM-1)] + target[IX(0,x,DIM-2)])); + target[IX(DIM-1,x,DIM-1)] = (float)(0.5f * (target[IX(DIM-2,x,DIM-1)] + target[IX(DIM-1,x,DIM-2)])); + + + target[IX(0,0,x)] = (float)(0.5f * (target[IX(1,0,x)] + target[IX(0,1,x)])); + target[IX(DIM-1,0,x)] = (float)(0.5f * (target[IX(DIM-2,0,x)] + target[IX(DIM-1,1,x)])); + target[IX(0,DIM-1,x)] = (float)(0.5f * (target[IX(1,DIM-1,x)] + target[IX(0,DIM-2,x)])); + target[IX(DIM-1,DIM-1,x)] = (float)(0.5f * (target[IX(DIM-2,DIM-1,x)] + target[IX(DIM-1,DIM-2,x)])); + + } + //sets the corners of the chunk + //this should logically follow from how we're treating the boundary planes + 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(DIM-1,0,0)] = (float)((target[IX(DIM-2,0,0)]+target[IX(DIM-1,1,0)]+target[IX(DIM-1,0,1)])/3.0); + target[IX(0,DIM-1,0)] = (float)((target[IX(1,DIM-1,0)]+target[IX(0,DIM-2,0)]+target[IX(0,DIM-1,1)])/3.0); + target[IX(0,0,DIM-1)] = (float)((target[IX(0,0,DIM-2)]+target[IX(1,0,DIM-1)]+target[IX(0,1,DIM-1)])/3.0); + target[IX(DIM-1,DIM-1,0)] = (float)((target[IX(DIM-2,DIM-1,0)]+target[IX(DIM-1,DIM-2,0)]+target[IX(DIM-1,DIM-1,1)])/3.0); + target[IX(0,DIM-1,DIM-1)] = (float)((target[IX(1,DIM-1,DIM-1)]+target[IX(0,DIM-2,DIM-1)]+target[IX(0,DIM-1,DIM-2)])/3.0); + target[IX(DIM-1,0,DIM-1)] = (float)((target[IX(DIM-1,0,DIM-2)]+target[IX(DIM-2,0,DIM-1)]+target[IX(DIM-1,1,DIM-1)])/3.0); + target[IX(DIM-1,DIM-1,DIM-1)] = (float)((target[IX(DIM-1,DIM-1,DIM-2)]+target[IX(DIM-1,DIM-2,DIM-1)]+target[IX(DIM-1,DIM-1,DIM-2)])/3.0); +} + /** * Sets the bounds reflecting off hard borders and otherwise assuming continuity */ @@ -345,18 +418,32 @@ LIBRARY_API void fluid_grid2_set_bounds( float * target ){ switch(vector_dir){ - // case BOUND_SET_PROJECTION_PHI: - // case BOUND_SET_PROJECTION_PHI_0: + + case BOUND_SET_PROJECTION_PHI: + case BOUND_SET_PROJECTION_PHI_0: case BOUND_SET_VECTOR_DIFFUSE_PHI_U: case BOUND_SET_VECTOR_DIFFUSE_PHI_V: case BOUND_SET_VECTOR_DIFFUSE_PHI_W: case BOUND_SET_DENSITY_PHI: + case BOUND_SET_VECTOR_U: + case BOUND_SET_VECTOR_V: + case BOUND_SET_VECTOR_W: + case BOUND_SET_DENSITY: + fluid_grid2_set_bounds_legacy(environment,vector_dir,target); + break; + + // case BOUND_SET_PROJECTION_PHI: + // case BOUND_SET_PROJECTION_PHI_0: + // case BOUND_SET_VECTOR_DIFFUSE_PHI_U: + // case BOUND_SET_VECTOR_DIFFUSE_PHI_V: + // case BOUND_SET_VECTOR_DIFFUSE_PHI_W: + // case BOUND_SET_DENSITY_PHI: // case BOUND_SET_VECTOR_U: // case BOUND_SET_VECTOR_V: // case BOUND_SET_VECTOR_W: // case BOUND_SET_DENSITY: - fluid_grid2_set_bounds_reflection(environment,vector_dir,target); - break; + // fluid_grid2_set_bounds_reflection(environment,vector_dir,target); + // break; // case BOUND_SET_PROJECTION_PHI: // case BOUND_SET_PROJECTION_PHI_0: @@ -371,18 +458,18 @@ LIBRARY_API void fluid_grid2_set_bounds( // fluid_grid2_set_bounds_continuity(environment,target); // break; - case BOUND_SET_PROJECTION_PHI: - case BOUND_SET_PROJECTION_PHI_0: + // case BOUND_SET_PROJECTION_PHI: + // case BOUND_SET_PROJECTION_PHI_0: // case BOUND_SET_VECTOR_DIFFUSE_PHI_U: // case BOUND_SET_VECTOR_DIFFUSE_PHI_V: // case BOUND_SET_VECTOR_DIFFUSE_PHI_W: // case BOUND_SET_DENSITY_PHI: - case BOUND_SET_VECTOR_U: - case BOUND_SET_VECTOR_V: - case BOUND_SET_VECTOR_W: - case BOUND_SET_DENSITY: - fluid_grid2_set_bounds_ghost_cell(environment,vector_dir,target); - break; + // case BOUND_SET_VECTOR_U: + // case BOUND_SET_VECTOR_V: + // case BOUND_SET_VECTOR_W: + // case BOUND_SET_DENSITY: + // fluid_grid2_set_bounds_ghost_cell(environment,vector_dir,target); + // break; // case BOUND_SET_PROJECTION_PHI: // case BOUND_SET_PROJECTION_PHI_0: diff --git a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java index 37b562e5..3ec4c34a 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java @@ -44,6 +44,7 @@ public class ImGuiFluidMonitor { } ImGui.text("Broadcast Size (This Frame): " + fluidManager.getBroadcastSize()); ImGui.text("Normalization Ratio: " + ServerFluidChunk.getNormalizationRatio()); + ImGui.text("Mass: " + ServerFluidChunk.getMassCount()); } if(ImGui.collapsingHeader("Client Data")){ diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index 62852fc1..54c8b5cf 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -196,6 +196,11 @@ public class ServerFluidChunk { */ public static float normalizationRatio = 0; + /** + * The amount of mass in the simulation + */ + public static float massCount = 0; + /** * Allocates the central arrays for this chunk */ @@ -628,6 +633,14 @@ public class ServerFluidChunk { return normalizationRatio; } + /** + * Gets the amount of mass in the simulation + * @return The amount of mass + */ + public static double getMassCount() { + return massCount; + } + } diff --git a/src/test/c/fluid/sim/grid2/full_sim_tests.c b/src/test/c/fluid/sim/grid2/full_sim_tests.c index cc50f429..dce26cce 100644 --- a/src/test/c/fluid/sim/grid2/full_sim_tests.c +++ b/src/test/c/fluid/sim/grid2/full_sim_tests.c @@ -26,6 +26,11 @@ */ #define FLUID_GRID2_PROJECTION_ERROR_MARGIN 0.00001f +/** + * Number of chunks + */ +#define CHUNK_DIM 4 + /** * Testing full sim routine */ @@ -34,7 +39,8 @@ int fluid_sim_grid2_full_sim_test1(){ int rVal = 0; Environment * env = fluid_environment_create(); Chunk ** queue = NULL; - queue = createChunkGrid(env,3,3,3); + queue = createChunkGrid(env,CHUNK_DIM,CHUNK_DIM,CHUNK_DIM); + int chunkCount = arrlen(queue); @@ -47,13 +53,14 @@ int fluid_sim_grid2_full_sim_test1(){ //actually simulate int frameCount = 1; for(int frame = 0; frame < frameCount; frame++){ - fluid_grid2_simulate(3*3*3,queue,env,FLUID_GRID2_SIM_STEP); + fluid_solve_bounds(chunkCount,queue,env); + fluid_grid2_simulate(chunkCount,queue,env,FLUID_GRID2_SIM_STEP); } //test the result float afterSum = chunk_queue_sum_density(queue); if(fabs(beforeSum - afterSum) > FLUID_GRID2_PROJECTION_ERROR_MARGIN){ - rVal += assertEqualsFloat(beforeSum,afterSum,"Advection changed density! %f %f \n"); + rVal += assertEqualsFloat(beforeSum,afterSum,"Simulation changed density! %f %f \n"); } return rVal; @@ -67,7 +74,8 @@ int fluid_sim_grid2_full_sim_test2(){ int rVal = 0; Environment * env = fluid_environment_create(); Chunk ** queue = NULL; - queue = createChunkGrid(env,3,3,3); + queue = createChunkGrid(env,CHUNK_DIM,CHUNK_DIM,CHUNK_DIM); + int chunkCount = arrlen(queue); @@ -80,13 +88,20 @@ int fluid_sim_grid2_full_sim_test2(){ //actually simulate int frameCount = 50; for(int frame = 0; frame < frameCount; frame++){ - fluid_grid2_simulate(3*3*3,queue,env,FLUID_GRID2_SIM_STEP); + fluid_solve_bounds(chunkCount,queue,env); + fluid_grid2_simulate(chunkCount,queue,env,FLUID_GRID2_SIM_STEP); + printf("Existing sum: %lf\n", env->state.existingDensity); + printf("Added density: %lf\n", env->state.newDensity); + printf("Adjustment Ratio: %f\n", env->state.normalizationRatio); + float afterSum = chunk_queue_sum_density(queue); + printf("AFter transform sum: %f\n",afterSum); + printf("\n"); } //test the result float afterSum = chunk_queue_sum_density(queue); if(fabs(beforeSum - afterSum) > FLUID_GRID2_PROJECTION_ERROR_MARGIN){ - rVal += assertEqualsFloat(beforeSum,afterSum,"Advection changed density! %f %f \n"); + rVal += assertEqualsFloat(beforeSum,afterSum,"Simulation changed density! %f %f \n"); } return rVal; @@ -100,26 +115,29 @@ int fluid_sim_grid2_full_sim_test3(){ int rVal = 0; Environment * env = fluid_environment_create(); Chunk ** queue = NULL; - queue = createChunkGrid(env,3,3,3); + queue = createChunkGrid(env,CHUNK_DIM,CHUNK_DIM,CHUNK_DIM); + int chunkCount = arrlen(queue); //setup chunk values Chunk * currentChunk = queue[0]; - chunk_fill_real(queue[13]->d[CENTER_LOC],MAX_FLUID_VALUE); - chunk_fill_real(queue[13]->u[CENTER_LOC],MAX_FLUID_VALUE); + chunk_fill_real(queue[CENTER_LOC]->d[CENTER_LOC],MAX_FLUID_VALUE); + chunk_fill_real(queue[CENTER_LOC]->u[CENTER_LOC],MAX_FLUID_VALUE); + queue[CENTER_LOC]->d[DIM*DIM*3+DIM*3+3] = 0; float beforeSum = chunk_queue_sum_density(queue); //actually simulate int frameCount = 50; for(int frame = 0; frame < frameCount; frame++){ - fluid_grid2_simulate(3*3*3,queue,env,FLUID_GRID2_SIM_STEP); - printf("Existing sum: %lf\n", env->state.existingDensity); - printf("Added density: %lf\n", env->state.newDensity); - printf("Adjustment Ratio: %f\n", env->state.normalizationRatio); - float afterSum = chunk_queue_sum_density(queue); - printf("AFter transform sum: %f\n",afterSum); - printf("\n"); + fluid_solve_bounds(chunkCount,queue,env); + fluid_grid2_simulate(chunkCount,queue,env,FLUID_GRID2_SIM_STEP); + // printf("Existing sum: %lf\n", env->state.existingDensity); + // printf("Added density: %lf\n", env->state.newDensity); + // printf("Adjustment Ratio: %f\n", env->state.normalizationRatio); + // float afterSum = chunk_queue_sum_density(queue); + // printf("AFter transform sum: %f\n",afterSum); + // printf("\n"); } //test the result