2 files + 185 − 54 Side-by-side Compare changes Side-by-side Inline Show whitespace changes Files 2 CMakeLists.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -98,7 +98,7 @@ endif() #------------------------------------------------------ #------------------------------------------------------ # Checks if compiler version is compatible with Pugs sources # Checks if compiler version is compatible with Pugs sources set(GNU_CXX_MIN_VERSION "10.0.0") set(GNU_CXX_MIN_VERSION "11.0.0") set(CLANG_CXX_MIN_VERSION "14.0.0") set(CLANG_CXX_MIN_VERSION "14.0.0") #------------------------------------------------------ #------------------------------------------------------ Loading src/mesh/GmshReader.cpp +184 −53 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,8 @@ GmshConnectivityBuilder<1>::GmshConnectivityBuilder(const GmshReader::GmshData& Array<int> cell_number_vector(nb_cells); Array<int> cell_number_vector(nb_cells); Array<unsigned int> cell_to_node_row(nb_cells + 1); Array<unsigned int> cell_to_node_row(nb_cells + 1); parallel_for(cell_to_node_row.size(), PUGS_LAMBDA(const CellId cell_id) { cell_to_node_row[cell_id] = 2 * cell_id; }); parallel_for( cell_to_node_row.size(), PUGS_LAMBDA(const CellId cell_id) { cell_to_node_row[cell_id] = 2 * cell_id; }); Array<unsigned int> cell_to_node_list(cell_to_node_row[cell_to_node_row.size() - 1]); Array<unsigned int> cell_to_node_list(cell_to_node_row[cell_to_node_row.size() - 1]); for (CellId cell_id = 0; cell_id < nb_cells; ++cell_id) { for (CellId cell_id = 0; cell_id < nb_cells; ++cell_id) { Loading Loading @@ -949,6 +950,10 @@ struct physical_section : seq<TAO_PEGTL_STRING("$PhysicalNames"), until<TAO_PEGT { { }; }; struct entities_section : seq<TAO_PEGTL_STRING("$Entities"), until<TAO_PEGTL_STRING("$EndEntities")>, ignored> { }; struct nodes_section : seq<TAO_PEGTL_STRING("$Nodes"), until<TAO_PEGTL_STRING("$EndNodes")>, ignored> struct nodes_section : seq<TAO_PEGTL_STRING("$Nodes"), until<TAO_PEGTL_STRING("$EndNodes")>, ignored> { { }; }; Loading Loading @@ -981,6 +986,7 @@ struct interpolation_scheme_section struct data_section struct data_section : sor<physical_section, : sor<physical_section, entities_section, nodes_section, nodes_section, elements_section, elements_section, periodic_section, periodic_section, Loading Loading @@ -1039,7 +1045,8 @@ inline auto remove_embedding_spaces = [](std::string_view line) -> std::string_v inline constexpr int number_of_gmsh_entities = 93; inline constexpr int number_of_gmsh_entities = 93; inline constexpr auto primitive_number_of_nodes = []() constexpr { inline constexpr auto primitive_number_of_nodes = []() constexpr { std::array<short, number_of_gmsh_entities> number_of_nodes; std::array<short, number_of_gmsh_entities> number_of_nodes; number_of_nodes.fill(-1); number_of_nodes.fill(-1); Loading Loading @@ -1078,9 +1085,11 @@ inline constexpr auto primitive_number_of_nodes = []() constexpr { number_of_nodes[92] = 125; // 125-node fourth order hexahedron number_of_nodes[92] = 125; // 125-node fourth order hexahedron return number_of_nodes; return number_of_nodes; }(); } (); inline constexpr auto entity_name = []() constexpr { inline constexpr auto entity_name = []() constexpr { std::array<std::string_view, number_of_gmsh_entities> name; std::array<std::string_view, number_of_gmsh_entities> name; name.fill("unknown"); name.fill("unknown"); name[0] = "edges"; name[0] = "edges"; Loading Loading @@ -1118,9 +1127,11 @@ inline constexpr auto entity_name = []() constexpr { name[92] = "125-node fourth order hexahedron"; name[92] = "125-node fourth order hexahedron"; return name; return name; }(); } (); inline constexpr auto supported_entity = []() constexpr { inline constexpr auto supported_entity = []() constexpr { std::array<bool, number_of_gmsh_entities> supported; std::array<bool, number_of_gmsh_entities> supported; supported.fill(false); supported.fill(false); supported[0] = true; // edge supported[0] = true; // edge Loading @@ -1133,7 +1144,8 @@ inline constexpr auto supported_entity = []() constexpr { supported[14] = true; // point supported[14] = true; // point return supported; return supported; }(); } (); inline auto tokenize = [](std::string_view& line, auto& tokens) { inline auto tokenize = [](std::string_view& line, auto& tokens) { size_t token_idx = 0; size_t token_idx = 0; Loading Loading @@ -1181,6 +1193,7 @@ inline auto tokenize_variable = [](std::string_view& line, std::vector<std::stri struct State struct State { { bool has_physiscal_section = false; bool has_physiscal_section = false; bool has_entities_section = false; bool has_nodes_section = false; bool has_nodes_section = false; bool has_elements_section = false; bool has_elements_section = false; bool has_periodic_section = false; bool has_periodic_section = false; Loading Loading @@ -1231,7 +1244,7 @@ struct actions<meshformat> } } std::cout << "- Reading Gmsh format " << gmsh_data.format.version << '\n'; std::cout << "- Reading Gmsh format " << gmsh_data.format.version << '\n'; const std::set<double> supported_versions = {2.2}; const std::set<double> supported_versions = {2.2, 4.1}; if (not supported_versions.contains(gmsh_data.format.version)) { if (not supported_versions.contains(gmsh_data.format.version)) { std::stringstream error_msg; std::stringstream error_msg; Loading Loading @@ -1270,6 +1283,7 @@ struct actions<physical_section> state.has_physiscal_section = true; state.has_physiscal_section = true; } } if ((gmsh_data.format.version == 2.2) or (gmsh_data.format.version == 4.1)) { std::string_view body = in.string_view(); std::string_view body = in.string_view(); auto pos = body.find('\n'); auto pos = body.find('\n'); Loading Loading @@ -1340,22 +1354,34 @@ struct actions<physical_section> << e.what(); << e.what(); throw NormalError(error_msg.str()); throw NormalError(error_msg.str()); } } } else { throw UnexpectedError("invalid file format version: " + std::to_string(gmsh_data.format.version)); } } } }; }; template <> template <> struct actions<nodes_section> struct actions<entities_section> { { template <typename Input> template <typename Input> static void static void apply(const Input& in, State& state, GmshReader::GmshData& gmsh_data) apply([[maybe_unused]] const Input& in, State& state, [[maybe_unused]] GmshReader::GmshData& gmsh_data) { { if (state.has_nodes_section) { if (state.has_entities_section) { throw NormalError("malformed Gmsh file, $Nodes section should appear only once"); throw NormalError("malformed Gmsh file, $Entities section should appear only once"); } else { } else { state.has_nodes_section = true; state.has_entities_section = true; } } } }; template <> struct actions<nodes_section> { template <typename Input> static void apply_2_2(const Input& in, GmshReader::GmshData& gmsh_data) { std::string_view body = in.string_view(); std::string_view body = in.string_view(); auto pos = body.find('\n'); auto pos = body.find('\n'); Loading Loading @@ -1422,6 +1448,111 @@ struct actions<nodes_section> gmsh_data.node_number = vertex_number_list; gmsh_data.node_number = vertex_number_list; gmsh_data.node_coordinate = vertex_list; gmsh_data.node_coordinate = vertex_list; } } template <typename Input> static void apply_4_1(const Input& in, GmshReader::GmshData& gmsh_data) { std::string_view body = in.string_view(); auto pos = body.find('\n'); if (pos == std::string_view::npos) { throw NormalError("malformed Gmsh file, $Nodes section is empty"); } body = body.substr(pos + 1); int nb_nodes; try { auto line = remove_embedding_spaces(get_next_line(body)); std::array<std::string_view, 4> tokens{}; size_t token_number = tokenize(line, tokens); if (token_number != 4) { throw std::runtime_error("malformed $Nodes descriptor expecting 4 values"); } // size_t nb_entity_blocks = parse_int(tokens[0]); nb_nodes = parse_int(tokens[1]); if (nb_nodes < 0) { throw std::runtime_error("number of vertices is negative"); } // size_t min_node_tag = parse_int(tokens[2]); // size_t max_node_tag = parse_int(tokens[3]); } catch (std::runtime_error& e) { std::stringstream error_msg; error_msg << "reading " << in.position().source << ':' << in.position().line + 1 << ": " << e.what(); throw NormalError(error_msg.str()); } const size_t number_of_nodes = nb_nodes; std::cout << "- Number Of Vertices: " << number_of_nodes << '\n'; Array<int> vertex_number_list{number_of_nodes}; Array<TinyVector<3>> vertex_list{number_of_nodes}; size_t i_node = 0; try { for (; i_node < number_of_nodes; ++i_node) { if (body.empty()) { std::stringstream error_msg; error_msg << "$Nodes section contains " << i_node << " entries, expecting " << number_of_nodes; throw std::runtime_error(error_msg.str()); } auto line = remove_embedding_spaces(get_next_line(body)); if (line.empty()) { throw std::runtime_error("empty entry"); } std::array<std::string_view, 4> tokens{}; size_t token_number = tokenize(line, tokens); if (token_number != 4) { std::stringstream error_msg; error_msg << "malformed Gmsh file, $Nodes section contains " << i_node << " entries, expecting " << number_of_nodes; throw std::runtime_error(error_msg.str()); } vertex_number_list[i_node] = parse_int(tokens[0]); vertex_list[i_node] = TinyVector<3>{parse_double(tokens[1]), parse_double(tokens[2]), parse_double(tokens[3])}; } } catch (std::runtime_error& e) { std::stringstream error_msg; error_msg << "reading " << in.position().source << ':' << in.position().line + i_node + 2 << ": " << e.what(); throw NormalError(error_msg.str()); } gmsh_data.node_number = vertex_number_list; gmsh_data.node_coordinate = vertex_list; } template <typename Input> static void apply(const Input& in, State& state, GmshReader::GmshData& gmsh_data) { if (state.has_nodes_section) { throw NormalError("malformed Gmsh file, $Nodes section should appear only once"); } else { state.has_nodes_section = true; } if (gmsh_data.format.version == 2.2) { apply_2_2(in, gmsh_data); } else if (gmsh_data.format.version == 4.1) { apply_4_1(in, gmsh_data); } else { throw UnexpectedError("invalid file format " + std::to_string(gmsh_data.format.version)); } } }; }; template <> template <> Loading
CMakeLists.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -98,7 +98,7 @@ endif() #------------------------------------------------------ #------------------------------------------------------ # Checks if compiler version is compatible with Pugs sources # Checks if compiler version is compatible with Pugs sources set(GNU_CXX_MIN_VERSION "10.0.0") set(GNU_CXX_MIN_VERSION "11.0.0") set(CLANG_CXX_MIN_VERSION "14.0.0") set(CLANG_CXX_MIN_VERSION "14.0.0") #------------------------------------------------------ #------------------------------------------------------ Loading
src/mesh/GmshReader.cpp +184 −53 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,8 @@ GmshConnectivityBuilder<1>::GmshConnectivityBuilder(const GmshReader::GmshData& Array<int> cell_number_vector(nb_cells); Array<int> cell_number_vector(nb_cells); Array<unsigned int> cell_to_node_row(nb_cells + 1); Array<unsigned int> cell_to_node_row(nb_cells + 1); parallel_for(cell_to_node_row.size(), PUGS_LAMBDA(const CellId cell_id) { cell_to_node_row[cell_id] = 2 * cell_id; }); parallel_for( cell_to_node_row.size(), PUGS_LAMBDA(const CellId cell_id) { cell_to_node_row[cell_id] = 2 * cell_id; }); Array<unsigned int> cell_to_node_list(cell_to_node_row[cell_to_node_row.size() - 1]); Array<unsigned int> cell_to_node_list(cell_to_node_row[cell_to_node_row.size() - 1]); for (CellId cell_id = 0; cell_id < nb_cells; ++cell_id) { for (CellId cell_id = 0; cell_id < nb_cells; ++cell_id) { Loading Loading @@ -949,6 +950,10 @@ struct physical_section : seq<TAO_PEGTL_STRING("$PhysicalNames"), until<TAO_PEGT { { }; }; struct entities_section : seq<TAO_PEGTL_STRING("$Entities"), until<TAO_PEGTL_STRING("$EndEntities")>, ignored> { }; struct nodes_section : seq<TAO_PEGTL_STRING("$Nodes"), until<TAO_PEGTL_STRING("$EndNodes")>, ignored> struct nodes_section : seq<TAO_PEGTL_STRING("$Nodes"), until<TAO_PEGTL_STRING("$EndNodes")>, ignored> { { }; }; Loading Loading @@ -981,6 +986,7 @@ struct interpolation_scheme_section struct data_section struct data_section : sor<physical_section, : sor<physical_section, entities_section, nodes_section, nodes_section, elements_section, elements_section, periodic_section, periodic_section, Loading Loading @@ -1039,7 +1045,8 @@ inline auto remove_embedding_spaces = [](std::string_view line) -> std::string_v inline constexpr int number_of_gmsh_entities = 93; inline constexpr int number_of_gmsh_entities = 93; inline constexpr auto primitive_number_of_nodes = []() constexpr { inline constexpr auto primitive_number_of_nodes = []() constexpr { std::array<short, number_of_gmsh_entities> number_of_nodes; std::array<short, number_of_gmsh_entities> number_of_nodes; number_of_nodes.fill(-1); number_of_nodes.fill(-1); Loading Loading @@ -1078,9 +1085,11 @@ inline constexpr auto primitive_number_of_nodes = []() constexpr { number_of_nodes[92] = 125; // 125-node fourth order hexahedron number_of_nodes[92] = 125; // 125-node fourth order hexahedron return number_of_nodes; return number_of_nodes; }(); } (); inline constexpr auto entity_name = []() constexpr { inline constexpr auto entity_name = []() constexpr { std::array<std::string_view, number_of_gmsh_entities> name; std::array<std::string_view, number_of_gmsh_entities> name; name.fill("unknown"); name.fill("unknown"); name[0] = "edges"; name[0] = "edges"; Loading Loading @@ -1118,9 +1127,11 @@ inline constexpr auto entity_name = []() constexpr { name[92] = "125-node fourth order hexahedron"; name[92] = "125-node fourth order hexahedron"; return name; return name; }(); } (); inline constexpr auto supported_entity = []() constexpr { inline constexpr auto supported_entity = []() constexpr { std::array<bool, number_of_gmsh_entities> supported; std::array<bool, number_of_gmsh_entities> supported; supported.fill(false); supported.fill(false); supported[0] = true; // edge supported[0] = true; // edge Loading @@ -1133,7 +1144,8 @@ inline constexpr auto supported_entity = []() constexpr { supported[14] = true; // point supported[14] = true; // point return supported; return supported; }(); } (); inline auto tokenize = [](std::string_view& line, auto& tokens) { inline auto tokenize = [](std::string_view& line, auto& tokens) { size_t token_idx = 0; size_t token_idx = 0; Loading Loading @@ -1181,6 +1193,7 @@ inline auto tokenize_variable = [](std::string_view& line, std::vector<std::stri struct State struct State { { bool has_physiscal_section = false; bool has_physiscal_section = false; bool has_entities_section = false; bool has_nodes_section = false; bool has_nodes_section = false; bool has_elements_section = false; bool has_elements_section = false; bool has_periodic_section = false; bool has_periodic_section = false; Loading Loading @@ -1231,7 +1244,7 @@ struct actions<meshformat> } } std::cout << "- Reading Gmsh format " << gmsh_data.format.version << '\n'; std::cout << "- Reading Gmsh format " << gmsh_data.format.version << '\n'; const std::set<double> supported_versions = {2.2}; const std::set<double> supported_versions = {2.2, 4.1}; if (not supported_versions.contains(gmsh_data.format.version)) { if (not supported_versions.contains(gmsh_data.format.version)) { std::stringstream error_msg; std::stringstream error_msg; Loading Loading @@ -1270,6 +1283,7 @@ struct actions<physical_section> state.has_physiscal_section = true; state.has_physiscal_section = true; } } if ((gmsh_data.format.version == 2.2) or (gmsh_data.format.version == 4.1)) { std::string_view body = in.string_view(); std::string_view body = in.string_view(); auto pos = body.find('\n'); auto pos = body.find('\n'); Loading Loading @@ -1340,22 +1354,34 @@ struct actions<physical_section> << e.what(); << e.what(); throw NormalError(error_msg.str()); throw NormalError(error_msg.str()); } } } else { throw UnexpectedError("invalid file format version: " + std::to_string(gmsh_data.format.version)); } } } }; }; template <> template <> struct actions<nodes_section> struct actions<entities_section> { { template <typename Input> template <typename Input> static void static void apply(const Input& in, State& state, GmshReader::GmshData& gmsh_data) apply([[maybe_unused]] const Input& in, State& state, [[maybe_unused]] GmshReader::GmshData& gmsh_data) { { if (state.has_nodes_section) { if (state.has_entities_section) { throw NormalError("malformed Gmsh file, $Nodes section should appear only once"); throw NormalError("malformed Gmsh file, $Entities section should appear only once"); } else { } else { state.has_nodes_section = true; state.has_entities_section = true; } } } }; template <> struct actions<nodes_section> { template <typename Input> static void apply_2_2(const Input& in, GmshReader::GmshData& gmsh_data) { std::string_view body = in.string_view(); std::string_view body = in.string_view(); auto pos = body.find('\n'); auto pos = body.find('\n'); Loading Loading @@ -1422,6 +1448,111 @@ struct actions<nodes_section> gmsh_data.node_number = vertex_number_list; gmsh_data.node_number = vertex_number_list; gmsh_data.node_coordinate = vertex_list; gmsh_data.node_coordinate = vertex_list; } } template <typename Input> static void apply_4_1(const Input& in, GmshReader::GmshData& gmsh_data) { std::string_view body = in.string_view(); auto pos = body.find('\n'); if (pos == std::string_view::npos) { throw NormalError("malformed Gmsh file, $Nodes section is empty"); } body = body.substr(pos + 1); int nb_nodes; try { auto line = remove_embedding_spaces(get_next_line(body)); std::array<std::string_view, 4> tokens{}; size_t token_number = tokenize(line, tokens); if (token_number != 4) { throw std::runtime_error("malformed $Nodes descriptor expecting 4 values"); } // size_t nb_entity_blocks = parse_int(tokens[0]); nb_nodes = parse_int(tokens[1]); if (nb_nodes < 0) { throw std::runtime_error("number of vertices is negative"); } // size_t min_node_tag = parse_int(tokens[2]); // size_t max_node_tag = parse_int(tokens[3]); } catch (std::runtime_error& e) { std::stringstream error_msg; error_msg << "reading " << in.position().source << ':' << in.position().line + 1 << ": " << e.what(); throw NormalError(error_msg.str()); } const size_t number_of_nodes = nb_nodes; std::cout << "- Number Of Vertices: " << number_of_nodes << '\n'; Array<int> vertex_number_list{number_of_nodes}; Array<TinyVector<3>> vertex_list{number_of_nodes}; size_t i_node = 0; try { for (; i_node < number_of_nodes; ++i_node) { if (body.empty()) { std::stringstream error_msg; error_msg << "$Nodes section contains " << i_node << " entries, expecting " << number_of_nodes; throw std::runtime_error(error_msg.str()); } auto line = remove_embedding_spaces(get_next_line(body)); if (line.empty()) { throw std::runtime_error("empty entry"); } std::array<std::string_view, 4> tokens{}; size_t token_number = tokenize(line, tokens); if (token_number != 4) { std::stringstream error_msg; error_msg << "malformed Gmsh file, $Nodes section contains " << i_node << " entries, expecting " << number_of_nodes; throw std::runtime_error(error_msg.str()); } vertex_number_list[i_node] = parse_int(tokens[0]); vertex_list[i_node] = TinyVector<3>{parse_double(tokens[1]), parse_double(tokens[2]), parse_double(tokens[3])}; } } catch (std::runtime_error& e) { std::stringstream error_msg; error_msg << "reading " << in.position().source << ':' << in.position().line + i_node + 2 << ": " << e.what(); throw NormalError(error_msg.str()); } gmsh_data.node_number = vertex_number_list; gmsh_data.node_coordinate = vertex_list; } template <typename Input> static void apply(const Input& in, State& state, GmshReader::GmshData& gmsh_data) { if (state.has_nodes_section) { throw NormalError("malformed Gmsh file, $Nodes section should appear only once"); } else { state.has_nodes_section = true; } if (gmsh_data.format.version == 2.2) { apply_2_2(in, gmsh_data); } else if (gmsh_data.format.version == 4.1) { apply_4_1(in, gmsh_data); } else { throw UnexpectedError("invalid file format " + std::to_string(gmsh_data.format.version)); } } }; }; template <> template <> Loading