14#include "arcane/ArcaneTypes.h"
15#include "arcane/utils/ArcanePrecomp.h"
16#include "arcane/utils/Iostream.h"
17#include "arcane/utils/StdHeader.h"
18#include "arcane/utils/HashTableMap.h"
19#include "arcane/utils/ValueConvert.h"
20#include "arcane/utils/ScopedPtr.h"
21#include "arcane/utils/ITraceMng.h"
22#include "arcane/utils/String.h"
23#include "arcane/utils/IOException.h"
24#include "arcane/utils/Collection.h"
25#include "arcane/utils/Enumerator.h"
26#include "arcane/utils/NotImplementedException.h"
27#include "arcane/utils/Real3.h"
29#include "arcane/AbstractService.h"
30#include "arcane/FactoryService.h"
31#include "arcane/IMainFactory.h"
32#include "arcane/IMeshReader.h"
33#include "arcane/ISubDomain.h"
34#include "arcane/IPrimaryMesh.h"
35#include "arcane/IItemFamily.h"
36#include "arcane/Item.h"
37#include "arcane/ItemEnumerator.h"
38#include "arcane/VariableTypes.h"
39#include "arcane/IVariableAccessor.h"
40#include "arcane/IParallelMng.h"
41#include "arcane/IIOMng.h"
42#include "arcane/IXmlDocumentHolder.h"
43#include "arcane/XmlNodeList.h"
44#include "arcane/XmlNode.h"
45#include "arcane/IMeshUtilities.h"
46#include "arcane/IMeshWriter.h"
47#include "arcane/BasicService.h"
49#define XDMF_USE_ANSI_STDLIB
50#include "vtkxdmf2/XdmfArray.h"
51#include "vtkxdmf2/XdmfAttribute.h"
52#include "vtkxdmf2/XdmfDOM.h"
53#include "vtkxdmf2/XdmfDataDesc.h"
54#include "vtkxdmf2/XdmfDataItem.h"
55#include "vtkxdmf2/XdmfGrid.h"
56#include "vtkxdmf2/XdmfTopology.h"
57#include "vtkxdmf2/XdmfGeometry.h"
58#include "vtkxdmf2/XdmfTime.h"
85 const String& file_name,
const String& dir_name,
bool use_internal_partition);
87 ISubDomain* subDomain() {
return m_sub_domain; }
90 ISubDomain* m_sub_domain;
91 eReturnType _readTopology(XdmfTopology*, XdmfInt64&, Int32Array&, Int32Array&, Int32Array&, SharedArray<Int32>);
92 eReturnType _readMixedTopology(XdmfTopology*, XdmfInt64, Int32Array&, Int32Array&, Int32Array&, SharedArray<Int32>);
102XmfMeshReader::XmfMeshReader(
const ServiceBuildInfo& sbi):AbstractService(sbi), m_sub_domain(sbi.subDomain()){}
109#define _addThisConnectivity(nNodes, arcType)\
110 cells_type.add(arcType);\
111 cells_nb_node.add(nNodes);\
112 for (XdmfInt32 z=0; z<nNodes; ++z)\
113 cells_connectivity.add(nodesUidArray[xdmfConnectivity->GetValueAsInt32(i++)]);
121_readMixedTopology(XdmfTopology *Topology,
122 XdmfInt64 nb_elements,
128 info() <<
"[_readMixedTopology] Entering";
129 XdmfArray *xdmfConnectivity=Topology->GetConnectivity(NULL, XDMF_TRUE);
130 XdmfInt32 numType=xdmfConnectivity->GetNumberType();
131 info() <<
"xdmfConnectivity.CoreLength=" << xdmfConnectivity->GetCoreLength()<<
" numType=" << numType;
132 if (numType != XDMF_INT32_TYPE)
133 throw NotSupportedException(A_FUNCINFO,
"Not supported connectivity num type");
134 XdmfInt32 nNodesForThisElement;
135 XdmfInt64 iElementsScaned=0;
136 for(XdmfInt64 i=0; iElementsScaned < nb_elements; iElementsScaned++){
138 switch (xdmfConnectivity->GetValueAsInt32(i++)){
139 case (XDMF_POLYVERTEX):
140 nNodesForThisElement=xdmfConnectivity->GetValueAsInt32(i++);
142 switch (nNodesForThisElement){
143 case (1): _addThisConnectivity(1, IT_Vertex);
break;
144 case (12): _addThisConnectivity(12, IT_Octaedron12);
break;
145 case (14): _addThisConnectivity(14, IT_Enneedron14);
break;
146 case (16): _addThisConnectivity(16, IT_Decaedron16);
break;
147 case (7): _addThisConnectivity(7, IT_HemiHexa7);
break;
148 case (6): _addThisConnectivity(6, IT_HemiHexa6);
break;
155 case (5): _addThisConnectivity(5, IT_HemiHexa5);
break;
156 case (55): _addThisConnectivity(5, IT_DiTetra5);
break;
158 throw FatalErrorException(A_FUNCINFO,
"XDMF_POLYVERTEX with unknown number of nodes");
161 case (XDMF_POLYLINE):
162 nNodesForThisElement=xdmfConnectivity->GetValueAsInt32(i++);
164 switch (nNodesForThisElement){
165 case (2): _addThisConnectivity(2, IT_Line2);
break;
166 default:
throw FatalErrorException(A_FUNCINFO,
"XDMF_POLYLINE with unknown number of nodes");
170 nNodesForThisElement=xdmfConnectivity->GetValueAsInt32(i++);
172 switch (nNodesForThisElement){
173 case (5): _addThisConnectivity(5, IT_Pentagon5);
break;
174 case (6): _addThisConnectivity(6, IT_Hexagon6);
break;
175 default:
throw FatalErrorException(A_FUNCINFO,
"XDMF_POLYGON with unknown number of nodes");
178 case (XDMF_TRI):_addThisConnectivity(3, IT_Triangle3);
break;
179 case (XDMF_QUAD):_addThisConnectivity(4, IT_Quad4);
break;
180 case (XDMF_TET):_addThisConnectivity(4, IT_Tetraedron4);
break;
181 case (XDMF_PYRAMID):_addThisConnectivity(5, IT_Pyramid5);
break;
182 case (XDMF_WEDGE ):_addThisConnectivity(6, IT_Pentaedron6);
break;
183 case (XDMF_HEX):_addThisConnectivity(8, IT_Hexaedron8);
break;
184 case (XDMF_TET_10):_addThisConnectivity(10, IT_Heptaedron10);
break;
188 case (XDMF_PYRAMID_13):
189 case (XDMF_WEDGE_15):
191 default:
throw NotSupportedException(A_FUNCINFO,
"Not supported topology type in a mixed one");
195 info() <<
"[_readMixedTopology] Done";
217_readTopology(XdmfTopology *Topology,
218 XdmfInt64& nb_elements,
224 info() <<
"[_readTopology] Entering";
225 if (!Topology)
throw FatalErrorException(A_FUNCINFO,
"Null topology");
226 if (Topology->UpdateInformation() != XDMF_SUCCESS)
throw FatalErrorException(A_FUNCINFO,
"Error in UpdateInformation");
227 if (Topology->Update() != XDMF_SUCCESS)
throw FatalErrorException(A_FUNCINFO,
"Error in Update");
228 nb_elements = Topology->GetNumberOfElements();
229 info() <<
"\tHave found a " << Topology->GetClassAsString() <<
" "
230 << Topology->GetTopologyTypeAsString() <<
" topology with " << nb_elements <<
" elements";
231 switch (Topology->GetTopologyType()){
233 case (XDMF_2DRECTMESH):
234 case (XDMF_2DCORECTMESH):
235 case (XDMF_3DRECTMESH):
236 case (XDMF_3DCORECTMESH):
237 case (XDMF_3DSMESH):{
239 if ((nb_elements%3)==0){
240 for(XdmfInt64 i=0; i<nb_elements/3; i+=3){
241 cells_type.add(IT_Triangle3);
242 cells_nb_node.add(3);
244 cells_connectivity.add(i+z);
246 }
else if ((nb_elements%4)==0){
247 for(XdmfInt64 i=0; i<nb_elements/4; i+=4){
248 cells_type.add(IT_Quad4);
249 cells_nb_node.add(4);
251 cells_connectivity.add(i+z);
253 }
else throw FatalErrorException(A_FUNCINFO,
"Could not match XDMF_3DSMESH with a known mesh");
257 case (XDMF_POLYVERTEX):
258 case (XDMF_POLYLINE):
270 case (XDMF_PYRAMID_13):
271 case (XDMF_WEDGE_15):
274 if (_readMixedTopology(Topology, nb_elements, cells_nb_node, cells_connectivity, cells_type, nodesUidArray) !=
RTOk)
275 throw FatalErrorException(A_FUNCINFO,
"Error in _readMixedTopology");
277 case (XDMF_NOTOPOLOGY):
278 default:
throw NotSupportedException(A_FUNCINFO,
"Not supported topology type");
282 info() <<
"[_readTopology] Release & Done";
306 const String& file_name,
const String& dir_name,
bool use_internal_partition)
311 bool itWasAnArcanProduction=
true;
313 info() <<
"[readMeshFromFile] Entering";
314 XdmfDOM *DOM =
new XdmfDOM();
319 XdmfXmlNode XdmfRoot = DOM->GetTree();
322 if (strcmp(DOM->Get(XdmfRoot,
"Version"),
"2.0")<0)
throw NotSupportedException(A_FUNCINFO,
"Not supported Xdmf-file version");
325 XdmfInt64 nRootChildren=DOM->GetNumberOfChildren(XdmfRoot);
326 info() <<
"GetNumberOfChildren=" << nRootChildren;
329 XdmfInt32 nDomains= DOM->FindNumberOfElements(
"Domain");
330 info() <<
"nDomains=" << nDomains;
333 for(XdmfInt64 iDomain=0; iDomain < nDomains; ++iDomain){
334 XdmfXmlNode foundDomain=DOM->FindElement(
"Domain", iDomain, XdmfRoot, 0);
335 if (foundDomain != NULL)
info() <<
"Have found domain" << iDomain;
338 XdmfInt32 nGrids= DOM->FindNumberOfElements(
"Grid", foundDomain);
339 info() <<
"nGrids=" << nGrids;
340 for(XdmfInt32 iGrid=0; iGrid < nGrids; ++iGrid){
344 XdmfXmlNode foundGrid=DOM->FindElement(
"Grid", iGrid, foundDomain, 0);
346 XdmfGrid *
Grid =
new XdmfGrid();
348 Grid->SetElement(foundGrid);
349 Grid->UpdateInformation();
350 info() <<
"Have found a " <<
Grid->GetGridTypeAsString() <<
" grid";
356 XdmfXmlNode cellsUniqueIDsXmlNode = DOM->FindElementByAttribute (
"Name",
"CellsUniqueIDs", 0, foundGrid);
358 if (cellsUniqueIDsXmlNode) {
359 info() <<
"[XmfMeshReader] cellsUidArray were found";
360 XdmfAttribute *attribute =
new XdmfAttribute();
361 attribute->SetDOM(DOM);
362 attribute->SetElement(cellsUniqueIDsXmlNode);
363 attribute->UpdateInformation();
365 XdmfArray *xmfGroup = attribute->GetValues();
366 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
367 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
368 XdmfInt64 nb_item = xmfGroup->GetNumberOfElements();
369 for(XdmfInt64 uid=0; uid<nb_item; ++uid)
370 cellsUidArray.
add(xmfGroup->GetValueAsInt32(uid));
371 }
else itWasAnArcanProduction=
false;
376 XdmfXmlNode nodesUniqueIDsXmlNode = DOM->FindElementByAttribute (
"Name",
"NodesUniqueIDs", 0, foundGrid);
378 if (nodesUniqueIDsXmlNode) {
379 info() <<
"[XmfMeshReader] nodesUidArray were found";
380 XdmfAttribute *attribute =
new XdmfAttribute();
381 attribute->SetDOM(DOM);
382 attribute->SetElement(nodesUniqueIDsXmlNode);
383 attribute->UpdateInformation();
385 XdmfArray *xmfGroup = attribute->GetValues();
386 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
387 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
388 XdmfInt64 nb_item = xmfGroup->GetNumberOfElements();
389 for(XdmfInt64 uid=0; uid<nb_item; ++uid)
390 nodesUidArray.
add(xmfGroup->GetValueAsInt32(uid));
392 else itWasAnArcanProduction=
false;
397 XdmfXmlNode nodesOwnerXmlNode = DOM->FindElementByAttribute (
"Name",
"NodesOwner", 0, foundGrid);
399 if (nodesOwnerXmlNode) {
400 info() <<
"[XmfMeshReader] nodesOwnerArray were found";
401 XdmfAttribute *attribute =
new XdmfAttribute();
402 attribute->SetDOM(DOM);
403 attribute->SetElement(nodesOwnerXmlNode);
404 attribute->UpdateInformation();
406 XdmfArray *xmfGroup = attribute->GetValues();
407 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
408 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
409 XdmfInt64 nb_item = xmfGroup->GetNumberOfElements();
410 for(XdmfInt64 uid=0; uid<nb_item; ++uid)
411 nodesOwnerArray.
add(xmfGroup->GetValueAsInt32(uid));
414 itWasAnArcanProduction=
false;
419 XdmfGeometry* xmfGometry =
Grid->GetGeometry();
422 info() <<
"\tHave found a " << xmfGometry->GetGeometryTypeAsString() <<
" geometry";
423 if (xmfGometry->GetGeometryType() != XDMF_GEOMETRY_XYZ)
425 xmfGometry->UpdateInformation();
426 xmfGometry->Update();
428 XdmfInt64 nbOfNodes = xmfGometry->GetNumberOfPoints();
433 if (!itWasAnArcanProduction){
434 info() <<
"If it is not ours, just fake the indirection process";
435 for(
Integer uid=0; uid<nbOfNodes; ++uid){
436 nodesUidArray.
add(uid);
437 cellsUidArray.
add(uid);
438 nodesOwnerArray.
add(uid);
442 XdmfArray *xdmfPoints = xmfGometry->GetPoints(XDMF_TRUE);
443 XdmfInt32 numType=xdmfPoints->GetNumberType();
444 if (numType!=XDMF_FLOAT32_TYPE)
throw NotSupportedException(A_FUNCINFO,
"Not supported geometry number type");
446 for(XdmfInt64 i=0; iNode<nbOfNodes; iNode++, i+=3){
447 Real3 coords=
Real3(xdmfPoints->GetValueAsFloat32(i),
448 xdmfPoints->GetValueAsFloat32(i+1),
449 xdmfPoints->GetValueAsFloat32(i+2));
450 nodes_coords.
nocheckAdd(nodesUidArray[iNode], coords);
457 XdmfInt64 nb_elements;
461 XdmfTopology *topology=
Grid->GetTopology();
462 if (_readTopology(topology, nb_elements, cells_nb_node, cells_connectivity, cells_type, nodesUidArray) !=
RTOk)
463 throw IOException(
"XmfMeshReader",
"_readTopology error");
467 if (nodesOwnerXmlNode && itWasAnArcanProduction){
468 info() <<
"[_XmfMeshReader] Create hash table for nodes owner";
469 for(
Integer i=0; i<nbOfNodes; ++i ){
471 nodes_owner_map.
nocheckAdd(nodesUidArray[i], nodesOwnerArray[i]);
479 info() <<
"[_XmfMeshReader] Création des mailles, nb_cell=" << nb_elements <<
" cells_type.size=" << cells_type.
size();
480 Integer connectivity_index = 0;
482 cells_infos.
add(cells_type[i]);
483 cells_infos.
add(cellsUidArray[i]);
484 for (
Integer z=0; z<cells_nb_node[i]; ++z )
485 cells_infos.
add(cells_connectivity[connectivity_index+z]);
486 connectivity_index += cells_nb_node[i];
492 info() <<
"[XmfMeshReader] ## Mesh 3D ##";
493 mesh->setDimension(3);
494 info() <<
"[XmfMeshReader] ## Allocating ##";
495 mesh->allocateCells(cells_type.
size(), cells_infos,
false);
501 info() <<
"[XmfMeshReader] internalNodes.size()="<<internalNodes.
size();
502 if (nodesOwnerXmlNode && itWasAnArcanProduction){
503 info() <<
"[XmfMeshReader] Setting nodes owners from xmf file";
504 for(
Integer i=0, is=internalNodes.
size(); i<is; ++i){
507 Int32 true_owner = nodes_owner_map[internal_node->
uniqueId()];
508 internal_node->
setOwner(true_owner,sid);
512 for(
Integer i=0, is=internalNodes.
size(); i<is; ++i)
513 internalNodes[i]->setOwner(sid,sid);
516 info() <<
"[XmfMeshReader] internalCells.size()="<<internalCells.
size();
517 for(
Integer i=0, is=internalCells.
size(); i<is; ++i)
518 internalCells[i]->setOwner(sid,sid);
523 info() <<
"[XmfMeshReader] ## Ending with endAllocate ##";
526 info() <<
"[XmfMeshReader] ## setOwnersFromCells ##";
527 mesh->setOwnersFromCells();
529 info() <<
"\n\n[XmfMeshReader] ## Now dealing with ghost's layer ##";
530 info() <<
"[XmfMeshReader] mesh.nbNode=" <<
mesh->nbNode() <<
" mesh.nbCell="<<
mesh->nbCell();
535 XdmfInt32 nAttributes=
Grid->GetNumberOfAttributes();
536 info() <<
"nAttributes=" << nAttributes;
537 for(XdmfInt64 iAttribute=0; iAttribute < nAttributes; ++iAttribute){
538 XdmfAttribute *attribute =
Grid->GetAttribute(iAttribute);
539 if ((attribute == NULL || (!itWasAnArcanProduction)))
continue;
540 if ((strcasecmp(attribute->GetName(),
"NodesUniqueIDs")==0)||
541 (strcasecmp(attribute->GetName(),
"CellsUniqueIDs")==0)||
542 (strcasecmp(attribute->GetName(),
"NodesOwner")==0)){
543 info() <<
"Skipping " << attribute->GetName();
547 XdmfArray *xmfGroup = attribute->GetValues();
548 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
549 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
553 Integer nb_item = xmfGroup->GetNumberOfElements() - 1;
557 for(XdmfInt64 z=0; z<nb_item; ++z )
558 unique_ids[z] = xmfGroup->GetValueAsInt32(z+1);
567 for(
Integer i=0; i<nb_item; ++i )
568 if (local_ids[i]!=NULL_ITEM_LOCAL_ID)
569 ids.
add(local_ids[i]);
571 info() <<
"Create group family=" << family->
name() <<
" name=" << attribute->GetName() <<
" ids=" << ids.
size();
572 family->
createGroup(attribute->GetName(),ids,
true);
578 info() <<
"[XmfMeshReader] ## Now insert coords ##";
581 nodes_coord_var[iNode] = nodes_coords[iNode->uniqueId()];
587 mesh->synchronizeGroupsAndVariables();
591 info() <<
"[readMeshFromFile] RTOk";
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Integer size() const
Nombre d'éléments du vecteur.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Exception lorsqu'une erreur fatale est survenue.
Table de hachage pour tableaux associatifs.
void nocheckAdd(KeyTypeConstRef id, const ValueType &value)
Ajoute la valeur value correspondant à la clé id.
Interface d'une famille d'entités.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
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.
Interface du service gérant la lecture d'un maillage.
eReturnType
Types des codes de retour d'une lecture ou écriture.
@ RTOk
Opération effectuée avec succès.
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 bool isParallel() const =0
Retourne true si l'exécution est parallèle.
Interface du gestionnaire d'un sous-domaine.
ItemUniqueId uniqueId() const
Numéro unique de l'entité
Structure interne d'une entité de maillage.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
Exception lorsqu'une opération n'est pas supportée.
Classe gérant un vecteur réel de 3 dimensions.
Structure contenant les informations pour créer un service.
Vecteur 1D de données avec sémantique par référence.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
TraceMessage info() const
Flot pour un message d'information.
virtual void build()
Construction de niveau build du service.
bool allowExtension(const String &str)
Vérifie si le service supporte les fichiers avec l'extension str.
virtual eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_node, const String &file_name, const String &dir_name, bool use_internal_partition)
Lit un maillage à partir d'un fichier.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
@ Grid
Utilise un noyau de calcul avec une synchronisations entre les blocs.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
std::int32_t Int32
Type entier signé sur 32 bits.