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); }
//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(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); }
int main(int argc, char** argv) { bool run = GL_TRUE; if(!glfwInit()) { exit(EXIT_FAILURE); } if(!glfwOpenWindow(windows_width, windows_height, 8, 8, 8, 8, 24, 0, GLFW_WINDOW)) { glfwTerminate(); exit(EXIT_FAILURE); } glewInit(); if (!glewIsSupported( "GL_VERSION_2_0 " "GL_ARB_pixel_buffer_object" )) { fprintf( stderr, "ERROR: Support for necessary OpenGL extensions missing."); fflush( stderr); return false; } //glfwSetKeyCallback(Viewer::keyCallback); //glfwSetMouseButtonCallback(Viewer::mouseButtonCallback); //glfwSetMousePosCallback(Viewer::mousePosCallback); //glfwSetMouseWheelCallback(Viewer::mouseWheelCallback); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); FluidSim sph; sph.initialize(); sph.resetFrameNum(); sph.outputObj(true); vec3 center(0.0f, -0.15f, 0.0f); Viewer::camera()->setFocal(center.x, center.y, center.z); Viewer::camera()->resetLookAt(); old_now = glfwGetTime(); while(run) { unsigned int frame_num = sph.getFrameNum(); if(frame_num > 450) exit(0); Viewer::camera()->aim(); printf("frame number: %d\n", frame_num); sph.compute(0.004); sph.draw(); utils::drawAxis(); utils::grabScreen(windows_width, windows_height, sph.getFrameNum()); now = glfwGetTime(); char fpsInfo[256]; sprintf(fpsInfo, "Frame: %u. Time cost per frame: %f", frame_num, now - old_now); old_now = now; glfwSetWindowTitle(fpsInfo); glfwSwapBuffers(); run = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED); } glfwTerminate(); exit(EXIT_SUCCESS); }