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() <<
"Tentative de lecture du fichier MED nommé=" << 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() <<
"Erreur lors de la lecture du nombre de maillages";
326 info() <<
"MED: nb_mesh=" << nb_mesh;
328 error() <<
"Aucun maillage n'est présent";
336 int nb_axis = MEDmeshnAxis(fid, mesh_index);
338 error() <<
"Impossible de lire le nombre d'axes (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() <<
"Impossible de lire les informations du maillage (MEDmeshInfo) r=" << err;
365 if (meshtype != MED_UNSTRUCTURED_MESH) {
366 error() <<
"Arcane ne gère que les maillages non structurés MED (MED_UNSTRUCTURED_MESH) type=" << meshtype;
369 Integer mesh_dimension = meshdim;
370 if (mesh_dimension != 2 && mesh_dimension != 3)
371 ARCANE_FATAL(
"Le lecteur MED ne gère que les maillages 2D ou 3D");
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() <<
"Impossible de lire le nombre de nœuds (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() <<
"Vérification du groupe 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(
"Impossible de lire le nombre d'entités géométriques 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(
"Impossible de lire les informations pour le géotype 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(
"Impossible de lire le nombre d'éléments pour le géotype={0} nom={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(
"Le type MED '{0}' n'est pas pris en charge par 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);
574 mesh->itemTypeMng()->setMeshWithGeneralCells(mesh);
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(
"Impossible de trouver l'ID de famille '{0}' pour la maille '{1}' de géotype '{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;
649 _clearItemsInGroups();
666 Int32 item_dimension = iinfo.dimension();
668 if (item_dimension != (mesh_dimension - 1))
671 info() <<
"Lecture des faces géotype=" << geotype <<
" arcane_type=" << iinfo.arcaneType()
674 const bool is_polygon = (iinfo.medType() == MED_POLYGON);
676 Int32 nb_item =
_readItems(
mesh, fid, meshname, iinfo, poly_nb_nodes, poly_types_id, med_connectivity, med_family_values);
681 Int32 nb_item_node = iinfo.nbNode();
682 Int32 nb_family_values = med_family_values.
size();
683 if (arcane_type == IT_NullType) {
685 ARCANE_FATAL(
"Le type MED '{0}' n'est pas pris en charge par Arcane", iinfo.medType());
689 info() <<
"FACES_INFOS nb_item=" << nb_item <<
" type=" << arcane_type
690 <<
" nb_family_values=" << nb_family_values <<
" connectivity_size=" << med_connectivity.
size();
692 const Int32* indirection = iinfo.indirection();
693 Int64 med_connectivity_index = 0;
695 for (
Int32 i = 0; i < nb_item; ++i) {
700 nb_item_node = poly_nb_nodes[i];
701 orig_nodes_id.
resize(nb_item_node);
702 cinfo_span = orig_nodes_id;
705 Span<med_int> med_cinfo_span(med_connectivity.
span().subspan(med_connectivity_index, nb_item_node));
707 for (
Integer k = 0; k < nb_item_node; ++k) {
708 cinfo_span[k] = med_cinfo_span[indirection[k]];
712 for (
Integer k = 0; k < nb_item_node; ++k)
713 cinfo_span[k] = med_cinfo_span[k];
716 med_connectivity_index += nb_item_node;
718 nodes_reorderer.reorder(arcane_type, cinfo_span);
723 Node first_node(MeshUtils::findOneItem(node_family, ordered_nodes[0]));
724 if (first_node.
null())
725 ARCANE_FATAL(
"Impossible de trouver le nœud uid={0} pour l'indice de face '{1}'", ordered_nodes[0], i);
728 info() <<
"ERREUR: Impossible de trouver la face dans le maillage i=" << i <<
" nœuds=" << ordered_nodes;
730 for (
Face subface : first_node.
faces()) {
732 for (
Node subnode : subface.nodes()) {
736 ARCANE_FATAL(
"Impossible de trouver la face avec les nœuds=", ordered_nodes);
741 if (i < nb_family_values) {
743 med_int f = med_family_values[i];
746 ARCANE_FATAL(
"Impossible de trouver l'ID de famille '{0}' pour la face '{1}' de géotype '{2}'",
747 f, i, iinfo.medType());
753 info() <<
"FIN_LECTURE_DES_ENTITES";
762 med_idt fid,
const char* meshname)
764 const bool do_verbose =
false;
772 int err = MEDmeshNodeCoordinateRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
775 error() <<
"Impossible de lire les coordonnées des nœuds err=" << err;
780 for (Int64 i = 0; i < nb_node; ++i) {
781 Real3 xyz(coordinates[i * 3], coordinates[(i * 3) + 1], coordinates[(i * 3) + 2]);
783 info() <<
"I=" << i <<
" XYZ=" << xyz;
784 nodes_coordinates[i + 1] = xyz;
787 else if (spacedim == 2) {
788 for (
Int64 i = 0; i < nb_node; ++i) {
789 Real3 xyz(coordinates[i * 2], coordinates[(i * 2) + 1], 0.0);
791 info() <<
"I=" << i <<
" XYZ=" << xyz;
792 nodes_coordinates[i + 1] = xyz;
796 ARCANE_THROW(NotImplementedException,
"spacedim!=2 && spacedim!=3");
804 nodes_coord_var[inode] = nodes_coordinates[node.uniqueId()];
834 constexpr bool is_verbose =
false;
836 connectivity.
clear();
837 family_values.
clear();
840 int med_item_type = iinfo.medType();
841 med_bool coordinatechangement = {};
842 med_bool geotransformation = {};
843 med_int nb_med_item = 0;
844 if (iinfo.medType() == MED_POLYHEDRON) {
845 nb_med_item = _readPolyhedrons(
mesh, fid, meshname, poly_nb_nodes, poly_types_id, connectivity);
847 else if (iinfo.medType() == MED_POLYGON) {
850 med_int nb_index = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
851 MED_INDEX_NODE, MED_NODAL, &coordinatechangement,
854 ARCANE_FATAL(
"Impossible de lire le med_item_type MED '{0}' erreur={1}", med_item_type, nb_index);
856 info() <<
"MED: Lecture des entités";
857 info() <<
"MED: type=" << med_item_type <<
" nb_index=" << nb_index;
860 nb_med_item = nb_index - 1;
861 poly_nb_nodes.
resize(nb_med_item);
862 poly_types_id.
resize(nb_med_item);
864 med_int nb_connectivity = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT,
865 MED_CELL, MED_POLYGON, MED_CONNECTIVITY, MED_NODAL,
866 &coordinatechangement, &geotransformation);
867 if (nb_connectivity < 0)
868 ARCANE_FATAL(
"Impossible d'obtenir la taille de connectivité pour MED_POLYGON err={0}", nb_connectivity);
874 connectivity.
resize(nb_connectivity);
875 info() <<
"Lecture des polygones nb_connectivity=" << nb_connectivity;
876 int r = MEDmeshPolygonRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, MED_NODAL,
877 indexes.
data(), connectivity.
data());
879 ARCANE_FATAL(
"Impossible de lire la connectivité pour MED_POLYGON err={0}", r);
880 info() <<
"INDEXES=" << indexes;
881 for (
Int32 i = 0; i < nb_med_item; ++i) {
882 Int16 nb_node_for_cell = CheckedConvert::toInt16(indexes[i + 1] - indexes[i]);
883 poly_nb_nodes[i] = nb_node_for_cell;
888 nb_med_item = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
889 MED_CONNECTIVITY, MED_NODAL, &coordinatechangement,
892 ARCANE_FATAL(
"Impossible de lire le med_item_type MED '{0}' erreur={1}", med_item_type, nb_med_item);
894 info() <<
"MED: Lecture des entités";
895 info() <<
"MED: type=" << med_item_type <<
" nb_item=" << nb_med_item;
896 if (nb_med_item == 0)
899 Int64 nb_node = iinfo.nbNode();
904 connectivity.
resize(nb_node * nb_med_item);
905 int err = MEDmeshElementConnectivityRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL,
906 med_item_type, MED_NODAL, MED_FULL_INTERLACE,
907 connectivity.
data());
909 ARCANE_FATAL(
"Impossible de lire la connectivité MED med_item_type '{0}' erreur={1}",
913 info() <<
"CON: " << connectivity;
915 med_int nb_med_family = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT,
916 MED_CELL, med_item_type, MED_FAMILY_NUMBER, MED_NODAL,
917 &coordinatechangement, &geotransformation);
918 info() <<
"nb_family=" << nb_med_family;
919 if (nb_med_family < 0)
920 ARCANE_FATAL(
"Impossible de lire la taille de la famille pour le type med_item_type={0} erreur={1}", med_item_type, nb_med_family);
921 if (nb_med_family > 0) {
922 family_values.
resize(nb_med_family);
923 int r = MEDmeshEntityFamilyNumberRd(fid, meshname, MED_NO_DT, MED_NO_IT,
924 MED_CELL, med_item_type, family_values.
data());
926 ARCANE_FATAL(
"Impossible de lire les valeurs de famille pour le type med_item_type={0} erreur={1}", med_item_type, nb_med_family);
928 info() <<
"FAM: " << family_values;
937med_int MEDMeshReader::
943 if (
mesh->parallelMng()->commSize() > 1)
944 ARCANE_FATAL(
"Les maillages MED polyédriques ne sont pas supportés en parallèle");
945 const bool is_verbose =
false;
947 med_bool coordinatechangement = {};
948 med_bool geotransformation = {};
949 const med_int med_item_type = MED_POLYHEDRON;
950 info() <<
"MED: Lecture des entités polyédriques";
953 med_int nb_face_index = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
954 MED_INDEX_FACE, MED_NODAL, &coordinatechangement,
956 if (nb_face_index < 0)
957 ARCANE_FATAL(
"Impossible de lire MED_INDEX_FACE pour le type Polyèdre erreur={0}", nb_face_index);
958 info() <<
"MED: type=" << med_item_type <<
" nb_face_index=" << nb_face_index;
959 if (nb_face_index < 1)
962 med_int nb_node_index = ::MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, med_item_type,
963 MED_INDEX_NODE, MED_NODAL, &coordinatechangement,
965 if (nb_node_index < 0)
966 ARCANE_FATAL(
"Impossible de lire MED_INDEX_NODE pour le type Polyèdre erreur={0}", nb_node_index);
968 info() <<
"MED: type=" << med_item_type <<
" nb_face_index=" << nb_face_index <<
" nb_node_index=" << nb_node_index;
969 med_int nb_med_item = nb_face_index - 1;
970 poly_nb_nodes.
resize(nb_med_item);
971 poly_types_id.
resize(nb_med_item);
973 med_int nb_connectivity = MEDmeshnEntity(fid, meshname, MED_NO_DT, MED_NO_IT,
974 MED_CELL, MED_POLYHEDRON, MED_CONNECTIVITY, MED_NODAL,
975 &coordinatechangement, &geotransformation);
976 if (nb_connectivity < 0)
977 ARCANE_FATAL(
"Impossible d'obtenir la taille de connectivité pour MED_POLYHEDRON err={0}", nb_connectivity);
982 UniqueArray<med_int> face_indexes(nb_face_index);
983 UniqueArray<med_int> node_indexes(nb_node_index);
984 connectivity.
clear();
985 connectivity.
reserve(nb_connectivity);
986 UniqueArray<med_int> med_connectivity(nb_connectivity);
987 info() <<
"Lecture des polyèdres nb_connectivity=" << nb_connectivity;
988 int r = MEDmeshPolyhedronRd(fid, meshname, MED_NO_DT, MED_NO_IT, MED_CELL, MED_NODAL,
989 face_indexes.data(), node_indexes.data(), med_connectivity.
data());
991 ARCANE_FATAL(
"Impossible de lire la connectivité pour MED_POLYGON err={0}", r);
993 info() <<
"FACE_INDEXES=" << face_indexes;
994 info() <<
"NODE_INDEXES=" << node_indexes;
995 info() <<
"CONNECTIVITY=" << med_connectivity;
997 UniqueArray<Int16> local_nodes_of_cell;
998 UniqueArray<Int32> nodes_of_cell;
999 UniqueArray<Int32> nodes_of_face;
1002 UniqueArray<Int16> arcane_faces_nb_node;
1003 UniqueArray<Int16> arcane_faces_nodes;
1005 std::map<Int32, Int16> connectivity_to_local_index;
1006 for (
Int32 z = 0; z < nb_med_item; ++z) {
1007 Int16 nb_local_node = 0;
1008 nodes_of_cell.clear();
1009 connectivity_to_local_index.clear();
1010 local_nodes_of_cell.clear();
1011 arcane_faces_nb_node.clear();
1012 arcane_faces_nodes.clear();
1013 Int32 connectivity_index = connectivity.
size();
1015 Int32 first_face_index = face_indexes[z] - 1;
1016 Int32 next_face_index = face_indexes[z + 1] - 1;
1017 Int32 cell_nb_face = next_face_index - first_face_index;
1018 Int32 cell_nb_node = node_indexes[next_face_index] - node_indexes[first_face_index];
1020 info() <<
"POLYHEDRAL_CELL=" << z <<
" nb_face=" << cell_nb_face
1021 <<
" nb_node=" << cell_nb_node <<
" first_face_index=" << first_face_index
1022 <<
" nb_info_in_connectivity=" << node_indexes[cell_nb_face];
1023 Int16 nb_connectivity_for_cell = 3 + cell_nb_node + cell_nb_face;
1024 connectivity.
add(nb_connectivity_for_cell);
1025 const Int64 scheme_version = 1;
1026 connectivity.
add(scheme_version);
1027 connectivity.
add(cell_nb_face);
1028 for (
Int32 k = 0; k < cell_nb_face; ++k) {
1029 Int32 first_node_index = node_indexes[first_face_index + k] - 1;
1030 Int32 next_node_index = node_indexes[first_face_index + k + 1] - 1;
1031 Int16 face_nb_node = CheckedConvert::toInt16(next_node_index - first_node_index);
1032 nodes_of_face.resize(face_nb_node);
1033 arcane_faces_nb_node.add(face_nb_node);
1034 connectivity.
add(face_nb_node);
1035 for (
Int32 p = 0; p < face_nb_node; ++p) {
1037 Int32 node_id = med_connectivity[first_node_index + p];
1038 auto x = connectivity_to_local_index.find(node_id);
1039 Int16 local_node_index = -1;
1040 if (x == connectivity_to_local_index.end()) {
1041 local_node_index = nb_local_node;
1042 connectivity_to_local_index[node_id] = nb_local_node;
1044 local_nodes_of_cell.add(local_node_index);
1045 nodes_of_cell.add(node_id);
1048 local_node_index = x->second;
1049 connectivity.
add(node_id);
1050 nodes_of_face[p] = local_node_index;
1051 arcane_faces_nodes.add(local_node_index);
1054 info() <<
" POLYHEDRAL_FACE=" << k <<
" nb_node=" << face_nb_node <<
" nodes=" << nodes_of_face.view();
1058 info() <<
"POLYHEDRAL_CELL=" << z <<
" nb_local_node=" << nodes_of_cell.size() <<
" nodes=" << nodes_of_cell
1059 <<
" nb_connectivity_for_cell=" << nb_connectivity_for_cell;
1060 info() <<
"POLYHEDRAL_CELL=" << z <<
" arcane_faces_nb_node=" << arcane_faces_nb_node <<
" nodes=" << arcane_faces_nodes;
1062 poly_types_id[z] = IT_GenericPolyhedron;
1063 poly_nb_nodes[z] = nb_connectivity_for_cell;
1072_readFamilies(med_idt fid,
const char* meshname)
1074 FixedArray<char, MED_NAME_SIZE + 1> familyname;
1076 info() <<
"Lecture des familles";
1079 med_int nb_family = MEDnFamily(fid, meshname);
1081 ARCANE_FATAL(
"Impossible de lire le nombre de familles (erreur={0})", nb_family);
1083 info() <<
"MED: nb_family= " << nb_family;
1084 for (med_int i = 0; i < nb_family; i++) {
1085 info() <<
"MED: Lecture de la famille i=" << i;
1087 med_int nb_group = MEDnFamilyGroup(fid, meshname, i + 1);
1089 ARCANE_FATAL(
"Impossible de lire le nombre de groupes pour l'indice de famille={0}", i);
1090 info() <<
"MED: indice de famille=" << i <<
" nb_group=" << nb_group;
1097 UniqueArray<char> all_group_names(MED_LNAME_SIZE * nb_group + 1);
1098 med_int family_number = 0;
1099 if (MEDfamilyInfo(fid, meshname, i + 1, familyname.data(), &family_number, all_group_names.data()) < 0)
1100 ARCANE_FATAL(
"Impossible de lire les noms de groupes à partir de l'indice de famille={0}", i);
1104 med_family.m_index = group_index;
1108 for (
Int32 z = 0; z < nb_group; ++z) {
1110 SmallSpan<char> med_group_name = all_group_names.smallSpan().subSpan(MED_LNAME_SIZE * z, MED_LNAME_SIZE);
1113 SmallArray<Byte, MED_LNAME_SIZE + 1> valid_name;
1115 for (; pos < MED_LNAME_SIZE; ++pos) {
1116 char c = med_group_name[pos];
1119 if (c ==
' ' || c ==
'_')
1121 valid_name.add(
static_cast<Byte>(c));
1123 String name(valid_name.view());
1124 med_group.m_names.add(name);
1125 info() <<
"ID de famille=" << family_number <<
" groupe='" << name <<
"'";
1150 for (
String name : group_names)
1151 pm->broadcastString(name, 0);
1156 String current_group_name;
1157 for (
Int32 i = 0; i < nb_group; ++i) {
1158 pm->broadcastString(current_group_name, 0);
1172class MEDMeshReaderService
1173:
public BasicService
1187 return str ==
"med";
1190 [[maybe_unused]]
const XmlNode& mesh_element,
1193 [[maybe_unused]]
bool use_internal_partition)
override
1195 ARCANE_UNUSED(dir_name);
1197 return reader.readMesh(
mesh, file_name);
1216class MEDCaseMeshReader
1229 , m_read_info(read_info)
1236 ARCANE_UNUSED(build_info);
1241 String fname = m_read_info.fileName();
1242 m_trace_mng->info() <<
"Lecteur MED (ICaseMeshReader) file_name=" << fname;
1265 if (read_info.format() ==
"med")
#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.
Face getFaceFromNodesUniqueId(Node node, Int64ConstArrayView face_nodes_unique_id)
Recherche une entité face à partir des numéros uniques de ces noeuds.
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.
Integer size() const
Nombre d'éléments du vecteur.
Classe de base d'un service.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
Vue modifiable d'un tableau d'un type T.
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
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.
const T * data() const
Accès à la racine du tableau hors toute protection.
Span< const T > span() const
Vue immutable sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Informations nécessaires pour la lecture d'un fichier de maillage.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Tableau 1D de taille fixe.
Interface du service de lecture du maillage à partir du jeu de données.
Interface d'une famille d'entités.
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
Interface d'un service de création/lecture du maillage.
Interface du service gérant la lecture d'un maillage.
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.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual void allocateCells(Integer nb_cell, Int64ConstArrayView cells_infos, bool one_alloc=true)=0
Allocation d'un maillage.
Interface du gestionnaire de traces.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Ajoute des entités.
Classe utilitaire pour imprimer les infos sur une entité.
Type d'une entité (Item).
Infos sur un type d'entité du maillage.
String typeName() const
Nom du type.
Gestionnaire des types d'entités d'un maillage.
ItemTypeId getPolygonType(Int16 nb_node) const
Retourne le type pour un polygone ayant nb_node.
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
void allocateMeshItems(IPrimaryMesh *pm) override
Alloue les entités du maillage géré par ce service.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Remplit build_info avec les informations nécessaires pour créer le maillage.
Service de lecture d'un maillage au format MED depuis le jeu de données.
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...
bool allowExtension(const String &str) override
Vérifie si le service supporte les fichiers avec l'extension str.
void build() override
Construction de niveau build du service.
eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_element, const String &file_name, const String &dir_name, bool use_internal_partition) override
Lit un maillage à partir d'un fichier.
Information sur une famille d'entité MED.
Int32 m_family_id
Id de la famille pour MED.
Int32 m_index
Index dans la liste des groupes Arcane.
Liste des groupes et des entités leur appartenant.
Int32 m_index
Index du groupe dans la liste des groupes.
UniqueArray< Int64 > m_unique_ids
Liste des uniqueId() des entités du groupe.
UniqueArray< String > m_names
Nom des groupes associés.
UniqueArray< Int32 > m_local_ids
Liste des localId() des entités du groupe.
Informations pour passer des types MED aux types Arcane pour les entités.
Lecteur de maillages au format MED.
void _broadcastGroups(ConstArrayView< String > names, IItemFamily *family)
Broadcast les groupes de group_names pour la famille family.
UniqueArray< MEDToArcaneItemInfo > m_med_to_arcane_types
Tableau de conversion entre les types MED et Arcane.
void _readAvailableTypes(med_idt fid, const char *meshname)
Récupère la liste des types géométriques présents dans le maillage.
IPrimaryMesh * m_mesh
Maillage en cours de lecture.
UniqueArray< MEDGroupInfo > m_med_groups
Liste des informations sur les groupes.
std::unordered_map< Int32, MEDFamilyInfo > m_med_families_map
Liste des familles.
std::unordered_map< med_int, Int32 > m_med_geotype_to_arcane_type_index
Table des index dans m_med_to_arcane_type de chaque geotype.
UniqueArray< med_int > m_med_geotypes_in_mesh
Liste des 'geotype' présents dans le maillage.
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)
Lit les informations des entités d'un type donné.
void _readFaces(IPrimaryMesh *mesh, Int32 mesh_dimension, med_idt fid, const char *meshname)
Lit les faces.
Paramètres nécessaires à la construction d'un maillage.
Vue sur les informations des noeuds.
FaceConnectedListViewType faces() const
Liste des faces du noeud.
Classe utilitaire pour réordonner les noeuds d'une entité.
Exception lorsqu'une fonction n'est pas implémentée.
Référence à une instance.
Structure contenant les informations pour créer un service.
Tableau 1D de données avec buffer pré-alloué sur la pile.
Vue d'un tableau d'éléments de type T.
Chaîne de caractères unicode.
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.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Cell > CellGroup
Groupe de mailles.
ItemGroupT< Face > FaceGroup
Groupe de faces.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-- 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.
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.
std::int16_t Int16
Type entier signé sur 16 bits.
unsigned char Byte
Type d'un octet.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.