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/core/AbstractService.h"
30#include "arcane/core/FactoryService.h"
31#include "arcane/core/IMainFactory.h"
32#include "arcane/core/IMeshReader.h"
33#include "arcane/core/ISubDomain.h"
34#include "arcane/core/IPrimaryMesh.h"
35#include "arcane/core/IItemFamily.h"
36#include "arcane/core/Item.h"
38#include "arcane/core/VariableTypes.h"
39#include "arcane/core/IVariableAccessor.h"
40#include "arcane/core/IParallelMng.h"
41#include "arcane/core/IIOMng.h"
42#include "arcane/core/IXmlDocumentHolder.h"
43#include "arcane/core/XmlNodeList.h"
44#include "arcane/core/XmlNode.h"
45#include "arcane/core/IMeshUtilities.h"
46#include "arcane/core/IMeshWriter.h"
47#include "arcane/core/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"
91 const String& file_name,
const String& dir_name,
bool use_internal_partition);
93 ISubDomain* subDomain() {
return m_sub_domain; }
97 ISubDomain* m_sub_domain;
110, m_sub_domain(sbi.subDomain())
116#define _addThisConnectivity(nNodes, arcType) \
117 cells_type.add(arcType); \
118 cells_nb_node.add(nNodes); \
119 for (XdmfInt32 z = 0; z < nNodes; ++z) \
120 cells_connectivity.add(nodesUidArray[xdmfConnectivity->GetValueAsInt32(i++)]);
126_readMixedTopology(XdmfTopology* Topology,
127 XdmfInt64 nb_elements,
133 info() <<
"[_readMixedTopology] Entering";
134 XdmfArray* xdmfConnectivity = Topology->GetConnectivity(NULL, XDMF_TRUE);
135 XdmfInt32 numType = xdmfConnectivity->GetNumberType();
136 info() <<
"xdmfConnectivity.CoreLength=" << xdmfConnectivity->GetCoreLength() <<
" numType=" << numType;
137 if (numType != XDMF_INT32_TYPE)
138 throw NotSupportedException(A_FUNCINFO,
"Not supported connectivity num type");
139 XdmfInt32 nNodesForThisElement;
140 XdmfInt64 iElementsScaned = 0;
141 for (XdmfInt64 i = 0; iElementsScaned < nb_elements; iElementsScaned++) {
143 switch (xdmfConnectivity->GetValueAsInt32(i++)) {
144 case (XDMF_POLYVERTEX):
145 nNodesForThisElement = xdmfConnectivity->GetValueAsInt32(i++);
147 switch (nNodesForThisElement) {
149 _addThisConnectivity(1, IT_Vertex);
152 _addThisConnectivity(12, IT_Octaedron12);
155 _addThisConnectivity(14, IT_Enneedron14);
158 _addThisConnectivity(16, IT_Decaedron16);
161 _addThisConnectivity(7, IT_HemiHexa7);
164 _addThisConnectivity(6, IT_HemiHexa6);
173 _addThisConnectivity(5, IT_HemiHexa5);
176 _addThisConnectivity(5, IT_DiTetra5);
179 throw FatalErrorException(A_FUNCINFO,
"XDMF_POLYVERTEX with unknown number of nodes");
182 case (XDMF_POLYLINE):
183 nNodesForThisElement = xdmfConnectivity->GetValueAsInt32(i++);
185 switch (nNodesForThisElement) {
187 _addThisConnectivity(2, IT_Line2);
190 throw FatalErrorException(A_FUNCINFO,
"XDMF_POLYLINE with unknown number of nodes");
194 nNodesForThisElement = xdmfConnectivity->GetValueAsInt32(i++);
196 switch (nNodesForThisElement) {
198 _addThisConnectivity(5, IT_Pentagon5);
201 _addThisConnectivity(6, IT_Hexagon6);
204 throw FatalErrorException(A_FUNCINFO,
"XDMF_POLYGON with unknown number of nodes");
208 _addThisConnectivity(3, IT_Triangle3);
211 _addThisConnectivity(4, IT_Quad4);
214 _addThisConnectivity(4, IT_Tetraedron4);
217 _addThisConnectivity(5, IT_Pyramid5);
220 _addThisConnectivity(6, IT_Pentaedron6);
223 _addThisConnectivity(8, IT_Hexaedron8);
226 _addThisConnectivity(10, IT_Heptaedron10);
231 case (XDMF_PYRAMID_13):
232 case (XDMF_WEDGE_15):
235 throw NotSupportedException(A_FUNCINFO,
"Not supported topology type in a mixed one");
239 info() <<
"[_readMixedTopology] Done";
260_readTopology(XdmfTopology* Topology,
261 XdmfInt64& nb_elements,
267 info() <<
"[_readTopology] Entering";
269 throw FatalErrorException(A_FUNCINFO,
"Null topology");
270 if (Topology->UpdateInformation() != XDMF_SUCCESS)
271 throw FatalErrorException(A_FUNCINFO,
"Error in UpdateInformation");
272 if (Topology->Update() != XDMF_SUCCESS)
273 throw FatalErrorException(A_FUNCINFO,
"Error in Update");
274 nb_elements = Topology->GetNumberOfElements();
275 info() <<
"\tHave found a " << Topology->GetClassAsString() <<
" "
276 << Topology->GetTopologyTypeAsString() <<
" topology with " << nb_elements <<
" elements";
277 switch (Topology->GetTopologyType()) {
279 case (XDMF_2DRECTMESH):
280 case (XDMF_2DCORECTMESH):
281 case (XDMF_3DRECTMESH):
282 case (XDMF_3DCORECTMESH):
283 case (XDMF_3DSMESH): {
285 if ((nb_elements % 3) == 0) {
286 for (XdmfInt64 i = 0; i < nb_elements / 3; i += 3) {
287 cells_type.add(IT_Triangle3);
288 cells_nb_node.add(3);
289 for (
Integer z = 0; z < 3; ++z)
290 cells_connectivity.add(i + z);
293 else if ((nb_elements % 4) == 0) {
294 for (XdmfInt64 i = 0; i < nb_elements / 4; i += 4) {
295 cells_type.add(IT_Quad4);
296 cells_nb_node.add(4);
297 for (
Integer z = 0; z < 4; ++z)
298 cells_connectivity.add(i + z);
302 throw FatalErrorException(A_FUNCINFO,
"Could not match XDMF_3DSMESH with a known mesh");
306 case (XDMF_POLYVERTEX):
307 case (XDMF_POLYLINE):
319 case (XDMF_PYRAMID_13):
320 case (XDMF_WEDGE_15):
323 if (_readMixedTopology(Topology, nb_elements, cells_nb_node, cells_connectivity, cells_type, nodesUidArray) !=
RTOk)
324 throw FatalErrorException(A_FUNCINFO,
"Error in _readMixedTopology");
326 case (XDMF_NOTOPOLOGY):
328 throw NotSupportedException(A_FUNCINFO,
"Not supported topology type");
332 info() <<
"[_readTopology] Release & Done";
354 const String& file_name,
const String& dir_name,
bool use_internal_partition)
359 bool itWasAnArcanProduction =
true;
361 info() <<
"[readMeshFromFile] Entering";
362 XdmfDOM* DOM =
new XdmfDOM();
365 if (DOM->SetInputFileName(file_name.
localstr()) != XDMF_SUCCESS)
367 if (DOM->Parse() != XDMF_SUCCESS)
369 XdmfXmlNode XdmfRoot = DOM->GetTree();
372 if (strcmp(DOM->Get(XdmfRoot,
"Version"),
"2.0") < 0)
376 XdmfInt64 nRootChildren = DOM->GetNumberOfChildren(XdmfRoot);
377 info() <<
"GetNumberOfChildren=" << nRootChildren;
380 XdmfInt32 nDomains = DOM->FindNumberOfElements(
"Domain");
381 info() <<
"nDomains=" << nDomains;
383 for (XdmfInt64 iDomain = 0; iDomain < nDomains; ++iDomain) {
384 XdmfXmlNode foundDomain = DOM->FindElement(
"Domain", iDomain, XdmfRoot, 0);
385 if (foundDomain != NULL)
386 info() <<
"Have found domain" << iDomain;
389 XdmfInt32 nGrids = DOM->FindNumberOfElements(
"Grid", foundDomain);
390 info() <<
"nGrids=" << nGrids;
391 for (XdmfInt32 iGrid = 0; iGrid < nGrids; ++iGrid) {
395 XdmfXmlNode foundGrid = DOM->FindElement(
"Grid", iGrid, foundDomain, 0);
396 if (foundGrid == NULL)
398 XdmfGrid*
Grid =
new XdmfGrid();
400 Grid->SetElement(foundGrid);
401 Grid->UpdateInformation();
402 info() <<
"Have found a " <<
Grid->GetGridTypeAsString() <<
" grid";
403 if (
Grid->GetGridType() != XDMF_GRID_UNIFORM)
409 XdmfXmlNode cellsUniqueIDsXmlNode = DOM->FindElementByAttribute(
"Name",
"CellsUniqueIDs", 0, foundGrid);
411 if (cellsUniqueIDsXmlNode) {
412 info() <<
"[XmfMeshReader] cellsUidArray were found";
413 XdmfAttribute* attribute =
new XdmfAttribute();
414 attribute->SetDOM(DOM);
415 attribute->SetElement(cellsUniqueIDsXmlNode);
416 attribute->UpdateInformation();
418 XdmfArray* xmfGroup = attribute->GetValues();
419 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
420 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
421 XdmfInt64 nb_item = xmfGroup->GetNumberOfElements();
422 for (XdmfInt64 uid = 0; uid < nb_item; ++uid)
423 cellsUidArray.
add(xmfGroup->GetValueAsInt32(uid));
426 itWasAnArcanProduction =
false;
431 XdmfXmlNode nodesUniqueIDsXmlNode = DOM->FindElementByAttribute(
"Name",
"NodesUniqueIDs", 0, foundGrid);
433 if (nodesUniqueIDsXmlNode) {
434 info() <<
"[XmfMeshReader] nodesUidArray were found";
435 XdmfAttribute* attribute =
new XdmfAttribute();
436 attribute->SetDOM(DOM);
437 attribute->SetElement(nodesUniqueIDsXmlNode);
438 attribute->UpdateInformation();
440 XdmfArray* xmfGroup = attribute->GetValues();
441 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
442 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
443 XdmfInt64 nb_item = xmfGroup->GetNumberOfElements();
444 for (XdmfInt64 uid = 0; uid < nb_item; ++uid)
445 nodesUidArray.
add(xmfGroup->GetValueAsInt32(uid));
448 itWasAnArcanProduction =
false;
453 XdmfXmlNode nodesOwnerXmlNode = DOM->FindElementByAttribute(
"Name",
"NodesOwner", 0, foundGrid);
455 if (nodesOwnerXmlNode) {
456 info() <<
"[XmfMeshReader] nodesOwnerArray were found";
457 XdmfAttribute* attribute =
new XdmfAttribute();
458 attribute->SetDOM(DOM);
459 attribute->SetElement(nodesOwnerXmlNode);
460 attribute->UpdateInformation();
462 XdmfArray* xmfGroup = attribute->GetValues();
463 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
464 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
465 XdmfInt64 nb_item = xmfGroup->GetNumberOfElements();
466 for (XdmfInt64 uid = 0; uid < nb_item; ++uid)
467 nodesOwnerArray.
add(xmfGroup->GetValueAsInt32(uid));
470 itWasAnArcanProduction =
false;
475 XdmfGeometry* xmfGometry =
Grid->GetGeometry();
478 info() <<
"\tHave found a " << xmfGometry->GetGeometryTypeAsString() <<
" geometry";
479 if (xmfGometry->GetGeometryType() != XDMF_GEOMETRY_XYZ)
481 xmfGometry->UpdateInformation();
482 xmfGometry->Update();
484 XdmfInt64 nbOfNodes = xmfGometry->GetNumberOfPoints();
489 if (!itWasAnArcanProduction) {
490 info() <<
"If it is not ours, just fake the indirection process";
491 for (
Integer uid = 0; uid < nbOfNodes; ++uid) {
492 nodesUidArray.
add(uid);
493 cellsUidArray.
add(uid);
494 nodesOwnerArray.
add(uid);
498 XdmfArray* xdmfPoints = xmfGometry->GetPoints(XDMF_TRUE);
499 XdmfInt32 numType = xdmfPoints->GetNumberType();
500 if (numType != XDMF_FLOAT32_TYPE)
503 for (XdmfInt64 i = 0; iNode < nbOfNodes; iNode++, i += 3) {
504 Real3 coords =
Real3(xdmfPoints->GetValueAsFloat32(i),
505 xdmfPoints->GetValueAsFloat32(i + 1),
506 xdmfPoints->GetValueAsFloat32(i + 2));
507 nodes_coords.
nocheckAdd(nodesUidArray[iNode], coords);
513 XdmfInt64 nb_elements;
517 XdmfTopology* topology =
Grid->GetTopology();
518 if (_readTopology(topology, nb_elements, cells_nb_node, cells_connectivity, cells_type, nodesUidArray) !=
RTOk)
519 throw IOException(
"XmfMeshReader",
"_readTopology error");
523 if (nodesOwnerXmlNode && itWasAnArcanProduction) {
524 info() <<
"[_XmfMeshReader] Create hash table for nodes owner";
525 for (
Integer i = 0; i < nbOfNodes; ++i) {
527 nodes_owner_map.
nocheckAdd(nodesUidArray[i], nodesOwnerArray[i]);
535 info() <<
"[_XmfMeshReader] Création des mailles, nb_cell=" << nb_elements <<
" cells_type.size=" << cells_type.
size();
536 Integer connectivity_index = 0;
538 cells_infos.
add(cells_type[i]);
539 cells_infos.
add(cellsUidArray[i]);
540 for (
Integer z = 0; z < cells_nb_node[i]; ++z)
541 cells_infos.
add(cells_connectivity[connectivity_index + z]);
542 connectivity_index += cells_nb_node[i];
548 info() <<
"[XmfMeshReader] ## Mesh 3D ##";
549 mesh->setDimension(3);
550 info() <<
"[XmfMeshReader] ## Allocating ##";
551 mesh->allocateCells(cells_type.
size(), cells_infos,
false);
557 info() <<
"[XmfMeshReader] internalNodes.size()=" << internalNodes.
size();
558 if (nodesOwnerXmlNode && itWasAnArcanProduction) {
559 info() <<
"[XmfMeshReader] Setting nodes owners from xmf file";
560 for (
Integer i = 0, is = internalNodes.
size(); i < is; ++i) {
563 Int32 true_owner = nodes_owner_map[internal_node->
uniqueId()];
564 internal_node->
setOwner(true_owner, sid);
568 for (
Integer i = 0, is = internalNodes.
size(); i < is; ++i)
569 internalNodes[i]->setOwner(sid, sid);
572 info() <<
"[XmfMeshReader] internalCells.size()=" << internalCells.
size();
573 for (
Integer i = 0, is = internalCells.
size(); i < is; ++i)
574 internalCells[i]->setOwner(sid, sid);
579 info() <<
"[XmfMeshReader] ## Ending with endAllocate ##";
582 info() <<
"[XmfMeshReader] ## setOwnersFromCells ##";
583 mesh->setOwnersFromCells();
585 info() <<
"\n\n[XmfMeshReader] ## Now dealing with ghost's layer ##";
586 info() <<
"[XmfMeshReader] mesh.nbNode=" <<
mesh->nbNode() <<
" mesh.nbCell=" <<
mesh->nbCell();
591 XdmfInt32 nAttributes =
Grid->GetNumberOfAttributes();
592 info() <<
"nAttributes=" << nAttributes;
593 for (XdmfInt64 iAttribute = 0; iAttribute < nAttributes; ++iAttribute) {
594 XdmfAttribute* attribute =
Grid->GetAttribute(iAttribute);
595 if ((attribute == NULL || (!itWasAnArcanProduction)))
597 if ((strcasecmp(attribute->GetName(),
"NodesUniqueIDs") == 0) ||
598 (strcasecmp(attribute->GetName(),
"CellsUniqueIDs") == 0) ||
599 (strcasecmp(attribute->GetName(),
"NodesOwner") == 0)) {
600 info() <<
"Skipping " << attribute->GetName();
604 XdmfArray* xmfGroup = attribute->GetValues();
605 info() << attribute->GetName() <<
"(" << attribute->GetAttributeTypeAsString() <<
", "
606 << attribute->GetAttributeCenterAsString() <<
", " << xmfGroup->GetNumberOfElements() <<
")";
610 Integer nb_item = xmfGroup->GetNumberOfElements() - 1;
614 for (XdmfInt64 z = 0; z < nb_item; ++z)
615 unique_ids[z] = xmfGroup->GetValueAsInt32(z + 1);
624 for (
Integer i = 0; i < nb_item; ++i)
625 if (local_ids[i] != NULL_ITEM_LOCAL_ID)
626 ids.
add(local_ids[i]);
628 info() <<
"Create group family=" << family->
name() <<
" name=" << attribute->GetName() <<
" ids=" << ids.
size();
629 family->
createGroup(attribute->GetName(), ids,
true);
635 info() <<
"[XmfMeshReader] ## Now insert coords ##";
638 nodes_coord_var[iNode] = nodes_coords[iNode->uniqueId()];
644 mesh->synchronizeGroupsAndVariables();
648 info() <<
"[readMeshFromFile] RTOk";
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
Integer size() const
Number of elements in the vector.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
void add(ConstReferenceType val)
Adds element val to the end of the array.
constexpr Integer size() const noexcept
Number of elements in the array.
Exception when a fatal error has occurred.
Hash table for associative arrays.
void nocheckAdd(KeyTypeConstRef id, const ValueType &value)
Adds the value value corresponding to the key id.
Interface of an entity family.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Creates an entity group named name containing the entities local_ids.
virtual String name() const =0
Family name.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converts an array of unique numbers to local numbers.
Interface of the service managing the reading of a mesh.
eReturnType
Types of return codes for a read or write operation.
@ RTOk
Operation successfully performed.
Exception when an input/output error is detected.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
Interface of the subdomain manager.
ItemUniqueId uniqueId() const
Unique number of the entity.
Internal structure of a mesh entity.
void setOwner(Integer suid, Int32 current_sub_domain)
Sets the sub-domain number of the entity owner.
Exception when an operation is not supported.
Class managing a 3-dimensional real vector.
Structure containing the information to create a service.
1D vector of data with reference semantics.
Unicode character string.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
TraceMessage info() const
Flow for an information message.
Mesh file reader in msh format.
virtual void build()
Build-level construction of the service.
bool allowExtension(const String &str)
Checks if the service supports files with the extension str.
virtual eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_node, const String &file_name, const String &dir_name, bool use_internal_partition)
Reads a mesh from a file.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
@ Grid
Uses a compute kernel with synchronization between blocks.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Int32 Integer
Type representing an integer.
ConstArrayView< ItemInternal * > ItemInternalList
Type of the internal list of entities.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
eItemKind
Mesh entity type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
std::int32_t Int32
Signed integer type of 32 bits.