Arcane  v3.15.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
VtkPolyhedralMeshIOService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* VtkPolyhedralMeshIOService (C) 2000-2024 */
9/* */
10/* Read/write fools for polyhedral mesh with vtk file format */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16#include <iostream>
17#include <numeric>
18#include <functional>
19#include <memory>
20
21#include <vtkUnstructuredGrid.h>
22#include <vtkUnstructuredGridReader.h>
23#include <vtkNew.h>
24#include <vtkCellIterator.h>
25#include <vtkIdTypeArray.h>
26#include <vtkCellData.h>
27#include <vtkPointData.h>
28#include <vtkDataSetAttributes.h>
29#include <vtkArrayDispatch.h>
30#include <vtkDataArrayAccessor.h>
31#include <vtkPolyDataReader.h>
32#include <vtkPolyData.h>
33
34#include <arccore/base/Ref.h>
35#include <arccore/base/String.h>
36#include <arccore/base/FatalErrorException.h>
37#include <vtkXMLUnstructuredGridReader.h>
38#include <vtkXMLPolyDataReader.h>
39
41#include "arcane/core/AbstractService.h"
42#include "arcane/core/ICaseMeshReader.h"
44#include "arcane/core/IMeshBuilder.h"
45#include "arcane/core/MeshBuildInfo.h"
46#include "arcane/core/IPrimaryMesh.h"
48#include "arcane/core/IMeshInitialAllocator.h"
49#include "arcane/core/IVariableMng.h"
51#include "arcane/utils/ITraceMng.h"
52#include "arcane/utils/UniqueArray.h"
53#include "arcane/utils/Real3.h"
54#include "arcane/mesh/CellFamily.h"
55#include "arcane/core/MeshVariableScalarRef.h"
56#include "arcane/core/MeshVariableArrayRef.h"
57
58#include "arcane/core/ItemAllocationInfo.h"
59#include "arcane/core/VariableBuildInfo.h"
60
61#include "arcane/utils/OStringStream.h"
62
63#include "arcane/core/IXmlDocumentHolder.h"
64#include "arcane/core/XmlNode.h"
65#include "arcane/core/internal/IVariableMngInternal.h"
66#include "arcane/core/datatype/DataTypeTraits.h"
67
68#include "arcane/std/VtkPolyhedralMeshIO_axl.h"
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73namespace Arcane
74{
75
76namespace VtkPolyhedralTools
77{
79 {
80 bool failure = false;
81 String failure_message;
82 String info_message;
83 };
84
86 {
87 bool print_mesh_info = false;
88 bool print_debug_info = false;
89 };
90} // namespace VtkPolyhedralTools
91
93: public TraceAccessor
94{
95 public:
96
98 : TraceAccessor(trace_mng)
99 , m_print_info_level(print_info_level)
100 {}
101
103 {
104
105 public:
106
108
109 VtkReader() = default;
110
111 static String supportedVtkExtensions() noexcept {return "vtk,vtu";};
112
113 Int64ConstArrayView cellUids();
114 Int64ConstArrayView nodeUids();
115 Int64ConstArrayView faceUids();
116 Int64ConstArrayView edgeUids();
117
118 Integer nbNodes();
119
120 Int64ConstArrayView cellNodes();
121 Int32ConstArrayView cellNbNodes();
122
123 Int64ConstArrayView faceNodes();
124 Int32ConstArrayView faceNbNodes();
125
126 Int64ConstArrayView edgeNodes();
127 Int32ConstArrayView edgeNbNodes();
128
129 Int64ConstArrayView faceCells();
130 Int32ConstArrayView faceNbCells();
131
132 Int32ConstArrayView edgeNbCells();
133 Int64ConstArrayView edgeCells();
134
135 Int32ConstArrayView cellNbFaces();
136 Int64ConstArrayView cellFaces();
137
138 Int32ConstArrayView edgeNbFaces();
139 Int64ConstArrayView edgeFaces();
140
141 Int32ConstArrayView cellNbEdges();
142 Int64ConstArrayView cellEdges();
143
144 Int32ConstArrayView faceNbEdges();
145 Int64ConstArrayView faceEdges();
146
147 Int32ConstArrayView nodeNbCells();
148 Int64ConstArrayView nodeCells();
149
150 Int32ConstArrayView nodeNbFaces();
151 Int64ConstArrayView nodeFaces();
152
153 Int32ConstArrayView nodeNbEdges();
154 Int64ConstArrayView nodeEdges();
155
156 Real3ArrayView nodeCoords();
157
158 bool readHasFailed() const noexcept { return m_read_status.failure; }
159 VtkPolyhedralTools::ReadStatus readStatus() const noexcept { return m_read_status; }
160
161 vtkCellData* cellData();
162 vtkPointData* pointData();
163 vtkCellData* faceData();
164
165 bool isEmpty() const noexcept { return m_is_empty; }
166 bool doRead() const noexcept { return m_do_read; }
167
168 private:
169
170 bool m_is_empty = true;
171 bool m_do_read = false;
172 String m_filename;
173 VtkPolyhedralTools::PrintInfoLevel m_print_info_level;
174 VtkPolyhedralTools::ReadStatus m_read_status;
175 vtkNew<vtkUnstructuredGridReader> m_vtk_grid_reader;
176 vtkNew<vtkXMLUnstructuredGridReader> m_vtk_xml_grid_reader;
177 vtkNew<vtkPolyDataReader> m_vtk_face_grid_reader;
178 vtkNew<vtkXMLPolyDataReader> m_vtk_xml_face_grid_reader;
179 vtkUnstructuredGrid* m_vtk_grid = nullptr;
180 vtkPolyData* m_vtk_face_grid = nullptr;
181 Int64UniqueArray m_cell_uids, m_node_uids, m_face_uids, m_edge_uids;
182 Int64UniqueArray m_face_node_uids, m_edge_node_uids, m_cell_node_uids;
183 Int64UniqueArray m_face_cell_uids, m_edge_cell_uids, m_edge_face_uids;
184 Int64UniqueArray m_cell_face_uids, m_cell_edge_uids, m_face_edge_uids;
185 Int64UniqueArray m_node_cell_uids, m_node_face_uids, m_node_edge_uids;
186 Int32UniqueArray m_face_nb_nodes, m_cell_nb_nodes, m_face_nb_cells;
187 Int32UniqueArray m_edge_nb_cells, m_edge_nb_faces, m_cell_nb_faces;
188 Int32UniqueArray m_node_nb_cells, m_node_nb_faces, m_node_nb_edges;
189 Int32UniqueArray m_cell_nb_edges, m_face_nb_edges, m_face_uid_indexes;
190 Int32UniqueArray m_cell_face_indexes, m_edge_nb_nodes;
191 using NodeUidToIndexMap = Int32UniqueArray; // use a map when no longer possible to index with node uids
192 using FaceUidToIndexMap = Int32UniqueArray; // use a map when no longer possible to index with face uids
193 using EdgeUidToIndexMap = Int32UniqueArray; // use a map when no longer possible to index with edge uids
194 NodeUidToIndexMap m_node_uid_to_index;
195 Real3UniqueArray m_node_coordinates;
196 vtkCellData* m_cell_data = nullptr;
197 vtkPointData* m_point_data = nullptr;
198 vtkCellData* m_face_data = nullptr;
199
200 void _printMeshInfos() const;
201
203 template <typename Connectivity2DArray>
205 void _readPlainTextVtkGrid(const String& filename);
206 void _readXlmVtkGrid(const String& filename);
207 void _checkVtkGrid() const;
208 void _readPlainTextVtkFaceGrid(const String& faces_filename);
209 void _readXmlVtkFaceGrid(const String& faces_filename);
210 };
211
212 public:
213
214 VtkPolyhedralTools::ReadStatus read(IPrimaryMesh* mesh, const String& filename, bool is_parallel_read)
215 {
217 // warning meaning of parallel_read not obvious :
218 // if is parallel_read => master reads + broadcast, if not all ranks read a pre-distributed mesh
219 bool do_read = is_parallel_read ? mesh->parallelMng()->isMasterIO() : true;
220 using VtkReaderPtr = std::unique_ptr<VtkReader>;
221 VtkReaderPtr reader = std::make_unique<VtkReader>();
222 if (do_read) reader = std::make_unique<VtkReader>( filename, m_print_info_level );
223 if (reader->readHasFailed())
224 return reader->readStatus();
226 _fillItemAllocationInfo(item_allocation_info, *reader);
227 auto polyhedral_mesh_allocator = mesh->initialAllocator()->polyhedralMeshAllocator();
229 _readVariablesAndGroups(mesh, *reader);
230 return reader->readStatus();
231 }
232
233 private:
234
235 VtkPolyhedralTools::PrintInfoLevel m_print_info_level;
236
238 {
239 eDataType m_type = DT_Unknown;
240 bool is_array = false;
241 };
242
243 void _readVariablesAndGroups(IPrimaryMesh* mesh, VtkReader& reader);
246
247 static void _fillItemAllocationInfo(ItemAllocationInfo& item_allocation_info, VtkReader& vtk_reader);
248 void _computeFaceVtkArcaneLidConversion(Int32Span face_vtk_to_arcane_lids, Int32Span arcane_to_vtk_lids, VtkPolyhedralMeshIOService::VtkReader& reader, IPrimaryMesh* mesh) const;
249 void _createEmptyVariablesAndGroups(IMesh* mesh, XmlNode::const_reference xml_node) const;
250 template <template <class> class VariableRootType , template <class> class ArrayVariableRootType>
251 void _createEmptyVariables(IMesh* mesh, const XmlNodeList& cell_variables_node, eItemKind item_kind) const;
252 void _createEmptyGroups(IMesh* mesh, const XmlNodeList& children, IItemFamily* item_family) const;
253};
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
260{
261 public:
262
263 class Builder : public IMeshBuilder
264 {
265 public:
266
268 : m_trace_mng(tm)
269 , m_read_info(read_info)
270 , m_print_info_level(print_info_level)
271 {}
272
274 {
275 build_info.addFactoryName("ArcanePolyhedralMeshFactory");
276 build_info.addNeedPartitioning(false);
277 MeshKind mk;
278 mk.setMeshStructure(eMeshStructure::Polyhedral);
279 build_info.addMeshKind(mk);
280 }
281
283 {
285 m_trace_mng->info() << "---Create Polyhedral mesh: " << pm->name() << "---";
286 m_trace_mng->info() << "--Read mesh file " << m_read_info.fileName();
287 VtkPolyhedralMeshIOService polyhedral_vtk_service{ m_trace_mng, m_print_info_level };
288 auto read_status = polyhedral_vtk_service.read(pm, m_read_info.fileName(),m_read_info.isParallelRead());
289 if (read_status.failure)
290 ARCANE_FATAL(read_status.failure_message);
291 m_trace_mng->info() << read_status.info_message;
292 }
293
294 private:
295
296 ITraceMng* m_trace_mng;
297 CaseMeshReaderReadInfo m_read_info;
298 VtkPolyhedralTools::PrintInfoLevel m_print_info_level;
299 };
300
303 {}
304
305 public:
306
308 {
309 IMeshBuilder* builder = nullptr;
310 if (VtkPolyhedralMeshIOService::VtkReader::supportedVtkExtensions().contains(read_info.format()))
311 builder = new Builder(traceMng(), read_info, VtkPolyhedralTools::PrintInfoLevel{ options()->getPrintMeshInfos(), options()->getPrintDebugInfos() });
312 return makeRef(builder);
313 }
314};
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
319ARCANE_REGISTER_SERVICE(VtkPolyhedralCaseMeshReader,
320 ServiceProperty("VtkPolyhedralCaseMeshReader", ST_CaseOption),
321 ARCANE_SERVICE_INTERFACE(ICaseMeshReader));
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
326void VtkPolyhedralMeshIOService::
327_fillItemAllocationInfo(ItemAllocationInfo& item_allocation_info, VtkReader& vtk_reader)
328{
329 auto nb_item_family = 4;
330 auto nb_connected_family = 3;
331 item_allocation_info.family_infos.resize(nb_item_family);
332 for (auto& family_info : item_allocation_info.family_infos) {
333 family_info.connected_family_info.resize(nb_connected_family);
334 }
335 // Create regular item families and connectivities
336 auto& cell_family_info = item_allocation_info.family_infos[0];
337 cell_family_info.name = "Cell";
338 cell_family_info.item_kind = IK_Cell;
339 cell_family_info.item_uids = vtk_reader.cellUids();
340 auto& node_family_info = item_allocation_info.family_infos[1];
341 node_family_info.name = "Node";
342 node_family_info.item_kind = IK_Node;
343 node_family_info.item_uids = vtk_reader.nodeUids();
344 auto& face_family_info = item_allocation_info.family_infos[2];
345 face_family_info.name = "Face";
346 face_family_info.item_kind = IK_Face;
347 face_family_info.item_uids = vtk_reader.faceUids();
348 auto& edge_family_info = item_allocation_info.family_infos[3];
349 edge_family_info.name = "Edge";
350 edge_family_info.item_kind = IK_Edge;
351 edge_family_info.item_uids = vtk_reader.edgeUids();
352 // Cell to nodes connectivity
353 auto cell_connected_family_index = 0;
354 auto& cell_connected_node_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
355 cell_connected_node_family_info.name = node_family_info.name;
356 cell_connected_node_family_info.item_kind = node_family_info.item_kind;
357 cell_connected_node_family_info.connectivity_name = "CellToNodes";
358 cell_connected_node_family_info.nb_connected_items_per_item = vtk_reader.cellNbNodes();
359 cell_connected_node_family_info.connected_items_uids = vtk_reader.cellNodes();
360 // Cell to faces connectivity
361 auto& cell_connected_face_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
362 cell_connected_face_family_info.name = face_family_info.name;
363 cell_connected_face_family_info.item_kind = face_family_info.item_kind;
364 cell_connected_face_family_info.connectivity_name = "CellToFaces";
365 cell_connected_face_family_info.nb_connected_items_per_item = vtk_reader.cellNbFaces();
366 cell_connected_face_family_info.connected_items_uids = vtk_reader.cellFaces();
367 // Cell to edges connectivity
368 auto& cell_connected_edge_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
369 cell_connected_edge_family_info.name = edge_family_info.name;
370 cell_connected_edge_family_info.item_kind = edge_family_info.item_kind;
371 cell_connected_edge_family_info.connectivity_name = "CellToEdges";
372 cell_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.cellNbEdges();
373 cell_connected_edge_family_info.connected_items_uids = vtk_reader.cellEdges();
374 // Face to cells connectivity
375 auto face_connected_family_index = 0;
376 auto& face_connected_cell_family_info = face_family_info.connected_family_info[face_connected_family_index++];
377 face_connected_cell_family_info.name = cell_family_info.name;
378 face_connected_cell_family_info.item_kind = cell_family_info.item_kind;
379 face_connected_cell_family_info.connectivity_name = "FaceToCells";
380 face_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.faceNbCells();
381 face_connected_cell_family_info.connected_items_uids = vtk_reader.faceCells();
382 // Face to nodes connectivity
383 auto& face_connected_node_family_info = face_family_info.connected_family_info[face_connected_family_index++];
384 face_connected_node_family_info.name = node_family_info.name;
385 face_connected_node_family_info.item_kind = node_family_info.item_kind;
386 face_connected_node_family_info.connectivity_name = "FaceToNodes";
387 face_connected_node_family_info.nb_connected_items_per_item = vtk_reader.faceNbNodes();
388 face_connected_node_family_info.connected_items_uids = vtk_reader.faceNodes();
389 // Face to edges connectivity
390 auto& face_connected_edge_family_info = face_family_info.connected_family_info[face_connected_family_index];
391 face_connected_edge_family_info.name = edge_family_info.name;
392 face_connected_edge_family_info.item_kind = edge_family_info.item_kind;
393 face_connected_edge_family_info.connectivity_name = "FaceToEdges";
394 face_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.faceNbEdges();
395 face_connected_edge_family_info.connected_items_uids = vtk_reader.faceEdges();
396 // Edge to cells connectivity
397 auto edge_connected_family_index = 0;
398 auto& edge_connected_cell_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
399 edge_connected_cell_family_info.name = cell_family_info.name;
400 edge_connected_cell_family_info.item_kind = cell_family_info.item_kind;
401 edge_connected_cell_family_info.connectivity_name = "EdgeToCells";
402 edge_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.edgeNbCells();
403 edge_connected_cell_family_info.connected_items_uids = vtk_reader.edgeCells();
404 // Edge to faces connectivity
405 auto& edge_connected_face_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
406 edge_connected_face_family_info.name = face_family_info.name;
407 edge_connected_face_family_info.item_kind = face_family_info.item_kind;
408 edge_connected_face_family_info.connectivity_name = "EdgeToFaces";
409 edge_connected_face_family_info.nb_connected_items_per_item = vtk_reader.edgeNbFaces();
410 edge_connected_face_family_info.connected_items_uids = vtk_reader.edgeFaces();
411 // Edge to nodes connectivity
412 auto& edge_connected_node_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
413 edge_connected_node_family_info.name = node_family_info.name;
414 edge_connected_node_family_info.item_kind = node_family_info.item_kind;
415 edge_connected_node_family_info.connectivity_name = "EdgeToNodes";
416 edge_connected_node_family_info.nb_connected_items_per_item = vtk_reader.edgeNbNodes();
417 edge_connected_node_family_info.connected_items_uids = vtk_reader.edgeNodes();
418 // Node to cells connectivity
419 auto node_connected_family_index = 0;
420 auto& node_connected_cell_family_info = node_family_info.connected_family_info[node_connected_family_index++];
421 node_connected_cell_family_info.name = cell_family_info.name;
422 node_connected_cell_family_info.item_kind = cell_family_info.item_kind;
423 node_connected_cell_family_info.connectivity_name = "NodeToCells";
424 node_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.nodeNbCells();
425 node_connected_cell_family_info.connected_items_uids = vtk_reader.nodeCells();
426 // Node to faces connectivity
427 auto& node_connected_face_family_info = node_family_info.connected_family_info[node_connected_family_index++];
428 node_connected_face_family_info.name = face_family_info.name;
429 node_connected_face_family_info.item_kind = face_family_info.item_kind;
430 node_connected_face_family_info.connectivity_name = "NodeToFaces";
431 node_connected_face_family_info.nb_connected_items_per_item = vtk_reader.nodeNbFaces();
432 node_connected_face_family_info.connected_items_uids = vtk_reader.nodeFaces();
433 // Node to edges connectivity
434 auto& node_connected_edge_family_info = node_family_info.connected_family_info[node_connected_family_index++];
435 node_connected_edge_family_info.name = edge_family_info.name;
436 node_connected_edge_family_info.item_kind = edge_family_info.item_kind;
437 node_connected_edge_family_info.connectivity_name = "NodeToEdges";
438 node_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.nodeNbEdges();
439 node_connected_edge_family_info.connected_items_uids = vtk_reader.nodeEdges();
440 // Node coordinates
441 node_family_info.item_coordinates_variable_name = "NodeCoord";
442 node_family_info.item_coordinates = vtk_reader.nodeCoords();
443}
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
447
448void VtkPolyhedralMeshIOService::
449_readVariablesAndGroups(IPrimaryMesh* mesh, VtkReader& reader)
450{
451 // Register variable and group info in an xml for non reader ranks
452 OStringStream created_infos_str;
453 created_infos_str() << "<?xml version='1.0' ?>\n";
454 created_infos_str() << "<infos>";
455 // Cell data
456 if (auto* cell_data = reader.cellData(); cell_data) {
457 // Read cell groups and variables
458 Int32SharedArray vtk_to_arcane_lids(mesh->cellFamily()->nbItem());
459 std::iota(vtk_to_arcane_lids.begin(), vtk_to_arcane_lids.end(), 0);
460 Int32SharedArray arcane_to_vtk_lids{ vtk_to_arcane_lids };
461 for (auto array_index = 0; array_index < cell_data->GetNumberOfArrays(); ++array_index) {
462 auto* cell_array = cell_data->GetArray(array_index);
463 if (!cell_array)
464 continue;
465 if (String name = cell_array->GetName(); name.substring(0, 6) == "GROUP_") {
466 _createGroup(cell_array, name.substring(6), mesh, mesh->cellFamily(), vtk_to_arcane_lids.constSpan());
467 created_infos_str() << "<cell-group name='" << name.substring(6) << "'/>";
468 }
469 else {
470 auto var_info = _createVariable(cell_array, name, mesh, mesh->cellFamily(), arcane_to_vtk_lids);
471 created_infos_str() << "<cell-variable name='" << name << "' "
472 << " data-type='" << dataTypeName(var_info.m_type) << "' "
473 << " is_array='" << std::boolalpha << var_info.is_array << "'/>";
474 }
475 if (m_print_info_level.print_debug_info) {
476 debug(Trace::High) << "Reading property " << cell_array->GetName();
477 for (auto tuple_index = 0; tuple_index < cell_array->GetNumberOfTuples(); ++tuple_index) {
478 for (auto component_index = 0; component_index < cell_array->GetNumberOfComponents(); ++component_index) {
479 debug(Trace::High) << cell_array->GetName() << "[" << tuple_index << "][" << component_index << "] = " << cell_array->GetComponent(tuple_index, component_index);
480 }
481 }
482 }
483 }
484 }
485 // Node data
486 if (auto* point_data = reader.pointData(); point_data) {
487 // Read node groups and variables
488 Int32SharedArray vtk_to_arcane_lids(mesh->nodeFamily()->nbItem());
489 std::iota(vtk_to_arcane_lids.begin(), vtk_to_arcane_lids.end(), 0);
490 Int32SharedArray arcane_to_vtk_lids{ vtk_to_arcane_lids };
491 for (auto array_index = 0; array_index < point_data->GetNumberOfArrays(); ++array_index) {
492 auto* point_array = point_data->GetArray(array_index);
493 if (String name = point_array->GetName(); name.substring(0, 6) == "GROUP_") {
494 _createGroup(point_array, name.substring(6), mesh, mesh->nodeFamily(), vtk_to_arcane_lids.constSpan());
495 created_infos_str() << "<node-group name='" << name.substring(6) << "'/>";
496 }
497 else {
498 auto var_info = _createVariable(point_array, name, mesh, mesh->nodeFamily(), arcane_to_vtk_lids);
499 created_infos_str() << "<node-variable name='" << name << "' "
500 << " data-type='" << dataTypeName(var_info.m_type) << "' "
501 << " is_array='" << std::boolalpha << var_info.is_array << "'/>";
502 }
503 if (m_print_info_level.print_debug_info) {
504 debug(Trace::High) << "Reading property " << point_array->GetName();
505 for (auto tuple_index = 0; tuple_index < point_array->GetNumberOfTuples(); ++tuple_index) {
506 for (auto component_index = 0; component_index < point_array->GetNumberOfComponents(); ++component_index) {
507 debug(Trace::High) << point_array->GetName() << "[" << tuple_index << "][" << component_index << "] = " << point_array->GetComponent(tuple_index, component_index);
508 }
509 }
510 }
511 }
512 }
513 // Face data
514 if (auto* face_data = reader.faceData(); face_data) {
515 // Read face groups and variables
516 Int32UniqueArray vtk_to_Arcane_lids(mesh->faceFamily()->nbItem());
517 Int32UniqueArray arcane_to_vtk_lids(mesh->faceFamily()->nbItem());
518 _computeFaceVtkArcaneLidConversion(vtk_to_Arcane_lids, arcane_to_vtk_lids, reader, mesh);
519 for (auto array_index = 0; array_index < face_data->GetNumberOfArrays(); ++array_index) {
520 auto* face_array = face_data->GetArray(array_index);
521 if (String name = face_array->GetName(); name.substring(0, 6) == "GROUP_") {
522 _createGroup(face_array, name.substring(6), mesh, mesh->faceFamily(), vtk_to_Arcane_lids);
523 created_infos_str() << "<face-group name='" << name << "'/>";
524 }
525 else {
526 auto var_info = _createVariable(face_array, name, mesh, mesh->faceFamily(), arcane_to_vtk_lids);
527 created_infos_str() << "<face-variable name='" << name << "' "
528 << " data-type='" << dataTypeName(var_info.m_type) << "' "
529 << " is_array='" << std::boolalpha << var_info.is_array << "'/>";
530 }
531 if (m_print_info_level.print_debug_info) {
532 debug(Trace::High) << "Reading property " << face_array->GetName();
533 for (auto tuple_index = 0; tuple_index < face_array->GetNumberOfTuples(); ++tuple_index) {
534 for (auto component_index = 0; component_index < face_array->GetNumberOfComponents(); ++component_index) {
535 debug(Trace::High) << face_array->GetName() << "[" << tuple_index << "][" << component_index << "] = " << face_array->GetComponent(tuple_index, component_index);
536 }
537 }
538 }
539 }
540 }
541 created_infos_str() << "</infos>";
542 // Create empty group and variables in non reader subdomain
543 ByteUniqueArray bytes;
544 auto* pm = mesh->parallelMng();
545 if (!reader.isEmpty() && pm->isMasterIO()) {
546 String str = created_infos_str.str();
547 ByteConstArrayView bv = str.utf8();
548 Integer len = bv.size();
549 bytes.resize(len + 1);
550 bytes.copy(bv);
551 }
552 pm->broadcastMemoryBuffer(bytes, pm->masterIORank());
553 if (reader.isEmpty()) {
554 std::unique_ptr<IXmlDocumentHolder> doc(IXmlDocumentHolder::loadFromBuffer(bytes, "InternalBuffer", traceMng()));
555 XmlNode doc_node = doc->documentNode();
556 _createEmptyVariablesAndGroups(mesh,doc_node);
557
558 }
559}
560
561/*---------------------------------------------------------------------------*/
562/*---------------------------------------------------------------------------*/
563
564void VtkPolyhedralMeshIOService::
565_createGroup(vtkDataArray* group_items, const String& group_name, IPrimaryMesh* mesh, IItemFamily* item_family, Int32ConstSpan vtkToArcaneLid) const
566{
567 ARCANE_CHECK_POINTER(group_items);
569 ARCANE_CHECK_POINTER(item_family);
570 if (group_items->GetNumberOfComponents() != 1)
571 fatal() << String::format("Cannot create item group {0}. Group information in data property must be a scalar", group_name);
572 debug() << "Create group " << group_name;
573 Int32UniqueArray arcane_lids;
574 arcane_lids.reserve((int)group_items->GetNumberOfValues());
575 using GroupDispatcher = vtkArrayDispatch::DispatchByValueType<vtkArrayDispatch::Integrals>;
576 auto group_creator = [&arcane_lids, &vtkToArcaneLid](auto* array) {
577 vtkIdType numTuples = array->GetNumberOfTuples();
578 vtkDataArrayAccessor<std::remove_pointer_t<decltype(array)>> array_accessor{ array };
579 auto local_id = 0;
580 for (vtkIdType tupleIdx = 0; tupleIdx < numTuples; ++tupleIdx) {
581 auto value = array_accessor.Get(tupleIdx, 0);
582 if (value)
583 arcane_lids.push_back(vtkToArcaneLid[local_id]);
584 ++local_id;
585 }
586 };
587 if (!GroupDispatcher::Execute(group_items, group_creator))
588 ARCANE_FATAL("Cannot create item group {0}. Group information in data property must be an integral type", group_name);
589 debug() << " local ids for item group " << group_name << " " << arcane_lids; // to remove
590 item_family->createGroup(group_name, arcane_lids);
591}
592
593/*---------------------------------------------------------------------------*/
594/*---------------------------------------------------------------------------*/
595
596template <typename vtkType>
598{
599 using type = vtkType;
600};
601
602template <>
604{
605 using type = Real;
606};
607
608template <>
610{
611 using type = Int64;
612};
613
614template <typename T> using to_arcane_type_t = typename ToArcaneType<T>::type;
615/*---------------------------------------------------------------------------*/
616
617VtkPolyhedralMeshIOService::VariableInfo VtkPolyhedralMeshIOService::
619{
623 if (item_values->GetNumberOfTuples() != item_family->nbItem())
624 ARCANE_FATAL("Cannot create variable {0}, {1} values are given for {2} items in {3} family",
625 variable_name, item_values->GetNumberOfTuples(), item_family->nbItem(), item_family->name());
626 debug() << "Create mesh variable " << variable_name;
628 auto variable_creator = [mesh, variable_name, item_family, arcane_to_vtk_lids, this, &var_info](auto* values) {
630 using ValueType = typename std::remove_pointer_t<decltype(values)>::ValueType;
631 auto* var = new ItemVariableScalarRefT<to_arcane_type_t<ValueType>>{ vbi, item_family->itemKind() };
632 mesh->variableMng()->_internalApi()->addAutoDestroyVariable(var);
633 vtkDataArrayAccessor<std::remove_pointer_t<decltype(values)>> values_accessor{ values };
634 ENUMERATE_ITEM (item, item_family->allItems()) {
635 (*var)[item] = (to_arcane_type_t<ValueType>)values_accessor.Get(arcane_to_vtk_lids[item.localId()], 0);
636 }
637 var_info.m_type = DataTypeTraitsT<to_arcane_type_t<ValueType>>::type();
638 var_info.is_array = false;
639 };
640 auto array_variable_creator = [mesh, variable_name, item_family, arcane_to_vtk_lids, this, &var_info](auto* values) {
641 VariableBuildInfo vbi{ mesh, variable_name };
642 using ValueType = typename std::remove_pointer_t<decltype(values)>::ValueType;
643 auto* var = new ItemVariableArrayRefT<to_arcane_type_t<ValueType>>{ vbi, item_family->itemKind() };
644 mesh->variableMng()->_internalApi()->addAutoDestroyVariable(var);
645 vtkDataArrayAccessor<std::remove_pointer_t<decltype(values)>> values_accessor{ values };
646 var->resize(values->GetNumberOfComponents());
647 ENUMERATE_ITEM (item, item_family->allItems()) {
648 auto index = 0;
649 for (auto& var_value : (*var)[item]) {
650 var_value = (to_arcane_type_t<ValueType>)values_accessor.Get(arcane_to_vtk_lids[item.localId()], index++);
651 }
652 }
653 var_info.m_type = DataTypeTraitsT<to_arcane_type_t<ValueType>>::type();
654 var_info.is_array = true;
655 };
656 // Restrict to int and real values
657 using ValueTypes = vtkTypeList_Create_6(double, float, int, long, long long, short);
658 using ArrayDispatcher = vtkArrayDispatch::DispatchByValueType<ValueTypes>;
659 // Create ScalarVariable
660 bool is_variable_created = false;
661 if (item_values->GetNumberOfComponents() == 1) {
662 is_variable_created = ArrayDispatcher::Execute(item_values, variable_creator);
663 }
664 // Create ArrayVariable
665 else { // ArrayVariable
666 is_variable_created = ArrayDispatcher::Execute(item_values, array_variable_creator);
667 }
668 if (!is_variable_created)
669 ARCANE_FATAL("Cannot create variable {0}, it's data type is not supported. Only real and integral types are supported", variable_name);
670 return var_info;
671}
672
673/*---------------------------------------------------------------------------*/
674/*---------------------------------------------------------------------------*/
675
676void VtkPolyhedralMeshIOService::
677_computeFaceVtkArcaneLidConversion(Int32Span face_vtk_to_arcane_lids, Int32Span arcane_to_vtk_lids, VtkPolyhedralMeshIOService::VtkReader& reader, IPrimaryMesh* mesh) const
678{
679 auto face_nodes_unique_ids = reader.faceNodes();
680 auto face_nb_nodes = reader.faceNbNodes();
681 auto current_face_index = 0;
682 auto current_face_index_in_face_nodes = 0;
683 Int32UniqueArray face_nodes_local_ids(face_nodes_unique_ids.size());
684 mesh->nodeFamily()->itemsUniqueIdToLocalId(face_nodes_local_ids, face_nodes_unique_ids);
685 for (auto current_face_nb_node : face_nb_nodes) {
686 auto current_face_nodes = face_nodes_local_ids.subConstView(current_face_index_in_face_nodes, current_face_nb_node);
687 current_face_index_in_face_nodes += current_face_nb_node;
688 Node face_first_node{ mesh->nodeFamily()->view()[current_face_nodes[0]] };
689 face_vtk_to_arcane_lids[current_face_index] = mesh_utils::getFaceFromNodesLocal(face_first_node, current_face_nodes).localId();
690 ++current_face_index;
691 }
692 auto vtk_lid = 0;
693 for (auto arcane_lid : face_vtk_to_arcane_lids) {
694 arcane_to_vtk_lids[arcane_lid] = vtk_lid;
695 ++vtk_lid;
696 }
697}
698
699/*---------------------------------------------------------------------------*/
700/*---------------------------------------------------------------------------*/
701
702template <template <class> class VariableRootType>
703VariableRef* _createVar(IMesh* mesh, const String& var_name, const String& var_data_type_name, eItemKind var_kind)
704{
705 bool has_error = false;
706 eDataType var_data_type = dataTypeFromName(var_data_type_name.localstr(),has_error);
707 if (has_error) {
708 ARCANE_FATAL("Invalid data type name {0} for Variable creation in VtkPolyhedralMeshIOService");
709 }
710 switch (var_data_type){
711 case DT_Int32:
712 return new VariableRootType<Int32>{VariableBuildInfo{mesh,var_name},var_kind};
713 break;
714 case DT_Int64:
715 return new VariableRootType<Int64>{VariableBuildInfo{mesh,var_name},var_kind};
716 break;
717 case DT_Real:
718 return new VariableRootType<Real>{VariableBuildInfo{mesh,var_name},var_kind};
719 break;
720 default :
721 ARCANE_FATAL("Handle only DT_Int32, DT_Int64, DT_Real in VtkPolyhedralMeshIOService");
722 }
723}
724
725/*---------------------------------------------------------------------------*/
726/*---------------------------------------------------------------------------*/
727
728template <template <class> class VariableRootType , template <class> class ArrayVariableRootType>
729void VtkPolyhedralMeshIOService::
730_createEmptyVariables(IMesh* mesh, const XmlNodeList& item_variables_node, eItemKind item_kind) const
731{
732 ARCANE_CHECK_PTR(mesh);
733 {
734 for (XmlNode xnode : item_variables_node) {
735 String name = xnode.attrValue("name");
736 debug() << "Create mesh variable: " << name;
737 String data_type_name = xnode.attrValue("data-type");
738 bool is_array = xnode.attrValue("is_array") == "true";
739 VariableRef* var = nullptr;
740 if (is_array) {
741 var = _createVar<ArrayVariableRootType>(mesh,name,data_type_name,item_kind);
742 }
743 else {
744 var = _createVar<VariableRootType>(mesh,name, data_type_name,item_kind);
745 }
746 mesh->variableMng()->_internalApi()->addAutoDestroyVariable(var);
747 }
748 }
749}
750
751/*---------------------------------------------------------------------------*/
752/*---------------------------------------------------------------------------*/
753
754void VtkPolyhedralMeshIOService::
755_createEmptyGroups(IMesh* mesh, const XmlNodeList& groups_node, IItemFamily* item_family) const
756{
757 for (XmlNode xnode : groups_node) {
758 String name = xnode.attrValue("name");
759 info() << "Building group: " << name;
760 item_family->createGroup(name);
761 }
762}
763
764
765
766/*---------------------------------------------------------------------------*/
767/*---------------------------------------------------------------------------*/
768
769void VtkPolyhedralMeshIOService::
770_createEmptyVariablesAndGroups(IMesh* mesh, XmlNode::const_reference variable_and_group_info) const
771{
772 ARCANE_CHECK_PTR(mesh);
773 auto document_node = variable_and_group_info.documentElement();
774 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children("cell-variable"), IK_Cell);
775 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children("node-variable"), IK_Node);
776 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children("face-variable"), IK_Face);
777
778 _createEmptyGroups(mesh, document_node.children("cell-group"), mesh->itemFamily(IK_Cell));
779 _createEmptyGroups(mesh, document_node.children("node-group"), mesh->itemFamily(IK_Node));
780 _createEmptyGroups(mesh, document_node.children("face-group"), mesh->itemFamily(IK_Face));
781}
782
783/*---------------------------------------------------------------------------*/
784/*---------------------------------------------------------------------------*/
785
786VtkPolyhedralMeshIOService::VtkReader::
787VtkReader(const String& filename, VtkPolyhedralTools::PrintInfoLevel print_info_level)
788: m_filename{ filename }
789, m_print_info_level{ print_info_level }
790{
791 m_is_empty = false;
792 m_do_read = true;
793 if (filename.empty()) {
794 m_read_status.failure = true;
795 m_read_status.failure_message = "filename for polyhedral vtk mesh is empty.";
796 return;
797 }
798 if (filename.endsWith("vtk"))
799 _readPlainTextVtkGrid(filename);
800 else if (filename.endsWith("vtu"))
801 _readXlmVtkGrid(filename);
802 else {
803 m_read_status.failure = true;
804 m_read_status.failure_message = String::format("Unsupported vtk extension for file {0}. Supported vtk extension for Polyhedral meshes are {1}",
805 filename,VtkReader::supportedVtkExtensions());
806 }
807 // Check vtk grid exists and not empty
808 if (!m_vtk_grid) {
809 m_read_status.failure = true;
810 m_read_status.failure_message = String::format("Cannot read vtk polyhedral file {0}. Vtk grid was not created.", filename);
811 return;
812 }
813 if (m_vtk_grid->GetNumberOfCells() == 0) {
814 m_read_status.failure = true;
815 m_read_status.failure_message = String::format("Cannot read vtk polyhedral file {0}. No cells were found.", filename);
816 return;
817 }
818 if (!m_vtk_grid->GetFaces()) {
819 m_read_status.failure = true;
820 m_read_status.failure_message = String::format("The given mesh vtk file {0} is not a polyhedral mesh, cannot read it", filename);
821 return;
822 }
823
824 m_cell_data = m_vtk_grid->GetCellData();
825 m_point_data = m_vtk_grid->GetPointData();
826
827 // Read face info (for variables and groups) if present
828 String faces_filename = m_filename + "faces.vtk";
829 std::ifstream ifile(faces_filename.localstr());
830 if (ifile) {
831 _readPlainTextVtkFaceGrid(faces_filename);
832 }
833 else{
834 faces_filename = m_filename + "faces.vtu";
835 ifile = std::ifstream{ faces_filename.localstr() };
836 if (ifile) {
837 _readXmlVtkFaceGrid(faces_filename);
838 }
839 }
840
841 StringUniqueArray faces_filename_and_extension;
842 faces_filename.split(faces_filename_and_extension,'.');
843
844 if (!ifile){
845 m_read_status.info_message = String::format("Information no face mesh given {0}{1} (.vtk or .vtu) to define face variables or groups on faces.",
846 faces_filename_and_extension[0],
847 faces_filename_and_extension[1]);
848 }
849 else {
850 if (m_vtk_face_grid) { // Check face vtk grid exists and not empty
851 if (m_vtk_face_grid->GetNumberOfCells() == 0) {
852 m_read_status.failure = true;
853 m_read_status.failure_message = m_read_status.failure_message + String::format(" Error in reading face information for groups in mesh file {0} ", faces_filename);
854 }
855 else {
856 m_face_data = m_vtk_face_grid->GetCellData();
857 }
858 }
859 else{
860 m_read_status.failure = true;
861 m_read_status.failure_message = m_read_status.failure_message + String::format("Face data could not be built from file {0}{1} (.vtk or .vtu).",
862 faces_filename_and_extension[0],
863 faces_filename_and_extension[1]);
864 }
865 }
866
867 if (m_print_info_level.print_mesh_info)
868 _printMeshInfos();
869}
870
871/*---------------------------------------------------------------------------*/
872/*---------------------------------------------------------------------------*/
873
874Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
875cellUids()
876{
877 if (!doRead()) return m_cell_uids;
878 if (m_cell_uids.empty()) {
879 _checkVtkGrid();
880 m_cell_uids.reserve(m_vtk_grid->GetNumberOfCells());
881 m_cell_nb_nodes.reserve(m_vtk_grid->GetNumberOfCells());
882 m_cell_node_uids.reserve(10 * m_vtk_grid->GetNumberOfCells()); // take a mean of 10 nodes per cell
883 auto* cell_iter = m_vtk_grid->NewCellIterator();
884 cell_iter->InitTraversal();
885 while (!cell_iter->IsDoneWithTraversal()) {
886 m_cell_uids.push_back(cell_iter->GetCellId());
887 m_cell_nb_nodes.push_back(Integer(cell_iter->GetNumberOfPoints()));
888 ArrayView<vtkIdType> cell_nodes{ Integer(cell_iter->GetNumberOfPoints()), cell_iter->GetPointIds()->GetPointer(0) };
889 std::for_each(cell_nodes.begin(), cell_nodes.end(), [this](auto uid) { this->m_cell_node_uids.push_back(uid); });
890 cell_iter->GoToNextCell();
891 }
892 }
893 return m_cell_uids;
894}
895
896/*---------------------------------------------------------------------------*/
897/*---------------------------------------------------------------------------*/
898
899Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
900nodeUids()
901{
902 if (!doRead()) return m_node_uids;
903 if (m_node_uids.empty()) {
904 _checkVtkGrid();
905 auto nb_nodes = m_vtk_grid->GetNumberOfPoints();
906 m_node_uids.resize(nb_nodes);
907 m_node_nb_cells.resize(nb_nodes);
908 m_node_cell_uids.reserve(8 * nb_nodes);
909 m_node_uid_to_index.resize(nb_nodes);
910 for (int node_index = 0; node_index < nb_nodes; ++node_index) {
911 Int64 node_uid = node_index;
912 m_node_uids[node_index] = node_uid;
913 auto cell_nodes = vtkIdList::New();
914 m_vtk_grid->GetPointCells(node_index, cell_nodes);
915 Int64Span cell_nodes_view((Int64*)cell_nodes->GetPointer(0), cell_nodes->GetNumberOfIds());
916 m_node_cell_uids.addRange(cell_nodes_view);
917 m_node_nb_cells[node_index] = (Int32)cell_nodes->GetNumberOfIds();
918 // uid and index might differ in the future (ex parallel read).
919 // This structure is created to be used in faceUids. Should be a map if node_uid is no longer the node index
920 m_node_uid_to_index[node_uid] = node_index;
921 }
922 }
923 return m_node_uids;
924}
925
926/*---------------------------------------------------------------------------*/
927/*---------------------------------------------------------------------------*/
928
929Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
930faceUids()
931{
932 // Needs nodeUids to be called first (no work done if already called)
933 nodeUids();
934
935 if (!doRead()) return m_face_uids;
936 if (!m_face_uids.empty())
937 return m_face_uids;
938 _checkVtkGrid();
939 auto* cell_iter = m_vtk_grid->NewCellIterator();
940 cell_iter->InitTraversal();
941 vtkIdType nb_face_estimation = 0;
942 while (!cell_iter->IsDoneWithTraversal()) {
943 vtkIdType cell_nb_faces = 0;
944 vtkIdType* points{ nullptr };
945 m_vtk_grid->GetFaceStream(cell_iter->GetCellId(), cell_nb_faces, points);
946 nb_face_estimation += cell_nb_faces;
947 cell_iter->GoToNextCell();
948 }
949 m_face_uids.reserve(nb_face_estimation);
950 auto const* faces = m_vtk_grid->GetFaces();
951 // This array contains the face info per cells (cf. vtk file)
952 // first_cell_nb_faces first_cell_first_face_nb_nodes first_cell_first_face_node_1 ... first_cell_first_face_node_n first_cell_second_face_nb_nodes etc
953
954 if (!faces) {
955 ARCANE_FATAL("Mesh {0} is not polyhedral: faces are not defined", m_filename);
956 }
957 Int64 face_uid = 0;
958 auto face_info_size = faces->GetNumberOfValues();
959 m_face_node_uids.reserve(face_info_size);
960 m_face_nb_nodes.reserve(nb_face_estimation);
961 m_face_cell_uids.reserve(2 * nb_face_estimation);
962 m_face_nb_cells.reserve(nb_face_estimation);
963 m_cell_face_uids.reserve(8 * m_cell_uids.size()); // take a mean of 8 faces per cell
964 m_cell_nb_faces.resize(m_cell_uids.size(), 0);
965 m_cell_face_indexes.resize(m_cell_uids.size(), -1);
966 m_face_uid_indexes.resize(2 * nb_face_estimation, -1);
967 Int64UniqueArray current_face_nodes, sorted_current_face_nodes;
968 current_face_nodes.reserve(10);
969 sorted_current_face_nodes.reserve(10);
970 UniqueArray<UniqueArray<Int64>> node_faces(m_node_uids.size());
971 UniqueArray<Int32> face_offsets;
972 face_offsets.reserve(nb_face_estimation);
973 face_offsets.push_back(0);
974 FaceUidToIndexMap face_uid_to_index;
975 face_uid_to_index.reserve(nb_face_estimation);
976 auto cell_index = 0;
977 auto cell_face_index = 0;
978 auto global_face_index = 0;
979 auto face_uid_index = 0;
980 for (int face_info_index = 0; face_info_index < face_info_size; cell_index++) { // face data are given by cell
981 auto current_cell_nb_faces = Int32(faces->GetValue(face_info_index++));
982 m_cell_face_indexes[m_cell_uids[cell_index]] = cell_face_index;
983 for (auto face_index = 0; face_index < current_cell_nb_faces; ++face_index, ++global_face_index) {
984 auto current_face_nb_nodes = Int32(faces->GetValue(face_info_index++));
985 m_cell_nb_faces[m_cell_uids[cell_index]] += 1;
986 for (int node_index = 0; node_index < current_face_nb_nodes; ++node_index) {
987 current_face_nodes.push_back(faces->GetValue(face_info_index++));
988 }
989 sorted_current_face_nodes.resize(current_face_nodes.size());
990 auto is_front_cell = mesh_utils::reorderNodesOfFace(current_face_nodes, sorted_current_face_nodes);
991 auto [is_face_found, existing_face_index] = _findFace(sorted_current_face_nodes, node_faces,
992 m_node_uid_to_index, m_face_nb_nodes,
993 face_uid_to_index, face_offsets, m_face_node_uids);
994 if (!is_face_found) {
995 for (auto node_uid : current_face_nodes) {
996 node_faces[m_node_uid_to_index[node_uid]].push_back(face_uid);
997 }
998 m_cell_face_uids.push_back(face_uid);
999 m_face_uids.push_back(face_uid); // todo parallel
1000 m_face_nb_nodes.push_back(current_face_nb_nodes);
1001 m_face_node_uids.addRange(sorted_current_face_nodes);
1002 m_face_nb_cells.push_back(1);
1003 m_face_uid_indexes[global_face_index] = face_uid_index;
1004 face_uid_to_index.push_back(face_uid_index);
1005 auto previous_offset = face_offsets.back();
1006 face_offsets.push_back(previous_offset + sorted_current_face_nodes.size());
1007 ++face_uid;
1008 ++face_uid_index;
1009 if (is_front_cell) {
1010 m_face_cell_uids.push_back(NULL_ITEM_UNIQUE_ID);
1011 m_face_cell_uids.push_back(m_cell_uids[cell_index]);
1012 }
1013 else {
1014 m_face_cell_uids.push_back(m_cell_uids[cell_index]);
1015 m_face_cell_uids.push_back(NULL_ITEM_UNIQUE_ID);
1016 }
1017 }
1018 else {
1019 m_cell_face_uids.push_back(m_face_uids[existing_face_index]);
1020 m_face_nb_cells[existing_face_index] += 1;
1021 m_face_uid_indexes[global_face_index] = existing_face_index;
1022 // add cell to face cell connectivity
1023 if (is_front_cell) {
1024 if (m_face_cell_uids[2 * existing_face_index + 1] != NULL_ITEM_UNIQUE_ID) {
1025 ARCANE_FATAL("Problem in face orientation, face uid {0}, nodes {1}, same orientation in cell {2} and {3}. Change mesh file.",
1026 m_face_uids[existing_face_index],
1027 current_face_nodes,
1028 m_face_cell_uids[2 * existing_face_index + 1],
1029 m_cell_uids[cell_index]);
1030 }
1031 m_face_cell_uids[2 * existing_face_index + 1] = m_cell_uids[cell_index];
1032 }
1033 else {
1034 if (m_face_cell_uids[2 * existing_face_index] != NULL_ITEM_UNIQUE_ID) {
1035 ARCANE_FATAL("Problem in face orientation, face uid {0}, nodes {1}, same orientation in cell {2} and {3}. Change mesh file.",
1036 m_face_uids[existing_face_index],
1037 current_face_nodes,
1038 m_face_cell_uids[2 * existing_face_index],
1039 m_cell_uids[cell_index]);
1040 }
1041 m_face_cell_uids[2 * existing_face_index] = m_cell_uids[cell_index];
1042 }
1043 }
1044 current_face_nodes.clear();
1045 sorted_current_face_nodes.clear();
1046 }
1047 cell_face_index += m_cell_nb_faces[m_cell_uids[cell_index]];
1048 }
1049 // fill node_face_uids and node_nb_faces from node_faces (array form [nb_nodes][nb_connected_faces])
1050 m_node_nb_faces.resize(m_node_uids.size(), 0);
1051 _flattenConnectivity(node_faces.constSpan(), m_node_nb_faces, m_node_face_uids);
1052
1053 if (m_print_info_level.print_debug_info) {
1054 std::cout << "================FACE NODES ==============" << std::endl;
1055 std::copy(m_face_node_uids.begin(), m_face_node_uids.end(), std::ostream_iterator<Int64>(std::cout, " "));
1056 std::cout << std::endl;
1057 std::copy(m_face_nb_nodes.begin(), m_face_nb_nodes.end(), std::ostream_iterator<Int64>(std::cout, " "));
1058 std::cout << std::endl;
1059 std::copy(m_cell_face_indexes.begin(), m_cell_face_indexes.end(), std::ostream_iterator<Int64>(std::cout, " "));
1060 std::cout << std::endl;
1061 }
1062
1063 return m_face_uids;
1064}
1065
1066/*---------------------------------------------------------------------------*/
1067/*---------------------------------------------------------------------------*/
1068
1069Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1070edgeUids()
1071{
1072 if (!doRead()) return m_edge_uids;
1073 if (!m_edge_uids.empty())
1074 return m_edge_uids;
1075
1076 nodeUids(); // Needed to be called first. No work done if already called
1077
1078 _checkVtkGrid();
1079 m_edge_uids.reserve(2 * m_vtk_grid->GetNumberOfPoints());
1080 auto const* faces = m_vtk_grid->GetFaces();
1081 // This array contains the face info per cells (cf. vtk file)
1082 // first_cell_nb_faces first_cell_first_face_nb_nodes first_cell_first_face_node_1 ... first_cell_first_face_node_n first_cell_second_face_nb_nodes etc
1083
1084 if (!faces) {
1085 ARCANE_FATAL("Mesh {0} is not polyhedral: faces are not defined", m_filename);
1086 }
1087 Int64 edge_uid = 0;
1088 auto nb_edge_estimation = 2 * m_edge_uids.capacity();
1089 m_edge_node_uids.reserve(nb_edge_estimation);
1090 auto face_info_size = faces->GetNumberOfValues();
1091 auto cell_index = 0;
1092 auto global_face_index = 0;
1093 auto new_edge_index = 0;
1094 UniqueArray<std::set<Int64>> edge_cells;
1095 UniqueArray<Int64UniqueArray> edge_faces;
1096 edge_cells.reserve(m_edge_uids.capacity());
1097 edge_faces.reserve(m_edge_uids.capacity());
1098 m_cell_nb_edges.resize(m_cell_uids.size(), 0);
1099 m_cell_edge_uids.reserve(20 * m_cell_uids.size()); // choose a value of 20 edge per cell
1100 UniqueArray<std::set<Int64>> face_edges;
1101 face_edges.resize(m_face_uids.size());
1102 UniqueArray<std::set<Int64>> cell_edges;
1103 cell_edges.resize(m_cell_uids.size());
1104 UniqueArray<Int64UniqueArray> node_edges;
1105 node_edges.resize(m_node_uids.size());
1106 EdgeUidToIndexMap edge_uid_to_index;
1107 edge_uid_to_index.reserve(nb_edge_estimation);
1108 Int32UniqueArray edge_offsets;
1109 edge_offsets.reserve(nb_edge_estimation);
1110 edge_offsets.push_back(0);
1111 m_edge_nb_nodes.reserve(nb_edge_estimation);
1112 for (int face_info_index = 0; face_info_index < face_info_size; ++cell_index) {
1113 auto current_cell_nb_faces = Int32(faces->GetValue(face_info_index++));
1114 for (auto face_index = 0; face_index < current_cell_nb_faces; ++face_index, ++global_face_index) {
1115 auto current_face_nb_nodes = Int32(faces->GetValue(face_info_index++));
1116 auto first_face_node_uid = Int32(faces->GetValue(face_info_index));
1117 UniqueArray<Int64> current_edge(2), sorted_edge(2);
1118 for (int node_index = 0; node_index < current_face_nb_nodes - 1; ++node_index) {
1119 current_edge = UniqueArray<Int64>{ faces->GetValue(face_info_index++), faces->GetValue(face_info_index) };
1120 mesh_utils::reorderNodesOfFace(current_edge, sorted_edge); // works for edges
1121 auto [is_edge_found, existing_edge_index] = _findFace(sorted_edge, node_edges,
1122 m_node_uid_to_index,
1123 m_edge_nb_nodes,
1124 edge_uid_to_index, edge_offsets, m_edge_node_uids); // works for edges
1125 if (!is_edge_found) {
1126 m_cell_nb_edges[cell_index] += 1;
1127 face_edges[m_face_uid_indexes[global_face_index]].insert(edge_uid);
1128 cell_edges[cell_index].insert(edge_uid);
1129 for (auto node : current_edge) {
1130 node_edges[node].push_back(edge_uid);
1131 }
1132 edge_cells.push_back(std::set{ m_cell_uids[cell_index] });
1133 edge_faces.push_back(Int64UniqueArray{ m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index] });
1134 m_edge_uids.push_back(edge_uid++); // todo parallel
1135 m_edge_node_uids.addRange(sorted_edge);
1136 edge_uid_to_index.push_back(new_edge_index);
1137 auto current_offset = edge_offsets.back();
1138 edge_offsets.push_back(current_offset + 2);
1139 m_edge_nb_nodes.push_back(2);
1140 ++new_edge_index;
1141 }
1142 else {
1143 edge_cells[existing_edge_index].insert(m_cell_uids[cell_index]);
1144 edge_faces[existing_edge_index].push_back(m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index]);
1145 face_edges[m_face_uid_indexes[global_face_index]].insert(m_edge_uids[existing_edge_index]);
1146 cell_edges[cell_index].insert(m_edge_uids[existing_edge_index]);
1147 }
1148 }
1149 current_edge = UniqueArray<Int64>{ faces->GetValue(face_info_index++), first_face_node_uid };
1150 mesh_utils::reorderNodesOfFace(current_edge, sorted_edge); // works for edges
1151 auto [is_edge_found, existing_edge_index] = _findFace(sorted_edge, node_edges,
1152 m_node_uid_to_index,
1153 m_edge_nb_nodes,
1154 edge_uid_to_index, edge_offsets, m_edge_node_uids); // works for edges
1155 if (!is_edge_found) {
1156 m_cell_nb_edges[cell_index] += 1;
1157 edge_cells.push_back(std::set{ m_cell_uids[cell_index] });
1158 edge_faces.push_back(Int64UniqueArray{ m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index] });
1159 face_edges[m_face_uid_indexes[global_face_index]].insert(edge_uid);
1160 cell_edges[cell_index].insert(edge_uid);
1161 for (auto node : current_edge) {
1162 node_edges[node].push_back(edge_uid);
1163 }
1164 m_edge_uids.push_back(edge_uid++); // todo parallel
1165 m_edge_node_uids.addRange(sorted_edge);
1166 edge_uid_to_index.push_back(new_edge_index);
1167 auto current_offset = edge_offsets.back();
1168 edge_offsets.push_back(current_offset + 2);
1169 m_edge_nb_nodes.push_back(2);
1170 ++new_edge_index;
1171 }
1172 else {
1173 edge_cells[existing_edge_index].insert(m_cell_uids[cell_index]);
1174 edge_faces[existing_edge_index].push_back(m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index]);
1175 face_edges[m_face_uid_indexes[global_face_index]].insert(m_edge_uids[existing_edge_index]);
1176 cell_edges[cell_index].insert(m_edge_uids[existing_edge_index]);
1177 }
1178 }
1179 }
1180 // fill edge_cell_uids and edge_nb_cells from edge_cells (array form [nb_edges][nb_connected_cells])
1181 m_edge_nb_cells.resize(m_edge_uids.size(), 0);
1182 _flattenConnectivity(edge_cells.constSpan(), m_edge_nb_cells, m_edge_cell_uids);
1183
1184 // fill edge faces uids
1185 m_edge_nb_faces.resize(m_edge_uids.size(), 0);
1186 _flattenConnectivity(edge_faces.constSpan(), m_edge_nb_faces, m_edge_face_uids);
1187
1188 // fill face edge uids
1189 m_face_nb_edges.resize(m_face_uids.size(), 0);
1190 _flattenConnectivity(face_edges.constSpan(), m_face_nb_edges, m_face_edge_uids);
1191
1192 // fill cell edge uids
1193 m_cell_nb_edges.resize(m_cell_uids.size(), 0);
1194 _flattenConnectivity(cell_edges, m_cell_nb_edges, m_cell_edge_uids);
1195
1196 // fill node edge uids
1197 m_node_nb_edges.resize(m_node_uids.size(), 0);
1198 _flattenConnectivity(node_edges, m_node_nb_edges, m_node_edge_uids);
1199
1200 if (m_print_info_level.print_debug_info) {
1201 std::cout << "================EDGE NODES ==============" << std::endl;
1202 std::copy(m_edge_node_uids.begin(), m_edge_node_uids.end(), std::ostream_iterator<Int64>(std::cout, " "));
1203 std::cout << std::endl;
1204 std::cout << "================FACE EDGES ==============" << std::endl;
1205 std::copy(m_face_nb_edges.begin(), m_face_nb_edges.end(), std::ostream_iterator<Int32>(std::cout, " "));
1206 std::cout << std::endl;
1207 std::copy(m_face_edge_uids.begin(), m_face_edge_uids.end(), std::ostream_iterator<Int64>(std::cout, " "));
1208 std::cout << std::endl;
1209 std::cout << "================CELL EDGES ==============" << std::endl;
1210 std::copy(m_cell_nb_edges.begin(), m_cell_nb_edges.end(), std::ostream_iterator<Int32>(std::cout, " "));
1211 std::cout << std::endl;
1212 std::copy(m_cell_edge_uids.begin(), m_cell_edge_uids.end(), std::ostream_iterator<Int64>(std::cout, " "));
1213 std::cout << std::endl;
1214 }
1215 return m_edge_uids;
1216}
1217
1218/*---------------------------------------------------------------------------*/
1219/*---------------------------------------------------------------------------*/
1220
1221std::pair<bool, Int32> VtkPolyhedralMeshIOService::VtkReader::
1222_findFace(const Int64UniqueArray& sorted_face_nodes,
1223 const UniqueArray<Int64UniqueArray>& node_face_uids,
1224 const NodeUidToIndexMap& node_uid_to_index,
1225 const Int32UniqueArray& face_nb_nodes,
1226 const FaceUidToIndexMap& face_uid_to_index,
1227 const UniqueArray<Int32>& face_offsets,
1228 const Int64UniqueArray& face_node_uids)
1229{
1230 auto first_node_uid = sorted_face_nodes[0];
1231 auto first_node_index = node_uid_to_index[first_node_uid];
1232 // If the face already exists it has already been registered in node_face connectivity
1233 for (auto face_uid : node_face_uids[first_node_index]) {
1234 auto face_index = face_uid_to_index[face_uid];
1235 auto face_offset = face_offsets[face_index];
1236 auto face_nb_node = face_nb_nodes[face_index];
1237 if (face_nb_node == sorted_face_nodes.size()) {
1238 bool is_same_face = true;
1239 for (auto index = 0; index < face_nb_node; ++index) {
1240 if (sorted_face_nodes[index] != face_node_uids[face_offset + index]) {
1241 is_same_face = false;
1242 }
1243 }
1244 if (is_same_face)
1245 return { true, face_index };
1246 }
1247 }
1248 return { false, -1 };
1249}
1250
1251/*---------------------------------------------------------------------------*/
1252/*---------------------------------------------------------------------------*/
1253
1254Integer VtkPolyhedralMeshIOService::VtkReader::
1255nbNodes()
1256{
1257 if (m_node_uids.empty())
1258 nodeUids();
1259 return m_node_uids.size();
1260}
1261
1262/*---------------------------------------------------------------------------*/
1263/*---------------------------------------------------------------------------*/
1264
1265Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1266cellNodes()
1267{
1268 if (m_cell_node_uids.empty())
1269 cellUids();
1270 return m_cell_node_uids;
1271}
1272
1273/*---------------------------------------------------------------------------*/
1274/*---------------------------------------------------------------------------*/
1275
1276Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1277cellNbNodes()
1278{
1279 if (m_cell_nb_nodes.empty())
1280 cellUids();
1281 return m_cell_nb_nodes;
1282}
1283
1284/*---------------------------------------------------------------------------*/
1285/*---------------------------------------------------------------------------*/
1286
1287Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1288faceNodes()
1289{
1290 if (m_face_node_uids.empty())
1291 faceUids();
1292 return m_face_node_uids;
1293}
1294
1295/*---------------------------------------------------------------------------*/
1296/*---------------------------------------------------------------------------*/
1297
1298Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1299faceNbNodes()
1300{
1301 if (m_face_nb_nodes.empty())
1302 faceUids();
1303 return m_face_nb_nodes;
1304}
1305
1306/*---------------------------------------------------------------------------*/
1307/*---------------------------------------------------------------------------*/
1308
1309Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1310edgeNbNodes()
1311{
1312 if (m_edge_node_uids.empty())
1313 edgeUids();
1314 return m_edge_nb_nodes;
1315}
1316
1317/*---------------------------------------------------------------------------*/
1318/*---------------------------------------------------------------------------*/
1319
1320Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1321edgeNodes()
1322{
1323 if (m_edge_node_uids.empty())
1324 edgeUids();
1325 return m_edge_node_uids;
1326}
1327
1328/*---------------------------------------------------------------------------*/
1329/*---------------------------------------------------------------------------*/
1330
1331Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1332faceCells()
1333{
1334 if (m_face_cell_uids.empty())
1335 faceUids();
1336 // debug
1337 if (m_print_info_level.print_debug_info) {
1338 std::cout << "=================FACE CELLS================="
1339 << "\n";
1340 std::copy(m_face_cell_uids.begin(), m_face_cell_uids.end(), std::ostream_iterator<Int64>(std::cout, " "));
1341 std::cout << "\n";
1342 std::cout << "=================END FACE CELLS================="
1343 << "\n";
1344 }
1345 return m_face_cell_uids;
1346}
1347
1348/*---------------------------------------------------------------------------*/
1349/*---------------------------------------------------------------------------*/
1350
1351Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1352faceNbCells()
1353{
1354 if (m_face_nb_cells.empty())
1355 faceUids();
1356 return m_face_nb_cells;
1357}
1358
1359/*---------------------------------------------------------------------------*/
1360/*---------------------------------------------------------------------------*/
1361
1362Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1363edgeNbCells()
1364{
1365 if (m_edge_nb_cells.empty())
1366 edgeUids();
1367 return m_edge_nb_cells;
1368}
1369
1370/*---------------------------------------------------------------------------*/
1371/*---------------------------------------------------------------------------*/
1372
1373Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1374edgeCells()
1375{
1376 if (m_edge_cell_uids.empty())
1377 edgeUids();
1378 return m_edge_cell_uids;
1379}
1380
1381/*---------------------------------------------------------------------------*/
1382/*---------------------------------------------------------------------------*/
1383
1384Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1385cellNbFaces()
1386{
1387 if (m_cell_nb_faces.empty())
1388 faceUids();
1389 return m_cell_nb_faces;
1390}
1391
1392/*---------------------------------------------------------------------------*/
1393/*---------------------------------------------------------------------------*/
1394
1395Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1396cellFaces()
1397{
1398 if (m_cell_face_uids.empty())
1399 faceUids();
1400 return m_cell_face_uids;
1401}
1402
1403/*---------------------------------------------------------------------------*/
1404/*---------------------------------------------------------------------------*/
1405
1406Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1407edgeNbFaces()
1408{
1409 if (m_edge_nb_faces.empty())
1410 edgeUids();
1411 return m_edge_nb_faces;
1412}
1413
1414/*---------------------------------------------------------------------------*/
1415/*---------------------------------------------------------------------------*/
1416
1417Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1418edgeFaces()
1419{
1420 if (m_edge_face_uids.empty())
1421 edgeUids();
1422 return m_edge_face_uids;
1423}
1424
1425/*---------------------------------------------------------------------------*/
1426/*---------------------------------------------------------------------------*/
1427
1428Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1429cellNbEdges()
1430{
1431 if (m_cell_nb_edges.empty())
1432 edgeUids();
1433 return m_cell_nb_edges;
1434}
1435
1436/*---------------------------------------------------------------------------*/
1437/*---------------------------------------------------------------------------*/
1438
1439Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1440cellEdges()
1441{
1442 if (m_cell_edge_uids.empty())
1443 edgeUids();
1444 return m_cell_edge_uids;
1445}
1446
1447/*---------------------------------------------------------------------------*/
1448/*---------------------------------------------------------------------------*/
1449
1450Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1451faceNbEdges()
1452{
1453 if (m_face_nb_edges.empty())
1454 edgeUids();
1455 return m_face_nb_edges;
1456}
1457
1458/*---------------------------------------------------------------------------*/
1459/*---------------------------------------------------------------------------*/
1460
1461Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1462faceEdges()
1463{
1464 if (m_face_edge_uids.empty())
1465 edgeUids();
1466 return m_face_edge_uids;
1467}
1468
1469/*---------------------------------------------------------------------------*/
1470/*---------------------------------------------------------------------------*/
1471
1472template <typename Connectivity2DArray>
1473void VtkPolyhedralMeshIOService::VtkReader::
1474_flattenConnectivity(Connectivity2DArray connected_item_2darray,
1475 Int32Span nb_connected_item_per_source_item,
1476 Int64UniqueArray& connected_item_array)
1477{
1478 // fill nb_connected_item_per_source_items
1479 std::transform(connected_item_2darray.begin(), connected_item_2darray.end(), nb_connected_item_per_source_item.begin(), [](auto const& connected_items) {
1480 return connected_items.size();
1481 });
1482 // fill connected_item_array
1483 connected_item_array.reserve(std::accumulate(nb_connected_item_per_source_item.begin(), nb_connected_item_per_source_item.end(), 0));
1484 std::for_each(connected_item_2darray.begin(), connected_item_2darray.end(), [&connected_item_array](auto const& connected_items) {
1485 for (auto const& connected_item : connected_items) {
1486 connected_item_array.push_back(connected_item);
1487 }
1488 });
1489}
1490
1491/*---------------------------------------------------------------------------*/
1492/*---------------------------------------------------------------------------*/
1493
1494Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1495nodeNbCells()
1496{
1497 if (m_node_nb_cells.empty())
1498 nodeUids();
1499 return m_node_nb_cells;
1500}
1501
1502/*---------------------------------------------------------------------------*/
1503/*---------------------------------------------------------------------------*/
1504
1505Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1506nodeCells()
1507{
1508 if (m_node_cell_uids.empty())
1509 nodeUids();
1510 return m_node_cell_uids;
1511}
1512
1513/*---------------------------------------------------------------------------*/
1514/*---------------------------------------------------------------------------*/
1515
1516Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1517nodeNbFaces()
1518{
1519 if (m_node_nb_faces.empty())
1520 faceUids();
1521 return m_node_nb_faces;
1522}
1523
1524/*---------------------------------------------------------------------------*/
1525/*---------------------------------------------------------------------------*/
1526
1527Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1528nodeFaces()
1529{
1530 if (m_node_face_uids.empty())
1531 faceUids();
1532 return m_node_face_uids;
1533}
1534
1535/*---------------------------------------------------------------------------*/
1536/*---------------------------------------------------------------------------*/
1537
1538Int32ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1539nodeNbEdges()
1540{
1541 if (m_node_nb_edges.empty())
1542 edgeUids();
1543 return m_node_nb_edges;
1544}
1545
1546/*---------------------------------------------------------------------------*/
1547/*---------------------------------------------------------------------------*/
1548
1549Int64ConstArrayView VtkPolyhedralMeshIOService::VtkReader::
1550nodeEdges()
1551{
1552 if (m_node_edge_uids.empty())
1553 edgeUids();
1554 return m_node_edge_uids;
1555}
1556
1557/*---------------------------------------------------------------------------*/
1558/*---------------------------------------------------------------------------*/
1559
1560Real3ArrayView VtkPolyhedralMeshIOService::VtkReader::
1561nodeCoords()
1562{
1563 if (!doRead()) return m_node_coordinates;
1564 if (m_node_coordinates.empty()) {
1565 _checkVtkGrid();
1566 auto point_coords = m_vtk_grid->GetPoints()->GetData();
1567 if (m_print_info_level.print_debug_info) {
1568 std::cout << "======= Point COORDS ====" << std::endl;
1569 std::ostringstream oss;
1570 point_coords->PrintSelf(oss, vtkIndent{ 2 });
1571 std::cout << oss.str() << std::endl;
1572 }
1573 auto nb_nodes = m_vtk_grid->GetNumberOfPoints();
1574 for (int i = 0; i < nb_nodes; ++i) {
1575 if (m_print_info_level.print_debug_info) {
1576 std::cout << "==========current point coordinates : ( ";
1577 std::cout << *(point_coords->GetTuple(i)) << " , ";
1578 std::cout << *(point_coords->GetTuple(i) + 1) << " , ";
1579 std::cout << *(point_coords->GetTuple(i) + 2) << " ) ===" << std::endl;
1580 }
1581 m_node_coordinates.add({ *(point_coords->GetTuple(i)),
1582 *(point_coords->GetTuple(i) + 1),
1583 *(point_coords->GetTuple(i) + 2) });
1584 }
1585 }
1586 return m_node_coordinates;
1587}
1588
1589/*---------------------------------------------------------------------------*/
1590/*---------------------------------------------------------------------------*/
1591
1592vtkCellData* VtkPolyhedralMeshIOService::VtkReader::
1593cellData()
1594{
1595 return m_cell_data;
1596}
1597
1598/*---------------------------------------------------------------------------*/
1599/*---------------------------------------------------------------------------*/
1600
1601vtkPointData* VtkPolyhedralMeshIOService::VtkReader::
1602pointData()
1603{
1604 return m_point_data;
1605}
1606
1607/*---------------------------------------------------------------------------*/
1608/*---------------------------------------------------------------------------*/
1609
1610void VtkPolyhedralMeshIOService::VtkReader::
1611_printMeshInfos() const
1612{
1613 _checkVtkGrid();
1614 std::cout << "-- VTK GRID READ "
1615 << " NB CELLS " << m_vtk_grid->GetNumberOfCells() << std::endl;
1616 // Parse cells
1617 auto* cell_iter = m_vtk_grid->vtkDataSet::NewCellIterator();
1618 cell_iter->InitTraversal();
1619 vtkIdType* cell_faces{ nullptr };
1620 vtkIdType nb_faces = 0;
1621 while (!cell_iter->IsDoneWithTraversal()) {
1622 std::cout << "---- visiting cell id " << cell_iter->GetCellId() << std::endl;
1623 std::cout << "---- cell number of faces " << cell_iter->GetNumberOfFaces() << std::endl;
1624 std::cout << "---- cell number of points " << cell_iter->GetNumberOfPoints() << std::endl;
1625 m_vtk_grid->GetFaceStream(cell_iter->GetCellId(), nb_faces, cell_faces);
1626 for (auto iface = 0; iface < nb_faces; ++iface) {
1627 auto face_nb_nodes = *cell_faces++;
1628 std::cout << "---- has face with " << face_nb_nodes << " nodes. Node ids : ";
1629 for (int inode = 0; inode < face_nb_nodes; ++inode) {
1630 std::cout << *cell_faces++ << " ";
1631 }
1632 std::cout << std::endl;
1633 }
1634 cell_iter->GoToNextCell();
1635 }
1636}
1637
1638/*---------------------------------------------------------------------------*/
1639/*---------------------------------------------------------------------------*/
1640
1641vtkCellData* VtkPolyhedralMeshIOService::VtkReader::faceData()
1642{
1643 return m_face_data;
1644}
1645/*---------------------------------------------------------------------------*/
1646/*---------------------------------------------------------------------------*/
1647
1648/*---------------------------------------------------------------------------*/
1649/*---------------------------------------------------------------------------*/
1650
1651void VtkPolyhedralMeshIOService::VtkReader::
1652_readPlainTextVtkGrid(const String& filename)
1653{
1654 m_vtk_grid_reader->SetFileName(filename.localstr());
1655 m_vtk_grid_reader->ReadAllScalarsOn();
1656 m_vtk_grid_reader->Update();
1657 m_vtk_grid = m_vtk_grid_reader->GetOutput();
1658}
1659
1660/*---------------------------------------------------------------------------*/
1661/*---------------------------------------------------------------------------*/
1662
1663void VtkPolyhedralMeshIOService::VtkReader::
1664_readXlmVtkGrid(const String& filename)
1665{
1666 m_vtk_xml_grid_reader->SetFileName(filename.localstr());
1667 m_vtk_xml_grid_reader->Update();
1668 m_vtk_grid = m_vtk_xml_grid_reader->GetOutput();
1669}
1670
1671/*---------------------------------------------------------------------------*/
1672/*---------------------------------------------------------------------------*/
1673
1674void VtkPolyhedralMeshIOService::VtkReader::
1675_readPlainTextVtkFaceGrid(const String& faces_filename)
1676{
1677 m_vtk_face_grid_reader->SetFileName(faces_filename.localstr());
1678 m_vtk_face_grid_reader->ReadAllScalarsOn();
1679 m_vtk_face_grid_reader->Update();
1680 m_vtk_face_grid = m_vtk_face_grid_reader->GetOutput();
1681}
1682
1683/*---------------------------------------------------------------------------*/
1684/*---------------------------------------------------------------------------*/
1685
1686void VtkPolyhedralMeshIOService::VtkReader::
1687_readXmlVtkFaceGrid(const String& faces_filename)
1688{
1689 m_vtk_xml_face_grid_reader->SetFileName(faces_filename.localstr());
1690 m_vtk_xml_face_grid_reader->Update();
1691 m_vtk_face_grid = m_vtk_xml_face_grid_reader->GetOutput();
1692}
1693
1694/*---------------------------------------------------------------------------*/
1695/*---------------------------------------------------------------------------*/
1696
1697void VtkPolyhedralMeshIOService::VtkReader::
1698_checkVtkGrid() const
1699{
1700 if (!m_vtk_grid)
1701 ARCANE_FATAL("Polyhedral vtk grid not loaded. Cannot continue.");
1702}
1703
1704/*---------------------------------------------------------------------------*/
1705/*---------------------------------------------------------------------------*/
1706
1707} // End namespace Arcane
Fichier de configuration d'Arcane.
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Déclarations des types généraux de Arcane.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions utilitaires sur le maillage.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Gestion des références à une classe C++.
Generation de la classe de base du Service.
CaseOptionsVtkPolyhedralMeshIO * options() const
Options du jeu de données du service.
Informations nécessaires pour la lecture d'un fichier de maillage.
Interface d'une famille d'entités.
Interface d'un service de création/lecture du maillage.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual IVariableMng * variableMng() const =0
Gestionnaire de variable associé
virtual void broadcastMemoryBuffer(ByteArray &bytes, Int32 rank)=0
Effectue un broadcast d'une zone mémoire.
virtual bool isMasterIO() const =0
true si l'instance est un gestionnaire maître des entrées/sorties.
virtual Integer masterIORank() const =0
Rang de l'instance gérant les entrées/sorties (pour laquelle isMasterIO() est vrai)
virtual IMeshInitialAllocator * initialAllocator()
Allocateur initial spécifique.
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Charge un document XML.
Definition DomUtils.cc:426
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
Paramètres nécessaires à la construction d'un maillage.
Caractéristiques d'un maillage.
Definition MeshKind.h:59
Structure contenant les informations pour créer un service.
Paramètres nécessaires à la construction d'une variable.
Infos caractérisant une variable.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Remplit build_info avec les informations nécessaires pour créer le maillage.
void allocateMeshItems(IPrimaryMesh *pm) override
Alloue les entités du maillage géré par ce service.
Ref< IMeshBuilder > createBuilder(const CaseMeshReaderReadInfo &read_info) const override
Retourne un builder pour créer et lire le maillage dont les informations sont spécifiées dans read_in...
Liste de noeuds d'un arbre DOM.
Definition XmlNodeList.h:33
Noeud d'un arbre DOM.
Definition XmlNode.h:51
const value_type & const_reference
Type référence constante d'un élément du tableau.
Definition XmlNode.h:67
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Vue modifiable d'un tableau d'un type T.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void push_back(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
Vue d'un tableau d'éléments de type T.
Definition Span.h:510
Chaîne de caractères unicode.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
Vecteur 1D de données avec sémantique par valeur (style STL).
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
Integer len(const char *s)
Retourne la longueur de la chaîne s.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Span< Int32 > Int32Span
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:733
Span< Int64 > Int64Span
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:731
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:550
ArrayView< Real3 > Real3ArrayView
Equivalent C d'un tableau à une dimension de Real3.
Definition UtilsTypes.h:678
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:693
@ ST_CaseOption
Le service s'utilise au niveau du jeu de données.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:546
SharedArray< Int32 > Int32SharedArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:592
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:687
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:552
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_Edge
Entité de maillage de genre arête.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Definition UtilsTypes.h:570
Span< const Int32 > Int32ConstSpan
Vue en lecture seule d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:765
eDataType
Type d'une donnée.
Definition DataTypes.h:39
@ DT_Int32
Donnée de type entier 32 bits.
Definition DataTypes.h:43
@ DT_Int64
Donnée de type entier 64 bits.
Definition DataTypes.h:44
@ DT_Unknown
Donnée de type inconnue ou non initialisée.
Definition DataTypes.h:56
@ DT_Real
Donnée de type réel.
Definition DataTypes.h:41
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:691
ARCANE_DATATYPE_EXPORT eDataType dataTypeFromName(const char *name, bool &has_error)
Trouve le type associé à name.
Definition DataTypes.cc:92
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Definition DataTypes.cc:70
Int32 Integer
Type représentant un entier.