### Adding equation unit test

parent a74e6600
 /* * eq_unit_test.hpp * * Created on: Oct 13, 2015 * Author: i-bird */ #ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_EQ_UNIT_TEST_HPP_ #define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_EQ_UNIT_TEST_HPP_ #define BOOST_TEST_DYN_LINK #include #include "Laplacian.hpp" #include "FiniteDifference/eq.hpp" #include "FiniteDifference/sum.hpp" #include "FiniteDifference/mul.hpp" #include "Grid/grid_dist_id.hpp" #include "Decomposition/CartDecomposition.hpp" #include "Vector/Vector.hpp" #include "Solvers/umfpack_solver.hpp" #include "data_type/aggregate.hpp" #include "FiniteDifference/FDScheme.hpp" constexpr unsigned int x = 0; constexpr unsigned int y = 1; constexpr unsigned int z = 2; constexpr unsigned int V = 0; BOOST_AUTO_TEST_SUITE( eq_test_suite ) //! [Definition of the system] struct lid_nn { // dimensionaly of the equation (2D problem 3D problem ...) static const unsigned int dims = 2; // number of fields in the system v_x, v_y, P so a total of 3 static const unsigned int nvar = 3; // boundary conditions PERIODIC OR NON_PERIODIC static const bool boundary[]; // type of space float, double, ... typedef float stype; // type of base grid, it is the distributed grid that will store the result // Note the first property is a 2D vector (velocity), the second is a scalar (Pressure) typedef grid_dist_id<2,float,aggregate,CartDecomposition<2,float>> b_grid; // type of SparseMatrix, for the linear system, this parameter is bounded by the solver // that you are using, in case of umfpack it is the only possible choice typedef SparseMatrix SparseMatrix_type; // type of Vector for the linear system, this parameter is bounded by the solver // that you are using, in case of umfpack it is the only possible choice typedef Vector Vector_type; // Define that the underline grid where we discretize the system of equation is staggered static const int grid_type = STAGGERED_GRID; }; const bool lid_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC}; //! [Definition of the system] //! [Definition of the equation of the system in the bulk and at the boundary] // Constant Field struct eta { typedef void const_field; static float val() {return 1.0;} }; // Convenient constants constexpr unsigned int v[] = {0,1}; constexpr unsigned int P = 2; constexpr unsigned int ic = 2; // Create field that we have v_x, v_y, P typedef Field v_x; typedef Field v_y; typedef Field Prs; // Eq1 V_x typedef mul,lid_nn> eta_lap_vx; typedef D p_x; typedef minus m_p_x; typedef sum vx_eq; // Eq2 V_y typedef mul,lid_nn> eta_lap_vy; typedef D p_y; typedef minus m_p_y; typedef sum vy_eq; // Eq3 Incompressibility typedef D dx_vx; typedef D dy_vy; typedef sum ic_eq; // Equation for boundary conditions /* Consider the staggered cell * \verbatim +--\$--+ | | # * # | | 0--\$--+ # = velocity(y) \$ = velocity(x) * = pressure \endverbatim * * * If we want to impose v_y = 0 on 0 we have to interpolate between # of this cell * and # of the previous cell on y, (Average) or Avg operator * */ // Directional Avg typedef Avg avg_vy; typedef Avg avg_vx; typedef Avg avg_vy_f; typedef Avg avg_vx_f; #define EQ_1 0 #define EQ_2 1 #define EQ_3 2 //! [Definition of the equation of the system in the bulk and at the boundary] template void lid_driven_cavity_2d() { Vcluster<> & v_cl = create_vcluster(); if (v_cl.getProcessingUnits() > 3) return; //! [lid-driven cavity 2D] // velocity in the grid is the property 0, pressure is the property 1 constexpr int velocity = 0; constexpr int pressure = 1; // Domain, a rectangle Box<2,float> domain({0.0,0.0},{3.0,1.0}); // Ghost (Not important in this case but required) Ghost<2,float> g(0.01); // Grid points on x=256 and y=64 long int sz[] = {256,64}; size_t szu; szu = (size_t)sz; szu = (size_t)sz; // We need one more point on the left and down part of the domain // This is given by the boundary conditions that we impose, the // reason is mathematical in order to have a well defined system // and cannot be discussed here Padding<2> pd({1,1},{0,0}); // Distributed grid that store the solution grid_dist_id<2,float,aggregate,CartDecomposition<2,float>> g_dist(szu,domain,g); // It is the maximum extension of the stencil Ghost<2,long int> stencil_max(1); // Finite difference scheme FDScheme fd(pd, stencil_max, domain,g_dist); // Here we impose the equation, we start from the incompressibility Eq imposed in the bulk with the // exception of the first point {0,0} and than we set P = 0 in {0,0}, why we are doing this is again // mathematical to have a well defined system, an intuitive explanation is that P and P + c are both // solution for the incompressibility equation, this produce an ill-posed problem to make it well posed // we set one point in this case {0,0} the pressure to a fixed constant for convenience P = 0 fd.impose(ic_eq(),0.0, EQ_3, {0,0},{sz-2,sz-2},true); fd.impose(Prs(), 0.0, EQ_3, {0,0},{0,0}); // Here we impose the Eq1 and Eq2 fd.impose(vx_eq(),0.0, EQ_1, {1,0},{sz-2,sz-2}); fd.impose(vy_eq(),0.0, EQ_2, {0,1},{sz-2,sz-2}); // v_x and v_y // Imposing B1 fd.impose(v_x(),0.0, EQ_1, {0,0},{0,sz-2}); fd.impose(avg_vy_f(),0.0, EQ_2 , {-1,0},{-1,sz-1}); // Imposing B2 fd.impose(v_x(),0.0, EQ_1, {sz-1,0},{sz-1,sz-2}); fd.impose(avg_vy(),1.0, EQ_2, {sz-1,0},{sz-1,sz-1}); // Imposing B3 fd.impose(avg_vx_f(),0.0, EQ_1, {0,-1},{sz-1,-1}); fd.impose(v_y(), 0.0, EQ_2, {0,0},{sz-2,0}); // Imposing B4 fd.impose(avg_vx(),0.0, EQ_1, {0,sz-1},{sz-1,sz-1}); fd.impose(v_y(), 0.0, EQ_2, {0,sz-1},{sz-2,sz-1}); // When we pad the grid, there are points of the grid that are not // touched by the previous condition. Mathematically this lead // to have too many variables for the conditions that we are imposing. // Here we are imposing variables that we do not touch to zero // // Padding pressure fd.impose(Prs(), 0.0, EQ_3, {-1,-1},{sz-1,-1}); fd.impose(Prs(), 0.0, EQ_3, {-1,sz-1},{sz-1,sz-1}); fd.impose(Prs(), 0.0, EQ_3, {-1,0},{-1,sz-2}); fd.impose(Prs(), 0.0, EQ_3, {sz-1,0},{sz-1,sz-2}); // Impose v_x Padding Impose v_y padding fd.impose(v_x(), 0.0, EQ_1, {-1,-1},{-1,sz-1}); fd.impose(v_y(), 0.0, EQ_2, {-1,-1},{sz-1,-1}); solver_type solver; auto x = solver.solve(fd.getA(),fd.getB()); //! [lid-driven cavity 2D] //! [Copy the solution to grid] fd.template copy(x,{0,0},{sz-1,sz-1},g_dist); std::string s = std::string(demangle(typeid(solver_type).name())); s += "_"; //! [Copy the solution to grid] g_dist.write(s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid"); #ifdef HAVE_OSX std::string file1 = std::string("test/") + s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + "_test_osx.vtk"; std::string file2 = s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk"; #else #if __GNUC__ == 6 std::string file1 = std::string("test/") + s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + "_test_GCC6.vtk"; std::string file2 = s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk"; #elif __GNUC__ == 5 std::string file1 = std::string("test/") + s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + "_test_GCC5.vtk"; std::string file2 = s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk"; #else std::string file1 = std::string("test/") + s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + "_test_GCC4.vtk"; std::string file2 = s + "lid_driven_cavity_p" + std::to_string(v_cl.getProcessingUnits()) + "_grid_" + std::to_string(v_cl.getProcessUnitID()) + ".vtk"; #endif #endif std::cout << "File1: " << file1 << std::endl; std::cout << "File2: " << file2 << std::endl; #ifndef SE_CLASS3 // Check that match bool test = compare(file1,file2); BOOST_REQUIRE_EQUAL(test,true); #endif } // Lid driven cavity, incompressible fluid BOOST_AUTO_TEST_CASE(lid_driven_cavity) { lid_driven_cavity_2d,lid_nn>(); } BOOST_AUTO_TEST_SUITE_END() #endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_EQ_UNIT_TEST_HPP_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment