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); }