//Main testing code //------------- int main(int argc, char **argv) { //Setup viewer stuff Gluvi::init("GFM Free Surface Liquid Solver with Static Variational Boundaries", &argc, argv); Gluvi::camera=&cam; Gluvi::userDisplayFunc=display; Gluvi::userMouseFunc=mouse; Gluvi::userDragFunc=drag; glClearColor(1,1,1,1); glutTimerFunc(1000, timer, 0); //Set up the simulation sim.initialize(grid_width, grid_resolution, grid_resolution); //set up a circle boundary sim.set_boundary(boundary_phi); //Stick some liquid particles in the domain for(int i = 0; i < sqr(grid_resolution); ++i) { float x = randhashf(i*2, 0,1); float y = randhashf(i*2+1, 0,1); Vec2f pt(x,y); if(boundary_phi(pt) > 0 && pt[0] > 0.5) sim.add_particle(pt); } Gluvi::run(); return 0; }
TEST(PressureTest, LinearEquationSetup_Complex) { glm::ivec2 size(50); FluidSim sim; sim.initialize(1.0f, size.x, size.y); sim.set_boundary(boundary_phi); AddParticles(size, sim, complex_boundary_phi); sim.add_force(0.01f); Velocity velocity(*device, size); Texture solidPhi(*device, size.x, size.y, vk::Format::eR32Sfloat); Texture liquidPhi(*device, size.x, size.y, vk::Format::eR32Sfloat); BuildInputs(*device, size, sim, velocity, solidPhi, liquidPhi); LinearSolver::Data data(*device, size, VMA_MEMORY_USAGE_CPU_ONLY); Buffer<glm::ivec2> valid(*device, size.x * size.y, VMA_MEMORY_USAGE_CPU_ONLY); Pressure pressure(*device, 0.01f, size, data, velocity, solidPhi, liquidPhi, valid); pressure.BuildLinearEquation(); device->Handle().waitIdle(); CheckDiagonal(size, data.Diagonal, sim, 1e-3f); // FIXME can we reduce error tolerance? CheckWeights(size, data.Lower, sim, 1e-3f); // FIXME can we reduce error tolerance? CheckDiv(size, data.B, sim); }
TEST(LinearSolverTests, IncompletePoisson_Simple_PCG) { glm::ivec2 size(50); FluidSim sim; sim.initialize(1.0f, size.x, size.y); sim.set_boundary(boundary_phi); AddParticles(size, sim, boundary_phi); sim.add_force(0.01f); sim.compute_phi(); sim.extrapolate_phi(); sim.apply_projection(0.01f); LinearSolver::Data data(*device, size, VMA_MEMORY_USAGE_CPU_ONLY); BuildLinearEquation(size, data.Diagonal, data.Lower, data.B, sim); IncompletePoisson preconditioner(*device, size); LinearSolver::Parameters params(LinearSolver::Parameters::SolverType::Iterative, 1000, 1e-5f); ConjugateGradient solver(*device, size, preconditioner); solver.Bind(data.Diagonal, data.Lower, data.B, data.X); solver.Solve(params); device->Queue().waitIdle(); CheckPressure(size, sim.pressure, data.X, 1e-5f); std::cout << "Solved with number of iterations: " << params.OutIterations << std::endl; }
TEST(LinearSolverTests, LocalGaussSeidel) { glm::ivec2 size(16); // maximum size FluidSim sim; sim.initialize(1.0f, size.x, size.y); sim.set_boundary(boundary_phi); AddParticles(size, sim, boundary_phi); sim.add_force(0.01f); sim.compute_phi(); sim.extrapolate_phi(); sim.apply_projection(0.01f); LinearSolver::Data data(*device, size, VMA_MEMORY_USAGE_CPU_ONLY); BuildLinearEquation(size, data.Diagonal, data.Lower, data.B, sim); LocalGaussSeidel solver(*device, size); solver.Bind(data.Diagonal, data.Lower, data.B, data.X); device->Execute([&](vk::CommandBuffer commandBuffer) { solver.Record(commandBuffer); }); device->Queue().waitIdle(); CheckPressure(size, sim.pressure, data.X, 1e-3f); }
TEST(LinearSolverTests, Multigrid_Simple_PCG) { glm::ivec2 size(64); FluidSim sim; sim.initialize(1.0f, size.x, size.y); sim.set_boundary(boundary_phi); AddParticles(size, sim, boundary_phi); sim.add_force(0.01f); sim.compute_phi(); sim.extrapolate_phi(); sim.apply_projection(0.01f); LinearSolver::Data data(*device, size, VMA_MEMORY_USAGE_CPU_ONLY); Velocity velocity(*device, size); Texture liquidPhi(*device, size.x, size.y, vk::Format::eR32Sfloat); Texture solidPhi(*device, size.x, size.y, vk::Format::eR32Sfloat); Buffer<glm::ivec2> valid(*device, size.x * size.y, VMA_MEMORY_USAGE_CPU_ONLY); SetSolidPhi(*device, size, solidPhi, sim, (float)size.x); SetLiquidPhi(*device, size, liquidPhi, sim, (float)size.x); BuildLinearEquation(size, data.Diagonal, data.Lower, data.B, sim); Pressure pressure(*device, 0.01f, size, data, velocity, solidPhi, liquidPhi, valid); Multigrid preconditioner(*device, size, 0.01f); preconditioner.BuildHierarchiesBind(pressure, solidPhi, liquidPhi); LinearSolver::Parameters params(LinearSolver::Parameters::SolverType::Iterative, 1000, 1e-5f); ConjugateGradient solver(*device, size, preconditioner); solver.Bind(data.Diagonal, data.Lower, data.B, data.X); preconditioner.BuildHierarchies(); solver.Solve(params); device->Queue().waitIdle(); CheckPressure(size, sim.pressure, data.X, 1e-5f); std::cout << "Solved with number of iterations: " << params.OutIterations << std::endl; }
TEST(PressureTest, Project_Complex) { glm::ivec2 size(50); FluidSim sim; sim.initialize(1.0f, size.x, size.y); sim.set_boundary(boundary_phi); AddParticles(size, sim, boundary_phi); sim.add_force(0.01f); Velocity velocity(*device, size); Texture solidPhi(*device, size.x, size.y, vk::Format::eR32Sfloat); Texture liquidPhi(*device, size.x, size.y, vk::Format::eR32Sfloat); BuildInputs(*device, size, sim, velocity, solidPhi, liquidPhi); LinearSolver::Data data(*device, size, VMA_MEMORY_USAGE_CPU_ONLY); std::vector<float> computedPressureData(size.x * size.y, 0.0f); for (std::size_t i = 0; i < computedPressureData.size(); i++) { computedPressureData[i] = (float)sim.pressure[i]; } CopyFrom(data.X, computedPressureData); Buffer<glm::ivec2> valid(*device, size.x * size.y, VMA_MEMORY_USAGE_CPU_ONLY); Pressure pressure(*device, 0.01f, size, data, velocity, solidPhi, liquidPhi, valid); pressure.ApplyPressure(); device->Handle().waitIdle(); CheckVelocity(*device, size, velocity, sim); CheckValid(size, sim, valid); }