From a83d395885ec82f26fb99fd2bcdd13e57852f153 Mon Sep 17 00:00:00 2001
From: adany292 <adany292@student.liu.se>
Date: Sun, 29 Dec 2024 19:56:57 +0100
Subject: [PATCH] Itterative SESPH/PCISPH improvement, precalulateed stifness
 cosnt

---
 src/FluidSimulationApp.cpp          |  5 --
 src/cuda/include/cuda_device_vars.h |  1 +
 src/cuda/include/init_cuda.h        |  9 +++
 src/cuda/init_cuda.cu               | 85 +++++++++++++++++++++++++++++
 src/cuda/pcisph_kernels.cu          | 50 ++++++++---------
 src/cuda/pcisph_update.cu           |  4 +-
 src/settings/constants.h            |  6 +-
 7 files changed, 126 insertions(+), 34 deletions(-)

diff --git a/src/FluidSimulationApp.cpp b/src/FluidSimulationApp.cpp
index db4d400..45773eb 100644
--- a/src/FluidSimulationApp.cpp
+++ b/src/FluidSimulationApp.cpp
@@ -245,28 +245,23 @@ namespace FluidSimulation {
                     break;
 
                 case RenderStage::ThicknessBuffer:
-                    printf("Render Thickness \n");
-                    printf("Thickness stage active \n");
                     m_fluidRenderer->renderThicknessFrame(particleCount, boundaryCount);
                     m_fluidRenderer->visualizeBuffer(RenderStage::ThicknessBuffer);
                     break;
                 
                 case RenderStage::FilteredThickness:
-                    printf("Render Filtered Thickness \n");
                     m_fluidRenderer->renderThicknessFrame(particleCount, boundaryCount);
                     m_fluidRenderer->renderThicknessFilterFrame();
                     m_fluidRenderer->visualizeBuffer(RenderStage::FilteredThickness);
                     break;
 
                 case RenderStage::LightAttenuation:
-                    printf("Render Filtered Thickness \n");
                     m_fluidRenderer->renderThicknessFrame(particleCount, boundaryCount);
                     m_fluidRenderer->renderThicknessFilterFrame();
                     m_fluidRenderer->renderThicknessAttenFrame();
                     break;
                 
                 case RenderStage::ScreenSpacedRender:
-                    printf("Render Screen Spaced \n");
                     m_fluidRenderer->renderDepthFrame(particleCount, boundaryCount);
                     m_fluidRenderer->renderDepthFilterFrame();
                     m_fluidRenderer->renderDepthNormalsFrame();
diff --git a/src/cuda/include/cuda_device_vars.h b/src/cuda/include/cuda_device_vars.h
index b4eeb12..69a8f20 100644
--- a/src/cuda/include/cuda_device_vars.h
+++ b/src/cuda/include/cuda_device_vars.h
@@ -14,6 +14,7 @@ extern cudaGraphicsResource_t cuda_vbo_boundary_resource;
 extern __constant__ float PI;
 extern __constant__ float H;
 extern __constant__ float H2;
+extern __constant__ float K_PCI;
 extern __constant__ float POLY6_CONST;
 extern __constant__ float SPIKY_GRAD_CONST;
 extern __constant__ float VISC_LAP_CONST;
diff --git a/src/cuda/include/init_cuda.h b/src/cuda/include/init_cuda.h
index a554776..ac02e55 100644
--- a/src/cuda/include/init_cuda.h
+++ b/src/cuda/include/init_cuda.h
@@ -37,6 +37,15 @@ void updateConstantsOnDevice(
     float smoothingRadius
 );
 
+void ComputePCISPHStiffness(
+    float timeStep,
+    float particleMass,
+    float restDensity,
+    float kernelRadius,
+    float restSpacing,
+    float spiky_d1_normalization
+);
+
 } // namespace FluidSimulationGPU
 
 #endif // INIT_CUDA_H
diff --git a/src/cuda/init_cuda.cu b/src/cuda/init_cuda.cu
index b5b629e..fa7bc1a 100644
--- a/src/cuda/init_cuda.cu
+++ b/src/cuda/init_cuda.cu
@@ -4,6 +4,7 @@
 #include "../settings/constants.h"
 
 #include "include/pcisph_kernels.h"
+#include "include/float3_helper_math.h"
 
 #include <cuda_runtime.h>
 #include <cuda_gl_interop.h>
@@ -20,6 +21,7 @@ cudaGraphicsResource_t cuda_vbo_boundary_resource;
 __constant__ float PI;
 __constant__ float H;
 __constant__ float H2;
+__constant__ float K_PCI;
 __constant__ float POLY6_CONST;
 __constant__ float SPIKY_GRAD_CONST;
 __constant__ float VISC_LAP_CONST;
@@ -71,6 +73,78 @@ unsigned int* d_boundaryCellEnd = nullptr;
 unsigned int* d_boundaryCellIndices = nullptr;
 unsigned int* d_boundaryParticleIndices = nullptr;    
 
+void ComputePCISPHStiffness(
+    float timeStep,
+    float particleMass,
+    float restDensity,
+    float kernelRadius,
+    float restSpacing,
+    float spiky_d1_normalization)
+{
+    // 1) Compute the factor often called 'beta' or something similar
+    //    in your code.  (Matches your "2 * (dt*m / rho0)^2" idea)
+    float mass = restDensity * powf(kernelRadius/2.0f, 3.f);
+
+    printf("Particle mass: %f \n", mass);
+    printf("Rest Density: %f \n", restDensity);
+
+    //cudaMemcpyToSymbol(PARTICLE_MASS, &mass, sizeof(float));
+    //cudaMemcpyToSymbol(REST_DENSITY, &restDensity, sizeof(float));
+
+    float dtm_rho = (timeStep * mass) / restDensity;
+    float beta = 2.0f * dtm_rho * dtm_rho;
+
+
+    // 2) Variables to accumulate gradient sums
+    float3 grad_sum     = make_float3(0.f, 0.f, 0.f);
+    float  sum_dot_grad = 0.f;
+
+    float kernelRadius2 = kernelRadius * kernelRadius;
+
+    // 3) Sample points in [-kernelRadius, +kernelRadius] in increments of restSpacing
+    for (float z = -kernelRadius; z <= kernelRadius + 1e-5f; z += restSpacing)
+    {
+        for (float y = -kernelRadius; y <= kernelRadius + 1e-5f; y += restSpacing)
+        {
+            for (float x = -kernelRadius; x <= kernelRadius + 1e-5f; x += restSpacing)
+            {
+                float3 r = make_float3(x, y, z);
+                float r2 = dot(r, r);
+
+                // Only compute if within kernel support
+                if (r2 < kernelRadius2 && r2 > 0.0f)  // avoid r=0 to prevent division by 0
+                {
+                    float r_norm = sqrtf(r2);
+                    // Spiky kernel gradient in 3D usually:
+                    //    grad W_spiky(r) = -C * ( (h - r)^2 / r ) * r̂
+                    //
+                    // If you're using a negative sign in spiky_d1_normalization,
+                    // you might want to omit the minus here, etc. Just be consistent.
+                    float3 grad = (r / r_norm) * spiky_d1_normalization * powf(kernelRadius - r_norm, 2.f);
+
+                    // Accumulate sums
+                    grad_sum += grad;
+                    sum_dot_grad += dot(grad, grad);
+                }
+            }
+        }
+    }
+
+    // 4) Compute dot of the sum of gradients
+    float dot_sum_grad = dot(grad_sum, grad_sum);
+
+    // 5) Combine to get grad_term:
+    //    grad_term ~ - [ (Σ gradW)^2 + Σ (gradW·gradW) ]
+    //    so we define:
+    float grad_term = - (dot_sum_grad + sum_dot_grad);
+
+    // 6) Finally, PCISPH stiffness factor k_PCI ~ -1 / (beta * grad_term)
+    float k_PCI = -1.f / (beta * grad_term);
+
+    printf("K_PCi precalc: %f \n", k_PCI);
+    cudaMemcpyToSymbol(K_PCI, &k_PCI, sizeof(float));
+}
+
 void initializeConstants()
 {
     // Host constants
@@ -98,6 +172,15 @@ void initializeConstants()
     cudaMemcpyToSymbol(BOUND_Y_MAX, &h_BOUND_Y_MAX, sizeof(float));
     cudaMemcpyToSymbol(BOUND_Z_MIN, &h_BOUND_Z_MIN, sizeof(float));
     cudaMemcpyToSymbol(BOUND_Z_MAX, &h_BOUND_Z_MAX, sizeof(float));
+
+    ComputePCISPHStiffness(
+        0.006,
+        h_PARTICLE_MASS,
+        h_REST_DENSITY,
+        h_H,
+        h_H/96.0f,
+        h_SPIKY_GRAD_CONST
+    );
 }
 
 // Register VBO with CUDA
