From 6f2388aab59ec96b949b5418ec5b2c2f05e44092 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <incardon@mpi-cbg.de> Date: Mon, 20 Apr 2020 17:32:33 +0200 Subject: [PATCH] Writer for SparseMatrix + Fixing DCPSE.hpp for parallel --- mpi_include | 2 +- mpi_libs | 2 +- src/CMakeLists.txt | 2 +- src/DCPSE_op/DCPSE_Solver.hpp | 60 +++++++++- src/DCPSE_op/DCPSE_copy/SupportBuilder.hpp | 5 +- src/DCPSE_op/DCPSE_op_test.cpp | 124 ++++++++++++++++++++- src/DCPSE_op/EqnsStructEigen.hpp | 12 ++ src/DCPSE_op/EqnsStructPetsc.hpp | 24 +++- src/Matrix/SparseMatrix_petsc.hpp | 41 +++++++ 9 files changed, 253 insertions(+), 19 deletions(-) diff --git a/mpi_include b/mpi_include index 16981421..4439b1ca 100644 --- a/mpi_include +++ b/mpi_include @@ -1 +1 @@ --I \ No newline at end of file +-I/home/i-bird/MPI/include \ No newline at end of file diff --git a/mpi_libs b/mpi_libs index 0519ecba..3a37a5cd 100644 --- a/mpi_libs +++ b/mpi_libs @@ -1 +1 @@ - \ No newline at end of file +-Wl,-rpath -Wl,/home/i-bird/MPI/lib -Wl,--enable-new-dtags -pthread /home/i-bird/MPI/lib/libmpi.so \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 124f6db8..44efcfaa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.8 FATAL_ERROR) ########################### Executables -add_executable(numerics DCPSE_op/DCPSE_op_test3d.cpp DCPSE_op/DCPSE_op_test2.cpp DCPSE_op/DCPSE_op_test.cpp main.cpp Matrix/SparseMatrix_unit_tests.cpp interpolation/interpolation_unit_tests.cpp Vector/Vector_unit_tests.cpp Solvers/petsc_solver_unit_tests.cpp FiniteDifference/FDScheme_unit_tests.cpp FiniteDifference/eq_unit_test_3d.cpp FiniteDifference/eq_unit_test.cpp Operators/Vector/vector_dist_operators_unit_tests.cpp ../../openfpm_vcluster/src/VCluster/VCluster.cpp ../../openfpm_devices/src/memory/CudaMemory.cu ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp DCPSE_op/DCPSE_Solver.hpp MatrixAssembler/MatrixAssembler.hpp DCPSE_op/EqnsStruct.hpp) +add_executable(numerics DCPSE_op/DCPSE_op_test3d.cpp DCPSE_op/DCPSE_op_test2.cpp DCPSE_op/DCPSE_op_test.cpp main.cpp Matrix/SparseMatrix_unit_tests.cpp interpolation/interpolation_unit_tests.cpp Vector/Vector_unit_tests.cpp Solvers/petsc_solver_unit_tests.cpp FiniteDifference/FDScheme_unit_tests.cpp FiniteDifference/eq_unit_test_3d.cpp FiniteDifference/eq_unit_test.cpp Operators/Vector/vector_dist_operators_unit_tests.cpp ../../openfpm_vcluster/src/VCluster/VCluster.cpp ../../openfpm_devices/src/memory/CudaMemory.cu ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp ) ########################### diff --git a/src/DCPSE_op/DCPSE_Solver.hpp b/src/DCPSE_op/DCPSE_Solver.hpp index ce939d08..1d93b4c4 100644 --- a/src/DCPSE_op/DCPSE_Solver.hpp +++ b/src/DCPSE_op/DCPSE_Solver.hpp @@ -295,7 +295,7 @@ class DCPSE_scheme: public MatrixAssembler while (it.isNext()) { auto p = it.get(); - exp.value(p) = x(p.getKey()*Sys_eqs::nvar + comp); + exp.value(p) = x(p.getKey()*Sys_eqs::nvar + comp + s_pnt*Sys_eqs::nvar); ++it; } } @@ -353,19 +353,61 @@ public: */ template<typename ... expr_type> void solve(expr_type ... exps) + { + if (sizeof...(exps) != Sys_eqs::nvar) + {std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\ + dimensionality, I am expecting " << Sys_eqs::nvar << + " properties " << std::endl;}; + typename Sys_eqs::solver_type solver; +// umfpack_solver<double> solver; + auto x = solver.solve(getA(opt),getB(opt)); + + unsigned int comp = 0; + copy_nested(x,comp,exps ...); + } + + /*! \brief Solve an equation + * + * \warning exp must be a scalar type + * + * \param exp where to store the result + * + */ + template<typename SolverType, typename ... expr_type> + void solve_with_solver(SolverType & solver, expr_type ... exps) { if (sizeof...(exps) != Sys_eqs::nvar) {std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\ dimensionality, I am expecting " << Sys_eqs::nvar << " properties " << std::endl;}; - umfpack_solver<double> solver; auto x = solver.solve(getA(opt),getB(opt)); unsigned int comp = 0; copy_nested(x,comp,exps ...); } + /*! \brief Solve an equation + * + * \warning exp must be a scalar type + * + * \param exp where to store the result + * + */ + template<typename SolverType, typename ... expr_type> + void try_solve_with_solver(SolverType & solver, expr_type ... exps) + { + if (sizeof...(exps) != Sys_eqs::nvar) + {std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\ + dimensionality, I am expecting " << Sys_eqs::nvar << + " properties " << std::endl;}; + + auto x = solver.try_solve(getA(opt),getB(opt)); + + unsigned int comp = 0; + copy_nested(x,comp,exps ...); + } + /*! \brief Constructor * * The periodicity is given by the grid b_g @@ -506,6 +548,14 @@ public: trpl.add(t2); } + triplet t3; + + t3.col() = tot * Sys_eqs::nvar; + t3.row() = tot * Sys_eqs::nvar; + t3.value() = 0; + + trpl.add(t3); + row_b++; row++; } @@ -577,6 +627,12 @@ public: // get the particle auto key = it.get(); + if (key == 298 && create_vcluster().rank() == 1) + { + int debug = 0; + debug++; + } + // Calculate the non-zero colums typename Sys_eqs::stype coeff = 1.0; op.template value_nz<Sys_eqs>(p_map,key,cols,coeff,0); diff --git a/src/DCPSE_op/DCPSE_copy/SupportBuilder.hpp b/src/DCPSE_op/DCPSE_copy/SupportBuilder.hpp index 8dfd39a4..ad34d8e0 100644 --- a/src/DCPSE_op/DCPSE_copy/SupportBuilder.hpp +++ b/src/DCPSE_op/DCPSE_copy/SupportBuilder.hpp @@ -11,6 +11,7 @@ #include <Space/Shape/Point.hpp> #include <Vector/vector_dist.hpp> #include "Support.hpp" +#include <utility> enum support_options { @@ -23,7 +24,7 @@ class SupportBuilder { private: vector_type &domain; - CellList<vector_type::dims, typename vector_type::stype, Mem_fast<HeapMemory, local_index_>> cellList; + decltype(std::declval<vector_type>().getCellList(0.0)) cellList; const Point<vector_type::dims, unsigned int> differentialSignature; typename vector_type::stype rCut; @@ -57,7 +58,7 @@ SupportBuilder<vector_type>::SupportBuilder(vector_type &domain, const Point<vec differentialSignature(differentialSignature), rCut(rCut) { - cellList = domain.template getCellList<CellList<vector_type::dims, typename vector_type::stype, Mem_fast<HeapMemory, local_index_>>>(rCut); + cellList = domain.getCellList(rCut); } template<typename vector_type> diff --git a/src/DCPSE_op/DCPSE_op_test.cpp b/src/DCPSE_op/DCPSE_op_test.cpp index 59e23e1d..0c4c19ac 100644 --- a/src/DCPSE_op/DCPSE_op_test.cpp +++ b/src/DCPSE_op/DCPSE_op_test.cpp @@ -974,7 +974,7 @@ BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests) BOOST_AUTO_TEST_CASE(dcpse_poisson_Robin_anal) { // int rank; // MPI_Comm_rank(MPI_COMM_WORLD, &rank); - const size_t sz[2] = {161,161}; + const size_t sz[2] = {50,50}; Box<2, double> box({0, 0}, {0.5, 0.5}); size_t bc[2] = {NON_PERIODIC, NON_PERIODIC}; double spacing = box.getHigh(0) / (sz[0] - 1); @@ -1000,15 +1000,96 @@ BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests) ++it; } + + // Add multi res patch 1 + + { + const size_t sz2[2] = {40,40}; + Box<2,double> bx({0.25 + it.getSpacing(0)/4.0,0.25 + it.getSpacing(0)/4.0},{sz2[0]*it.getSpacing(0)/2.0 + 0.25 + it.getSpacing(0)/4.0, sz2[1]*it.getSpacing(0)/2.0 + 0.25 + it.getSpacing(0)/4.0}); + openfpm::vector<size_t> rem; + + auto it = domain.getDomainIterator(); + + while (it.isNext()) + { + auto k = it.get(); + + Point<2,double> xp = domain.getPos(k); + + if (bx.isInside(xp) == true) + { + rem.add(k.getKey()); + } + + ++it; + } + + domain.remove(rem); + + auto it2 = domain.getGridIterator(sz2); + while (it2.isNext()) { + domain.add(); + + auto key = it2.get(); + double x = key.get(0) * spacing/2.0 + 0.25 + spacing/4.0; + domain.getLastPos()[0] = x; + double y = key.get(1) * spacing/2.0 + 0.25 + spacing/4.0; + domain.getLastPos()[1] = y; + + ++it2; + } + } + + // Add multi res patch 2 + + { + const size_t sz2[2] = {40,40}; + Box<2,double> bx({0.25 + 21.0*spacing/8.0,0.25 + 21.0*spacing/8.0},{sz2[0]*spacing/4.0 + 0.25 + 21.0*spacing/8.0, sz2[1]*spacing/4.0 + 0.25 + 21*spacing/8.0}); + openfpm::vector<size_t> rem; + + auto it = domain.getDomainIterator(); + + while (it.isNext()) + { + auto k = it.get(); + + Point<2,double> xp = domain.getPos(k); + + if (bx.isInside(xp) == true) + { + rem.add(k.getKey()); + } + + ++it; + } + + domain.remove(rem); + + auto it2 = domain.getGridIterator(sz2); + while (it2.isNext()) { + domain.add(); + + auto key = it2.get(); + double x = key.get(0) * spacing/4.0 + 0.25 + 21*spacing/8.0; + domain.getLastPos()[0] = x; + double y = key.get(1) * spacing/4.0 + 0.25 + 21*spacing/8.0; + domain.getLastPos()[1] = y; + + ++it2; + } + } + + /////////////////////// + BOOST_TEST_MESSAGE("Sync domain across processors..."); domain.map(); domain.ghost_get<0>(); - Derivative_x Dx(domain, 2, rCut,1.9,support_options::RADIUS); - Derivative_y Dy(domain, 2, rCut,1.9,support_options::RADIUS); + Derivative_x Dx(domain, 2, rCut / 3.0 ,1.9/*,support_options::RADIUS*/); + Derivative_y Dy(domain, 2, rCut / 3.0 ,1.9/*,support_options::RADIUS*/); //Gradient Grad(domain, 2, rCut); - Laplacian Lap(domain, 2, rCut,1.9,support_options::RADIUS); + Laplacian Lap(domain, 2, rCut / 3.0 ,1.9/*,support_options::RADIUS*/); //Advection Adv(domain, 3, rCut, 3); //Solver Sol_Lap(Lap),Sol_Dx(Dx); @@ -1090,6 +1171,9 @@ BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests) } ++it2; } + + domain.ghost_get<1,3>(); + DCPSE_scheme<equations2d1,decltype(domain)> Solver( domain); auto Poisson = Lap(v); auto D_x = Dx(v); @@ -1099,8 +1183,35 @@ BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests) Solver.impose(D_x, r_p, 0); Solver.impose(v, dw_p, 0); Solver.impose(v, l_p, 0); - Solver.solve(sol); + + petsc_solver<double> solver; + + solver.setRestart(500); + +// auto A = Solver.getA(); +// A.write("Matrix_anal_sol"); + +// solver.setSolver(KSPGMRES); +// solver.setPreconditioner(PCKSP); +// solver.setRestart(300); + +/* solver.setPreconditioner(PCHYPRE_BOOMERAMG); + solver.setPreconditionerAMG_nl(6); + solver.setPreconditionerAMG_maxit(10); + solver.setPreconditionerAMG_relax("SOR/Jacobi"); + solver.setPreconditionerAMG_cycleType("V",0,4); + solver.setPreconditionerAMG_coarsenNodalType(0); + solver.setPreconditionerAMG_coarsen("HMIS");*/ + +// solver.log_monitor(); + + Solver.solve_with_solver(solver,sol); + + domain.ghost_get<2>(); + DCPSE_sol=Lap(sol); + domain.ghost_get<5>(); + double worst1 = 0.0; v=abs(DCPSE_sol-RHS); @@ -1115,6 +1226,7 @@ BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests) } std::cout << "Maximum Analytic Error: " << worst1 << std::endl; + domain.ghost_get<4>(); domain.write("Robin_anasol"); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1123,7 +1235,7 @@ BOOST_AUTO_TEST_SUITE(dcpse_op_suite_tests) BOOST_AUTO_TEST_CASE(dcpse_poisson_Dirichlet_anal) { // int rank; // MPI_Comm_rank(MPI_COMM_WORLD, &rank); - const size_t sz[2] = {81,81}; + const size_t sz[2] = {512,512}; Box<2, double> box({0, 0}, {1, 1}); size_t bc[2] = {NON_PERIODIC, NON_PERIODIC}; double spacing = box.getHigh(0) / (sz[0] - 1); diff --git a/src/DCPSE_op/EqnsStructEigen.hpp b/src/DCPSE_op/EqnsStructEigen.hpp index c5c954e4..36d2e3bc 100644 --- a/src/DCPSE_op/EqnsStructEigen.hpp +++ b/src/DCPSE_op/EqnsStructEigen.hpp @@ -27,6 +27,8 @@ struct equations2d1 { //! type of Vector for the linear solver typedef Vector<double> Vector_type; + + typedef umfpack_solver<double> solver_type; }; struct equations2d2 { @@ -49,6 +51,8 @@ struct equations2d2 { //! type of Vector for the linear solver typedef Vector<double> Vector_type; + + typedef umfpack_solver<double> solver_type; }; @@ -72,6 +76,8 @@ struct equations2d1p { //! type of Vector for the linear solver typedef Vector<double> Vector_type; + + typedef umfpack_solver<double> solver_type; }; struct equations2d2p { @@ -94,6 +100,8 @@ struct equations2d2p { //! type of Vector for the linear solver typedef Vector<double> Vector_type; + + typedef umfpack_solver<double> solver_type; }; struct equations3d3 { @@ -116,6 +124,8 @@ struct equations3d3 { //! type of Vector for the linear solver typedef Vector<double> Vector_type; + + typedef umfpack_solver<double> solver_type; }; struct equations3d1 { @@ -138,6 +148,8 @@ struct equations3d1 { //! type of Vector for the linear solver typedef Vector<double> Vector_type; + + typedef umfpack_solver<double> solver_type; }; diff --git a/src/DCPSE_op/EqnsStructPetsc.hpp b/src/DCPSE_op/EqnsStructPetsc.hpp index 51edf411..5ea1e106 100644 --- a/src/DCPSE_op/EqnsStructPetsc.hpp +++ b/src/DCPSE_op/EqnsStructPetsc.hpp @@ -26,7 +26,9 @@ struct equations2d1 { typedef SparseMatrix<double, int, PETSC_BASE> SparseMatrix_type; //! type of Vector for the linear solver - typedef Vector<double> Vector_type; + typedef Vector<double, PETSC_BASE> Vector_type; + + typedef petsc_solver<double> solver_type; }; struct equations2d2 { @@ -48,7 +50,9 @@ struct equations2d2 { typedef SparseMatrix<double, int, PETSC_BASE> SparseMatrix_type; //! type of Vector for the linear solver - typedef Vector<double> Vector_type; + typedef Vector<double, PETSC_BASE> Vector_type; + + typedef petsc_solver<double> solver_type; }; @@ -71,7 +75,9 @@ struct equations2d1p { typedef SparseMatrix<double, int, PETSC_BASE> SparseMatrix_type; //! type of Vector for the linear solver - typedef Vector<double> Vector_type; + typedef Vector<double, PETSC_BASE> Vector_type; + + typedef petsc_solver<double> solver_type; }; struct equations2d2p { @@ -93,7 +99,9 @@ struct equations2d2p { typedef SparseMatrix<double, int, PETSC_BASE> SparseMatrix_type; //! type of Vector for the linear solver - typedef Vector<double> Vector_type; + typedef Vector<double, PETSC_BASE> Vector_type; + + typedef petsc_solver<double> solver_type; }; struct equations3d3 { @@ -115,7 +123,9 @@ struct equations3d3 { typedef SparseMatrix<double, int, PETSC_BASE> SparseMatrix_type; //! type of Vector for the linear solver - typedef Vector<double> Vector_type; + typedef Vector<double, PETSC_BASE> Vector_type; + + typedef petsc_solver<double> solver_type; }; struct equations3d1 { @@ -137,7 +147,9 @@ struct equations3d1 { typedef SparseMatrix<double, int, PETSC_BASE> SparseMatrix_type; //! type of Vector for the linear solver - typedef Vector<double> Vector_type; + typedef Vector<double, PETSC_BASE> Vector_type; + + typedef petsc_solver<double> solver_type; }; diff --git a/src/Matrix/SparseMatrix_petsc.hpp b/src/Matrix/SparseMatrix_petsc.hpp index 3534924b..a03b0671 100644 --- a/src/Matrix/SparseMatrix_petsc.hpp +++ b/src/Matrix/SparseMatrix_petsc.hpp @@ -12,6 +12,7 @@ #include "Vector/map_vector.hpp" #include <boost/mpl/int.hpp> #include <petscmat.h> +#include "VTKWriter/VTKWriter.hpp" #define PETSC_BASE 2 @@ -352,6 +353,46 @@ public: return 0; } + + /* Write matrix on vtk + * + * + */ + bool write(std::string out) + { + Vcluster<> & v_cl = create_vcluster(); + + openfpm::vector<Point<2, double>> row_col; + openfpm::vector<aggregate<double>> values; + + row_col.resize(trpl.size()); + values.resize(trpl.size()); + + for (int i = 0 ; i < trpl.size() ; i++) + { + row_col.template get<0>(i)[1] = trpl.get(i).row(); + row_col.template get<0>(i)[0] = trpl.get(i).col(); + + values.template get<0>(i) = trpl.get(i).value(); + } + + auto ft = file_type::BINARY; + + // VTKWriter for a set of points + VTKWriter<boost::mpl::pair<openfpm::vector<Point<2, double>>, + openfpm::vector<aggregate<double>>>, + VECTOR_POINTS> vtk_writer; + + vtk_writer.add(row_col,values,row_col.size()); + + std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".vtk")); + + openfpm::vector<std::string> prp_names; + prp_names.add("value"); + + // Write the VTK file + return vtk_writer.write(output,prp_names,"particles","",ft); + } }; -- GitLab