diff --git a/src/output/VTKWriter.hpp b/src/output/VTKWriter.hpp index 5d85b3630e2afc77ef7f2a3422b2f7d207abe5b7..e1ce501814c5a71e686b103417c3f118998f4053 100644 --- a/src/output/VTKWriter.hpp +++ b/src/output/VTKWriter.hpp @@ -8,12 +8,14 @@ #include <output/OutputNamedItemValueSet.hpp> #include <utils/Exceptions.hpp> #include <utils/Messenger.hpp> +#include <utils/PugsAssert.hpp> #include <fstream> #include <iomanip> #include <iostream> #include <sstream> #include <string> +#include <unordered_map> class VTKWriter { @@ -234,6 +236,10 @@ class VTKWriter std::visit([&, name = name](auto&& item_value) { return this->_write_cell_pvtu(fout, name, item_value); }, item_value_variant); } + if constexpr (MeshType::Dimension == 3) { + fout << "<PDataArray type=\"Int64\" IdType=\"1\" Name=\"faces\"/>\n"; + fout << "<PDataArray type=\"Int64\" IdType=\"1\" Name=\"faceoffsets\"/>\n"; + } fout << "</PCells>\n"; fout << "<PPointData>\n"; @@ -347,6 +353,10 @@ class VTKWriter types[j] = 12; break; } + case CellType::Diamond: { + types[j] = 42; + break; + } default: { std::ostringstream os; os << __FILE__ << ':' << __LINE__ << ": unknown cell type"; @@ -356,7 +366,62 @@ class VTKWriter }); _write_array(fout, "types", types); } + if constexpr (MeshType::Dimension == 3) { + const auto& cell_to_face_matrix = mesh->connectivity().cellToFaceMatrix(); + const auto& cell_to_node_matrix = mesh->connectivity().cellToNodeMatrix(); + const auto& face_to_node_matrix = mesh->connectivity().faceToNodeMatrix(); + const auto& cell_face_is_reversed = mesh->connectivity().cellFaceIsReversed(); + + Array<size_t> faces_offsets(mesh->numberOfCells()); + size_t next_offset = 0; + fout << "<DataArray type=\"Int64\" IdType=\"1\" Name=\"faces\">\n"; + for (CellId cell_id = 0; cell_id < mesh->numberOfCells(); ++cell_id) { + const auto& cell_nodes = cell_to_node_matrix[cell_id]; + std::unordered_map<size_t, size_t> node_id_to_local_number_in_cell; + for (size_t i_cell_node = 0; i_cell_node < cell_nodes.size(); ++i_cell_node) { + node_id_to_local_number_in_cell[cell_nodes[i_cell_node]] = i_cell_node; + } + + const auto& cell_faces = cell_to_face_matrix[cell_id]; + fout << cell_faces.size() << '\n'; + next_offset++; + for (size_t i_cell_face = 0; i_cell_face < cell_faces.size(); ++i_cell_face) { + const FaceId& face_id = cell_faces[i_cell_face]; + const auto& face_nodes = face_to_node_matrix[face_id]; + fout << face_nodes.size(); + next_offset++; + Array<size_t> face_node_in_cell(face_nodes.size()); + + for (size_t i_face_node = 0; i_face_node < face_nodes.size(); ++i_face_node) { + const NodeId& node_id = face_nodes[i_face_node]; + auto i_node_id_to_local_number_in_cell = node_id_to_local_number_in_cell.find(node_id); + Assert(i_node_id_to_local_number_in_cell != node_id_to_local_number_in_cell.end()); + face_node_in_cell[i_face_node] = i_node_id_to_local_number_in_cell->second; + } + + if (cell_face_is_reversed(cell_id, i_cell_face)) { + for (size_t i = 0; i < face_node_in_cell.size(); ++i) { + fout << ' ' << face_node_in_cell[face_node_in_cell.size() - 1 - i]; + } + } else { + for (size_t i = 0; i < face_node_in_cell.size(); ++i) { + fout << ' ' << face_node_in_cell[i]; + } + } + + next_offset += face_nodes.size(); + fout << '\n'; + } + faces_offsets[cell_id] = next_offset; + } + fout << "</DataArray>\n"; + fout << "<DataArray type=\"Int64\" IdType=\"1\" Name=\"faceoffsets\">\n"; + for (size_t i_face_offsets = 0; i_face_offsets < faces_offsets.size(); ++i_face_offsets) { + fout << faces_offsets[i_face_offsets] << '\n'; + } + fout << "</DataArray>\n"; + } fout << "</Cells>\n"; fout << "</Piece>\n"; fout << "</UnstructuredGrid>\n";