14#include "arcane/utils/TraceAccessor.h"
15#include "arcane/utils/Array.h"
16#include "arcane/utils/IOException.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/NotSupportedException.h"
20#include "arcane/utils/Real3.h"
21#include "arcane/utils/OStringStream.h"
22#include "arcane/utils/FixedArray.h"
23#include "arcane/utils/SmallArray.h"
24#include "arcane/utils/PlatformUtils.h"
25#include "arcane/utils/CheckedConvert.h"
27#include "arcane/core/IMeshReader.h"
28#include "arcane/core/IPrimaryMesh.h"
29#include "arcane/core/IItemFamily.h"
30#include "arcane/core/ItemGroup.h"
31#include "arcane/core/VariableTypes.h"
32#include "arcane/core/IParallelMng.h"
34#include "arcane/core/IMeshModifier.h"
35#include "arcane/core/MeshKind.h"
36#include "arcane/core/NodesOfItemReorderer.h"
37#include "arcane/core/internal/MshMeshGenerationInfo.h"
40#include "arcane/std/internal/IosFile.h"
41#include "arcane/std/internal/IosGmsh.h"
82class MshParallelMeshReader
101 class MshToArcaneTypeInfo
105 MshToArcaneTypeInfo() =
default;
107 : m_msh_type(msh_type)
108 , m_arcane_type_info(iti)
109 , m_reorder_infos(reorder_infos)
115 Int32 m_msh_type = -1;
136 Int64 entity_tag = -1;
169 items_infos.add(type_id);
170 items_infos.add(unique_id);
171 items_infos.addRange(nodes_uid);
199 explicit MshParallelMeshReader(
ITraceMng* tm);
207 IMesh* m_mesh =
nullptr;
209 Int32 m_master_io_rank = A_NULL_RANK;
210 bool m_is_parallel =
false;
230 void _readMeshFromFile();
232 void _allocateCells();
233 void _allocateGroups();
240 void _readPhysicalNames();
243 void _readOneEntity(
Int32 entity_dim,
Int32 entity_index_in_dim);
246 Int32 _getIntegerAndBroadcast();
247 Int64 _getInt64AndBroadcast();
257 void _goToNextLine();
260 const MshToArcaneTypeInfo& mshToArcaneTypeInfo(
Int32 msh_type)
const;
275 inline std::pair<Int64, Int64>
276 _interval(Int32 index, Int32 nb_interval, Int64 size)
278 Int64 isize = size / nb_interval;
279 Int64 ibegin = index * isize;
281 if ((index + 1) == nb_interval)
282 isize = size - ibegin;
283 return { ibegin, isize };
293MshParallelMeshReader::
316 s = f->getNextLine();
320 info(4) <<
"BroadcastNextLine: " << s;
321 m_parallel_mng->broadcastString(s, m_master_io_rank);
323 info(4) <<
"GetNextLine: " << s;
336 Int32 is_end_int = 0;
338 is_end_int = f->isEnd() ? 1 : 0;
339 info(4) <<
"IsEndOfFile_Master: " << is_end_int;
343 info(4) <<
"IsEndOfFile: " << is_end_int;
344 m_parallel_mng->broadcast(
ArrayView<Int32>(1, &is_end_int), m_master_io_rank);
346 bool is_end = (is_end_int != 0);
347 info(4) <<
"IsEnd: " << is_end;
356_getIntegerAndBroadcast()
361 v[0] = f->getInteger();
363 m_parallel_mng->broadcast(v.
view(), m_master_io_rank);
371Int64 MshParallelMeshReader::
372_getInt64AndBroadcast()
374 IosFile* f = m_ios_file.get();
375 FixedArray<Int64, 1> v;
379 m_parallel_mng->broadcast(v.view(), m_master_io_rank);
387void MshParallelMeshReader::
390 IosFile* f = m_ios_file.get();
393 f->binaryRead(values);
396 for (
Int64& v : values)
401 m_parallel_mng->broadcast(values, m_master_io_rank);
407void MshParallelMeshReader::
410 IosFile* f = m_ios_file.get();
413 f->binaryRead(values);
416 for (
Int32& v : values)
421 m_parallel_mng->broadcast(values, m_master_io_rank);
427void MshParallelMeshReader::
430 IosFile* f = m_ios_file.get();
433 f->binaryRead(values);
436 for (
double& v : values)
441 m_parallel_mng->broadcast(values, m_master_io_rank);
447Real3 MshParallelMeshReader::
450 IosFile* f = m_ios_file.get();
454 f->binaryRead(SmallSpan<Real3>(&v, 1));
457 Real x = f->getReal();
458 Real y = f->getReal();
459 Real z = f->getReal();
468Int32 MshParallelMeshReader::
471 IosFile* f = m_ios_file.get();
475 f->binaryRead(SmallSpan<Int32>(&v, 1));
484Int64 MshParallelMeshReader::
487 IosFile* f = m_ios_file.get();
491 f->binaryRead(SmallSpan<Int64>(&v, 1));
500void MshParallelMeshReader::
503 if (m_ios_file.get())
504 m_ios_file->goToEndOfLine();
515 Real min_value = -max_value;
516 Real3 min_box(max_value, max_value, max_value);
517 Real3 max_box(min_value, min_value, min_value);
518 const Int64 nb_node = m_mesh_allocate_info.nodes_coordinates.largeSize();
519 for (
Real3 pos : m_mesh_allocate_info.nodes_coordinates) {
533 Real min_x = min_box.
x;
534 Real max_x = max_box.
x;
538 info() <<
"MIN_MAX_X=" << global_min_x <<
" " << global_max_x;
544 for (
Int64 i = 0; i < nb_node; ++i) {
545 Int32 part =
static_cast<Int32>((m_mesh_allocate_info.nodes_coordinates[i].x - global_min_x) / diff_v);
546 part = std::clamp(part, 0,
m_nb_part - 1);
547 nodes_part[i] = part;
552 for (
Int64 i = 0; i < nb_node; ++i) {
554 Int64 uid = m_mesh_allocate_info.nodes_unique_id[i];
555 ++nb_node_per_rank[rank];
556 m_mesh_allocate_info.nodes_rank_map.insert(std::make_pair(uid, rank));
559 info() <<
"NB_NODE_PER_RANK=" << nb_node_per_rank;
592 _getInt64ArrayAndBroadcast(nodes_info.
view());
594 Int64 nb_node_block =
static_cast<Int32>(nodes_info[0]);
595 Int64 total_nb_node = nodes_info[1];
596 Int64 min_node_tag = nodes_info[2];
597 Int64 max_node_tag = nodes_info[3];
602 if (total_nb_node < 0)
605 info() <<
"[Nodes] nb_node_block=" << nb_node_block
606 <<
" total_nb_node=" << total_nb_node
607 <<
" min_tag=" << min_node_tag
608 <<
" max_tag=" << max_node_tag
610 <<
" nb_rank=" << m_parallel_mng->commSize();
613 node_blocks.
resize(nb_node_block);
615 for (
Int32 i = 0; i < nb_node_block; ++i) {
617 node_block.
index = i;
618 _readNodesOneEntity(node_block);
630void MshParallelMeshReader::
631_readNodesOneEntity(MshNodeBlock& node_block)
641 _getInt32ArrayAndBroadcast(entity_infos.
view());
642 Int32 nb_node2 = CheckedConvert::toInt32(_getInt64AndBroadcast());
648 Int32 entity_dim = entity_infos[0];
649 node_block.entity_dim = entity_dim;
651 Int32 entity_tag = entity_infos[1];
652 node_block.entity_tag = entity_tag;
655 node_block.nb_node = nb_node2;
657 Int32 parametric_coordinates = entity_infos[2];
659 info(4) <<
"[Nodes] index=" << node_block.index <<
" entity_dim=" << entity_dim <<
" entity_tag=" << entity_tag
660 <<
" parametric=" << parametric_coordinates
661 <<
" nb_node2=" << nb_node2;
663 if (parametric_coordinates != 0)
677 info(4) <<
"Reading UIDS part i=" << i_part <<
" dest_rank=" << dest_rank <<
" nb_to_read=" << nb_to_read;
678 if (my_rank == dest_rank || my_rank == m_master_io_rank) {
679 nodes_uids.
resize(nb_to_read);
686 ios_file->binaryRead(nodes_uids.
view());
689 for (
Integer i = 0; i < nb_to_read; ++i) {
691 nodes_uids[i] = ios_file->getInt64();
695 if (dest_rank != m_master_io_rank) {
696 pm->send(nodes_uids, dest_rank);
699 else if (my_rank == dest_rank) {
700 pm->
recv(nodes_uids, m_master_io_rank);
704 if (my_rank == dest_rank) {
705 m_mesh_allocate_info.nodes_unique_id.addRange(nodes_uids);
706 node_block.nb_node = nodes_uids.
size();
714 info(4) <<
"Reading COORDS part i=" << i_part <<
" dest_rank=" << dest_rank <<
" nb_to_read=" << nb_to_read;
715 if (my_rank == dest_rank || my_rank == m_master_io_rank) {
716 nodes_coordinates.
resize(nb_to_read);
723 ios_file->binaryRead(nodes_coordinates.
view());
726 for (
Integer i = 0; i < nb_to_read; ++i) {
727 nodes_coordinates[i] = _getReal3();
731 if (dest_rank != m_master_io_rank) {
732 pm->send(nodes_coordinates, dest_rank);
735 else if (my_rank == dest_rank) {
736 pm->
recv(nodes_coordinates, m_master_io_rank);
740 if (my_rank == dest_rank) {
741 m_mesh_allocate_info.nodes_coordinates.addRange(nodes_coordinates);
757 IosFile* ios_file = m_ios_file.get();
766 info() <<
"Reading block nb_entity=" << nb_entity_in_block <<
" item_nb_node=" << item_nb_node;
774 const Int64 nb_to_read = _interval(i_part,
m_nb_part, nb_entity_in_block).second;
778 info(4) <<
"Reading block part i_part=" << i_part
779 <<
" nb_to_read=" << nb_to_read <<
" dest_rank=" << dest_rank;
781 const Int64 nb_uid = nb_to_read;
782 const Int64 nb_connectivity = nb_uid * item_nb_node;
783 if (my_rank == dest_rank || my_rank == m_master_io_rank) {
785 connectivities.
resize(nb_connectivity);
789 Int64 nb_to_read = nb_uid * (item_nb_node + 1);
790 tmp_uid_and_connectivities.
resize(nb_to_read);
791 ios_file->binaryRead(tmp_uid_and_connectivities.
view());
793 for (
Int64 i = 0; i < nb_uid; ++i) {
794 Int64 item_unique_id = tmp_uid_and_connectivities[index];
796 uids[i] = item_unique_id;
797 for (
Int32 j = 0; j < item_nb_node; ++j) {
798 connectivities[(i * item_nb_node) + j] = tmp_uid_and_connectivities[index];
805 for (
Int64 i = 0; i < nb_uid; ++i) {
806 Int64 item_unique_id = ios_file->getInt64();
807 uids[i] = item_unique_id;
808 for (
Int32 j = 0; j < item_nb_node; ++j)
809 connectivities[(i * item_nb_node) + j] = ios_file->getInt64();
812 if (dest_rank != m_master_io_rank) {
813 pm->send(uids, dest_rank);
814 pm->send(connectivities, dest_rank);
817 else if (my_rank == dest_rank) {
818 pm->
recv(uids, m_master_io_rank);
819 pm->
recv(connectivities, m_master_io_rank);
821 if (my_rank == dest_rank) {
861 IosFile* ios_file = m_ios_file.get();
867 _getInt64ArrayAndBroadcast(elements_info.
view());
869 Int64 nb_block = elements_info[0];
870 Int64 number_of_elements = elements_info[1];
871 Int64 min_element_tag = elements_info[2];
872 Int64 max_element_tag = elements_info[3];
877 info() <<
"[Elements] nb_block=" << nb_block
878 <<
" nb_elements=" << number_of_elements
879 <<
" min_element_tag=" << min_element_tag
880 <<
" max_element_tag=" << max_element_tag;
882 if (number_of_elements < 0)
900 _getInt32ArrayAndBroadcast(block_info.
view());
902 Int32 entity_dim = block_info[0];
903 Int32 entity_tag = block_info[1];
904 Int32 entity_type = block_info[2];
905 Int64 nb_entity_in_block = _getInt64AndBroadcast();
913 info() <<
"[Elements] index=" << block.index <<
" entity_dim=" << entity_dim
914 <<
" entity_tag=" << entity_tag
915 <<
" msh_entity_type=" << entity_type <<
" nb_in_block=" << nb_entity_in_block
916 <<
" arcane_item_type=" << item_type <<
" item_nb_node=" << item_nb_node;
918 block.nb_entity = nb_entity_in_block;
919 block.item_type = item_type;
920 block.item_nb_node = item_nb_node;
921 block.dimension = entity_dim;
922 block.entity_tag = entity_tag;
923 block.reorder_infos = msh_tinfo.m_reorder_infos;
924 if (entity_type == MSH_PNT) {
929 Int64 item_unique_id = NULL_ITEM_UNIQUE_ID;
931 [[maybe_unused]]
Int64 unused_id = _getInt64();
932 item_unique_id = _getInt64();
934 info() <<
"Adding unique node uid=" << item_unique_id;
938 block.uids.add(item_unique_id);
954 mesh_dimension =
math::max(mesh_dimension, block.dimension);
955 if (mesh_dimension < 0)
956 ARCANE_FATAL(
"Invalid computed mesh dimension '{0}'", mesh_dimension);
957 if (mesh_dimension != 2 && mesh_dimension != 3)
959 info() <<
"Computed mesh dimension = " << mesh_dimension;
961 bool allow_multi_dim_cell = m_mesh->meshKind().isNonManifold();
962 bool use_experimental_type_for_cell =
false;
963 if (allow_multi_dim_cell) {
965 use_experimental_type_for_cell =
true;
967 use_experimental_type_for_cell = (v.value() != 0);
969 info() <<
"Use experimental cell type?=" << use_experimental_type_for_cell;
970 ItemTypeMng* item_type_mng = m_mesh->itemTypeMng();
972 const Int32 block_dim = block.dimension;
975 info() <<
"Reading block dim=" << block_dim <<
" type_name=" << item_type_name;
976 if (block_dim == mesh_dimension)
977 _computeOwnItems(block, m_mesh_allocate_info.cells_infos,
false);
978 else if (allow_multi_dim_cell) {
981 bool use_sub_dim_cell =
false;
982 if (mesh_dimension == 3 && (block_dim == 2 || block_dim == 1))
984 use_sub_dim_cell =
true;
985 else if (mesh_dimension == 2 && block_dim == 1)
987 use_sub_dim_cell =
true;
988 if (!use_experimental_type_for_cell)
989 use_sub_dim_cell =
false;
990 if (use_sub_dim_cell) {
993 if (mesh_dimension == 3) {
994 if (block.item_type == IT_Triangle3)
995 block.item_type =
ItemTypeId(IT_Cell3D_Triangle3);
996 else if (block.item_type == IT_Triangle6)
997 block.item_type =
ItemTypeId(ITI_Cell3D_Triangle6);
998 else if (block.item_type == IT_Quad4)
999 block.item_type =
ItemTypeId(IT_Cell3D_Quad4);
1000 else if (block.item_type == IT_Quad8)
1001 block.item_type =
ItemTypeId(IT_Cell3D_Quad8);
1002 else if (block.item_type == IT_Quad9)
1003 block.item_type =
ItemTypeId(IT_Cell3D_Quad9);
1004 else if (block.item_type == IT_Line2)
1005 block.item_type =
ItemTypeId(IT_Cell3D_Line2);
1006 else if (block.item_type == IT_Line3)
1007 block.item_type =
ItemTypeId(IT_Cell3D_Line3);
1009 ARCANE_FATAL(
"Not supported sub dimension cell type={0} for 3D mesh", item_type_name);
1011 else if (mesh_dimension == 2) {
1012 if (block.item_type == IT_Line2)
1015 ARCANE_FATAL(
"Not supported sub dimension cell type={0} for 2D mesh", item_type_name);
1017 block.is_built_as_cells =
true;
1018 _computeOwnItems(block, m_mesh_allocate_info.cells_infos,
false);
1023 return mesh_dimension;
1037 if (my_rank != dest_rank) {
1038 work_values.
resize(size);
1039 view = work_values.
view();
1041 pm->broadcast(view, dest_rank);
1055 const Int32 my_rank = pm->commRank();
1058 if (dest_rank == my_rank)
1059 size = values.size();
1061 return _broadcastArrayWithSize(pm, values, work_values, dest_rank, size);
1069void MshParallelMeshReader::
1070_computeOwnItems(MshElementBlock& block, MshItemKindInfo& item_kind_info,
bool is_generate_uid)
1074 IParallelMng* pm = m_parallel_mng;
1075 const Int32 my_rank = pm->commRank();
1078 const ItemTypeId item_type = block.item_type;
1079 const Int32 item_nb_node = block.item_nb_node;
1081 UniqueArray<Int64> connectivities;
1082 UniqueArray<Int64> uids;
1083 UniqueArray<Int32> nodes_rank;
1085 SmallSpan<const Int16> reorder_infos = block.reorder_infos;
1086 bool has_reorder_info = !reorder_infos.empty();
1088 if (is_print_level1)
1089 info() <<
"Compute own items block_index=" << block.index <<
" nb_part=" << nb_part
1090 <<
" has_reorder?=" << has_reorder_info;
1092 SmallArray<Int64> arcane_reordered_uids;
1093 if (has_reorder_info)
1094 arcane_reordered_uids.resize(item_nb_node);
1095 for (
Int32 i_part = 0; i_part < nb_part; ++i_part) {
1098 ArrayView<Int64> connectivities_view = _broadcastArray(pm, block.connectivities.view(), connectivities, dest_rank);
1099 ArrayView<Int64> uids_view = _broadcastArray(pm, block.uids.view(), uids, dest_rank);
1101 Int32 nb_item = uids_view.size();
1102 nodes_rank.resize(nb_item);
1103 nodes_rank.fill(-1);
1108 for (
Int32 i = 0; i < nb_item; ++i) {
1109 Int64 first_node_uid = connectivities_view[i * item_nb_node];
1110 auto x = m_mesh_allocate_info.nodes_rank_map.find(first_node_uid);
1111 if (x == m_mesh_allocate_info.nodes_rank_map.end())
1114 Int32 rank = x->second;
1115 nodes_rank[i] = rank;
1118 for (
Int32 i = 0; i < nb_item; ++i) {
1119 const Int32 rank = nodes_rank[i];
1120 if (rank != my_rank)
1125 ConstArrayView<Int64> v = connectivities_view.subView(i * item_nb_node, item_nb_node);
1126 Int64 uid = uids_view[i];
1127 if (is_generate_uid)
1129 uid = NULL_ITEM_UNIQUE_ID;
1130 if (has_reorder_info) {
1133 for (
Int32 zz = 0; zz < item_nb_node; ++zz)
1134 arcane_reordered_uids[zz] = v[reorder_infos[zz]];
1135 v = arcane_reordered_uids.view();
1137 item_kind_info.addItem(item_type, uid, v);
1167 const IItemFamily* node_family = m_mesh->nodeFamily();
1171 ConstArrayView<Int64> uids = _broadcastArray(pm, m_mesh_allocate_info.nodes_unique_id.view(), uids_storage, dest_rank);
1172 ConstArrayView<Real3> coords = _broadcastArray(pm, m_mesh_allocate_info.nodes_coordinates.view(), coords_storage, dest_rank);
1175 local_ids.
resize(nb_item);
1181 for (
Int32 i = 0; i < nb_item; ++i) {
1182 NodeLocalId nid(local_ids[i]);
1184 nodes_coord_var[nid] = coords[i];
1192void MshParallelMeshReader::
1196 Integer nb_elements = m_mesh_allocate_info.cells_infos.nb_item;
1197 info() <<
"nb_of_elements=cells_type.size()=" << nb_elements;
1198 Integer nb_cell_node = m_mesh_allocate_info.cells_infos.items_infos.
size();
1199 info() <<
"nb_cell_node=cells_connectivity.size()=" << nb_cell_node;
1202 info() <<
"Building cells, nb_cell=" << nb_elements <<
" nb_cell_node=" << nb_cell_node;
1204 info() <<
"## Allocating ##";
1205 pmesh->
allocateCells(nb_elements, m_mesh_allocate_info.cells_infos.items_infos,
false);
1206 info() <<
"## Ending ##";
1208 info() <<
"## Done ##";
1214void MshParallelMeshReader::
1217 IMesh* mesh = m_mesh;
1219 Int32 face_dim = mesh_dim - 1;
1220 UniqueArray<MshEntitiesWithNodes> entity_list;
1221 UniqueArray<MshPhysicalName> physical_name_list;
1222 IItemFamily* node_family = mesh->nodeFamily();
1224 for (MshElementBlock& block : m_mesh_allocate_info.element_blocks) {
1225 entity_list.clear();
1226 physical_name_list.clear();
1227 Int32 block_index = block.index;
1228 Int32 block_dim = block.dimension;
1231 Int64 block_entity_tag = block.entity_tag;
1232 if (block_entity_tag < 0) {
1233 info(5) <<
"[Groups] Skipping block index=" << block_index <<
" because it has no entity";
1236 if (block_dim == 0) {
1237 const MshEntitiesNodes* entity = m_mesh_info->findNodeEntities(block_entity_tag);
1239 info(5) <<
"[Groups] Skipping block index=" << block_index
1240 <<
" because entity tag is invalid";
1243 Int64 entity_physical_tag = entity->physicalTag();
1244 MshPhysicalName physical_name = m_mesh_info->findPhysicalName(block_dim, entity_physical_tag);
1245 physical_name_list.add(physical_name);
1248 m_mesh_info->findEntities(block_dim, block_entity_tag, entity_list);
1249 for (
const MshEntitiesWithNodes& x : entity_list) {
1250 Int64 entity_physical_tag = x.physicalTag();
1251 MshPhysicalName physical_name = m_mesh_info->findPhysicalName(block_dim, entity_physical_tag);
1252 physical_name_list.add(physical_name);
1255 for (
const MshPhysicalName& physical_name : physical_name_list) {
1256 if (physical_name.isNull()) {
1257 info(5) <<
"[Groups] Skipping block index=" << block_index
1258 <<
" because entity physical tag is invalid";
1261 String group_name = physical_name.name();
1262 info(4) <<
"[Groups] Block index=" << block_index <<
" dim=" << block_dim
1263 <<
" name='" << group_name <<
"' built_as_cells=" << block.is_built_as_cells;
1264 if (block_dim == mesh_dim || block.is_built_as_cells) {
1267 else if (block_dim == face_dim) {
1280 UniqueArray<Int64>& nodes_uids = m_mesh_allocate_info.nodes_unique_id;
1282 for (
const MshNodeBlock& block : m_mesh_allocate_info.node_blocks) {
1283 ArrayView<Int64> block_uids = nodes_uids.subView(block.index_in_allocation_info, block.nb_node);
1284 MshPhysicalName physical_name = m_mesh_info->findPhysicalName(block.entity_dim, block.entity_tag);
1285 String group_name = physical_name.name();
1286 info(4) <<
"NodeBlock name=" << group_name <<
" index=" << block.index
1287 <<
" index_in_allocation=" << block.index_in_allocation_info
1288 <<
" nb_node=" << block.nb_node;
1297 if (!group_name.null())
1317 _addFaceGroupOnePart(block, connectivities_view, group_name);
1324void MshParallelMeshReader::
1326 const String& group_name)
1329 const Int32 item_nb_node = block.item_nb_node;
1330 const Int32 block_index = block.index;
1332 const Int32 nb_entity = connectivities.
size() / item_nb_node;
1336 FaceGroup face_group =
mesh->faceFamily()->findGroup(group_name,
true);
1341 const Int32 face_nb_node = nb_entity * item_nb_node;
1346 Integer faces_nodes_unique_id_index = 0;
1359 for (
Integer i_face = 0; i_face < nb_entity; ++i_face) {
1360 for (
Integer z = 0; z < item_nb_node; ++z)
1361 orig_nodes_id[z] = connectivities[faces_nodes_unique_id_index + z];
1362 m_nodes_reorderer.reorder(type_id, orig_nodes_id);
1364 for (
Integer z = 0; z < item_nb_node; ++z)
1365 faces_nodes_unique_id[faces_nodes_unique_id_index + z] = sorted_nodes[z];
1366 faces_first_node_unique_id[i_face] = sorted_nodes[0];
1367 faces_nodes_unique_id_index += item_nb_node;
1373 faces_nodes_unique_id_index = 0;
1374 for (
Integer i_face = 0; i_face < nb_entity; ++i_face) {
1375 const Integer n = item_nb_node;
1376 Int32 face_first_node_lid = faces_first_node_local_id[i_face];
1377 if (face_first_node_lid != NULL_ITEM_LOCAL_ID) {
1378 Int64ConstArrayView face_nodes_id(item_nb_node, &faces_nodes_unique_id[faces_nodes_unique_id_index]);
1379 Node current_node(mesh_nodes[faces_first_node_local_id[i_face]]);
1380 Face face = MeshUtils::getFaceFromNodesUniqueId(current_node, face_nodes_id);
1385 if (!m_is_parallel) {
1387 ostr() <<
"(Nodes:";
1388 for (
Integer z = 0; z < n; ++z)
1389 ostr() <<
' ' << face_nodes_id[z];
1390 ostr() <<
" - node_lid=" << current_node.localId() <<
")";
1391 String error_string =
"INTERNAL: MshMeshReader face index={0} with nodes '{1}' is not in node/face connectivity.";
1392 if (!is_non_manifold)
1393 error_string = error_string +
"\n This errors may occur if the mesh is non-manifold."
1394 "\n See Arcane documentation to specify the mesh is a non manifold one.\n";
1399 faces_id.
add(face.localId());
1402 faces_nodes_unique_id_index += n;
1404 info(4) <<
"Adding " << faces_id.
size() <<
" faces from block index=" << block_index
1405 <<
" to group '" << face_group.
name() <<
"'";
1422 ArrayView<Int64> uids_view = _broadcastArray(pm, block_uids, uids, dest_rank);
1423 _addCellOrNodeGroupOnePart(uids_view, group_name, block_index, family, filter_invalid);
1430void MshParallelMeshReader::
1449 if (m_is_parallel || filter_invalid) {
1450 auto items_begin = items_lid.begin();
1451 Int64 new_size = std::remove(items_begin, items_lid.end(), NULL_ITEM_LOCAL_ID) - items_begin;
1452 items_lid.resize(new_size);
1455 info() <<
"Adding " << items_lid.size() <<
" items from block index=" << block_index
1456 <<
" to group '" << group_name <<
"' for family=" << family->
name();
1470void MshParallelMeshReader::
1474 String quote_mark =
"\"";
1475 Int32 nb_name = _getIntegerAndBroadcast();
1476 info() <<
"nb_physical_name=" << nb_name;
1480 for (
Int32 i = 0; i < nb_name; ++i) {
1481 Int32 dim = _getIntegerAndBroadcast();
1482 Int32 tag = _getIntegerAndBroadcast();
1484 if (dim < 0 || dim > 3)
1485 ARCANE_FATAL(
"Invalid value for physical name dimension dim={0}", dim);
1489 if (s.startsWith(quote_mark))
1491 if (s.endsWith(quote_mark))
1492 s = s.substring(0, s.length() - 1);
1493 m_mesh_info->physical_name_list.add(dim, tag, s);
1494 info(4) <<
"[PhysicalName] index=" << i <<
" dim=" << dim <<
" tag=" << tag <<
" name='" << s <<
"'";
1498 if (s !=
"$EndPhysicalNames")
1499 ARCANE_FATAL(
"found '{0}' and expected '$EndPhysicalNames'", s);
1537 IosFile* ios_file = m_ios_file.get();
1540 _getInt64ArrayAndBroadcast(nb_dim_item.
view());
1544 info() <<
"[Entities] nb_0d=" << nb_dim_item[0] <<
" nb_1d=" << nb_dim_item[1]
1545 <<
" nb_2d=" << nb_dim_item[2] <<
" nb_3d=" << nb_dim_item[3];
1552 for (
Int64 i = 0; i < nb_dim_item[0]; ++i) {
1555 Int32 tag = _getInt32();
1556 Real3 xyz = _getReal3();
1557 Int64 num_physical_tag = _getInt64();
1558 if (num_physical_tag > 1)
1559 ARCANE_FATAL(
"NotImplemented numPhysicalTag>1 (n={0}, index={1} xyz={2})",
1560 num_physical_tag, i, xyz);
1562 Int32 physical_tag = -1;
1563 if (num_physical_tag == 1)
1564 physical_tag = _getInt32();
1565 if (is_print_level1)
1566 info() <<
"[Entities] point tag=" << tag <<
" pos=" << xyz <<
" phys_tag=" << physical_tag;
1569 tag_info[1] = physical_tag;
1571 m_parallel_mng->broadcast(tag_info.
view(), m_master_io_rank);
1572 m_mesh_info->entities_nodes_list.add(MshEntitiesNodes(tag_info[0], tag_info[1]));
1578 for (
Int32 i_dim = 1; i_dim <= 3; ++i_dim)
1579 for (
Int32 i = 0; i < nb_dim_item[i_dim]; ++i)
1580 _readOneEntity(i_dim, i);
1591void MshParallelMeshReader::
1592_readOneEntity(
Int32 entity_dim,
Int32 entity_index_in_dim)
1609 if (is_print_level1)
1610 info() <<
"[Entities] Reading entity dim=" << entity_dim <<
" index_in_dim=" << entity_index_in_dim;
1612 dim_and_tag_info.
add(entity_dim);
1614 Int32 tag = _getInt32();
1615 dim_and_tag_info.
add(tag);
1616 Real3 min_pos = _getReal3();
1617 Real3 max_pos = _getReal3();
1618 Int64 nb_physical_tag = _getInt64();
1619 dim_and_tag_info.
add(nb_physical_tag);
1620 for (
Int32 z = 0; z < nb_physical_tag; ++z) {
1621 Int32 physical_tag = _getInt32();
1622 dim_and_tag_info.
add(physical_tag);
1623 if (is_print_level2)
1624 info(4) <<
"[Entities] z=" << z <<
" physical_tag=" << physical_tag;
1627 Int64 nb_bounding_group = _getInt64();
1628 dim_and_tag_info.
add(nb_bounding_group);
1629 for (Int64 z = 0; z < nb_bounding_group; ++z) {
1630 Int32 boundary_tag = _getInt32();
1631 if (is_print_level2)
1632 info(4) <<
"[Entities] z=" << z <<
" boundary_tag=" << boundary_tag;
1634 if (is_print_level2)
1635 info(4) <<
"[Entities] dim=" << entity_dim <<
" tag=" << tag
1636 <<
" min_pos=" << min_pos <<
" max_pos=" << max_pos
1637 <<
" nb_phys_tag=" << nb_physical_tag
1638 <<
" nb_bounding=" << nb_bounding_group;
1640 Int32 info_size = dim_and_tag_info.
size();
1641 m_parallel_mng->broadcast(ArrayView<Int32>(1, &info_size), m_master_io_rank);
1642 dim_and_tag_info.
resize(info_size);
1643 m_parallel_mng->broadcast(dim_and_tag_info.
view(), m_master_io_rank);
1646 Int32 dim = CheckedConvert::toInt32(dim_and_tag_info[0]);
1647 Int64 tag = dim_and_tag_info[1];
1648 Int64 nb_physical_tag = dim_and_tag_info[2];
1649 for (
Int32 z = 0; z < nb_physical_tag; ++z) {
1650 Int64 physical_tag = dim_and_tag_info[3 + z];
1651 if (is_print_level2)
1652 info(4) <<
"[Entities] adding info dim=" << entity_dim <<
" tag=" << tag
1653 <<
" physical_tag=" << physical_tag;
1654 m_mesh_info->entities_with_nodes_list[dim - 1].add(MshEntitiesWithNodes(dim, tag, physical_tag));
1684 Int64 nb_link = _getInt64AndBroadcast();
1685 info() <<
"[Periodic] nb_link=" << nb_link;
1691 MshPeriodicInfo& periodic_info = m_mesh_info->m_periodic_info;
1692 periodic_info.m_periodic_list.resize(nb_link);
1693 for (
Int64 ilink = 0; ilink < nb_link; ++ilink) {
1694 MshPeriodicOneInfo& one_info = periodic_info.m_periodic_list[ilink];
1696 _getInt32ArrayAndBroadcast(entity_info.
view());
1698 if (is_print_level1)
1699 info() <<
"[Periodic] link_index=" << ilink <<
" dim=" << entity_info[0] <<
" entity_tag=" << entity_info[1]
1700 <<
" entity_tag_master=" << entity_info[2];
1701 one_info.m_entity_dim = entity_info[0];
1702 one_info.m_entity_tag = entity_info[1];
1703 one_info.m_entity_tag_master = entity_info[2];
1705 Int64 num_affine = _getInt64AndBroadcast();
1706 if (is_print_level2)
1707 info() <<
"[Periodic] num_affine=" << num_affine;
1710 one_info.m_nb_corresponding_node = CheckedConvert::toInt32(_getInt64AndBroadcast());
1711 if (is_print_level1)
1712 info() <<
"[Periodic] nb_corresponding_node=" << one_info.m_nb_corresponding_node;
1715 if (is_print_level2)
1722 if (s !=
"$EndPeriodic")
1723 ARCANE_FATAL(
"found '{0}' and expected '$EndPeriodic'", s);
1736 constexpr Int32 MAX_SIZE = 128;
1739 Int32 read_size = CheckedConvert::toInt32(expected_bytes.
size());
1741 if (read_size >= MAX_SIZE)
1742 ARCANE_FATAL(
"local buffer is too small (size={0} max={1})", read_size, MAX_SIZE);
1743 IosFile* f = m_ios_file.get();
1745 f->binaryRead(bytes_to_read);
1746 s =
String(bytes_to_read);
1747 info() <<
"S=" << s;
1748 if (m_is_parallel) {
1749 m_parallel_mng->broadcastString(s, m_master_io_rank);
1757 if (s != expected_value)
1758 ARCANE_FATAL(
"found '{0}' and expected '{1}'", s, expected_value);
1765void MshParallelMeshReader::
1770 info() <<
"Reading 'msh' file in parallel";
1774 const int MSH_BINARY_TYPE = 1;
1777 Real version = ios_file->getReal();
1779 ARCANE_THROW(
IOException,
"Wrong msh file version '{0}'. Only version '4.1' is supported in parallel", version);
1780 Integer file_type = ios_file->getInteger();
1781 if (file_type == MSH_BINARY_TYPE)
1784 Int32 data_size = ios_file->getInteger();
1785 ARCANE_UNUSED(data_size);
1787 ARCANE_FATAL(
"Only 'size_t' of size '8' is allowed (current size is '{0}')", data_size);
1792 Int32 int_value_one = 0;
1794 if (int_value_one != 1)
1795 ARCANE_FATAL(
"Bad endianess for file. Read int as value '{0}' (expected=1)", int_value_one);
1801 if (!ios_file->lookForString(
"$EndMeshFormat"))
1811 if (next_line ==
"$PhysicalNames") {
1812 _readPhysicalNames();
1818 if (next_line ==
"$Entities") {
1823 if (next_line !=
"$Nodes")
1824 ARCANE_THROW(IOException,
"Unexpected string '{0}'. Valid values are '$Nodes'", next_line);
1830 if (ios_file && !ios_file->lookForString(
"$EndNodes"))
1834 if (ios_file && !ios_file->lookForString(
"$Elements"))
1840 if (ios_file && !ios_file->lookForString(
"$EndElements"))
1843 info() <<
"Computed mesh dimension = " << mesh_dimension;
1848 info() <<
"NextLine=" << next_line;
1854 if (next_line ==
"$Periodic") {
1867void MshParallelMeshReader::
1874 _addMshTypeInfo(MSH_PNT, ITI_Vertex);
1875 _addMshTypeInfo(MSH_LIN_2, ITI_Line2);
1876 _addMshTypeInfo(MSH_LIN_3, ITI_Line3);
1877 _addMshTypeInfo(MSH_TRI_3, ITI_Triangle3);
1878 _addMshTypeInfo(MSH_QUA_4, ITI_Quad4);
1879 _addMshTypeInfo(MSH_QUA_8, ITI_Quad8);
1880 _addMshTypeInfo(MSH_QUA_9, ITI_Quad9);
1881 _addMshTypeInfo(MSH_TET_4, ITI_Tetraedron4);
1882 _addMshTypeInfo(MSH_HEX_8, ITI_Hexaedron8);
1883 _addMshTypeInfo(MSH_PRI_6, ITI_Pentaedron6);
1884 _addMshTypeInfo(MSH_PRI_15, ITI_Pentaedron15);
1885 _addMshTypeInfo(MSH_PYR_5, ITI_Pyramid5);
1886 _addMshTypeInfo(MSH_PYR_13, ITI_Pyramid13);
1887 _addMshTypeInfo(MSH_TRI_6, ITI_Triangle6);
1889 FixedArray<Int16, 10> x({ 0, 1, 2, 3, 4, 5, 6, 7, 9, 8 });
1890 _addMshTypeInfo(MSH_TET_10, ITI_Tetraedron10, x.view());
1893 FixedArray<Int16, 20> x({ 0, 1, 2, 3, 4, 5, 6, 7,
1894 8, 11, 13, 9, 16, 18, 19, 17, 10, 12, 14, 15 });
1895 _addMshTypeInfo(MSH_HEX_20, ITI_Hexaedron20, x.view());
1898 FixedArray<Int16, 27> x({ 0, 1, 2, 3, 4, 5, 6, 7,
1899 8, 11, 13, 9, 16, 18, 19, 17, 10, 12, 14, 15,
1900 22, 23, 21, 24, 20, 25, 26 });
1901 _addMshTypeInfo(MSH_HEX_27, ITI_Hexaedron27, x.view());
1908void MshParallelMeshReader::
1916 ItemTypeMng* item_type_mng = m_mesh->itemTypeMng();
1917 ItemTypeInfo* iti = item_type_mng->typeFromId(arcane_type);
1925mshToArcaneTypeInfo(
Int32 msh_type)
const
1929 if (tx.m_arcane_type_info)
1932 ARCANE_THROW(NotSupportedException,
"MSH type '{0}' is not supported in Arcane", msh_type);
1943 m_mesh_info = impl::MshMeshGenerationInfo::getReference(
mesh,
true);
1944 info() <<
"Trying to read in parallel 'msh' file '" << filename <<
"'"
1945 <<
" use_internal_partition=" << use_internal_partition;
1949 if (!use_internal_partition)
1951 m_parallel_mng = pm;
1972 m_master_io_rank = master_io_rank;
1978 info() <<
"Is file readable ?=" << is_readable;
1979 file_readable[0] = is_readable ? 1 : 0;
1981 error() <<
"Unable to read file '" << filename <<
"'";
1983 pm->broadcast(file_readable.
view(), master_io_rank);
1984 if (file_readable[0] == 0) {
1988 std::ifstream ifile;
1993 ifile.open(filename.
localstr(), ios::binary);
1996 m_ios_file = ios_file;
1998 if (IosFile::isEqualString(mesh_format_str,
"$MeshFormat")) {
1999 _readMeshFromFile();
2000 if (!use_internal_partition) {
2001 info() <<
"Synchronize groups and variables";
2002 mesh->synchronizeGroupsAndVariables();
2007 info() <<
"The file does not begin with '$MeshFormat' returning RTError";
2015createMshParallelMeshReader(
ITraceMng* tm)
#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_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
ArrayView< T > view() const
Vue mutable sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
static ARCCORE_BASE_EXPORT std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Classe template pour convertir un type.
Tableau 1D de taille fixe.
constexpr __host__ __device__ ArrayView< T > view()
Vue modifiable sur le tableau.
constexpr __host__ __device__ SmallSpan< T, NbElement > span()
Vue modifiable sur le tableau.
Informations sur le type flottant.
Interface d'une famille d'entités.
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual String name() const =0
Nom de la famille.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
eReturnType
Types des codes de retour d'une lecture ou écriture.
@ RTError
Erreur lors de l'opération.
@ RTOk
Opération effectuée avec succès.
virtual const MeshKind meshKind() const =0
Caractéristiques du maillage.
virtual IPrimaryMesh * toPrimaryMesh()=0
Retourne l'instance sous la forme d'un IPrimaryMesh.
Exception lorsqu'une erreur d'entrée/sortie est détectée.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual IParallelMng * sequentialParallelMng()=0
Retourne un gestionnaire de parallélisme séquentiel.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual bool isMasterIO() const =0
true si l'instance est un gestionnaire maître des entrées/sorties.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual Integer masterIORank() const =0
Rang de l'instance gérant les entrées/sorties (pour laquelle isMasterIO() est vrai)
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual void endAllocate()=0
Indique une fin d'allocation de mailles.
virtual void allocateCells(Integer nb_cell, Int64ConstArrayView cells_infos, bool one_alloc=true)=0
Allocation d'un maillage.
virtual void setDimension(Integer dim)=0
Positionne la dimension du maillage (1D, 2D ou 3D).
Interface du gestionnaire de traces.
Routines des Lecture/Ecriture d'un fichier.
Groupe d'entités de maillage.
const String & name() const
Nom du groupe.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Ajoute des entités.
Type d'une entité (Item).
Infos sur un type d'entité du maillage.
Integer nbLocalNode() const
Nombre de noeuds de l'entité
String typeName() const
Nom du type.
ItemTypeId itemTypeId() const
Numéro du type.
Gestionnaire des types d'entités d'un maillage.
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
bool isNonManifold() const
Vrai si la structure du maillage est eMeshCellDimensionKind::NonManifold.
Informations pour créer les entités d'un genre.
Informations pour créer les entités Arcane.
UniqueArray< Int64 > nodes_unique_id
UniqueId() des noeuds de ma partie.
std::unordered_map< Int64, Int32 > nodes_rank_map
Tableau associatif (uniqueId(),rang) auquel le noeud appartiendra.
UniqueArray< Real3 > nodes_coordinates
Coordonnées des noeuds de ma partie.
Informations de correspondance entre le type MSH et le type Arcane.
Lecteur de fichiers de maillage au format msh.
bool _getIsEndOfFileAndBroadcast()
Retourne true si on est à la fin du fichier.
Int32 m_verbosity_level
Niveau de verbosité
void _readPeriodic()
Lecture des informations périodiques.
Integer _readElementsFromFile()
Lecture des éléments (mailles,faces,...)
void _addCellOrNodeGroup(ArrayView< Int64 > block_uids, Int32 block_index, const String &group_name, IItemFamily *family, bool filter_invalid)
Ajoute des mailles ou noeuds au groupe group_name.
void _readAndCheck(const String &expected_value)
Tente de lire la valeur value.
UniqueArray< Int32 > m_parts_rank
Liste des rangs qui participent à la conservation des données.
void _readEntities()
Lecture des entités.
Int32 m_nb_part
Nombre de partitions pour la lecture des noeuds et blocs.
UniqueArray< MshToArcaneTypeInfo > m_msh_to_arcane_type_infos
Informations de conversion entre les types MSH et Arcane pour les entités.
eReturnType readMeshFromMshFile(IMesh *mesh, const String &filename, bool use_internal_partition) override
Lit le maillage contenu dans le fichier filename et le construit dans mesh.
void _readNodesFromFile()
Lecture des noeuds du maillage.
void _setNodesCoordinates()
Positionne les coordonnées des noeuds.
bool m_is_binary
Vrai si le format est binaire.
void _addFaceGroup(const MshElementBlock &block, const String &group_name)
Ajoute des faces au groupe group_name.
void _computeNodesPartition()
void _readOneElementBlock(MshElementBlock &block)
Lit un bloc d'entité de type 'Element'.
String _getNextLineAndBroadcast()
Lis la valeur de la prochaine ligne et la broadcast aux autres rangs.
Vue sur les informations des noeuds.
Classe utilitaire pour réordonner les noeuds d'une entité.
Exception lorsqu'une opération n'est pas supportée.
Classe gérant un vecteur de réel de dimension 3.
Référence à une instance.
InstanceType * get() const
Instance associée ou nullptr si aucune.
Tableau 1D de données avec buffer pré-alloué sur la pile.
Vue d'un tableau d'éléments de type T.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Vue d'un tableau d'éléments de type T.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Span< const Byte > bytes() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
static String collapseWhiteSpace(const String &rhs)
Effectue une normalisation des caractères espaces.
Classe d'accès aux traces.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
Vecteur 1D de données avec sémantique par valeur (style STL).
Infos pour les entités 0D.
Infos pour les entités 1D, 2D et 3D.
Informations sur la périodicité
UniqueArray< double > m_affine_values
Liste des valeurs affines.
UniqueArray< Int64 > m_corresponding_nodes
Liste de couples (uniqueId noeud esclave, unique() noeud maître)
Infos sur un nom physique.
Informations d'un maillage issu du format 'msh'.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
ItemGroupT< Face > FaceGroup
Groupe de faces.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
@ ReduceSum
Somme des valeurs.
@ ReduceMin
Minimum des valeurs.
@ ReduceMax
Maximum des valeurs.
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
std::int16_t Int16
Type entier signé sur 16 bits.
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.
Infos d'un bloc pour $Elements pour la version 4.
ItemTypeId item_type
Type Arcane de l'entité
UniqueArray< Int64 > connectivities
< Liste des uniqueId() du bloc
Int64 nb_entity
Nombre d'entités du bloc.
Int32 item_nb_node
Nombre de noeuds de l'entité.
SmallSpan< const Int16 > reorder_infos
Si non vide, contient les indirections pour la renumérotation.
Int32 dimension
Dimension de l'entité
Int32 index
Index du bloc dans la liste.
Infos d'un bloc pour $Nodes.
Int32 index
Index du bloc dans la liste.
Int32 entity_dim
Dimension de l'entité associée.
Int64 index_in_allocation_info
Index dans MshMeshAllocateInfo des noeuds de ce bloc.
Int32 nb_node
Nombre d'entités du bloc.
Real x
première composante du triplet