@@ -166,6 +249,8 @@ void initializeFluidDeviceArrays(
 
     // Initialize positions_pred to initial positions
     cudaMemcpy(d_positions_pred, h_positions, numParticles * sizeof(float3), cudaMemcpyHostToDevice);
+
+
 }
 
 void initializeBoundryDeviceArrays(
diff --git a/src/cuda/pcisph_kernels.cu b/src/cuda/pcisph_kernels.cu
index 0357fd8..d5c995e 100644
--- a/src/cuda/pcisph_kernels.cu
+++ b/src/cuda/pcisph_kernels.cu
@@ -139,7 +139,7 @@ __global__ void updatePressures(
     int idx = blockIdx.x * blockDim.x + threadIdx.x;
 
     if (idx < numParticles) {
-        float deltaP = -density_errors[idx] / A;
+        float deltaP = -density_errors[idx] / K_PCI;
         pressure_increments[idx] = deltaP;
     }
 }
@@ -211,29 +211,29 @@ __global__ void computePressureForces(
                 // Boundary neighbors
                 // ------------
             
-                /*
-                unsigned int b_startIdx = boundaryCellStart[neighborCellIndex];
-                unsigned int b_endIdx = boundaryCellEnd[neighborCellIndex];
-
-                if (b_startIdx != 0xFFFFFFFF) {
-                    for (unsigned int j = b_startIdx; j < b_endIdx; ++j) {
-                        float3 pos_j = boundaryPositions[j];
-                        // Mirror pressure: p_b = p_i, and use REST_DENSITY for boundary
-                        float deltaP_j = deltaP_i; // Pressure mirroring
-
-                        float3 r = pos_i - pos_j;
-                        float distSq = dot(r, r);
-                        if (distSq < H2 && distSq > 0.0001f) {
-                            float dist = sqrtf(distSq);
-                            float gradW = spikyKernelGrad(dist);
-                            float3 gradWij = gradW * (r / dist);
-                            // Using Equation (85): p_i and p_b = p_i; densities: ρ_i and ρ_0
-                            float factor = - (deltaP_i + deltaP_j) / (REST_DENSITY * REST_DENSITY);
-                            fPressure += factor * gradWij * PARTICLE_MASS * PARTICLE_MASS;
-                        }
-                    }
-                } 
-                */
+                
+                // unsigned int b_startIdx = boundaryCellStart[neighborCellIndex];
+                // unsigned int b_endIdx = boundaryCellEnd[neighborCellIndex];
+
+                // if (b_startIdx != 0xFFFFFFFF) {
+                //     for (unsigned int j = b_startIdx; j < b_endIdx; ++j) {
+                //         float3 pos_j = boundaryPositions[j];
+                //         // Mirror pressure: p_b = p_i, and use REST_DENSITY for boundary
+                //         float deltaP_j = deltaP_i; // Pressure mirroring
+
+                //         float3 r = pos_i - pos_j;
+                //         float distSq = dot(r, r);
+                //         if (distSq < H2 && distSq > 0.0001f) {
+                //             float dist = sqrtf(distSq);
+                //             float gradW = spikyKernelGrad(dist);
+                //             float3 gradWij = gradW * (r / dist);
+                //             // Using Equation (85): p_i and p_b = p_i; densities: ρ_i and ρ_0
+                //             float factor = - (deltaP_i + deltaP_j) / (REST_DENSITY * REST_DENSITY);
+                //             fPressure += factor * gradWij * PARTICLE_MASS * PARTICLE_MASS;
+                //         }
+                //     }
+                // } 
+                
             }
         }
     }
@@ -369,7 +369,7 @@ __global__ void computeViscosityAndExternalForces(
         float3 vel_i = velocities[idx];
 
         float3 fViscosity = make_float3(0.0f, 0.0f, 0.0f);
-        float3 fGravity = make_float3(0.0f, -20.0f, 0.0f) * PARTICLE_MASS;
+        float3 fGravity = make_float3(0.0f, -10.0f, 0.0f) * PARTICLE_MASS;
 
         unsigned int cellIndex = cellIndices[idx];
 
diff --git a/src/cuda/pcisph_update.cu b/src/cuda/pcisph_update.cu
index 757f723..4b296be 100644
--- a/src/cuda/pcisph_update.cu
+++ b/src/cuda/pcisph_update.cu
@@ -22,7 +22,7 @@ void updateParticles(float deltaTime)
     int blocksPerGrid = (NUM_PARTICLES + threadsPerBlock - 1) / threadsPerBlock;
 
     // Time step should be small but we can run updateParticles multiple times during display
-    float timeStep = 0.004f;
+    float timeStep = 0.006f;
 
     // -------------------- Neighbor Search --------------------
     int gridSizeX, gridSizeY, gridSizeZ;
@@ -99,6 +99,8 @@ void updateParticles(float deltaTime)
     float rho0 = h_REST_DENSITY;
     float A = 2.0f * timeStep * timeStep * m * m / (rho0 * rho0) * totalSumGradW2;
 
+    //printf("K_PCI: %f \n", A);
+
     // ------------ Iterative Pressure Correction Loop --------------------
 
     const int maxIterations = 3;
diff --git a/src/settings/constants.h b/src/settings/constants.h
index d34d1eb..de8dea1 100644
--- a/src/settings/constants.h
+++ b/src/settings/constants.h
@@ -12,11 +12,11 @@ const float h_BOUND_Z_MAX = 4.0f;
 const float h_GAS_CONSTANT = 0.02f;
 const float h_VISCOSITY = 0.04f;
 
-const float h_PARTICLE_MASS = 0.01f;
-const float h_REST_DENSITY = 800.0f;
+const float h_PARTICLE_MASS = 0.005f;
+const float h_REST_DENSITY = 600.0f;
 
 const float h_PI = 3.14159265358979323846f;
-const float h_H = 0.25f; // Smoothing radius
+const float h_H = 0.20f; // Smoothing radius
 
 const int NUM_PARTICLES = 50000;
 
-- 
GitLab