14#include "arcane/utils/ITraceMng.h"
15#include "arcane/utils/SmallArray.h"
16#include "arcane/utils/FixedArray.h"
17#include "arcane/utils/Convert.h"
18#include "arcane/utils/CheckedConvert.h"
20#include "arcane/core/IMeshReader.h"
21#include "arcane/core/BasicService.h"
23#include "arcane/core/IPrimaryMesh.h"
24#include "arcane/core/IItemFamily.h"
25#include "arcane/core/ICaseMeshReader.h"
26#include "arcane/core/IMeshBuilder.h"
27#include "arcane/core/IParallelMng.h"
28#include "arcane/core/MeshPartInfo.h"
29#include "arcane/core/NodesOfItemReorderer.h"
31#include "arcane/core/ItemPrinter.h"
32#include "arcane/core/internal/ItemTypeMngInternal.h"
65 class MEDToArcaneItemInfo
69 MEDToArcaneItemInfo(
int dimension,
int nb_node, med_int med_type,
71 : m_dimension(dimension)
73 , m_med_type(med_type)
74 , m_arcane_type(arcane_type)
75 , m_indirection(indirection)
80 int dimension()
const {
return m_dimension; }
81 int nbNode()
const {
return m_nb_node; }
82 med_int medType()
const {
return m_med_type; }
83 Int16 arcaneType()
const {
return m_arcane_type; }
84 const Int32* indirection()
const {
return m_indirection; }
90 med_int m_med_type = {};
92 const Int32* m_indirection =
nullptr;
100 explicit MEDFamilyInfo(
Int32 family_id)
124 explicit MEDGroupInfo(
Int32 index)
145 _initMEDToArcaneTypes();
162 explicit AutoCloseMED(med_idt
id)
191 void _initMEDToArcaneTypes();
192 void _addTypeInfo(
int dimension,
int nb_node, med_int med_type,
ItemTypeId arcane_type)
194 _addTypeInfo(dimension, nb_node, med_type, arcane_type,
nullptr);
196 void _addTypeInfo(
int dimension,
int nb_node, med_int med_type,
ItemTypeId arcane_type,
197 const Int32* indirection)
199 MEDToArcaneItemInfo t(dimension, nb_node, med_type, arcane_type, indirection);
204 void _readAndCreateCells(IPrimaryMesh* mesh, Int32 mesh_dimension, med_idt fid,
const char* meshname);
205 void _readFaces(IPrimaryMesh* mesh, Int32 mesh_dimension, med_idt fid,
const char* meshname);
208 _readNodesCoordinates(IPrimaryMesh* mesh, Int64 nb_node, Int32 spacedim,
209 med_idt fid,
const char* meshname);
210 void _readFamilies(med_idt fid,
const char* meshname);
212 void _clearItemsInGroups()
215 g.m_unique_ids.clear();
216 g.m_local_ids.clear();
220 med_int _readPolyhedrons(IPrimaryMesh* mesh, med_idt fid,
const char* meshname,
221 Array<Int16>& poly_nb_nodes,
222 Array<Int16>& poly_types_id,
223 Array<med_int>& connectivity);
233 const Int32 Hexaedron8_indirection[] = { 1, 0, 3, 2, 5, 4, 7, 6 };
234 const Int32 Hexaedron20_indirection[] = { 1, 8, 10, 3, 9, 2, 0, 11, 5, 14, 18, 7, 6, 4, 16, 15, 13, 12, 17, 19 };
235 const Int32 Pyramid5_indirection[] = { 1, 0, 3, 2, 4 };
236 const Int32 Quad4_indirection[] = { 1, 0, 3, 2 };
237 const Int32 Quad8_indirection[] = { 1, 0, 3, 2, 4, 7, 6, 5 };
238 const Int32 Triangle3_indirection[] = { 1, 0, 2 };
240 const Int32 Tetraedron4_indirection[] = { 1, 0, 2, 3 };
247_initMEDToArcaneTypes()
254 _addTypeInfo(1, 2, MED_SEG2, ITI_Line2);
255 _addTypeInfo(1, 3, MED_SEG3, ITI_Line3);
256 _addTypeInfo(1, 4, MED_SEG4, ITI_NullType);
259 _addTypeInfo(2, 3, MED_TRIA3, ITI_Triangle3, Triangle3_indirection);
260 _addTypeInfo(2, 4, MED_QUAD4, ITI_Quad4, Quad4_indirection);
261 _addTypeInfo(2, 6, MED_TRIA6, ITI_NullType);
262 _addTypeInfo(2, 7, MED_TRIA7, ITI_NullType);
263 _addTypeInfo(2, 8, MED_QUAD8, ITI_Quad8, Quad8_indirection);
264 _addTypeInfo(2, 9, MED_QUAD9, ITI_NullType);
267 _addTypeInfo(3, 4, MED_TETRA4, ITI_Tetraedron4);
268 _addTypeInfo(3, 5, MED_PYRA5, ITI_Pyramid5, Pyramid5_indirection);
269 _addTypeInfo(3, 6, MED_PENTA6, ITI_Pentaedron6);
270 _addTypeInfo(3, 8, MED_HEXA8, ITI_Hexaedron8);
271 _addTypeInfo(3, 10, MED_TETRA10, ITI_Tetraedron10);
272 _addTypeInfo(3, 12, MED_OCTA12, ITI_Octaedron12);
273 _addTypeInfo(3, 13, MED_PYRA13, ITI_NullType);
274 _addTypeInfo(3, 15, MED_PENTA15, ITI_NullType);
275 _addTypeInfo(3, 18, MED_PENTA18, ITI_NullType);
276 _addTypeInfo(3, 20, MED_HEXA20, ITI_Hexaedron20);
277 _addTypeInfo(3, 27, MED_HEXA27, ITI_NullType);
285 _addTypeInfo(2, 0, MED_POLYGON, ITI_GenericPolygon);
286 _addTypeInfo(2, 0, MED_POLYGON2, ITI_NullType);
287 _addTypeInfo(3, 0, MED_POLYHEDRON, ITI_GenericPolyhedron);
301 info() <<
"Trying to read MED File name=" << file_name;
303 return _readMesh(mesh, file_name);
312 const med_idt fid = MEDfileOpen(filename.localstr(), MED_ACC_RDONLY);
314 MESSAGE(
"ERROR: can not open MED file ");
315 error() <<
"ERROR: can not open MED file '" << filename <<
"'";
321 int nb_mesh = MEDnMesh(fid);
323 error() <<
"Error reading number of meshes";
326 info() <<
"MED: nb_mesh=" << nb_mesh;
328 error() <<
"No mesh is present";
336 int nb_axis = MEDmeshnAxis(fid, mesh_index);
338 error() <<
"Can not read number of axis (MEDmeshnAxis)";
341 info() <<
"MED: nb_axis=" << nb_axis;
343 UniqueArray<char> axisname(MED_SNAME_SIZE * nb_axis + 1,
'\0');
344 UniqueArray<char> unitname(MED_SNAME_SIZE * nb_axis + 1,
'\0');
346 char meshname[MED_NAME_SIZE + 1];
348 char meshdescription[MED_COMMENT_SIZE + 1];
349 meshdescription[0] =
'\0';
350 char dtunit[MED_SNAME_SIZE + 1];
352 med_int spacedim = 0;
354 med_mesh_type meshtype = MED_UNDEF_MESH_TYPE;
355 med_sorting_type sortingtype = MED_SORT_UNDEF;
357 med_axis_type axistype = MED_UNDEF_AXIS_TYPE;
359 err = MEDmeshInfo(fid, mesh_index, meshname, &spacedim, &meshdim, &meshtype, meshdescription,
360 dtunit, &sortingtype, &nstep, &axistype, axisname.data(), unitname.data());
362 error() <<
"Can not read mesh info (MEDmeshInfo) r=" << err;
365 if (meshtype != MED_UNSTRUCTURED_MESH) {
366 error() <<
"Arcane handle only MED unstructured mesh (MED_UNSTRUCTURED_MESH) type=" << meshtype;
369 Integer mesh_dimension = meshdim;
370 if (mesh_dimension != 2 && mesh_dimension != 3)
371 ARCANE_FATAL(
"MED reader handles only 2D or 3D meshes");
373 info() <<
"MED: name=" << meshname;
374 info() <<
"MED: description=" << meshdescription;
375 info() <<
"MED: spacedim=" << spacedim;
376 info() <<
"MED: meshdim=" << meshdim;
377 info() <<
"MED: dtunit=" << dtunit;
378 info() <<
"MED: meshtype=" << meshtype;
379 info() <<
"MED: sortingtype=" << sortingtype;
380 info() <<
"MED: axistype=" << axistype;
381 info() <<
"MED: nstep=" << nstep;
386 med_bool coordinatechangement;
387 med_bool geotransformation;
390 med_int med_nb_node = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NO_GEOTYPE,
391 MED_COORDINATE, MED_NO_CMODE, &coordinatechangement,
393 if (med_nb_node < 0) {
394 error() <<
"Can not read number of nodes (MEDmeshnEntity) err=" << med_nb_node;
397 nb_node = med_nb_node;
399 info() <<
"MED: nb_node=" << nb_node;
401 mesh->setDimension(mesh_dimension);
406 mesh->itemTypeMng()->buildPolygonTypes();
408 IParallelMng* pm = mesh->parallelMng();
409 bool is_parallel = pm->isParallel();
410 Int32 rank = mesh->meshPartInfo().partRank();
412 bool is_read_items = !(is_parallel && rank != 0);
415 _readFamilies(fid, meshname);
416 _readAndCreateCells(mesh, mesh_dimension, fid, meshname);
425 UniqueArray<String> cell_group_names;
426 IItemFamily* cell_family = mesh->cellFamily();
433 UniqueArray<Int32> cell_local_ids;
435 Int32 nb_cell_in_group = g.m_unique_ids.size();
436 cell_local_ids.resize(nb_cell_in_group);
437 cell_family->itemsUniqueIdToLocalId(cell_local_ids, g.m_unique_ids);
438 for (
const String& name : g.m_names) {
439 info() <<
"Group=" << name <<
" index=" << g.m_index <<
" nb_item=" << nb_cell_in_group;
440 CellGroup cell_group = cell_family->findGroup(name,
true);
441 cell_group.
addItems(cell_local_ids);
442 cell_group_names.add(name);
453 bool is_face_group_disabled =
false;
455 is_face_group_disabled = (v.value());
456 if (!is_face_group_disabled)
457 _readFaces(mesh, mesh_dimension, fid, meshname);
460 UniqueArray<String> face_group_names;
461 IItemFamily* face_family = mesh->faceFamily();
465 Int32 nb_face_in_group = g.m_local_ids.size();
466 info() <<
"Check Group index=" << g.m_index <<
" nb_item=" << nb_face_in_group;
467 if (nb_face_in_group == 0)
469 for (
const String& name : g.m_names) {
470 info() <<
"FaceGroup=" << name <<
" index=" << g.m_index <<
" nb_item=" << nb_face_in_group;
471 FaceGroup face_group = face_family->findGroup(name,
true);
473 face_group_names.add(name);
481 return _readNodesCoordinates(mesh, nb_node, spacedim, fid, meshname);
495 med_bool coordinatechangement;
496 med_bool geotransformation;
497 med_int nb_geo = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, MED_GEO_ALL,
498 MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
501 ARCANE_FATAL(
"Can not read number of geometric entities nb_geo={0}", nb_geo);
502 info() <<
"MED: nb_geotype = " << nb_geo;
505 for (med_int it = 1; it <= nb_geo; it++) {
507 med_geometry_type geotype = MED_GEO_ALL;
511 med_int type_ret = MEDmeshEntityInfo(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, it,
512 geotype_name.data(), &geotype);
514 ARCANE_FATAL(
"Can not read informations for geotype index={0} ret={1}", it, type_ret);
516 med_int nb_item = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, geotype,
517 MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
520 ARCANE_FATAL(
"Can not read number of items for geotype={0} name={1} ret={2}",
521 geotype, geotype_name.data(), nb_item);
522 info() <<
"MED: type=" << geotype <<
" '" << geotype_name.data() <<
"' nb_item=" << nb_item;
533 _clearItemsInGroups();
538 Int64 cell_unique_id = 0;
554 Int32 item_dimension = iinfo.dimension();
556 if (item_dimension != mesh_dimension)
558 Int32 nb_item =
_readItems(
mesh, fid, meshname, iinfo, poly_nb_nodes, poly_types_id, med_connectivity, med_family_values);
562 Int16 arcane_type = iinfo.arcaneType();
563 Int32 nb_item_node = iinfo.nbNode();
564 Int32 nb_family_values = med_family_values.
size();
565 if (arcane_type == IT_NullType) {
567 ARCANE_FATAL(
"MED type '{0}' is not supported by Arcane", iinfo.medType());
569 Int64 cells_infos_index = 0;
570 Int64 med_connectivity_index = 0;
571 const bool is_poly = (iinfo.medType() == MED_POLYGON) || (iinfo.medType() == MED_POLYHEDRON);
575 UniqueArray<Int64> cells_infos;
577 cells_infos.resize(2 * nb_item + med_connectivity.
size());
579 cells_infos.resize((2 + nb_item_node) * nb_item);
581 info() <<
"CELL_INFOS size=" << cells_infos.size() <<
" nb_item=" << nb_item
582 <<
" type=" << arcane_type;
584 const Int32* indirection = iinfo.indirection();
585 for (Int32 i = 0; i < nb_item; ++i) {
586 Int64 current_cell_unique_id = cell_unique_id;
589 nb_item_node = poly_nb_nodes[i];
590 arcane_type = poly_types_id[i];
591 cells_infos[cells_infos_index] = arcane_type;
593 cells_infos[cells_infos_index] = current_cell_unique_id;
595 Span<Int64> cinfo_span(cells_infos.span().subspan(cells_infos_index, nb_item_node));
596 Span<med_int> med_cinfo_span(med_connectivity.
span().subspan(med_connectivity_index, nb_item_node));
597 for (
Integer k = 0; k < nb_item_node; ++k) {
598 cinfo_span[k] = med_cinfo_span[k];
602 cells_infos[cells_infos_index] = arcane_type;
604 cells_infos[cells_infos_index] = current_cell_unique_id;
606 Span<Int64> cinfo_span(cells_infos.span().subspan(cells_infos_index, nb_item_node));
607 Span<med_int> med_cinfo_span(med_connectivity.
span().subspan(med_connectivity_index, nb_item_node));
609 for (
Integer k = 0; k < nb_item_node; ++k) {
610 cinfo_span[k] = med_cinfo_span[indirection[k]];
614 for (
Integer k = 0; k < nb_item_node; ++k)
615 cinfo_span[k] = med_cinfo_span[k];
618 if (i < nb_family_values) {
620 med_int f = med_family_values[i];
623 ARCANE_FATAL(
"Can not find family id '{0}' for cell '{1}' of geotype '{2}'",
624 f, i, iinfo.medType());
626 m_med_groups[x->second.m_index].m_unique_ids.add(current_cell_unique_id);
629 med_connectivity_index += nb_item_node;
630 cells_infos_index += nb_item_node;
648 _clearItemsInGroups();
665 Int32 item_dimension = iinfo.dimension();
667 if (item_dimension != (mesh_dimension - 1))
670 info() <<
"Reading faces geotype=" << geotype <<
" arcane_type=" << iinfo.arcaneType()
673 const bool is_polygon = (iinfo.medType() == MED_POLYGON);
675 Int32 nb_item =
_readItems(
mesh, fid, meshname, iinfo, poly_nb_nodes, poly_types_id, med_connectivity, med_family_values);
680 Int32 nb_item_node = iinfo.nbNode();
681 Int32 nb_family_values = med_family_values.
size();
682 if (arcane_type == IT_NullType) {
684 ARCANE_FATAL(
"MED type '{0}' is not supported by Arcane", iinfo.medType());
688 info() <<
"FACES_INFOS nb_item=" << nb_item <<
" type=" << arcane_type
689 <<
" nb_family_values=" << nb_family_values <<
" connectivity_size=" << med_connectivity.
size();
691 const Int32* indirection = iinfo.indirection();
692 Int64 med_connectivity_index = 0;
694 for (
Int32 i = 0; i < nb_item; ++i) {
698 nb_item_node = poly_nb_nodes[i];
699 orig_nodes_id.
resize(nb_item_node);
700 cinfo_span = orig_nodes_id;
703 Span<med_int> med_cinfo_span(med_connectivity.
span().subspan(med_connectivity_index, nb_item_node));
705 for (
Integer k = 0; k < nb_item_node; ++k) {
706 cinfo_span[k] = med_cinfo_span[indirection[k]];
710 for (
Integer k = 0; k < nb_item_node; ++k)
711 cinfo_span[k] = med_cinfo_span[k];
714 med_connectivity_index += nb_item_node;
716 nodes_reorderer.reorder(arcane_type, cinfo_span);
721 Node first_node(MeshUtils::findOneItem(node_family, ordered_nodes[0]));
722 if (first_node.
null())
723 ARCANE_FATAL(
"Can not find node uid={0} for face index '{1}'", ordered_nodes[0], i);
726 info() <<
"ERROR: Can not find face in mesh i=" << i <<
" nodes=" << ordered_nodes;
728 for (
Face subface : first_node.
faces()) {
730 for (
Node subnode : subface.nodes()) {
734 ARCANE_FATAL(
"Can not find face with nodes=", ordered_nodes);
739 if (i < nb_family_values) {
741 med_int f = med_family_values[i];
744 ARCANE_FATAL(
"Can not find family id '{0}' for face '{1}' of geotype '{2}'",
745 f, i, iinfo.medType());
751 info() <<
"END_READING_ITEMS";
760 med_idt fid,
const char* meshname)
762 const bool do_verbose =
false;
770 int err = MEDmeshNodeCoordinateRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
773 error() <<
"Can not read nodes coordinates err=" << err;
778 for (Int64 i = 0; i < nb_node; ++i) {
779 Real3 xyz(coordinates[i * 3], coordinates[(i * 3) + 1], coordinates[(i * 3) + 2]);
781 info() <<
"I=" << i <<
" XYZ=" << xyz;
782 nodes_coordinates[i + 1] = xyz;
785 else if (spacedim == 2) {
786 for (
Int64 i = 0; i < nb_node; ++i) {
787 Real3 xyz(coordinates[i * 2], coordinates[(i * 2) + 1], 0.0);
789 info() <<
"I=" << i <<
" XYZ=" << xyz;
790 nodes_coordinates[i + 1] = xyz;
794 ARCANE_THROW(NotImplementedException,
"spacedim!=2 && spacedim!=3");
802 nodes_coord_var[inode] = nodes_coordinates[node.uniqueId()];
832 constexpr bool is_verbose =
false;
834 connectivity.
clear();
835 family_values.
clear();
838 int med_item_type = iinfo.medType();
839 med_bool coordinatechangement = {};
840 med_bool geotransformation = {};
841 med_int nb_med_item = 0;
842 if (iinfo.medType() == MED_POLYHEDRON) {
843 nb_med_item = _readPolyhedrons(
mesh, fid, meshname, poly_nb_nodes, poly_types_id, connectivity);
845 else if (iinfo.medType() == MED_POLYGON) {
848 med_int nb_index = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
849 MED_INDEX_NODE, MED_NODAL, &coordinatechangement,
852 ARCANE_FATAL(
"Can not read MED med_item_type '{0}' error={1}", med_item_type, nb_index);
854 info() <<
"MED: Reading items";
855 info() <<
"MED: type=" << med_item_type <<
" nb_index=" << nb_index;
858 nb_med_item = nb_index - 1;
859 poly_nb_nodes.
resize(nb_med_item);
860 poly_types_id.
resize(nb_med_item);
862 med_int nb_connectivity = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT,
863 MED_CELL, MED_POLYGON, MED_CONNECTIVITY, MED_NODAL,
864 &coordinatechangement, &geotransformation);
865 if (nb_connectivity < 0)
866 ARCANE_FATAL(
"Can not get connectivity size for MED_POLYGON err={0}", nb_connectivity);
872 connectivity.
resize(nb_connectivity);
873 info() <<
"Reading polygons nb_connectivity=" << nb_connectivity;
874 int r = MEDmeshPolygonRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, MED_NODAL,
875 indexes.
data(), connectivity.
data());
877 ARCANE_FATAL(
"Can not read connectivity for MED_POLYGON err={0}", r);
878 info() <<
"INDEXES=" << indexes;
879 for (
Int32 i = 0; i < nb_med_item; ++i) {
880 Int16 nb_node_for_cell = CheckedConvert::toInt16(indexes[i + 1] - indexes[i]);
881 poly_nb_nodes[i] = nb_node_for_cell;
886 nb_med_item = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
887 MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
890 ARCANE_FATAL(
"Can not read MED med_item_type '{0}' error={1}", med_item_type, nb_med_item);
892 info() <<
"MED: Reading items";
893 info() <<
"MED: type=" << med_item_type <<
" nb_item=" << nb_med_item;
894 if (nb_med_item == 0)
897 Int64 nb_node = iinfo.nbNode();
902 connectivity.
resize(nb_node * nb_med_item);
903 int err = MEDmeshElementConnectivityRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,
904 med_item_type, MED_NODAL, MED_FULL_INTERLACE,
905 connectivity.
data());
907 ARCANE_FATAL(
"Can not read connectivity MED med_item_type '{0}' error={1}",
911 info() <<
"CON: " << connectivity;
913 med_int nb_med_family = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT,
914 MED_CELL, med_item_type, MED_FAMILY_NUMBER, MED_NODAL,
915 &coordinatechangement, &geotransformation);
916 info() <<
"nb_family=" << nb_med_family;
917 if (nb_med_family < 0)
918 ARCANE_FATAL(
"Can not read family size for type med_item_type={0} error={1}", med_item_type, nb_med_family);
919 if (nb_med_family > 0) {
920 family_values.
resize(nb_med_family);
921 int r = MEDmeshEntityFamilyNumberRd(fid, meshname, MED_NO_DT, MED_NO_IT,
922 MED_CELL, med_item_type, family_values.
data());
924 ARCANE_FATAL(
"Can not read family values for type med_item_type={0} error={1}", med_item_type, nb_med_family);
926 info() <<
"FAM: " << family_values;
935med_int MEDMeshReader::
941 if (
mesh->parallelMng()->commSize() > 1)
942 ARCANE_FATAL(
"MED polyhedral mesh in not support in parallel");
943 const bool is_verbose =
false;
945 med_bool coordinatechangement = {};
946 med_bool geotransformation = {};
947 const med_int med_item_type = MED_POLYHEDRON;
948 info() <<
"MED: Reading polyhedron items";
950 med_int nb_face_index = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
951 MED_INDEX_FACE, MED_NODAL, &coordinatechangement,
953 if (nb_face_index < 0)
954 ARCANE_FATAL(
"Can not read MED_INDEX_FACE for Polyhedron type error={0}", nb_face_index);
955 info() <<
"MED: type=" << med_item_type <<
" nb_face_index=" << nb_face_index;
956 if (nb_face_index < 1)
959 med_int nb_node_index = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
960 MED_INDEX_NODE, MED_NODAL, &coordinatechangement,
962 if (nb_node_index < 0)
963 ARCANE_FATAL(
"Can not read MED_INDEX_NODE for Polyhedron type error={0}", nb_node_index);
965 info() <<
"MED: type=" << med_item_type <<
" nb_face_index=" << nb_face_index <<
" nb_node_index=" << nb_node_index;
966 med_int nb_med_item = nb_face_index - 1;
967 poly_nb_nodes.
resize(nb_med_item);
968 poly_types_id.
resize(nb_med_item);
970 med_int nb_connectivity = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT,
971 MED_CELL, MED_POLYHEDRON, MED_CONNECTIVITY, MED_NODAL,
972 &coordinatechangement, &geotransformation);
973 if (nb_connectivity < 0)
974 ARCANE_FATAL(
"Can not get connectivity size for MED_POLYHEDRON err={0}", nb_connectivity);
979 UniqueArray<med_int> face_indexes(nb_face_index);
980 UniqueArray<med_int> node_indexes(nb_node_index);
981 connectivity.
clear();
982 connectivity.
reserve(nb_connectivity);
983 UniqueArray<med_int> med_connectivity(nb_connectivity);
984 info() <<
"Reading polyhedron nb_connectivity=" << nb_connectivity;
985 int r = MEDmeshPolyhedronRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, MED_NODAL,
986 face_indexes.data(), node_indexes.data(), med_connectivity.
data());
988 ARCANE_FATAL(
"Can not read connectivity for MED_POLYGON err={0}", r);
990 info() <<
"FACE_INDEXES=" << face_indexes;
991 info() <<
"NODE_INDEXES=" << node_indexes;
992 info() <<
"CONNECTIVITY=" << med_connectivity;
994 UniqueArray<Int16> local_nodes_of_cell;
995 UniqueArray<Int32> nodes_of_cell;
996 UniqueArray<Int32> nodes_of_face;
999 UniqueArray<Int16> arcane_faces_nb_node;
1000 UniqueArray<Int16> arcane_faces_nodes;
1002 std::map<Int32, Int16> connectivity_to_local_index;
1003 for (
Int32 z = 0; z < nb_med_item; ++z) {
1004 Int16 nb_local_node = 0;
1005 nodes_of_cell.clear();
1006 connectivity_to_local_index.clear();
1007 local_nodes_of_cell.clear();
1008 arcane_faces_nb_node.clear();
1009 arcane_faces_nodes.clear();
1010 Int32 connectivity_index = connectivity.
size();
1012 Int32 first_face_index = face_indexes[z] - 1;
1013 Int32 next_face_index = face_indexes[z + 1] - 1;
1014 Int32 cell_nb_face = next_face_index - first_face_index;
1015 Int32 cell_nb_node = node_indexes[next_face_index] - node_indexes[first_face_index];
1017 info() <<
"POLYHEDRAL_CELL=" << z <<
" nb_face=" << cell_nb_face
1018 <<
" nb_node=" << cell_nb_node <<
" first_face_index=" << first_face_index
1019 <<
" nb_info_in_connectivity=" << node_indexes[cell_nb_face];
1020 Int16 nb_connectivity_for_cell = 3 + cell_nb_node + cell_nb_face;
1021 connectivity.
add(nb_connectivity_for_cell);
1022 const Int64 scheme_version = 1;
1023 connectivity.
add(scheme_version);
1024 connectivity.
add(cell_nb_face);
1025 for (
Int32 k = 0; k < cell_nb_face; ++k) {
1026 Int32 first_node_index = node_indexes[first_face_index + k] - 1;
1027 Int32 next_node_index = node_indexes[first_face_index + k + 1] - 1;
1028 Int16 face_nb_node = CheckedConvert::toInt16(next_node_index - first_node_index);
1029 nodes_of_face.resize(face_nb_node);
1030 arcane_faces_nb_node.add(face_nb_node);
1031 connectivity.
add(face_nb_node);
1032 for (
Int32 p = 0; p < face_nb_node; ++p) {
1034 Int32 node_id = med_connectivity[first_node_index + p];
1035 auto x = connectivity_to_local_index.find(node_id);
1036 Int16 local_node_index = -1;
1037 if (x == connectivity_to_local_index.end()) {
1038 local_node_index = nb_local_node;
1039 connectivity_to_local_index[node_id] = nb_local_node;
1041 local_nodes_of_cell.add(local_node_index);
1042 nodes_of_cell.add(node_id);
1045 local_node_index = x->second;
1046 connectivity.
add(node_id);
1047 nodes_of_face[p] = local_node_index;
1048 arcane_faces_nodes.add(local_node_index);
1051 info() <<
" POLYHEDRAL_FACE=" << k <<
" nb_node=" << face_nb_node <<
" nodes=" << nodes_of_face.view();
1055 info() <<
"POLYHEDRAL_CELL=" << z <<
" nb_local_node=" << nodes_of_cell.size() <<
" nodes=" << nodes_of_cell
1056 <<
" nb_connectivity_for_cell=" << nb_connectivity_for_cell;
1057 info() <<
"POLYHEDRAL_CELL=" << z <<
" arcane_faces_nb_node=" << arcane_faces_nb_node <<
" nodes=" << arcane_faces_nodes;
1059 poly_types_id[z] = IT_GenericPolyhedron;
1060 poly_nb_nodes[z] = nb_connectivity_for_cell;
1069_readFamilies(med_idt fid,
const char* meshname)
1071 FixedArray<char, MED_NAME_SIZE + 1> familyname;
1073 info() <<
"Read families";
1076 med_int nb_family = MEDnFamily(fid, meshname);
1078 ARCANE_FATAL(
"Can not read number of families (error={0})", nb_family);
1080 info() <<
"MED: nb_family= " << nb_family;
1081 for (med_int i = 0; i < nb_family; i++) {
1082 info() <<
"MED: Read family i=" << i;
1084 med_int nb_group = MEDnFamilyGroup(fid, meshname, i + 1);
1086 ARCANE_FATAL(
"Can not read number of groups for family index={0}", i);
1087 info() <<
"MED: family index=" << i <<
" nb_group=" << nb_group;
1094 UniqueArray<char> all_group_names(MED_LNAME_SIZE * nb_group + 1);
1095 med_int family_number = 0;
1096 if (MEDfamilyInfo(fid, meshname, i + 1, familyname.data(), &family_number, all_group_names.data()) < 0)
1097 ARCANE_FATAL(
"Can not read group names from family index={0}", i);
1101 med_family.m_index = group_index;
1105 for (
Int32 z = 0; z < nb_group; ++z) {
1107 SmallSpan<char> med_group_name = all_group_names.smallSpan().subSpan(MED_LNAME_SIZE * z, MED_LNAME_SIZE);
1110 SmallArray<Byte, MED_LNAME_SIZE + 1> valid_name;
1112 for (; pos < MED_LNAME_SIZE; ++pos) {
1113 char c = med_group_name[pos];
1116 if (c ==
' ' || c ==
'_')
1118 valid_name.add(
static_cast<Byte>(c));
1120 String name(valid_name.view());
1121 med_group.m_names.add(name);
1122 info() <<
"Family id=" << family_number <<
" group='" << name <<
"'";
1147 for (
String name : group_names)
1148 pm->broadcastString(name, 0);
1153 String current_group_name;
1154 for (
Int32 i = 0; i < nb_group; ++i) {
1155 pm->broadcastString(current_group_name, 0);
1169class MEDMeshReaderService
1170:
public BasicService
1184 return str ==
"med";
1187 [[maybe_unused]]
const XmlNode& mesh_element,
1190 [[maybe_unused]]
bool use_internal_partition)
override
1192 ARCANE_UNUSED(dir_name);
1194 return reader.readMesh(
mesh, file_name);
1213class MEDCaseMeshReader
1226 , m_read_info(read_info)
1233 ARCANE_UNUSED(build_info);
1238 String fname = m_read_info.fileName();
1239 m_trace_mng->info() <<
"MED Reader (ICaseMeshReader) file_name=" << fname;
1262 if (read_info.format() ==
"med")
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Utility functions for the mesh.
Face getFaceFromNodesUniqueId(Node node, Int64ConstArrayView face_nodes_unique_id)
Searches for a face entity using the unique numbers of these nodes.
This file contains the various service factories and macros for registering services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
Integer size() const
Number of elements in the vector.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
Modifiable view of an array of type T.
Base class for 1D data vectors.
Span< const T > span() const
Immutable view of this array.
void resize(Int64 s)
Changes the number of elements in the array to s.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
const T * data() const
Access to the root of the array without any protection.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
Necessary information for reading a mesh file.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Interface for the mesh reading service from the dataset.
Interface of an entity family.
virtual ItemGroup findGroup(const String &name) const =0
Searches for a group.
virtual NodeGroup allNodes()=0
Group of all nodes.
Interface of a mesh creation/reading service.
Interface of the service managing the reading of a mesh.
eReturnType
Types of return codes for a read or write operation.
@ RTError
Error during the operation.
@ RTOk
Operation successfully performed.
virtual ItemTypeMng * itemTypeMng() const =0
Associated entity type manager.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual VariableNodeReal3 & nodesCoordinates()=0
Node coordinates.
virtual void allocateCells(Integer nb_cell, Int64ConstArrayView cells_infos, bool one_alloc=true)=0
Allocation of a mesh.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Adds entities.
Utility class for printing information about an entity.
Type of an entity (Item).
Info on a mesh entity type.
String typeName() const
Type name.
Mesh entity type manager.
void setMeshWithGeneralCells(IMesh *mesh) noexcept
Allows the mesh to indicate to the ItemTypeMng if it has generic cells.
ItemTypeId getPolygonType(Int16 nb_node) const
Returns the type for a polygon having nb_node.
ItemTypeInfo * typeFromId(Integer id) const
Type corresponding to the number id.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
constexpr bool null() const
true if the entity is null (i.e. not connected to the mesh)
void allocateMeshItems(IPrimaryMesh *pm) override
Allocates the mesh entities managed by this service.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Fills build_info with the necessary information to create the mesh.
Service for reading a mesh in MED format from the dataset.
Ref< IMeshBuilder > createBuilder(const CaseMeshReaderReadInfo &read_info) const override
Returns a builder to create and read the mesh whose information is specified in read_info.
bool allowExtension(const String &str) override
Checks if the service supports files with the extension str.
void build() override
Build-level construction of the service.
eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_element, const String &file_name, const String &dir_name, bool use_internal_partition) override
Reads a mesh from a file.
Information about a MED entity family.
Int32 m_family_id
Family ID for MED.
Int32 m_index
Index in the Arcane group list.
List of groups and the entities belonging to them.
Int32 m_index
Index of the group in the group list.
UniqueArray< Int64 > m_unique_ids
List of uniqueId() of the group's entities.
UniqueArray< String > m_names
Associated group names.
UniqueArray< Int32 > m_local_ids
List of localId() of the group's entities.
Information for mapping MED types to Arcane types for entities.
void _broadcastGroups(ConstArrayView< String > names, IItemFamily *family)
Broadcast the groups of group_names for the family family.
UniqueArray< MEDToArcaneItemInfo > m_med_to_arcane_types
Conversion table between MED and Arcane types.
void _readAvailableTypes(med_idt fid, const char *meshname)
Retrieves the list of geometric types present in the mesh.
IPrimaryMesh * m_mesh
Mesh currently being read.
UniqueArray< MEDGroupInfo > m_med_groups
List of group information.
std::unordered_map< Int32, MEDFamilyInfo > m_med_families_map
List of families.
std::unordered_map< med_int, Int32 > m_med_geotype_to_arcane_type_index
Table of indices in m_med_to_arcane_type for each geotype.
UniqueArray< med_int > m_med_geotypes_in_mesh
List of 'geotypes' present in the mesh.
Int32 _readItems(IPrimaryMesh *mesh, med_idt fid, const char *meshnane, const MEDToArcaneItemInfo &iinfo, Array< Int16 > &poly_nb_nodes, Array< Int16 > &poly_types, Array< med_int > &connectivity, Array< med_int > &family_values)
Reads information about entities of a given type.
void _readFaces(IPrimaryMesh *mesh, Int32 mesh_dimension, med_idt fid, const char *meshname)
Reads the faces.
Parameters necessary for building a mesh.
View of node information.
FaceConnectedListViewType faces() const
List of faces of the node.
Utility class to reorder the nodes of an entity.
Exception when a function is not implemented.
Reference to an instance.
Structure containing the information to create a service.
1D data array with pre-allocated stack buffer.
View of an array of elements of type T.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
ItemGroupT< Cell > CellGroup
Group of cells.
ItemGroupT< Face > FaceGroup
Group of faces.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
@ ST_SubDomain
The service is used at the subdomain level.
std::int16_t Int16
Signed integer type of 16 bits.
unsigned char Byte
Type of a byte.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.