Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
XmfMeshReader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* XmfMeshReader.cc (C) 2000-2010 */
9/* */
10/* Reading/Writing of a file in XMF format. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
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"
28
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"
48
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"
59
60/*#define H5_USE_16_API
61#include <hdf5.h>*/
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66namespace Arcane
67{
68
69using namespace xdmf2;
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
77class XmfMeshReader : public AbstractService
78, public IMeshReader
79{
80 public:
81
82 XmfMeshReader(const ServiceBuildInfo& sbi);
83
84 public:
85
86 virtual void build() {}
87
88 bool allowExtension(const String& str) { return (str == "xmf"); }
89
90 virtual eReturnType readMeshFromFile(IPrimaryMesh* mesh, const XmlNode& mesh_node,
91 const String& file_name, const String& dir_name, bool use_internal_partition);
92
93 ISubDomain* subDomain() { return m_sub_domain; }
94
95 private:
96
97 ISubDomain* m_sub_domain;
98 eReturnType _readTopology(XdmfTopology*, XdmfInt64&, Int32Array&, Int32Array&, Int32Array&, SharedArray<Int32>);
99 eReturnType _readMixedTopology(XdmfTopology*, XdmfInt64, Int32Array&, Int32Array&, Int32Array&, SharedArray<Int32>);
100};
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108XmfMeshReader::XmfMeshReader(const ServiceBuildInfo& sbi)
109: AbstractService(sbi)
110, m_sub_domain(sbi.subDomain())
111{}
112
113/*****************************************************************************\
114* [_addThisConnectivity] *
115\*****************************************************************************/
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++)]);
121
122/*****************************************************************************\
123* [_readMixedTopology] *
124\*****************************************************************************/
125IMeshReader::eReturnType XmfMeshReader::
126_readMixedTopology(XdmfTopology* Topology,
127 XdmfInt64 nb_elements,
128 Int32Array& cells_nb_node,
129 Int32Array& cells_connectivity,
130 Int32Array& cells_type,
131 SharedArray<Int32> nodesUidArray)
132{
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++) {
142 // info() << "[_readMixedTopology] scan=" << iElementsScaned << "/" << nb_elements;
143 switch (xdmfConnectivity->GetValueAsInt32(i++)) {
144 case (XDMF_POLYVERTEX): // 0x1
145 nNodesForThisElement = xdmfConnectivity->GetValueAsInt32(i++);
146 // info() << "[_readMixedTopology] XDMF_POLYVERTEX(" << nNodesForThisElement << ")";
147 switch (nNodesForThisElement) {
148 case (1):
149 _addThisConnectivity(1, IT_Vertex);
150 break;
151 case (12):
152 _addThisConnectivity(12, IT_Octaedron12);
153 break;
154 case (14):
155 _addThisConnectivity(14, IT_Enneedron14);
156 break;
157 case (16):
158 _addThisConnectivity(16, IT_Decaedron16);
159 break;
160 case (7):
161 _addThisConnectivity(7, IT_HemiHexa7);
162 break;
163 case (6):
164 _addThisConnectivity(6, IT_HemiHexa6);
165 break;
166 // GG: I comment out these two cases because in the Oct2015 version it does not compile
167 // not because IT_AntiWedgetLeft6 equals 16 and thus the same value in the switch
168 // as for IT_Decaedron16. Anyway, I think the previous case did not work
169 // because the value for 6 nodes is already taken by IT_HemiHexa6.
170 //case (IT_AntiWedgeLeft6): _addThisConnectivity(6, IT_AntiWedgeLeft6); break;
171 //case (IT_AntiWedgeRight6): _addThisConnectivity(6, IT_AntiWedgeRight6); break;
172 case (5):
173 _addThisConnectivity(5, IT_HemiHexa5);
174 break;
175 case (55):
176 _addThisConnectivity(5, IT_DiTetra5);
177 break;
178 default:
179 throw FatalErrorException(A_FUNCINFO, "XDMF_POLYVERTEX with unknown number of nodes");
180 }
181 break;
182 case (XDMF_POLYLINE): // 0x2
183 nNodesForThisElement = xdmfConnectivity->GetValueAsInt32(i++);
184 // info() << "[_readMixedTopology] XDMF_POLYLINE("<<nNodesForThisElement<<")";
185 switch (nNodesForThisElement) {
186 case (2):
187 _addThisConnectivity(2, IT_Line2);
188 break;
189 default:
190 throw FatalErrorException(A_FUNCINFO, "XDMF_POLYLINE with unknown number of nodes");
191 }
192 break;
193 case (XDMF_POLYGON): // 0x3
194 nNodesForThisElement = xdmfConnectivity->GetValueAsInt32(i++);
195 // info() << "[_readMixedTopology] XDMF_POLYGON("<<nNodesForThisElement<<")";
196 switch (nNodesForThisElement) {
197 case (5):
198 _addThisConnectivity(5, IT_Pentagon5);
199 break;
200 case (6):
201 _addThisConnectivity(6, IT_Hexagon6);
202 break;
203 default:
204 throw FatalErrorException(A_FUNCINFO, "XDMF_POLYGON with unknown number of nodes");
205 }
206 break;
207 case (XDMF_TRI):
208 _addThisConnectivity(3, IT_Triangle3);
209 break; // 0x4
210 case (XDMF_QUAD):
211 _addThisConnectivity(4, IT_Quad4);
212 break; // 0x5
213 case (XDMF_TET):
214 _addThisConnectivity(4, IT_Tetraedron4);
215 break; // 0x6
216 case (XDMF_PYRAMID):
217 _addThisConnectivity(5, IT_Pyramid5);
218 break; // 0x7
219 case (XDMF_WEDGE):
220 _addThisConnectivity(6, IT_Pentaedron6);
221 break; // 0x8
222 case (XDMF_HEX):
223 _addThisConnectivity(8, IT_Hexaedron8);
224 break; // 0x9
225 case (XDMF_TET_10):
226 _addThisConnectivity(10, IT_Heptaedron10);
227 break; // 0x0026
228 case (XDMF_EDGE_3):
229 case (XDMF_TRI_6):
230 case (XDMF_QUAD_8):
231 case (XDMF_PYRAMID_13):
232 case (XDMF_WEDGE_15):
233 case (XDMF_HEX_20):
234 default:
235 throw NotSupportedException(A_FUNCINFO, "Not supported topology type in a mixed one");
236 }
237 }
238 // delete xdmfConnectivity;
239 info() << "[_readMixedTopology] Done";
240 return RTOk;
241}
242
243/*****************************************************************************\
244* [_readTopology] *
245 XML Element : Topology
246 XML Attribute : Name = Any String
247 XML Attribute : TopologyType = Polyvertex | Polyline | Polygon |
248 Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
249 Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
250 Wedge_15 | Hexahedron_20 |
251 Mixed |
252 2DSMesh | 2DRectMesh | 2DCoRectMesh |
253 3DSMesh | 3DRectMesh | 3DCoRectMesh
254 XML Attribute : NumberOfElements = Number of Cells
255 XML Attribute : NodesPerElement = # (Only Important for Polyvertex, Polygon and Polyline)
256 XML Attribute : Order = Order of Nodes if not Default
257 XML BaseOffset: Offset if not 0
258\*****************************************************************************/
259IMeshReader::eReturnType XmfMeshReader::
260_readTopology(XdmfTopology* Topology,
261 XdmfInt64& nb_elements,
262 Int32Array& cells_nb_node,
263 Int32Array& cells_connectivity,
264 Int32Array& cells_type,
265 SharedArray<Int32> nodesUidArray)
266{
267 info() << "[_readTopology] Entering";
268 if (!Topology)
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()) {
278 case (XDMF_2DSMESH): // 0x0100
279 case (XDMF_2DRECTMESH): // 0x0101
280 case (XDMF_2DCORECTMESH): // 0x0102
281 case (XDMF_3DRECTMESH): // 0x1101
282 case (XDMF_3DCORECTMESH): // 0x1102
283 case (XDMF_3DSMESH): { // 0x1100
284 // Try to do something with these kind of structured topologies
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);
291 }
292 }
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);
299 }
300 }
301 else
302 throw FatalErrorException(A_FUNCINFO, "Could not match XDMF_3DSMESH with a known mesh");
303 return RTOk;
304 }
305 // Otherwise, read a mixed topology should do the trick
306 case (XDMF_POLYVERTEX): // 0x1
307 case (XDMF_POLYLINE): // 0x2
308 case (XDMF_POLYGON): // 0x3
309 case (XDMF_TRI): // 0x4
310 case (XDMF_QUAD): // 0x5
311 case (XDMF_TET): // 0x6
312 case (XDMF_PYRAMID): // 0x7
313 case (XDMF_WEDGE): // 0x8
314 case (XDMF_HEX): // 0x9
315 case (XDMF_EDGE_3): // 0x0022
316 case (XDMF_TRI_6): // 0x0024
317 case (XDMF_QUAD_8): // 0x0025
318 case (XDMF_TET_10): // 0x0026
319 case (XDMF_PYRAMID_13): // 0x0027
320 case (XDMF_WEDGE_15): // 0x0028
321 case (XDMF_HEX_20): // 0x0029
322 case (XDMF_MIXED): // 0x0070
323 if (_readMixedTopology(Topology, nb_elements, cells_nb_node, cells_connectivity, cells_type, nodesUidArray) != RTOk)
324 throw FatalErrorException(A_FUNCINFO, "Error in _readMixedTopology");
325 break;
326 case (XDMF_NOTOPOLOGY): // 0x0
327 default:
328 throw NotSupportedException(A_FUNCINFO, "Not supported topology type");
329 }
330 // Topology->Release();
331 // delete Topology;
332 info() << "[_readTopology] Release & Done";
333 return RTOk;
334}
335
336/*****************************************************************************
337 [readMeshFromFile]
338The organization of XDMF begins with the Xdmf element. So that parsers can
339distinguish from previous versions of XDMF, there exists a Version attribute
340(currently at 2.0).
341
342Xdmf elements contain one or more Domain elements (computational
343domain). There is seldom motivation to have more than one Domain.
344
345A Domain can have one or more Grid elements.
346
347Each Grid contains a Topology, Geometry, and zero or more Attribute elements.
348
349Topology specifies the connectivity of the grid while
350Geometry specifies the location of the grid nodes.
351*****************************************************************************/
353readMeshFromFile(IPrimaryMesh* mesh, const XmlNode& mesh_node,
354 const String& file_name, const String& dir_name, bool use_internal_partition)
355{
356 IParallelMng* pm = mesh->parallelMng();
357 bool is_parallel = pm->isParallel();
358 Integer sid = pm->commRank();
359 bool itWasAnArcanProduction = true;
360
361 info() << "[readMeshFromFile] Entering";
362 XdmfDOM* DOM = new XdmfDOM();
363
364 // Parse the XML File
365 if (DOM->SetInputFileName(file_name.localstr()) != XDMF_SUCCESS)
366 throw FatalErrorException(A_FUNCINFO, "SetInputFileName");
367 if (DOM->Parse() != XDMF_SUCCESS)
368 throw FatalErrorException(A_FUNCINFO, "Parse");
369 XdmfXmlNode XdmfRoot = DOM->GetTree();
370
371 // Version verification
372 if (strcmp(DOM->Get(XdmfRoot, "Version"), "2.0") < 0)
373 throw NotSupportedException(A_FUNCINFO, "Not supported Xdmf-file version");
374
375 // Now scan all of its children
376 XdmfInt64 nRootChildren = DOM->GetNumberOfChildren(XdmfRoot);
377 info() << "GetNumberOfChildren=" << nRootChildren;
378
379 //Xdmf elements contain one or more Domain elements
380 XdmfInt32 nDomains = DOM->FindNumberOfElements("Domain");
381 info() << "nDomains=" << nDomains;
382
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;
387
388 // A Domain can have one or more Grid elements.
389 XdmfInt32 nGrids = DOM->FindNumberOfElements("Grid", foundDomain);
390 info() << "nGrids=" << nGrids;
391 for (XdmfInt32 iGrid = 0; iGrid < nGrids; ++iGrid) {
392 /*****************************
393 Looking for the domain's Grid
394 ******************************/
395 XdmfXmlNode foundGrid = DOM->FindElement("Grid", iGrid, foundDomain, 0);
396 if (foundGrid == NULL)
397 throw FatalErrorException(A_FUNCINFO, "Grid not found for domain");
398 XdmfGrid* Grid = new XdmfGrid();
399 Grid->SetDOM(DOM);
400 Grid->SetElement(foundGrid);
401 Grid->UpdateInformation();
402 info() << "Have found a " << Grid->GetGridTypeAsString() << " grid";
403 if (Grid->GetGridType() != XDMF_GRID_UNIFORM)
404 throw NotSupportedException(A_FUNCINFO, "Not supported GRID type");
405
406 /*****************************************************
407 Looking for XML attribute which Name="CellsUniqueIDs"
408 ******************************************************/
409 XdmfXmlNode cellsUniqueIDsXmlNode = DOM->FindElementByAttribute("Name", "CellsUniqueIDs", 0, foundGrid);
410 Int32UniqueArray cellsUidArray;
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();
417 attribute->Update();
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));
424 }
425 else
426 itWasAnArcanProduction = false;
427
428 /*****************************************************
429 Looking for XML attribute which Name="NodesUniqueIDs"
430 ******************************************************/
431 XdmfXmlNode nodesUniqueIDsXmlNode = DOM->FindElementByAttribute("Name", "NodesUniqueIDs", 0, foundGrid);
432 SharedArray<Int32> nodesUidArray;
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();
439 attribute->Update();
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));
446 }
447 else
448 itWasAnArcanProduction = false;
449
450 /*****************************************************
451 Looking for XML attribute which Name="NodesOwner"
452 ******************************************************/
453 XdmfXmlNode nodesOwnerXmlNode = DOM->FindElementByAttribute("Name", "NodesOwner", 0, foundGrid);
454 Int32UniqueArray nodesOwnerArray;
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();
461 attribute->Update();
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));
468 }
469 else
470 itWasAnArcanProduction = false;
471
472 /******************************
473 Each Grid contains a Geometry,
474 *******************************/
475 XdmfGeometry* xmfGometry = Grid->GetGeometry();
476 if (!xmfGometry)
477 ARCANE_FATAL("No xmfGeometry");
478 info() << "\tHave found a " << xmfGometry->GetGeometryTypeAsString() << " geometry";
479 if (xmfGometry->GetGeometryType() != XDMF_GEOMETRY_XYZ)
480 throw NotSupportedException(A_FUNCINFO, "Not supported geometry type");
481 xmfGometry->UpdateInformation();
482 xmfGometry->Update();
483 HashTableMapT<Int64, Real3> nodes_coords(xmfGometry->GetNumberOfPoints(), true);
484 XdmfInt64 nbOfNodes = xmfGometry->GetNumberOfPoints();
485
486 /****************************************************
487 If it is not ours, just fake the indirection process
488 *****************************************************/
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);
495 }
496 }
497
498 XdmfArray* xdmfPoints = xmfGometry->GetPoints(XDMF_TRUE); // true to create the array
499 XdmfInt32 numType = xdmfPoints->GetNumberType();
500 if (numType != XDMF_FLOAT32_TYPE)
501 throw NotSupportedException(A_FUNCINFO, "Not supported geometry number type");
502 XdmfInt64 iNode = 0;
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);
508 }
509
510 /******************************
511 Each Grid contains a Topology,
512 *******************************/
513 XdmfInt64 nb_elements;
514 Int32UniqueArray cells_nb_node;
515 Int32UniqueArray cells_connectivity;
516 Int32UniqueArray cells_type;
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");
520
521 // Create hash table for nodes owner.
522 HashTableMapT<Int64, Int32> nodes_owner_map(nbOfNodes, true);
523 if (nodesOwnerXmlNode && itWasAnArcanProduction) {
524 info() << "[_XmfMeshReader] Create hash table for nodes owner";
525 for (Integer i = 0; i < nbOfNodes; ++i) {
526 //info() << nodesUidArray[i] <<":"<<nodesOwnerArray[i];
527 nodes_owner_map.nocheckAdd(nodesUidArray[i], nodesOwnerArray[i]);
528 }
529 }
530
531 /****************************
532 * Now building cells_infos *
533 ****************************/
534 Int64UniqueArray cells_infos;
535 info() << "[_XmfMeshReader] Création des mailles, nb_cell=" << nb_elements << " cells_type.size=" << cells_type.size();
536 Integer connectivity_index = 0;
537 for (Integer i = 0; i < cells_type.size(); ++i) {
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];
543 }
544
545 /********************************
546 * Setting Dimension & Allocating *
547 ********************************/
548 info() << "[XmfMeshReader] ## Mesh 3D ##";
549 mesh->setDimension(3);
550 info() << "[XmfMeshReader] ## Allocating ##";
551 mesh->allocateCells(cells_type.size(), cells_infos, false);
552
553 /**********************************************************************
554 Positions the node owners based on the node groups
555 ***********************************************************************/
556 ItemInternalList internalNodes(mesh->itemsInternal(IK_Node));
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) {
561 ItemInternal* internal_node = internalNodes[i];
562 //info() << "[XmfMeshReader] "<<internal_node->uniqueId()<<":"<<nodes_owner_map[internal_node->uniqueId()];
563 Int32 true_owner = nodes_owner_map[internal_node->uniqueId()];
564 internal_node->setOwner(true_owner, sid);
565 }
566 }
567 else {
568 for (Integer i = 0, is = internalNodes.size(); i < is; ++i)
569 internalNodes[i]->setOwner(sid, sid);
570 }
571 ItemInternalList internalCells(mesh->itemsInternal(IK_Cell));
572 info() << "[XmfMeshReader] internalCells.size()=" << internalCells.size();
573 for (Integer i = 0, is = internalCells.size(); i < is; ++i)
574 internalCells[i]->setOwner(sid, sid);
575
576 /********************************************
577 * Now finishing & preparing for ghost layout *
578 ********************************************/
579 info() << "[XmfMeshReader] ## Ending with endAllocate ##";
580 mesh->endAllocate();
581 if (is_parallel) {
582 info() << "[XmfMeshReader] ## setOwnersFromCells ##";
583 mesh->setOwnersFromCells();
584 }
585 info() << "\n\n[XmfMeshReader] ## Now dealing with ghost's layer ##";
586 info() << "[XmfMeshReader] mesh.nbNode=" << mesh->nbNode() << " mesh.nbCell=" << mesh->nbCell();
587
588 /***********************************************************
589 and zero or more Attribute elements (fetching Other Groups)
590 ************************************************************/
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)))
596 continue;
597 if ((strcasecmp(attribute->GetName(), "NodesUniqueIDs") == 0) ||
598 (strcasecmp(attribute->GetName(), "CellsUniqueIDs") == 0) ||
599 (strcasecmp(attribute->GetName(), "NodesOwner") == 0)) {
600 info() << "Skipping " << attribute->GetName();
601 continue;
602 }
603 attribute->Update();
604 XdmfArray* xmfGroup = attribute->GetValues();
605 info() << attribute->GetName() << "(" << attribute->GetAttributeTypeAsString() << ", "
606 << attribute->GetAttributeCenterAsString() << ", " << xmfGroup->GetNumberOfElements() << ")";
607
608 eItemKind itemKind = (eItemKind)xmfGroup->GetValueAsInt32(0);
609 IItemFamily* family = mesh->itemFamily(itemKind);
610 Integer nb_item = xmfGroup->GetNumberOfElements() - 1;
611 Int64UniqueArray unique_ids(nb_item);
612
613 // The following elements contain the uniqueId() of the group entities.
614 for (XdmfInt64 z = 0; z < nb_item; ++z)
615 unique_ids[z] = xmfGroup->GetValueAsInt32(z + 1);
616
617 // Retrieves the corresponding localId().
618 Int32UniqueArray local_ids(unique_ids.size());
619 family->itemsUniqueIdToLocalId(local_ids, unique_ids, false);
620
621 // Not all entities are necessarily in the current mesh and
622 // they must therefore be filtered.
624 for (Integer i = 0; i < nb_item; ++i)
625 if (local_ids[i] != NULL_ITEM_LOCAL_ID)
626 ids.add(local_ids[i]);
627
628 info() << "Create group family=" << family->name() << " name=" << attribute->GetName() << " ids=" << ids.size();
629 family->createGroup(attribute->GetName(), ids, true);
630 }
631
632 /*********************
633 * Now insert coords *
634 *********************/
635 info() << "[XmfMeshReader] ## Now insert coords ##";
636 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
637 ENUMERATE_NODE (iNode, mesh->ownNodes()) {
638 nodes_coord_var[iNode] = nodes_coords[iNode->uniqueId()];
639 }
640
641 /****************************************
642 * Synchronizing groups/variables & nodes *
643 ****************************************/
644 mesh->synchronizeGroupsAndVariables();
645 }
646 }
647
648 info() << "[readMeshFromFile] RTOk";
649 // delete DOM;
650 // delete geometry;
651 // delete topology;
652 return RTOk;
653}
654
655/*---------------------------------------------------------------------------*/
656/*---------------------------------------------------------------------------*/
657
658} // namespace Arcane
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Types and macros for iterating over mesh entities.
#define ENUMERATE_NODE(name, group)
Generic enumerator for a node group.
#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.
Base class of a service.
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.
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.
Definition IItemFamily.h:83
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.
Definition IMeshReader.h:33
eReturnType
Types of return codes for a read or write operation.
Definition IMeshReader.h:38
@ RTOk
Operation successfully performed.
Definition IMeshReader.h:39
Exception when an input/output error is detected.
Definition IOException.h:34
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.
Definition ISubDomain.h:75
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.
Class managing a 3-dimensional real vector.
Definition Real3.h:132
Structure containing the information to create a service.
1D vector of data with reference semantics.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
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.
Node of a DOM tree.
Definition XmlNode.h:51
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.
Definition UtilsTypes.h:339
Int32 Integer
Type representing an integer.
ConstArrayView< ItemInternal * > ItemInternalList
Type of the internal list of entities.
Definition ItemTypes.h:466
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:341
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.
Definition UtilsTypes.h:127
std::int32_t Int32
Signed integer type of 32 bits.