From 14ce1a731a00cc2e0d0facd8f4548f683759abbf Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 11 May 2018 17:31:07 +0200 Subject: [PATCH] Improved 1d mesh management - Uses a new mesh interface (pretty crap, using dimension to deduce mesh kind) - 1d mesh reader almost functionnal (missing boundaries) - 1d mesh based scheme plugged in a really ugly way (proof of concept) --- src/main.cpp | 229 +++++++++++++++++++++++++++------------- src/mesh/GmshReader.cpp | 19 ++-- src/mesh/GmshReader.hpp | 11 +- src/mesh/Mesh.hpp | 13 ++- 4 files changed, 181 insertions(+), 91 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fb2da6d32..8b76ec57f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,104 +124,183 @@ int main(int argc, char *argv[]) if (filename != "") { std::cout << "Reading (gmsh) " << rang::style::underline << filename << rang::style::reset << " ...\n"; GmshReader gmsh_reader(filename); + std::shared_ptr<IMesh> p_mesh = gmsh_reader.mesh(); + + switch (p_mesh->meshDimension()) { + case 1: { + typedef Connectivity1D ConnectivityType; + typedef Mesh<ConnectivityType> MeshType; + typedef MeshData<MeshType> MeshDataType; + typedef FiniteVolumesEulerUnknowns<MeshDataType> UnknownsType; + + const MeshType& mesh = dynamic_cast<const MeshType&>(*gmsh_reader.mesh()); + + Kokkos::Timer timer; + timer.reset(); + MeshDataType mesh_data(mesh); + + std::vector<BoundaryConditionHandler> bc_list; + // { // quite dirty! + // for (size_t i_boundary=0; i_boundary<mesh.connectivity().numberOfNodeBoundaries(); ++i_boundary) { + // ConnectivityType::NodesBoundary nodes_boundary = mesh.connectivity().nodesBoundary(i_boundary); + // unsigned int ref = nodes_boundary.first; + // TinyVector<2> normal(0,0); + // if ((ref == 5) or (ref == 6)) { + // normal = TinyVector<2>(0,1); + // } else { + // normal = TinyVector<2>(1,0); + // } + // const Kokkos::View<const unsigned int*> nodes_ids = nodes_boundary.second; + // std::vector<unsigned int> node_boundary_vector(nodes_ids.extent(0)); + // for (size_t r=0; r<nodes_ids.extent(0); ++r) { + // node_boundary_vector[r] = nodes_ids[r]; + // } + // SymmetryBoundaryCondition<MeshType::dimension>* sym_bc + // = new SymmetryBoundaryCondition<MeshType::dimension>(node_boundary_vector, normal); + // std::shared_ptr<SymmetryBoundaryCondition<MeshType::dimension>> bc(sym_bc); + // bc_list.push_back(BoundaryConditionHandler(bc)); + // } + // } + + UnknownsType unknowns(mesh_data); + + unknowns.initializeSod(); + + AcousticSolver<MeshDataType> acoustic_solver(mesh_data, unknowns, bc_list); + + typedef TinyVector<MeshType::dimension> Rd; + + const Kokkos::View<const double*> Vj = mesh_data.Vj(); + const Kokkos::View<const Rd**> Cjr = mesh_data.Cjr(); + + const double tmax=0.2; + double t=0; + + int itermax=std::numeric_limits<int>::max(); + int iteration=0; + + Kokkos::View<double*> rhoj = unknowns.rhoj(); + Kokkos::View<double*> ej = unknowns.ej(); + Kokkos::View<double*> pj = unknowns.pj(); + Kokkos::View<double*> gammaj = unknowns.gammaj(); + Kokkos::View<double*> cj = unknowns.cj(); + + BlockPerfectGas block_eos(rhoj, ej, pj, gammaj, cj); + + VTKWriter vtk_writer("mesh", 0.01); + + while((t<tmax) and (iteration<itermax)) { + vtk_writer.write(mesh, t); + double dt = 0.4*acoustic_solver.acoustic_dt(Vj, cj); + if (t+dt>tmax) { + dt=tmax-t; + } + acoustic_solver.computeNextStep(t,dt, unknowns); - typedef Mesh<Connectivity2D> MeshType; - typedef MeshData<MeshType> MeshDataType; - typedef FiniteVolumesEulerUnknowns<MeshDataType> UnknownsType; + block_eos.updatePandCFromRhoE(); + + t += dt; + ++iteration; + } + vtk_writer.write(mesh, t, true); // forces last output - MeshType& mesh = gmsh_reader.mesh(); + std::cout << "* " << rang::style::underline << "Final time" << rang::style::reset + << ": " << rang::fgB::green << t << rang::fg::reset << " (" << iteration << " iterations)\n"; - Kokkos::Timer timer; - timer.reset(); - MeshDataType mesh_data(mesh); + method_cost_map["AcousticSolverWithMesh"] = timer.seconds(); - std::vector<BoundaryConditionHandler> bc_list; - { // quite dirty! - for (size_t i_boundary=0; i_boundary<mesh.connectivity().numberOfNodeBoundaries(); ++i_boundary) { - Connectivity2D::NodesBoundary nodes_boundary = mesh.connectivity().nodesBoundary(i_boundary); - unsigned int ref = nodes_boundary.first; - TinyVector<2> normal(0,0); - if ((ref == 5) or (ref == 6)) { - normal = TinyVector<2>(0,1); - } else { - normal = TinyVector<2>(1,0); - } - const Kokkos::View<const unsigned int*> nodes_ids = nodes_boundary.second; - std::vector<unsigned int> node_boundary_vector(nodes_ids.extent(0)); - for (size_t r=0; r<nodes_ids.extent(0); ++r) { - node_boundary_vector[r] = nodes_ids[r]; + break; + } + case 2: { + typedef Connectivity2D ConnectivityType; + typedef Mesh<ConnectivityType> MeshType; + typedef MeshData<MeshType> MeshDataType; + typedef FiniteVolumesEulerUnknowns<MeshDataType> UnknownsType; + + const MeshType& mesh = dynamic_cast<const MeshType&>(*gmsh_reader.mesh()); + + Kokkos::Timer timer; + timer.reset(); + MeshDataType mesh_data(mesh); + + std::vector<BoundaryConditionHandler> bc_list; + { // quite dirty! + for (size_t i_boundary=0; i_boundary<mesh.connectivity().numberOfNodeBoundaries(); ++i_boundary) { + ConnectivityType::NodesBoundary nodes_boundary = mesh.connectivity().nodesBoundary(i_boundary); + unsigned int ref = nodes_boundary.first; + TinyVector<2> normal(0,0); + if ((ref == 5) or (ref == 6)) { + normal = TinyVector<2>(0,1); + } else { + normal = TinyVector<2>(1,0); + } + const Kokkos::View<const unsigned int*> nodes_ids = nodes_boundary.second; + std::vector<unsigned int> node_boundary_vector(nodes_ids.extent(0)); + for (size_t r=0; r<nodes_ids.extent(0); ++r) { + node_boundary_vector[r] = nodes_ids[r]; + } + SymmetryBoundaryCondition<MeshType::dimension>* sym_bc + = new SymmetryBoundaryCondition<MeshType::dimension>(node_boundary_vector, normal); + std::shared_ptr<SymmetryBoundaryCondition<MeshType::dimension>> bc(sym_bc); + bc_list.push_back(BoundaryConditionHandler(bc)); } - SymmetryBoundaryCondition<MeshType::dimension>* sym_bc - = new SymmetryBoundaryCondition<MeshType::dimension>(node_boundary_vector, normal); - std::shared_ptr<SymmetryBoundaryCondition<MeshType::dimension>> bc(sym_bc); - bc_list.push_back(BoundaryConditionHandler(bc)); } - // PressureBoundaryCondition* pres_bc1 - // = new PressureBoundaryCondition(0.1, - // std::vector<unsigned int>({static_cast<unsigned int>(mesh.numberOfCells())})); - // std::shared_ptr<PressureBoundaryCondition> bc1(pres_bc1); - // bc_list.push_back(BoundaryConditionHandler(bc1)); - } + UnknownsType unknowns(mesh_data); - UnknownsType unknowns(mesh_data); - - unknowns.initializeSod(); + unknowns.initializeSod(); - AcousticSolver<MeshDataType> acoustic_solver(mesh_data, unknowns, bc_list); + AcousticSolver<MeshDataType> acoustic_solver(mesh_data, unknowns, bc_list); - typedef TinyVector<MeshType::dimension> Rd; + typedef TinyVector<MeshType::dimension> Rd; - const Kokkos::View<const double*> Vj = mesh_data.Vj(); - const Kokkos::View<const Rd**> Cjr = mesh_data.Cjr(); + const Kokkos::View<const double*> Vj = mesh_data.Vj(); + const Kokkos::View<const Rd**> Cjr = mesh_data.Cjr(); - const double tmax=0.2; - double t=0; + const double tmax=0.2; + double t=0; - int itermax=std::numeric_limits<int>::max(); - int iteration=0; + int itermax=std::numeric_limits<int>::max(); + int iteration=0; - Kokkos::View<double*> rhoj = unknowns.rhoj(); - Kokkos::View<double*> ej = unknowns.ej(); - Kokkos::View<double*> pj = unknowns.pj(); - Kokkos::View<double*> gammaj = unknowns.gammaj(); - Kokkos::View<double*> cj = unknowns.cj(); + Kokkos::View<double*> rhoj = unknowns.rhoj(); + Kokkos::View<double*> ej = unknowns.ej(); + Kokkos::View<double*> pj = unknowns.pj(); + Kokkos::View<double*> gammaj = unknowns.gammaj(); + Kokkos::View<double*> cj = unknowns.cj(); - BlockPerfectGas block_eos(rhoj, ej, pj, gammaj, cj); + BlockPerfectGas block_eos(rhoj, ej, pj, gammaj, cj); - VTKWriter vtk_writer("mesh", 0.01); + VTKWriter vtk_writer("mesh", 0.01); - while((t<tmax) and (iteration<itermax)) { - vtk_writer.write(mesh, t); - double dt = 0.4*acoustic_solver.acoustic_dt(Vj, cj); - if (t+dt>tmax) { - dt=tmax-t; - } - acoustic_solver.computeNextStep(t,dt, unknowns); + while((t<tmax) and (iteration<itermax)) { + vtk_writer.write(mesh, t); + double dt = 0.4*acoustic_solver.acoustic_dt(Vj, cj); + if (t+dt>tmax) { + dt=tmax-t; + } + acoustic_solver.computeNextStep(t,dt, unknowns); - block_eos.updatePandCFromRhoE(); + block_eos.updatePandCFromRhoE(); - t += dt; - ++iteration; - } - vtk_writer.write(mesh, t, true); // forces last output - - std::ofstream gnuplot("sol.gnu"); - for (size_t j=0; j<mesh.numberOfCells(); ++j) { - for (int r=0; r<mesh.connectivity().cellNbNodes()[j]; ++r) { - const Rd& x = mesh.xr()[mesh.connectivity().cellNodes()(j,r)]; - gnuplot << x[0] << ' ' << x[1] << '\n'; + t += dt; + ++iteration; } - const Rd& x = mesh.xr()[mesh.connectivity().cellNodes()(j,0)]; - gnuplot << x[0] << ' ' << x[1] << "\n\n"; - } - gnuplot.close(); + vtk_writer.write(mesh, t, true); // forces last output - std::cout << "* " << rang::style::underline << "Final time" << rang::style::reset - << ": " << rang::fgB::green << t << rang::fg::reset << " (" << iteration << " iterations)\n"; + std::cout << "* " << rang::style::underline << "Final time" << rang::style::reset + << ": " << rang::fgB::green << t << rang::fg::reset << " (" << iteration << " iterations)\n"; - method_cost_map["AcousticSolverWithMesh"] = timer.seconds(); + method_cost_map["AcousticSolverWithMesh"] = timer.seconds(); + break; + } + case 3: { + break; + } + } + std::cout << "* " << rang::fgB::red << "Could not be uglier!" << rang::fg::reset << " (" << __FILE__ << ':' << __LINE__ << ")\n"; + } else { // class for acoustic solver test Kokkos::Timer timer; diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp index 18e301b35..ba398607b 100644 --- a/src/mesh/GmshReader.cpp +++ b/src/mesh/GmshReader.cpp @@ -5,6 +5,7 @@ #include <set> #include <rang.hpp> +#include <Connectivity1D.hpp> #include <Connectivity2D.hpp> #include <Mesh.hpp> #include <map> @@ -805,7 +806,7 @@ GmshReader::__proceedData() for (size_t j=nb_triangles; j<nb_triangles+nb_quadrangles; ++j) { cell_nb_nodes[j] = 4; } - Connectivity2D* p_connectivity = new Connectivity2D(cell_nb_nodes, cell_nodes); + std::shared_ptr<Connectivity2D> p_connectivity(new Connectivity2D(cell_nb_nodes, cell_nodes)); Connectivity2D& connectivity = *p_connectivity; std::map<unsigned int, std::vector<unsigned int>> ref_faces_map; @@ -856,7 +857,7 @@ GmshReader::__proceedData() xr[i][0] = __vertices[i][0]; xr[i][1] = __vertices[i][1]; } - m_mesh = new MeshType(std::shared_ptr<Connectivity2D>(p_connectivity), xr); + m_mesh = std::shared_ptr<IMesh>(new MeshType(p_connectivity, xr)); } else if ((dimension1_mask, elementNumber)>0) { @@ -874,13 +875,17 @@ GmshReader::__proceedData() cell_nb_nodes[j] = 2; } - // std::shared_ptr<Connectivity1D> connectivity(new Connectivity1D()); - // m_connectivity = new Connectivity2D(cell_nb_nodes, cell_nodes); - // Connectivity2D& connectivity = *m_connectivity; + std::shared_ptr<Connectivity1D> connectivity(new Connectivity1D(cell_nb_nodes, cell_nodes)); + typedef Mesh<Connectivity1D> MeshType; + typedef TinyVector<1, double> Rd; + Kokkos::View<Rd*> xr("xr", __vertices.extent(0)); + for (size_t i=0; i<__vertices.extent(0); ++i) { + xr[i][0] = __vertices[i][0]; + } + + m_mesh = std::shared_ptr<IMesh>(new MeshType(connectivity, xr)); - std::cerr << "*** using a 1d mesh (Implementation in progress)\n"; - std::exit(0); } else { std::cerr << "*** using a dimension 0 mesh is forbidden!\n"; std::exit(0); diff --git a/src/mesh/GmshReader.hpp b/src/mesh/GmshReader.hpp index 1baddb1ee..fb41a5c35 100644 --- a/src/mesh/GmshReader.hpp +++ b/src/mesh/GmshReader.hpp @@ -184,17 +184,12 @@ private: */ void __readPhysicalNames2_2(); - Mesh<Connectivity2D>* m_mesh; + std::shared_ptr<IMesh> m_mesh; public: - // Connectivity2D& connectivity() - // { - // return *m_connectivity; - // } - - Mesh<Connectivity2D>& mesh() + std::shared_ptr<IMesh> mesh() const { - return *m_mesh; + return m_mesh; } GmshReader(const std::string& filename); diff --git a/src/mesh/Mesh.hpp b/src/mesh/Mesh.hpp index 40936ce84..2b05731f5 100644 --- a/src/mesh/Mesh.hpp +++ b/src/mesh/Mesh.hpp @@ -6,8 +6,14 @@ #include <memory> +struct IMesh +{ + virtual const size_t meshDimension() const = 0; + ~IMesh() = default; +}; + template <typename ConnectivityType> -class Mesh +class Mesh final : public IMesh { public: typedef ConnectivityType Connectivity; @@ -20,6 +26,11 @@ private: public: + const size_t meshDimension() const + { + return dimension; + } + const Connectivity& connectivity() const { return *m_connectivity; -- GitLab