Skip to content
Snippets Groups Projects
Commit adda73c6 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Continue mesh format 4.1 implementation [ci-skip]

parent 8ca23d45
No related branches found
No related tags found
No related merge requests found
......@@ -39,7 +39,8 @@ GmshConnectivityBuilder<1>::GmshConnectivityBuilder(const GmshReader::GmshData&
Array<int> cell_number_vector(nb_cells);
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]);
for (CellId cell_id = 0; cell_id < nb_cells; ++cell_id) {
......@@ -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>
{
};
......@@ -981,6 +986,7 @@ struct interpolation_scheme_section
struct data_section
: sor<physical_section,
entities_section,
nodes_section,
elements_section,
periodic_section,
......@@ -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 auto primitive_number_of_nodes = []() constexpr {
inline constexpr auto primitive_number_of_nodes = []() constexpr
{
std::array<short, number_of_gmsh_entities> number_of_nodes;
number_of_nodes.fill(-1);
......@@ -1078,9 +1085,11 @@ inline constexpr auto primitive_number_of_nodes = []() constexpr {
number_of_nodes[92] = 125; // 125-node fourth order hexahedron
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;
name.fill("unknown");
name[0] = "edges";
......@@ -1118,9 +1127,11 @@ inline constexpr auto entity_name = []() constexpr {
name[92] = "125-node fourth order hexahedron";
return name;
}();
}
();
inline constexpr auto supported_entity = []() constexpr {
inline constexpr auto supported_entity = []() constexpr
{
std::array<bool, number_of_gmsh_entities> supported;
supported.fill(false);
supported[0] = true; // edge
......@@ -1133,7 +1144,8 @@ inline constexpr auto supported_entity = []() constexpr {
supported[14] = true; // point
return supported;
}();
}
();
inline auto tokenize = [](std::string_view& line, auto& tokens) {
size_t token_idx = 0;
......@@ -1181,6 +1193,7 @@ inline auto tokenize_variable = [](std::string_view& line, std::vector<std::stri
struct State
{
bool has_physiscal_section = false;
bool has_entities_section = false;
bool has_nodes_section = false;
bool has_elements_section = false;
bool has_periodic_section = false;
......@@ -1231,7 +1244,7 @@ struct actions<meshformat>
}
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)) {
std::stringstream error_msg;
......@@ -1270,6 +1283,7 @@ struct actions<physical_section>
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();
auto pos = body.find('\n');
......@@ -1340,22 +1354,34 @@ struct actions<physical_section>
<< e.what();
throw NormalError(error_msg.str());
}
} else {
throw UnexpectedError("invalid file format version: " + std::to_string(gmsh_data.format.version));
}
}
};
template <>
struct actions<nodes_section>
struct actions<entities_section>
{
template <typename Input>
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) {
throw NormalError("malformed Gmsh file, $Nodes section should appear only once");
if (state.has_entities_section) {
throw NormalError("malformed Gmsh file, $Entities section should appear only once");
} 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();
auto pos = body.find('\n');
......@@ -1422,6 +1448,111 @@ struct actions<nodes_section>
gmsh_data.node_number = vertex_number_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 <>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment