3#include <vtkUnstructuredGrid.h>
4#include <vtkAppendFilter.h>
6#include <vtkCellData.h>
7#include <vtkPointData.h>
16 vtkUnstructuredGrid& ugrid,
const double scale,
int dimension_to_copy)
18 const std::string fname =
19 "chi_mesh::UnpartitionedMesh::CopyUGridCellsAndPoints";
21 typedef Vec3* Vec3Ptr;
24 const vtkIdType total_cell_count = ugrid.GetNumberOfCells();
25 const vtkIdType total_point_count = ugrid.GetNumberOfPoints();
27 bool has_cell_gids = ugrid.GetCellData()->GetGlobalIds();
28 bool has_pnts_gids = ugrid.GetPointData()->GetGlobalIds();
29 bool has_global_ids = has_cell_gids and has_pnts_gids;
33 if (not ugrid.GetCellData()->GetArray(block_id_array_name.c_str()))
34 throw std::logic_error(fname +
": grid has no \"" + block_id_array_name +
37 auto block_id_array = vtkIntArray::SafeDownCast(
38 ugrid.GetCellData()->GetArray(block_id_array_name.c_str()));
41 "Failed to cast BlockID array to vtkInt");
45 std::vector<CellPtr> cells(total_cell_count,
nullptr);
46 std::vector<Vec3Ptr> vertices(total_point_count,
nullptr);
48 auto cell_gids_ptr = ugrid.GetCellData()->GetGlobalIds();
49 auto pnts_gids_ptr = ugrid.GetPointData()->GetGlobalIds();
51 auto cell_gids = vtkIdTypeArray::SafeDownCast(cell_gids_ptr);
52 auto pnts_gids = vtkIdTypeArray::SafeDownCast(pnts_gids_ptr);
57 int cid_offset = 0, pid_offset = 0;
59 vtkIdType min_cid = total_point_count;
60 vtkIdType min_pid = total_point_count;
62 for (vtkIdType c = 0; c < total_cell_count; ++c)
63 min_cid = std::min(min_cid, cell_gids->GetValue(c));
65 for (vtkIdType p = 0; p < total_point_count; ++p)
66 min_pid = std::min(min_pid, pnts_gids->GetValue(p));
68 cid_offset -=
static_cast<int>(min_cid);
69 pid_offset -=
static_cast<int>(min_pid);
73 std::vector<vtkIdType> node_map(total_point_count, 0);
74 for (vtkIdType p = 0; p < total_point_count; ++p)
75 node_map[p] = pnts_gids->GetValue(p) + pid_offset;
78 for (vtkIdType c = 0; c < total_cell_count; ++c)
80 auto vtk_cell = ugrid.GetCell(
static_cast<vtkIdType
>(c));
81 auto vtk_celldim = vtk_cell->GetCellDimension();
82 const vtkIdType cell_gid = cell_gids->GetValue(c) + cid_offset;
84 if (vtk_celldim != dimension_to_copy)
continue;
88 else if (vtk_celldim == 2)
90 else if (vtk_celldim == 1)
92 else if (vtk_celldim == 0)
95 throw std::logic_error(fname +
": Unsupported cell dimension ." +
96 std::to_string(vtk_celldim));
99 for (uint64_t& vid : raw_cell->vertex_ids)
103 for (
auto& face : raw_cell->faces)
104 for (uint64_t& vid : face.vertex_ids)
107 raw_cell->material_id = block_id_array->GetValue(c);
109 cells[cell_gid] = raw_cell;
113 for (vtkIdType p = 0; p < total_point_count; ++p)
115 auto point = ugrid.GetPoint(
static_cast<vtkIdType
>(p));
116 const vtkIdType point_gid = pnts_gids->GetValue(p) + pid_offset;
118 auto vertex =
new Vec3(point[0], point[1], point[2]);
122 vertices.at(point_gid) = vertex;
126 for (vtkIdType c = 0; c < total_cell_count; ++c)
127 if (cells[c] ==
nullptr)
128 throw std::logic_error(fname +
": Cell pointer not assigned ");
131 for (vtkIdType p = 0; p < total_point_count; ++p)
132 if (vertices[p] ==
nullptr)
133 throw std::logic_error(fname +
": Vertex pointer not assigned");
137 for (
auto& vertex_ptr : vertices)
143 for (vtkIdType c = 0; c < total_cell_count; ++c)
145 auto vtk_cell = ugrid.GetCell(
static_cast<vtkIdType
>(c));
146 auto vtk_celldim = vtk_cell->GetCellDimension();
148 if (vtk_celldim != dimension_to_copy)
continue;
150 if (vtk_celldim == 3)
152 else if (vtk_celldim == 2)
154 else if (vtk_celldim == 1)
156 else if (vtk_celldim == 0)
159 throw std::logic_error(fname +
": Unsupported cell dimension.");
161 raw_cells_.back()->material_id = block_id_array->GetValue(c);
165 for (
size_t p = 0; p < total_point_count; ++p)
167 auto point = ugrid.GetPoint(
static_cast<vtkIdType
>(p));
169 Vec3 vertex(point[0], point[1], point[2]);
173 vertices_.emplace_back(point[0], point[1], point[2]);
178 for (
size_t p = 0; p < total_point_count; ++p)
183 vertex.x, vertex.x, vertex.y, vertex.y, vertex.z, vertex.z});
199 const std::vector<int>& material_ids)
201 const size_t total_cell_count = raw_cells_.size();
203 for (
size_t c = 0; c < total_cell_count; ++c)
204 raw_cells_[c]->material_id = material_ids[c];
210 std::vector<vtkUGridPtrAndName>& bndry_grid_blocks)
212 const double EPSILON = 1.0e-12;
214 std::vector<LightWeightFace*> bndry_faces;
215 for (
auto& cell_ptr : raw_cells_)
216 for (
auto& face : cell_ptr->faces)
217 if (not face.has_neighbor) bndry_faces.push_back(&face);
219 Chi::log.
Log() <<
"Number of boundary faces: " << bndry_faces.size();
222 std::set<uint64_t> bndry_vids_set;
223 for (
const auto& face_ptr : bndry_faces)
224 for (
const auto vid : face_ptr->vertex_ids)
225 bndry_vids_set.insert(vid);
228 uint64_t bndry_id = 0;
229 for (
const auto& ugrid_name : bndry_grid_blocks)
231 auto ugrid = ugrid_name.first;
233 mesh_options_.boundary_id_map[bndry_id] = ugrid_name.second;
236 bool mapping_failed =
false;
237 std::vector<size_t> vertex_map(ugrid->GetNumberOfPoints(), 0);
238 for (
size_t p = 0; p < ugrid->GetNumberOfPoints(); ++p)
241 ugrid->GetPoint(
static_cast<vtkIdType
>(p), &point.
x);
243 bool map_found =
false;
244 for (
const auto vid : bndry_vids_set)
245 if ((point - vertices_[vid]).NormSquare() < EPSILON)
255 <<
"chi_mesh::UnpartitionedMesh::"
256 "SetBoundaryIDsFromBlocks: Failed to map a vertex. " +
257 point.
PrintStr() +
" for boundary " + ugrid_name.second +
258 " therefore the boundary assignment was skipped.";
259 mapping_failed =
true;
264 if (mapping_failed)
continue;
267 std::map<uint64_t, std::set<size_t>> vertex_face_subs;
268 for (
size_t f = 0; f < bndry_faces.size(); ++f)
269 for (
const auto vid : bndry_faces[f]->vertex_ids)
270 vertex_face_subs[vid].insert(f);
273 size_t num_faces_boundarified = 0;
274 auto& bndry_block = ugrid_name.first;
275 size_t num_bndry_block_cells = bndry_block->GetNumberOfCells();
276 for (
size_t bc = 0; bc < num_bndry_block_cells; ++bc)
278 auto bndry_cell = bndry_block->GetCell(
static_cast<vtkIdType
>(bc));
282 std::set<size_t> face_ids_short_list;
283 std::set<uint64_t> bndry_cell_id_set;
284 size_t num_points = bndry_cell->GetNumberOfPoints();
285 for (
size_t p = 0; p < num_points; ++p)
287 auto point_id = bndry_cell->GetPointId(
static_cast<int>(p));
288 bndry_cell_id_set.insert(vertex_map[point_id]);
289 for (
size_t face_id : vertex_face_subs[vertex_map[point_id]])
290 face_ids_short_list.insert(face_id);
293 for (
size_t face_id : face_ids_short_list)
295 auto& face = bndry_faces[face_id];
296 const auto& face_vids = face->vertex_ids;
297 std::set<uint64_t> face_id_set(face_vids.begin(), face_vids.end());
299 if (face_id_set == bndry_cell_id_set)
301 face->neighbor = bndry_id;
302 ++num_faces_boundarified;
307 Chi::log.
Log() <<
"UnpartitionedMesh: assigned " << num_faces_boundarified
308 <<
" to boundary id " << bndry_id <<
" with name "
309 << ugrid_name.second;
#define ChiLogicalErrorIf(condition, message)
LogStream Log(LOG_LVL level=LOG_0)
static LightWeightCell * CreateCellFromVTKLine(vtkCell *vtk_cell)
void CopyUGridCellsAndPoints(vtkUnstructuredGrid &ugrid, double scale, int dimension_to_copy)
static LightWeightCell * CreateCellFromVTKVertex(vtkCell *vtk_cell)
void SetMaterialIDsFromList(const std::vector< int > &material_ids)
std::vector< chi_mesh::Vertex > vertices_
void SetBoundaryIDsFromBlocks(std::vector< vtkUGridPtrAndName > &bndry_grid_blocks)
static LightWeightCell * CreateCellFromVTKPolygon(vtkCell *vtk_cell)
std::vector< LightWeightCell * > raw_cells_
static LightWeightCell * CreateCellFromVTKPolyhedron(vtkCell *vtk_cell)
std::shared_ptr< BoundBox > bound_box_
std::string material_id_fieldname
std::string PrintStr() const