22#include <vtkUnstructuredGrid.h>
23#include <vtkUnstructuredGridReader.h>
25#include <vtkCellIterator.h>
26#include <vtkIdTypeArray.h>
27#include <vtkCellData.h>
28#include <vtkPointData.h>
29#include <vtkDataSetAttributes.h>
30#include <vtkArrayDispatch.h>
31#include <vtkDataArrayAccessor.h>
32#include <vtkPolyDataReader.h>
33#include <vtkPolyData.h>
34#include <vtkSmartPointer.h>
35#include <vtkCellArray.h>
38#include <arccore/base/String.h>
39#include <arccore/base/FatalErrorException.h>
40#include <vtkXMLUnstructuredGridReader.h>
41#include <vtkXMLPolyDataReader.h>
44#include "arcane/core/AbstractService.h"
45#include "arcane/core/ICaseMeshReader.h"
47#include "arcane/core/IMeshBuilder.h"
48#include "arcane/core/MeshBuildInfo.h"
49#include "arcane/core/IPrimaryMesh.h"
51#include "arcane/core/IMeshInitialAllocator.h"
52#include "arcane/core/IVariableMng.h"
54#include "arcane/utils/ITraceMng.h"
55#include "arcane/utils/UniqueArray.h"
56#include "arcane/utils/Real3.h"
57#include "arcane/mesh/CellFamily.h"
58#include "arcane/core/MeshVariableScalarRef.h"
59#include "arcane/core/MeshVariableArrayRef.h"
61#include "arcane/core/ItemAllocationInfo.h"
62#include "arcane/core/VariableBuildInfo.h"
64#include "arcane/utils/OStringStream.h"
66#include "arcane/core/IXmlDocumentHolder.h"
67#include "arcane/core/XmlNode.h"
68#include "arcane/core/internal/IVariableMngInternal.h"
69#include "arcane/core/datatype/DataTypeTraits.h"
71#include "arcane/std/VtkPolyhedralMeshIO_axl.h"
79namespace VtkPolyhedralTools
90 bool print_mesh_info =
false;
91 bool print_debug_info =
false;
95class VtkPolyhedralMeshIOService
102 , m_print_info_level(print_info_level)
112 VtkReader() =
default;
114 static String supportedVtkExtensions()
noexcept {
return "vtk,vtu";};
164 bool readHasFailed()
const noexcept {
return m_read_status.failure; }
167 vtkCellData* cellData();
168 vtkPointData* pointData();
169 vtkCellData* faceData();
171 bool isEmpty()
const noexcept {
return m_is_empty; }
172 bool doRead()
const noexcept {
return m_do_read; }
176 bool m_is_empty =
true;
177 bool m_do_read =
false;
181 vtkNew<vtkUnstructuredGridReader> m_vtk_grid_reader;
182 vtkNew<vtkXMLUnstructuredGridReader> m_vtk_xml_grid_reader;
183 vtkNew<vtkPolyDataReader> m_vtk_face_grid_reader;
184 vtkNew<vtkXMLPolyDataReader> m_vtk_xml_face_grid_reader;
185 vtkUnstructuredGrid* m_vtk_grid =
nullptr;
186 vtkPolyData* m_vtk_face_grid =
nullptr;
202 NodeUidToIndexMap m_node_uid_to_index;
204 vtkCellData* m_cell_data =
nullptr;
205 vtkPointData* m_point_data =
nullptr;
206 vtkCellData* m_face_data =
nullptr;
207 vtkCellArray* m_poly_data =
nullptr;
209 void _printMeshInfos()
const;
212 template <
typename Connectivity2DArray>
213 static void _flattenConnectivity(Connectivity2DArray connected_item_2darray,
Int32Span nb_connected_item_per_source_item,
Int64UniqueArray& connected_item_array);
214 void _readPlainTextVtkGrid(
const String& filename);
215 void _readXlmVtkGrid(
const String& filename);
216 void _checkVtkGrid()
const;
217 void _readPlainTextVtkFaceGrid(
const String& faces_filename);
218 void _readXmlVtkFaceGrid(
const String& faces_filename);
219 void _readfaceNodesInFaceMesh();
229 bool do_read = is_parallel_read ?
mesh->parallelMng()->isMasterIO() :
true;
230 using VtkReaderPtr = std::unique_ptr<VtkReader>;
231 VtkReaderPtr reader = std::make_unique<VtkReader>();
232 if (do_read) reader = std::make_unique<VtkReader>( filename, m_print_info_level );
233 if (reader->readHasFailed())
234 return reader->readStatus();
236 _fillItemAllocationInfo(item_allocation_info, *reader);
237 auto polyhedral_mesh_allocator =
mesh->initialAllocator()->polyhedralMeshAllocator();
238 polyhedral_mesh_allocator->allocateItems(item_allocation_info);
239 _readVariablesAndGroups(
mesh, *reader);
240 return reader->readStatus();
250 bool is_array =
false;
260 template <
template <
class>
class VariableRootType ,
template <
class>
class ArrayVariableRootType>
268class VtkPolyhedralCaseMeshReader
279 , m_read_info(read_info)
280 , m_print_info_level(print_info_level)
288 mk.setMeshStructure(eMeshStructure::Polyhedral);
295 m_trace_mng->info() <<
"---Create Polyhedral mesh: " << pm->
name() <<
"---";
296 m_trace_mng->info() <<
"--Read mesh file " << m_read_info.fileName();
298 auto read_status = polyhedral_vtk_service.read(pm, m_read_info.fileName(),m_read_info.isParallelRead());
299 if (read_status.failure)
301 m_trace_mng->info() << read_status.info_message;
320 if (VtkPolyhedralMeshIOService::VtkReader::supportedVtkExtensions().contains(read_info.format()))
330 ServiceProperty(
"VtkPolyhedralCaseMeshReader",
ST_CaseOption),
336void VtkPolyhedralMeshIOService::
337_fillItemAllocationInfo(ItemAllocationInfo& item_allocation_info, VtkReader& vtk_reader)
339 auto nb_item_family = 4;
340 auto nb_connected_family = 3;
341 item_allocation_info.family_infos.resize(nb_item_family);
342 for (
auto& family_info : item_allocation_info.family_infos) {
343 family_info.connected_family_info.resize(nb_connected_family);
346 auto& cell_family_info = item_allocation_info.family_infos[0];
347 cell_family_info.name =
"Cell";
348 cell_family_info.item_kind =
IK_Cell;
349 cell_family_info.item_uids = vtk_reader.cellUids();
350 auto& node_family_info = item_allocation_info.family_infos[1];
351 node_family_info.name =
"Node";
352 node_family_info.item_kind =
IK_Node;
353 node_family_info.item_uids = vtk_reader.nodeUids();
354 auto& face_family_info = item_allocation_info.family_infos[2];
355 face_family_info.name =
"Face";
356 face_family_info.item_kind =
IK_Face;
357 face_family_info.item_uids = vtk_reader.faceUids();
358 auto& edge_family_info = item_allocation_info.family_infos[3];
359 edge_family_info.name =
"Edge";
360 edge_family_info.item_kind =
IK_Edge;
361 edge_family_info.item_uids = vtk_reader.edgeUids();
363 auto cell_connected_family_index = 0;
364 auto& cell_connected_node_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
365 cell_connected_node_family_info.name = node_family_info.name;
366 cell_connected_node_family_info.item_kind = node_family_info.item_kind;
367 cell_connected_node_family_info.connectivity_name =
"CellToNodes";
368 cell_connected_node_family_info.nb_connected_items_per_item = vtk_reader.cellNbNodes();
369 cell_connected_node_family_info.connected_items_uids = vtk_reader.cellNodes();
371 auto& cell_connected_face_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
372 cell_connected_face_family_info.name = face_family_info.name;
373 cell_connected_face_family_info.item_kind = face_family_info.item_kind;
374 cell_connected_face_family_info.connectivity_name =
"CellToFaces";
375 cell_connected_face_family_info.nb_connected_items_per_item = vtk_reader.cellNbFaces();
376 cell_connected_face_family_info.connected_items_uids = vtk_reader.cellFaces();
378 auto& cell_connected_edge_family_info = cell_family_info.connected_family_info[cell_connected_family_index++];
379 cell_connected_edge_family_info.name = edge_family_info.name;
380 cell_connected_edge_family_info.item_kind = edge_family_info.item_kind;
381 cell_connected_edge_family_info.connectivity_name =
"CellToEdges";
382 cell_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.cellNbEdges();
383 cell_connected_edge_family_info.connected_items_uids = vtk_reader.cellEdges();
385 auto face_connected_family_index = 0;
386 auto& face_connected_cell_family_info = face_family_info.connected_family_info[face_connected_family_index++];
387 face_connected_cell_family_info.name = cell_family_info.name;
388 face_connected_cell_family_info.item_kind = cell_family_info.item_kind;
389 face_connected_cell_family_info.connectivity_name =
"FaceToCells";
390 face_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.faceNbCells();
391 face_connected_cell_family_info.connected_items_uids = vtk_reader.faceCells();
393 auto& face_connected_node_family_info = face_family_info.connected_family_info[face_connected_family_index++];
394 face_connected_node_family_info.name = node_family_info.name;
395 face_connected_node_family_info.item_kind = node_family_info.item_kind;
396 face_connected_node_family_info.connectivity_name =
"FaceToNodes";
397 face_connected_node_family_info.nb_connected_items_per_item = vtk_reader.faceNbNodes();
398 face_connected_node_family_info.connected_items_uids = vtk_reader.faceNodes();
400 auto& face_connected_edge_family_info = face_family_info.connected_family_info[face_connected_family_index];
401 face_connected_edge_family_info.name = edge_family_info.name;
402 face_connected_edge_family_info.item_kind = edge_family_info.item_kind;
403 face_connected_edge_family_info.connectivity_name =
"FaceToEdges";
404 face_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.faceNbEdges();
405 face_connected_edge_family_info.connected_items_uids = vtk_reader.faceEdges();
407 auto edge_connected_family_index = 0;
408 auto& edge_connected_cell_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
409 edge_connected_cell_family_info.name = cell_family_info.name;
410 edge_connected_cell_family_info.item_kind = cell_family_info.item_kind;
411 edge_connected_cell_family_info.connectivity_name =
"EdgeToCells";
412 edge_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.edgeNbCells();
413 edge_connected_cell_family_info.connected_items_uids = vtk_reader.edgeCells();
415 auto& edge_connected_face_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
416 edge_connected_face_family_info.name = face_family_info.name;
417 edge_connected_face_family_info.item_kind = face_family_info.item_kind;
418 edge_connected_face_family_info.connectivity_name =
"EdgeToFaces";
419 edge_connected_face_family_info.nb_connected_items_per_item = vtk_reader.edgeNbFaces();
420 edge_connected_face_family_info.connected_items_uids = vtk_reader.edgeFaces();
422 auto& edge_connected_node_family_info = edge_family_info.connected_family_info[edge_connected_family_index++];
423 edge_connected_node_family_info.name = node_family_info.name;
424 edge_connected_node_family_info.item_kind = node_family_info.item_kind;
425 edge_connected_node_family_info.connectivity_name =
"EdgeToNodes";
426 edge_connected_node_family_info.nb_connected_items_per_item = vtk_reader.edgeNbNodes();
427 edge_connected_node_family_info.connected_items_uids = vtk_reader.edgeNodes();
429 auto node_connected_family_index = 0;
430 auto& node_connected_cell_family_info = node_family_info.connected_family_info[node_connected_family_index++];
431 node_connected_cell_family_info.name = cell_family_info.name;
432 node_connected_cell_family_info.item_kind = cell_family_info.item_kind;
433 node_connected_cell_family_info.connectivity_name =
"NodeToCells";
434 node_connected_cell_family_info.nb_connected_items_per_item = vtk_reader.nodeNbCells();
435 node_connected_cell_family_info.connected_items_uids = vtk_reader.nodeCells();
437 auto& node_connected_face_family_info = node_family_info.connected_family_info[node_connected_family_index++];
438 node_connected_face_family_info.name = face_family_info.name;
439 node_connected_face_family_info.item_kind = face_family_info.item_kind;
440 node_connected_face_family_info.connectivity_name =
"NodeToFaces";
441 node_connected_face_family_info.nb_connected_items_per_item = vtk_reader.nodeNbFaces();
442 node_connected_face_family_info.connected_items_uids = vtk_reader.nodeFaces();
444 auto& node_connected_edge_family_info = node_family_info.connected_family_info[node_connected_family_index++];
445 node_connected_edge_family_info.name = edge_family_info.name;
446 node_connected_edge_family_info.item_kind = edge_family_info.item_kind;
447 node_connected_edge_family_info.connectivity_name =
"NodeToEdges";
448 node_connected_edge_family_info.nb_connected_items_per_item = vtk_reader.nodeNbEdges();
449 node_connected_edge_family_info.connected_items_uids = vtk_reader.nodeEdges();
451 node_family_info.item_coordinates_variable_name =
"NodeCoord";
452 node_family_info.item_coordinates = vtk_reader.nodeCoords();
458void VtkPolyhedralMeshIOService::
462 OStringStream created_infos_str;
463 created_infos_str() <<
"<?xml version='1.0' ?>\n";
464 created_infos_str() <<
"<infos>";
466 if (
auto* cell_data = reader.cellData(); cell_data) {
469 std::iota(vtk_to_arcane_lids.begin(), vtk_to_arcane_lids.end(), 0);
471 for (
auto array_index = 0; array_index < cell_data->GetNumberOfArrays(); ++array_index) {
472 auto* cell_array = cell_data->GetArray(array_index);
475 if (String name = cell_array->GetName(); name.substring(0, 6) ==
"GROUP_") {
476 _createGroup(cell_array, name.substring(6), mesh, mesh->cellFamily(), vtk_to_arcane_lids.constSpan());
477 created_infos_str() <<
"<cell-group name='" << name.substring(6) <<
"'/>";
480 auto var_info = _createVariable(cell_array, name, mesh, mesh->cellFamily(), arcane_to_vtk_lids);
481 created_infos_str() <<
"<cell-variable name='" << name <<
"' "
482 <<
" data-type='" <<
dataTypeName(var_info.m_type) <<
"' "
483 <<
" is_array='" << std::boolalpha << var_info.is_array <<
"'/>";
485 if (m_print_info_level.print_debug_info) {
487 for (
auto tuple_index = 0; tuple_index < cell_array->GetNumberOfTuples(); ++tuple_index) {
488 for (
auto component_index = 0; component_index < cell_array->GetNumberOfComponents(); ++component_index) {
489 debug(
Trace::High) << cell_array->GetName() <<
"[" << tuple_index <<
"][" << component_index <<
"] = " << cell_array->GetComponent(tuple_index, component_index);
496 if (
auto* point_data = reader.pointData(); point_data) {
499 std::iota(vtk_to_arcane_lids.begin(), vtk_to_arcane_lids.end(), 0);
501 for (
auto array_index = 0; array_index < point_data->GetNumberOfArrays(); ++array_index) {
502 auto* point_array = point_data->GetArray(array_index);
503 if (String name = point_array->GetName(); name.substring(0, 6) ==
"GROUP_") {
504 _createGroup(point_array, name.substring(6), mesh, mesh->nodeFamily(), vtk_to_arcane_lids.constSpan());
505 created_infos_str() <<
"<node-group name='" << name.substring(6) <<
"'/>";
508 auto var_info = _createVariable(point_array, name, mesh, mesh->nodeFamily(), arcane_to_vtk_lids);
509 created_infos_str() <<
"<node-variable name='" << name <<
"' "
510 <<
" data-type='" <<
dataTypeName(var_info.m_type) <<
"' "
511 <<
" is_array='" << std::boolalpha << var_info.is_array <<
"'/>";
513 if (m_print_info_level.print_debug_info) {
515 for (
auto tuple_index = 0; tuple_index < point_array->GetNumberOfTuples(); ++tuple_index) {
516 for (
auto component_index = 0; component_index < point_array->GetNumberOfComponents(); ++component_index) {
517 debug(
Trace::High) << point_array->GetName() <<
"[" << tuple_index <<
"][" << component_index <<
"] = " << point_array->GetComponent(tuple_index, component_index);
524 if (
auto* face_data = reader.faceData(); face_data) {
528 _computeFaceVtkArcaneLidConversion(vtk_to_Arcane_lids, arcane_to_vtk_lids, reader, mesh);
529 for (
auto array_index = 0; array_index < face_data->GetNumberOfArrays(); ++array_index) {
530 auto* face_array = face_data->GetArray(array_index);
531 if (String name = face_array->GetName(); name.substring(0, 6) ==
"GROUP_") {
532 _createGroup(face_array, name.substring(6), mesh, mesh->faceFamily(), vtk_to_Arcane_lids);
533 created_infos_str() <<
"<face-group name='" << name <<
"'/>";
536 auto var_info = _createVariable(face_array, name, mesh, mesh->faceFamily(), arcane_to_vtk_lids);
537 created_infos_str() <<
"<face-variable name='" << name <<
"' "
538 <<
" data-type='" <<
dataTypeName(var_info.m_type) <<
"' "
539 <<
" is_array='" << std::boolalpha << var_info.is_array <<
"'/>";
541 if (m_print_info_level.print_debug_info) {
543 for (
auto tuple_index = 0; tuple_index < face_array->GetNumberOfTuples(); ++tuple_index) {
544 for (
auto component_index = 0; component_index < face_array->GetNumberOfComponents(); ++component_index) {
545 debug(
Trace::High) << face_array->GetName() <<
"[" << tuple_index <<
"][" << component_index <<
"] = " << face_array->GetComponent(tuple_index, component_index);
551 created_infos_str() <<
"</infos>";
554 auto* pm = mesh->parallelMng();
555 if (!reader.isEmpty() && pm->isMasterIO()) {
556 String str = created_infos_str.str();
559 bytes.resize(len + 1);
562 pm->broadcastMemoryBuffer(bytes, pm->masterIORank());
563 if (reader.isEmpty()) {
565 XmlNode doc_node = doc->documentNode();
566 _createEmptyVariablesAndGroups(mesh,doc_node);
574void VtkPolyhedralMeshIOService::
580 if (group_items->GetNumberOfComponents() != 1)
581 fatal() << String::format(
"Cannot create item group {0}. Group information in data property must be a scalar", group_name);
582 debug() <<
"Create group " << group_name;
584 arcane_lids.
reserve((
int)group_items->GetNumberOfValues());
585 using GroupDispatcher = vtkArrayDispatch::DispatchByValueType<vtkArrayDispatch::Integrals>;
586 auto group_creator = [&arcane_lids, &vtkToArcaneLid](
auto* array) {
587 vtkIdType numTuples = array->GetNumberOfTuples();
588 vtkDataArrayAccessor<std::remove_pointer_t<
decltype(array)>> array_accessor{ array };
590 for (vtkIdType tupleIdx = 0; tupleIdx < numTuples; ++tupleIdx) {
591 auto value = array_accessor.Get(tupleIdx, 0);
593 arcane_lids.push_back(vtkToArcaneLid[local_id]);
597 if (!GroupDispatcher::Execute(group_items, group_creator))
598 ARCANE_FATAL(
"Cannot create item group {0}. Group information in data property must be an integral type", group_name);
599 debug() <<
" local ids for item group " << group_name <<
" " << arcane_lids;
600 item_family->createGroup(group_name, arcane_lids);
606template <
typename vtkType>
609 using type = vtkType;
624template <
typename T>
using to_arcane_type_t =
typename ToArcaneType<T>::type;
633 if (item_values->GetNumberOfTuples() != item_family->
nbItem())
634 ARCANE_FATAL(
"Cannot create variable {0}, {1} values are given for {2} items in {3} family",
635 variable_name, item_values->GetNumberOfTuples(), item_family->
nbItem(), item_family->
name());
636 debug() <<
"Create mesh variable " << variable_name;
638 auto variable_creator = [
mesh, variable_name, item_family, arcane_to_vtk_lids,
this, &var_info](
auto* values) {
640 using ValueType =
typename std::remove_pointer_t<
decltype(values)>::ValueType;
641 auto* var =
new ItemVariableScalarRefT<to_arcane_type_t<ValueType>>{ vbi, item_family->itemKind() };
643 vtkDataArrayAccessor<std::remove_pointer_t<
decltype(values)>> values_accessor{ values };
645 (*var)[item] = (to_arcane_type_t<ValueType>)values_accessor.Get(arcane_to_vtk_lids[item.localId()], 0);
647 var_info.m_type = DataTypeTraitsT<to_arcane_type_t<ValueType>>::type();
648 var_info.is_array =
false;
650 auto array_variable_creator = [mesh, variable_name, item_family, arcane_to_vtk_lids,
this, &var_info](
auto* values) {
651 VariableBuildInfo vbi{ mesh, variable_name };
652 using ValueType =
typename std::remove_pointer_t<
decltype(values)>::ValueType;
653 auto* var =
new ItemVariableArrayRefT<to_arcane_type_t<ValueType>>{ vbi, item_family->itemKind() };
655 vtkDataArrayAccessor<std::remove_pointer_t<
decltype(values)>> values_accessor{ values };
656 var->resize(values->GetNumberOfComponents());
659 for (
auto& var_value : (*var)[item]) {
660 var_value = (to_arcane_type_t<ValueType>)values_accessor.Get(arcane_to_vtk_lids[item.localId()], index++);
663 var_info.m_type = DataTypeTraitsT<to_arcane_type_t<ValueType>>::type();
664 var_info.is_array =
true;
667 using ValueTypes = vtkTypeList_Create_6(
double,
float,
int,
long,
long long,
short);
668 using ArrayDispatcher = vtkArrayDispatch::DispatchByValueType<ValueTypes>;
670 bool is_variable_created =
false;
671 if (item_values->GetNumberOfComponents() == 1) {
672 is_variable_created = ArrayDispatcher::Execute(item_values, variable_creator);
676 is_variable_created = ArrayDispatcher::Execute(item_values, array_variable_creator);
678 if (!is_variable_created)
679 ARCANE_FATAL(
"Cannot create variable {0}, it's data type is not supported. Only real and integral types are supported", variable_name);
686void VtkPolyhedralMeshIOService::
689 auto face_nodes_unique_ids = reader.faceNodesInFaceMesh();
690 auto face_nb_nodes = reader.faceNbNodesInFaceMesh();
691 auto current_face_index = 0;
692 auto current_face_index_in_face_nodes = 0;
694 mesh->nodeFamily()->itemsUniqueIdToLocalId(face_nodes_local_ids, face_nodes_unique_ids);
695 for (
auto current_face_nb_node : face_nb_nodes) {
696 auto current_face_nodes = face_nodes_local_ids.subConstView(current_face_index_in_face_nodes, current_face_nb_node);
697 current_face_index_in_face_nodes += current_face_nb_node;
698 Node face_first_node{ mesh->nodeFamily()->view()[current_face_nodes[0]] };
699 face_vtk_to_arcane_lids[current_face_index] = MeshUtils::getFaceFromNodesLocalId(face_first_node, current_face_nodes).localId();
700 ++current_face_index;
703 for (
auto arcane_lid : face_vtk_to_arcane_lids) {
704 arcane_to_vtk_lids[arcane_lid] = vtk_lid;
712template <
template <
class>
class VariableRootType>
715 bool has_error =
false;
718 ARCANE_FATAL(
"Invalid data type name {0} for Variable creation in VtkPolyhedralMeshIOService");
720 switch (var_data_type){
731 ARCANE_FATAL(
"Handle only DT_Int32, DT_Int64, DT_Real in VtkPolyhedralMeshIOService");
738template <
template <
class>
class VariableRootType ,
template <
class>
class ArrayVariableRootType>
739void VtkPolyhedralMeshIOService::
742 ARCANE_CHECK_PTR(mesh);
744 for (XmlNode xnode : item_variables_node) {
745 String name = xnode.attrValue(
"name");
746 debug() <<
"Create mesh variable: " << name;
747 String data_type_name = xnode.attrValue(
"data-type");
748 bool is_array = xnode.attrValue(
"is_array") ==
"true";
749 VariableRef* var =
nullptr;
751 var = _createVar<ArrayVariableRootType>(mesh,name,data_type_name,item_kind);
754 var = _createVar<VariableRootType>(mesh,name, data_type_name,item_kind);
756 mesh->variableMng()->_internalApi()->addAutoDestroyVariable(var);
764void VtkPolyhedralMeshIOService::
767 for (XmlNode xnode : groups_node) {
768 String name = xnode.attrValue(
"name");
769 info() <<
"Building group: " << name;
770 item_family->createGroup(name);
779void VtkPolyhedralMeshIOService::
782 ARCANE_CHECK_PTR(mesh);
783 auto document_node = variable_and_group_info.documentElement();
784 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children(
"cell-variable"),
IK_Cell);
785 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children(
"node-variable"),
IK_Node);
786 _createEmptyVariables<ItemVariableScalarRefT,ItemVariableArrayRefT>(mesh, document_node.children(
"face-variable"),
IK_Face);
788 _createEmptyGroups(mesh, document_node.children(
"cell-group"), mesh->itemFamily(
IK_Cell));
789 _createEmptyGroups(mesh, document_node.children(
"node-group"), mesh->itemFamily(
IK_Node));
790 _createEmptyGroups(mesh, document_node.children(
"face-group"), mesh->itemFamily(
IK_Face));
796VtkPolyhedralMeshIOService::VtkReader::
798: m_filename{ filename }
799, m_print_info_level{ print_info_level }
803 if (filename.empty()) {
804 m_read_status.failure =
true;
805 m_read_status.failure_message =
"filename for polyhedral vtk mesh is empty.";
808 if (filename.endsWith(
"vtk"))
809 _readPlainTextVtkGrid(filename);
810 else if (filename.endsWith(
"vtu"))
811 _readXlmVtkGrid(filename);
813 m_read_status.failure =
true;
814 m_read_status.failure_message = String::format(
"Unsupported vtk extension for file {0}. Supported vtk extension for Polyhedral meshes are {1}",
815 filename,VtkReader::supportedVtkExtensions());
819 m_read_status.failure =
true;
820 m_read_status.failure_message = String::format(
"Cannot read vtk polyhedral file {0}. Vtk grid was not created.", filename);
823 if (m_vtk_grid->GetNumberOfCells() == 0) {
824 m_read_status.failure =
true;
825 m_read_status.failure_message = String::format(
"Cannot read vtk polyhedral file {0}. No cells were found.", filename);
828 if (!m_vtk_grid->GetFaces()) {
829 m_read_status.failure =
true;
830 m_read_status.failure_message = String::format(
"The given mesh vtk file {0} is not a polyhedral mesh, cannot read it", filename);
834 m_cell_data = m_vtk_grid->GetCellData();
835 m_point_data = m_vtk_grid->GetPointData();
838 String faces_filename = m_filename +
"faces.vtk";
839 std::ifstream ifile(faces_filename.localstr());
841 _readPlainTextVtkFaceGrid(faces_filename);
844 faces_filename = m_filename +
"faces.vtp";
845 ifile = std::ifstream{ faces_filename.localstr() };
847 _readXmlVtkFaceGrid(faces_filename);
852 faces_filename.split(faces_filename_and_extension,
'.');
855 m_read_status.info_message = String::format(
"Information no face mesh given {0}{1} (.vtk or .vtp) to define face variables or groups on faces.",
856 faces_filename_and_extension[0],
857 faces_filename_and_extension[1]);
860 if (m_vtk_face_grid) {
861 if (m_vtk_face_grid->GetNumberOfCells() == 0) {
862 m_read_status.failure =
true;
863 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);
866 m_face_data = m_vtk_face_grid->GetCellData();
867 m_poly_data = m_vtk_face_grid->GetPolys();
871 m_read_status.failure =
true;
872 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).",
873 faces_filename_and_extension[0],
874 faces_filename_and_extension[1]);
878 if (m_print_info_level.print_mesh_info)
888 if (!doRead())
return m_cell_uids;
889 if (m_cell_uids.empty()) {
891 m_cell_uids.reserve(m_vtk_grid->GetNumberOfCells());
892 m_cell_nb_nodes.reserve(m_vtk_grid->GetNumberOfCells());
893 m_cell_node_uids.reserve(10 * m_vtk_grid->GetNumberOfCells());
894 auto* cell_iter = m_vtk_grid->NewCellIterator();
895 cell_iter->InitTraversal();
896 while (!cell_iter->IsDoneWithTraversal()) {
897 m_cell_uids.push_back(cell_iter->GetCellId());
898 m_cell_nb_nodes.push_back(
Integer(cell_iter->GetNumberOfPoints()));
899 ArrayView<vtkIdType> cell_nodes{
Integer(cell_iter->GetNumberOfPoints()), cell_iter->GetPointIds()->GetPointer(0) };
900 std::for_each(cell_nodes.begin(), cell_nodes.end(), [
this](
auto uid) { this->m_cell_node_uids.push_back(uid); });
901 cell_iter->GoToNextCell();
913 if (!doRead())
return m_node_uids;
914 if (m_node_uids.empty()) {
916 auto nb_nodes = m_vtk_grid->GetNumberOfPoints();
917 m_node_uids.resize(nb_nodes);
918 m_node_nb_cells.resize(nb_nodes);
919 m_node_cell_uids.reserve(8 * nb_nodes);
920 m_node_uid_to_index.resize(nb_nodes);
921 for (
int node_index = 0; node_index < nb_nodes; ++node_index) {
922 Int64 node_uid = node_index;
923 m_node_uids[node_index] = node_uid;
924 auto cell_nodes = vtkIdList::New();
925 m_vtk_grid->GetPointCells(node_index, cell_nodes);
926 Int64Span cell_nodes_view((
Int64*)cell_nodes->GetPointer(0), cell_nodes->GetNumberOfIds());
927 m_node_cell_uids.addRange(cell_nodes_view);
928 m_node_nb_cells[node_index] = (
Int32)cell_nodes->GetNumberOfIds();
931 m_node_uid_to_index[node_uid] = node_index;
946 if (!doRead())
return m_face_uids;
947 if (!m_face_uids.empty())
950 auto* cell_iter = m_vtk_grid->NewCellIterator();
951 cell_iter->InitTraversal();
952 vtkIdType nb_face_estimation = 0;
953 while (!cell_iter->IsDoneWithTraversal()) {
954 vtkIdType cell_nb_faces = 0;
955 vtkIdType* points{
nullptr };
956 m_vtk_grid->GetFaceStream(cell_iter->GetCellId(), cell_nb_faces, points);
957 nb_face_estimation += cell_nb_faces;
958 cell_iter->GoToNextCell();
960 m_face_uids.reserve(nb_face_estimation);
961 auto const* faces = m_vtk_grid->GetFaces();
966 ARCANE_FATAL(
"Mesh {0} is not polyhedral: faces are not defined", m_filename);
969 auto face_info_size = faces->GetNumberOfValues();
970 m_face_node_uids.reserve(face_info_size);
971 m_face_nb_nodes.reserve(nb_face_estimation);
972 m_face_cell_uids.reserve(2 * nb_face_estimation);
973 m_face_nb_cells.reserve(nb_face_estimation);
974 m_cell_face_uids.reserve(8 * m_cell_uids.size());
975 m_cell_nb_faces.resize(m_cell_uids.size(), 0);
976 m_cell_face_indexes.resize(m_cell_uids.size(), -1);
977 m_face_uid_indexes.resize(2 * nb_face_estimation, -1);
979 current_face_nodes.
reserve(10);
980 sorted_current_face_nodes.reserve(10);
981 UniqueArray<UniqueArray<Int64>> node_faces(m_node_uids.size());
982 UniqueArray<Int32> face_offsets;
983 face_offsets.reserve(nb_face_estimation);
984 face_offsets.push_back(0);
985 FaceUidToIndexMap face_uid_to_index;
986 face_uid_to_index.reserve(nb_face_estimation);
988 auto cell_face_index = 0;
989 auto global_face_index = 0;
990 auto face_uid_index = 0;
991 for (
int face_info_index = 0; face_info_index < face_info_size; cell_index++) {
992 auto current_cell_nb_faces =
Int32(faces->GetValue(face_info_index++));
993 m_cell_face_indexes[m_cell_uids[cell_index]] = cell_face_index;
994 for (
auto face_index = 0; face_index < current_cell_nb_faces; ++face_index, ++global_face_index) {
995 auto current_face_nb_nodes =
Int32(faces->GetValue(face_info_index++));
996 m_cell_nb_faces[m_cell_uids[cell_index]] += 1;
997 for (
int node_index = 0; node_index < current_face_nb_nodes; ++node_index) {
998 current_face_nodes.push_back(faces->GetValue(face_info_index++));
1000 sorted_current_face_nodes.resize(current_face_nodes.size());
1001 auto is_front_cell = mesh_utils::reorderNodesOfFace(current_face_nodes, sorted_current_face_nodes);
1002 auto [is_face_found, existing_face_index] = _findFace(sorted_current_face_nodes, node_faces,
1003 m_node_uid_to_index, m_face_nb_nodes,
1004 face_uid_to_index, face_offsets, m_face_node_uids);
1005 if (!is_face_found) {
1006 for (
auto node_uid : current_face_nodes) {
1007 node_faces[m_node_uid_to_index[node_uid]].push_back(face_uid);
1009 m_cell_face_uids.push_back(face_uid);
1010 m_face_uids.push_back(face_uid);
1011 m_face_nb_nodes.push_back(current_face_nb_nodes);
1012 m_face_node_uids.addRange(sorted_current_face_nodes);
1013 m_face_nb_cells.push_back(1);
1014 m_face_uid_indexes[global_face_index] = face_uid_index;
1015 face_uid_to_index.push_back(face_uid_index);
1016 auto previous_offset = face_offsets.back();
1017 face_offsets.push_back(previous_offset + sorted_current_face_nodes.size());
1020 if (is_front_cell) {
1021 m_face_cell_uids.push_back(NULL_ITEM_UNIQUE_ID);
1022 m_face_cell_uids.push_back(m_cell_uids[cell_index]);
1025 m_face_cell_uids.push_back(m_cell_uids[cell_index]);
1026 m_face_cell_uids.push_back(NULL_ITEM_UNIQUE_ID);
1030 m_cell_face_uids.push_back(m_face_uids[existing_face_index]);
1031 m_face_nb_cells[existing_face_index] += 1;
1032 m_face_uid_indexes[global_face_index] = existing_face_index;
1034 if (is_front_cell) {
1035 if (m_face_cell_uids[2 * existing_face_index + 1] != NULL_ITEM_UNIQUE_ID) {
1036 ARCANE_FATAL(
"Problem in face orientation, face uid {0}, nodes {1}, same orientation in cell {2} and {3}. Change mesh file.",
1037 m_face_uids[existing_face_index],
1039 m_face_cell_uids[2 * existing_face_index + 1],
1040 m_cell_uids[cell_index]);
1042 m_face_cell_uids[2 * existing_face_index + 1] = m_cell_uids[cell_index];
1045 if (m_face_cell_uids[2 * existing_face_index] != NULL_ITEM_UNIQUE_ID) {
1046 ARCANE_FATAL(
"Problem in face orientation, face uid {0}, nodes {1}, same orientation in cell {2} and {3}. Change mesh file.",
1047 m_face_uids[existing_face_index],
1049 m_face_cell_uids[2 * existing_face_index],
1050 m_cell_uids[cell_index]);
1052 m_face_cell_uids[2 * existing_face_index] = m_cell_uids[cell_index];
1055 current_face_nodes.clear();
1056 sorted_current_face_nodes.clear();
1058 cell_face_index += m_cell_nb_faces[m_cell_uids[cell_index]];
1061 m_node_nb_faces.resize(m_node_uids.size(), 0);
1062 _flattenConnectivity(node_faces.constSpan(), m_node_nb_faces, m_node_face_uids);
1064 if (m_print_info_level.print_debug_info) {
1065 std::cout <<
"================FACE NODES ==============" << std::endl;
1066 std::copy(m_face_node_uids.begin(), m_face_node_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1067 std::cout << std::endl;
1068 std::copy(m_face_nb_nodes.begin(), m_face_nb_nodes.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1069 std::cout << std::endl;
1070 std::copy(m_cell_face_indexes.begin(), m_cell_face_indexes.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1071 std::cout << std::endl;
1083 if (!doRead())
return m_edge_uids;
1084 if (!m_edge_uids.empty())
1090 m_edge_uids.reserve(2 * m_vtk_grid->GetNumberOfPoints());
1091 auto const* faces = m_vtk_grid->GetFaces();
1096 ARCANE_FATAL(
"Mesh {0} is not polyhedral: faces are not defined", m_filename);
1099 auto nb_edge_estimation = 2 * m_edge_uids.capacity();
1100 m_edge_node_uids.reserve(nb_edge_estimation);
1101 auto face_info_size = faces->GetNumberOfValues();
1102 auto cell_index = 0;
1103 auto global_face_index = 0;
1104 auto new_edge_index = 0;
1105 UniqueArray<std::set<Int64>> edge_cells;
1106 UniqueArray<Int64UniqueArray> edge_faces;
1107 edge_cells.reserve(m_edge_uids.capacity());
1108 edge_faces.reserve(m_edge_uids.capacity());
1109 m_cell_nb_edges.resize(m_cell_uids.size(), 0);
1110 m_cell_edge_uids.reserve(20 * m_cell_uids.size());
1111 UniqueArray<std::set<Int64>> face_edges;
1112 face_edges.resize(m_face_uids.size());
1113 UniqueArray<std::set<Int64>> cell_edges;
1114 cell_edges.resize(m_cell_uids.size());
1115 UniqueArray<Int64UniqueArray> node_edges;
1116 node_edges.resize(m_node_uids.size());
1117 EdgeUidToIndexMap edge_uid_to_index;
1118 edge_uid_to_index.reserve(nb_edge_estimation);
1120 edge_offsets.
reserve(nb_edge_estimation);
1121 edge_offsets.push_back(0);
1122 m_edge_nb_nodes.reserve(nb_edge_estimation);
1123 for (
int face_info_index = 0; face_info_index < face_info_size; ++cell_index) {
1124 auto current_cell_nb_faces =
Int32(faces->GetValue(face_info_index++));
1125 for (
auto face_index = 0; face_index < current_cell_nb_faces; ++face_index, ++global_face_index) {
1126 auto current_face_nb_nodes =
Int32(faces->GetValue(face_info_index++));
1127 auto first_face_node_uid =
Int32(faces->GetValue(face_info_index));
1128 UniqueArray<Int64> current_edge(2), sorted_edge(2);
1129 for (
int node_index = 0; node_index < current_face_nb_nodes - 1; ++node_index) {
1130 current_edge = UniqueArray<Int64>{ faces->GetValue(face_info_index++), faces->GetValue(face_info_index) };
1131 mesh_utils::reorderNodesOfFace(current_edge, sorted_edge);
1132 auto [is_edge_found, existing_edge_index] = _findFace(sorted_edge, node_edges,
1133 m_node_uid_to_index,
1135 edge_uid_to_index, edge_offsets, m_edge_node_uids);
1136 if (!is_edge_found) {
1137 m_cell_nb_edges[cell_index] += 1;
1138 face_edges[m_face_uid_indexes[global_face_index]].insert(edge_uid);
1139 cell_edges[cell_index].insert(edge_uid);
1140 for (
auto node : current_edge) {
1141 node_edges[node].push_back(edge_uid);
1143 edge_cells.push_back(std::set{ m_cell_uids[cell_index] });
1144 edge_faces.push_back(
Int64UniqueArray{ m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index] });
1145 m_edge_uids.push_back(edge_uid++);
1146 m_edge_node_uids.addRange(sorted_edge);
1147 edge_uid_to_index.push_back(new_edge_index);
1148 auto current_offset = edge_offsets.back();
1149 edge_offsets.push_back(current_offset + 2);
1150 m_edge_nb_nodes.push_back(2);
1154 edge_cells[existing_edge_index].insert(m_cell_uids[cell_index]);
1155 edge_faces[existing_edge_index].push_back(m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index]);
1156 face_edges[m_face_uid_indexes[global_face_index]].insert(m_edge_uids[existing_edge_index]);
1157 cell_edges[cell_index].insert(m_edge_uids[existing_edge_index]);
1160 current_edge = UniqueArray<Int64>{ faces->GetValue(face_info_index++), first_face_node_uid };
1161 mesh_utils::reorderNodesOfFace(current_edge, sorted_edge);
1162 auto [is_edge_found, existing_edge_index] = _findFace(sorted_edge, node_edges,
1163 m_node_uid_to_index,
1165 edge_uid_to_index, edge_offsets, m_edge_node_uids);
1166 if (!is_edge_found) {
1167 m_cell_nb_edges[cell_index] += 1;
1168 edge_cells.push_back(std::set{ m_cell_uids[cell_index] });
1169 edge_faces.push_back(
Int64UniqueArray{ m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index] });
1170 face_edges[m_face_uid_indexes[global_face_index]].insert(edge_uid);
1171 cell_edges[cell_index].insert(edge_uid);
1172 for (
auto node : current_edge) {
1173 node_edges[node].push_back(edge_uid);
1175 m_edge_uids.push_back(edge_uid++);
1176 m_edge_node_uids.addRange(sorted_edge);
1177 edge_uid_to_index.push_back(new_edge_index);
1178 auto current_offset = edge_offsets.back();
1179 edge_offsets.push_back(current_offset + 2);
1180 m_edge_nb_nodes.push_back(2);
1184 edge_cells[existing_edge_index].insert(m_cell_uids[cell_index]);
1185 edge_faces[existing_edge_index].push_back(m_cell_face_uids[m_cell_face_indexes[cell_index] + face_index]);
1186 face_edges[m_face_uid_indexes[global_face_index]].insert(m_edge_uids[existing_edge_index]);
1187 cell_edges[cell_index].insert(m_edge_uids[existing_edge_index]);
1192 m_edge_nb_cells.resize(m_edge_uids.size(), 0);
1193 _flattenConnectivity(edge_cells.constSpan(), m_edge_nb_cells, m_edge_cell_uids);
1196 m_edge_nb_faces.resize(m_edge_uids.size(), 0);
1197 _flattenConnectivity(edge_faces.constSpan(), m_edge_nb_faces, m_edge_face_uids);
1200 m_face_nb_edges.resize(m_face_uids.size(), 0);
1201 _flattenConnectivity(face_edges.constSpan(), m_face_nb_edges, m_face_edge_uids);
1204 m_cell_nb_edges.resize(m_cell_uids.size(), 0);
1205 _flattenConnectivity(cell_edges, m_cell_nb_edges, m_cell_edge_uids);
1208 m_node_nb_edges.resize(m_node_uids.size(), 0);
1209 _flattenConnectivity(node_edges, m_node_nb_edges, m_node_edge_uids);
1211 if (m_print_info_level.print_debug_info) {
1212 std::cout <<
"================EDGE NODES ==============" << std::endl;
1213 std::copy(m_edge_node_uids.begin(), m_edge_node_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1214 std::cout << std::endl;
1215 std::cout <<
"================FACE EDGES ==============" << std::endl;
1216 std::copy(m_face_nb_edges.begin(), m_face_nb_edges.end(), std::ostream_iterator<Int32>(std::cout,
" "));
1217 std::cout << std::endl;
1218 std::copy(m_face_edge_uids.begin(), m_face_edge_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1219 std::cout << std::endl;
1220 std::cout <<
"================CELL EDGES ==============" << std::endl;
1221 std::copy(m_cell_nb_edges.begin(), m_cell_nb_edges.end(), std::ostream_iterator<Int32>(std::cout,
" "));
1222 std::cout << std::endl;
1223 std::copy(m_cell_edge_uids.begin(), m_cell_edge_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1224 std::cout << std::endl;
1232std::pair<bool, Int32> VtkPolyhedralMeshIOService::VtkReader::
1234 const UniqueArray<Int64UniqueArray>& node_face_uids,
1235 const NodeUidToIndexMap& node_uid_to_index,
1237 const FaceUidToIndexMap& face_uid_to_index,
1238 const UniqueArray<Int32>& face_offsets,
1241 auto first_node_uid = sorted_face_nodes[0];
1242 auto first_node_index = node_uid_to_index[first_node_uid];
1244 for (
auto face_uid : node_face_uids[first_node_index]) {
1245 auto face_index = face_uid_to_index[face_uid];
1246 auto face_offset = face_offsets[face_index];
1247 auto face_nb_node = face_nb_nodes[face_index];
1248 if (face_nb_node == sorted_face_nodes.size()) {
1249 bool is_same_face =
true;
1250 for (
auto index = 0; index < face_nb_node; ++index) {
1251 if (sorted_face_nodes[index] != face_node_uids[face_offset + index]) {
1252 is_same_face =
false;
1256 return {
true, face_index };
1259 return {
false, -1 };
1265Integer VtkPolyhedralMeshIOService::VtkReader::
1268 if (m_node_uids.empty())
1270 return m_node_uids.size();
1279 if (m_cell_node_uids.empty())
1281 return m_cell_node_uids;
1290 if (m_cell_nb_nodes.empty())
1292 return m_cell_nb_nodes;
1301 if (m_face_node_uids.empty())
1303 return m_face_node_uids;
1312 if (m_face_nb_nodes.empty())
1314 return m_face_nb_nodes;
1321faceNodesInFaceMesh()
1323 if (m_face_node_uids_in_face_mesh.empty())
1324 _readfaceNodesInFaceMesh();
1325 return m_face_node_uids_in_face_mesh;
1332faceNbNodesInFaceMesh()
1334 if (m_face_nb_nodes_in_face_mesh.empty())
1335 _readfaceNodesInFaceMesh();
1336 return m_face_nb_nodes_in_face_mesh;
1345 if (m_edge_node_uids.empty())
1347 return m_edge_nb_nodes;
1356 if (m_edge_node_uids.empty())
1358 return m_edge_node_uids;
1367 if (m_face_cell_uids.empty())
1370 if (m_print_info_level.print_debug_info) {
1371 std::cout <<
"=================FACE CELLS================="
1373 std::copy(m_face_cell_uids.begin(), m_face_cell_uids.end(), std::ostream_iterator<Int64>(std::cout,
" "));
1375 std::cout <<
"=================END FACE CELLS================="
1378 return m_face_cell_uids;
1387 if (m_face_nb_cells.empty())
1389 return m_face_nb_cells;
1398 if (m_edge_nb_cells.empty())
1400 return m_edge_nb_cells;
1409 if (m_edge_cell_uids.empty())
1411 return m_edge_cell_uids;
1420 if (m_cell_nb_faces.empty())
1422 return m_cell_nb_faces;
1431 if (m_cell_face_uids.empty())
1433 return m_cell_face_uids;
1442 if (m_edge_nb_faces.empty())
1444 return m_edge_nb_faces;
1453 if (m_edge_face_uids.empty())
1455 return m_edge_face_uids;
1464 if (m_cell_nb_edges.empty())
1466 return m_cell_nb_edges;
1475 if (m_cell_edge_uids.empty())
1477 return m_cell_edge_uids;
1486 if (m_face_nb_edges.empty())
1488 return m_face_nb_edges;
1497 if (m_face_edge_uids.empty())
1499 return m_face_edge_uids;
1505template <
typename Connectivity2DArray>
1506void VtkPolyhedralMeshIOService::VtkReader::
1507_flattenConnectivity(Connectivity2DArray connected_item_2darray,
1508 Int32Span nb_connected_item_per_source_item,
1512 std::transform(connected_item_2darray.begin(), connected_item_2darray.end(), nb_connected_item_per_source_item.begin(), [](
auto const& connected_items) {
1513 return connected_items.size();
1516 connected_item_array.reserve(std::accumulate(nb_connected_item_per_source_item.begin(), nb_connected_item_per_source_item.end(), 0));
1517 std::for_each(connected_item_2darray.begin(), connected_item_2darray.end(), [&connected_item_array](
auto const& connected_items) {
1518 for (auto const& connected_item : connected_items) {
1519 connected_item_array.push_back(connected_item);
1530 if (m_node_nb_cells.empty())
1532 return m_node_nb_cells;
1541 if (m_node_cell_uids.empty())
1543 return m_node_cell_uids;
1552 if (m_node_nb_faces.empty())
1554 return m_node_nb_faces;
1563 if (m_node_face_uids.empty())
1565 return m_node_face_uids;
1574 if (m_node_nb_edges.empty())
1576 return m_node_nb_edges;
1585 if (m_node_edge_uids.empty())
1587 return m_node_edge_uids;
1596 if (!doRead())
return m_node_coordinates;
1597 if (m_node_coordinates.empty()) {
1599 auto point_coords = m_vtk_grid->GetPoints()->GetData();
1600 if (m_print_info_level.print_debug_info) {
1601 std::cout <<
"======= Point COORDS ====" << std::endl;
1602 std::ostringstream oss;
1603 point_coords->PrintSelf(oss, vtkIndent{ 2 });
1604 std::cout << oss.str() << std::endl;
1606 auto nb_nodes = m_vtk_grid->GetNumberOfPoints();
1607 for (
int i = 0; i < nb_nodes; ++i) {
1608 if (m_print_info_level.print_debug_info) {
1609 std::cout <<
"==========current point coordinates : ( ";
1610 std::cout << *(point_coords->GetTuple(i)) <<
" , ";
1611 std::cout << *(point_coords->GetTuple(i) + 1) <<
" , ";
1612 std::cout << *(point_coords->GetTuple(i) + 2) <<
" ) ===" << std::endl;
1614 m_node_coordinates.add({ *(point_coords->GetTuple(i)),
1615 *(point_coords->GetTuple(i) + 1),
1616 *(point_coords->GetTuple(i) + 2) });
1619 return m_node_coordinates;
1625vtkCellData* VtkPolyhedralMeshIOService::VtkReader::
1634vtkPointData* VtkPolyhedralMeshIOService::VtkReader::
1637 return m_point_data;
1643void VtkPolyhedralMeshIOService::VtkReader::
1644_printMeshInfos()
const
1647 std::cout <<
"-- VTK GRID READ "
1648 <<
" NB CELLS " << m_vtk_grid->GetNumberOfCells() << std::endl;
1650 auto* cell_iter = m_vtk_grid->vtkDataSet::NewCellIterator();
1651 cell_iter->InitTraversal();
1652 vtkIdType* cell_faces{
nullptr };
1653 vtkIdType nb_faces = 0;
1654 while (!cell_iter->IsDoneWithTraversal()) {
1655 std::cout <<
"---- visiting cell id " << cell_iter->GetCellId() << std::endl;
1656 std::cout <<
"---- cell number of faces " << cell_iter->GetNumberOfFaces() << std::endl;
1657 std::cout <<
"---- cell number of points " << cell_iter->GetNumberOfPoints() << std::endl;
1658 m_vtk_grid->GetFaceStream(cell_iter->GetCellId(), nb_faces, cell_faces);
1659 for (
auto iface = 0; iface < nb_faces; ++iface) {
1660 auto face_nb_nodes = *cell_faces++;
1661 std::cout <<
"---- has face with " << face_nb_nodes <<
" nodes. Node ids : ";
1662 for (
int inode = 0; inode < face_nb_nodes; ++inode) {
1663 std::cout << *cell_faces++ <<
" ";
1665 std::cout << std::endl;
1667 cell_iter->GoToNextCell();
1674vtkCellData* VtkPolyhedralMeshIOService::VtkReader::faceData()
1684void VtkPolyhedralMeshIOService::VtkReader::
1685_readPlainTextVtkGrid(
const String& filename)
1687 m_vtk_grid_reader->SetFileName(filename.localstr());
1688 m_vtk_grid_reader->ReadAllScalarsOn();
1689 m_vtk_grid_reader->Update();
1690 m_vtk_grid = m_vtk_grid_reader->GetOutput();
1696void VtkPolyhedralMeshIOService::VtkReader::
1697_readXlmVtkGrid(
const String& filename)
1699 m_vtk_xml_grid_reader->SetFileName(filename.localstr());
1700 m_vtk_xml_grid_reader->Update();
1701 m_vtk_grid = m_vtk_xml_grid_reader->GetOutput();
1707void VtkPolyhedralMeshIOService::VtkReader::
1708_readPlainTextVtkFaceGrid(
const String& faces_filename)
1710 m_vtk_face_grid_reader->SetFileName(faces_filename.localstr());
1711 m_vtk_face_grid_reader->ReadAllScalarsOn();
1712 m_vtk_face_grid_reader->Update();
1713 m_vtk_face_grid = m_vtk_face_grid_reader->GetOutput();
1719void VtkPolyhedralMeshIOService::VtkReader::
1720_readXmlVtkFaceGrid(
const String& faces_filename)
1722 m_vtk_xml_face_grid_reader->SetFileName(faces_filename.localstr());
1723 m_vtk_xml_face_grid_reader->Update();
1724 m_vtk_face_grid = m_vtk_xml_face_grid_reader->GetOutput();
1730void VtkPolyhedralMeshIOService::VtkReader::
1731_readfaceNodesInFaceMesh()
1733 m_face_nb_nodes_in_face_mesh.resize(m_poly_data->GetNumberOfCells());
1734 m_face_node_uids_in_face_mesh.reserve(m_poly_data->GetNumberOfCells() * m_poly_data->GetMaxCellSize());
1735 m_poly_data->InitTraversal();
1736 vtkIdType face_nb_nodes;
1737 vtkIdType* face_nodes;
1739 auto face_nb_node_index = 0;
1742 current_face_node_uids.
reserve(m_poly_data->GetMaxCellSize());
1743 reordered_current_face_node_uids.reserve(m_poly_data->GetMaxCellSize());
1745 while (m_poly_data->GetNextCell(face_nb_nodes, face_nodes)) {
1746 m_face_nb_nodes_in_face_mesh[face_nb_node_index] = face_nb_nodes;
1747 ConstArrayView<vtkIdType> face_nodes_view(face_nb_nodes, face_nodes);
1748 current_face_node_uids.resize(face_nb_nodes);
1749 reordered_current_face_node_uids.resize(face_nb_nodes);
1750 std::copy(face_nodes_view.begin(), face_nodes_view.end(), current_face_node_uids.begin());
1751 MeshUtils::reorderNodesOfFace(current_face_node_uids, reordered_current_face_node_uids);
1752 std::copy(reordered_current_face_node_uids.begin(), reordered_current_face_node_uids.end(), std::back_inserter(m_face_node_uids_in_face_mesh));
1753 ++face_nb_node_index;
1759void VtkPolyhedralMeshIOService::VtkReader::
1760_checkVtkGrid()
const
1763 ARCANE_FATAL(
"Polyhedral vtk grid not loaded. Cannot continue.");
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.
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.
ArcaneVtkPolyhedralMeshIOObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
Informations nécessaires pour la lecture d'un fichier de maillage.
Interface d'une famille d'entités.
virtual String name() const =0
Nom de la famille.
virtual Integer nbItem() const =0
Nombre d'entités.
virtual String name() const =0
Nom du maillage.
Interface d'un service de création/lecture du maillage.
virtual IVariableMng * variableMng() const =0
Gestionnaire de variable associé
Interface du gestionnaire de traces.
virtual void addAutoDestroyVariable(VariableRef *var)=0
Ajoute la variable à la liste des variables qui sont conservées jusqu'à la fin de l'exécution.
virtual IVariableMngInternal * _internalApi()=0
API interne à Arcane.
static IXmlDocumentHolder * loadFromBuffer(Span< const Byte > buffer, const String &name, ITraceMng *tm)
Charge un document XML.
Paramètres nécessaires à la construction d'un maillage.
MeshBuildInfo & addNeedPartitioning(bool v)
Indique si le générateur nécessite d'appeler un partitionneur.
MeshBuildInfo & addMeshKind(const MeshKind &v)
Positionne les caractéristiques du maillage.
MeshBuildInfo & addFactoryName(const String &factory_name)
Positionne le nom de la fabrique pour créer ce maillage.
Caractéristiques d'un maillage.
Référence à une instance.
Structure contenant les informations pour créer un service.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
Infos caractérisant une variable.
Référence à 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.
const value_type & const_reference
Type référence constante d'un élément du tableau.
#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< Int64 > Int64Span
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
std::int64_t Int64
Type entier signé sur 64 bits.
ArrayView< Real3 > Real3ArrayView
Equivalent C d'un tableau à une dimension de Real3.
Int32 Integer
Type représentant un entier.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
@ ST_CaseOption
Le service s'utilise au niveau du jeu de données.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
SharedArray< Int32 > Int32SharedArray
Tableau dynamique à une dimension d'entiers 32 bits.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
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.
double Real
Type représentant un réel.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Span< Int32 > Int32Span
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
eDataType
Type d'une donnée.
@ DT_Int32
Donnée de type entier 32 bits.
@ DT_Int64
Donnée de type entier 64 bits.
@ DT_Unknown
Donnée de type inconnue ou non initialisée.
@ DT_Real
Donnée de type réel.
Span< const Int32 > Int32ConstSpan
Vue en lecture seule d'un tableau à une dimension d'entiers 32 bits.
ARCANE_DATATYPE_EXPORT eDataType dataTypeFromName(const char *name, bool &has_error)
Trouve le type associé à name.
const char * dataTypeName(eDataType type)
Nom du type de donnée.
std::int32_t Int32
Type entier signé sur 32 bits.