Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
XmfMeshWriter.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* XmfMeshWriter.cc (C) 2000-2009 */
9/* */
10/* Ecriture d'un fichier au format Xmf. */
11/*****************************************************************************
12/* TODO: - Work on Precision (="4"), which could be adjusted.
13 - Test for new output file
14*/
15/*****************************************************************************
16 * [Topology]
17 *****************************************************************************
18 XML Element : Topology
19 XML Attribute : Name = Any String
20 XML Attribute : TopologyType = Polyvertex | Polyline | Polygon |
21 Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
22 Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
23 Wedge_15 | Hexahedron_20 |
24 Mixed |
25 2DSMesh | 2DRectMesh | 2DCoRectMesh |
26 3DSMesh | 3DRectMesh | 3DCoRectMesh
27 XML Attribute : NumberOfElements = Number of Cells
28 XML Attribute : NodesPerElement = # (Only Important for Polyvertex, Polygon and Polyline)
29 XML Attribute : Order = Order of Nodes if not Default
30 XML BaseOffset: Offset if not 0
31******************************************************************************
32XdmfTopology has the general class (XDMF_STRUCTURED | XDMF_UNSTRUCTURED)
33and the specific BASE type (TETRAHEDRON | 3DSMESH etc.).
34******************************************************************************
35For unstructured meshes, XdmfTopology also contains the connectivity array.
36For structured meshes, connectivity is implicit (i.e. X[i] is connected to X[i+1])
37*****************************************************************************/
38
39/*****************************************************************************
40 * [Geometry]
41 *****************************************************************************
42 XdmfGeometry is a required part of an XdmfGrid. Geometry can be specified in several different ways :
43
44 XDMF_GEOMETRY_XYZ : X0,Y0,Z0,X1,Y1,Z1 ..... XN,YN,ZN for every point
45 XDMF_GEOMETRY_X_Y_Z : X0,X1 ... XN,Y0,Y1 ... YN,Z0,Z1 ... ZN for every point
46 XDMF_GEOMETRY_VXVYVZ : X0,X1 ... XN,Y0,Y1 ... YN,Z0,Z1 ... ZN for XAxis, YAxis, ZAxis
47 XDMF_GEOMETRY_ORIGIN_DXDYDZ : Xorigin, Yorigin, Zorigin, Dx, Dy, Dz
48 ******************************************************************************
49 XML Element : Grid
50 XML Attribute : Name = Any String
51 XML Attribute : GeometryType = XYZ* | XY | X_Y_Z | X_Y | VXVYVZ | ORIGIN_DXDYDZ
52 ******************************************************************************
53 Example :
54 <Grid Name="Mesh" GridType="Uniform">
55 <Topology ...
56 <Geometry ...
57 <Attribute ...
58 </Grid>
59*****************************************************************************/
60
61/***************************************************************************** \
62* [DataItem] *
63******************************************************************************
64An XdmfDataItem is a container for data. It is of one of these types :
65
66 Uniform ...... A single DataStructure
67 HyperSlab .... A DataTransform that Subsamples some DataStructure
68 Coordinates .. A DataTransform that Subsamples via Parametric Coordinates
69 Function ..... A DataTransform described by some function
70 Collection ... Contains an Array of 1 or more DataStructures or DataTransforms
71 Tree ......... A Hierarchical group of other DataItems
72
73If not specified in the "ItemType" a Uniform item is assumed.
74A Uniform DataItem is a XdmfDataStructure or an XdmfDataTransform.
75Both XdmfDataStructure and XdmfDataTransform are maintined for backwards compatibility.
76******************************************************************************
77 XML Attribute : Name = Any String, DataItems have an optional name.
78 XML Attribute : ItemType = Uniform* | Collection | Tree | HyperSlab | Coordinates | Function
79 XML Attribute : Dimensions = K J I
80 Dimensions are listed with the slowest varying dimension first.
81 (i.e. KDim JDim IDim).
82 XML Attribute : NumberType = Float* | Int | UInt | Char | UChar
83 Type is "Char | Float | Int | Compound" with the default being Float.
84 XML Attribute : Precision = 1 | 4 | 8
85 Precision is BytesPerElement and defaults to 4 for Ints and Floats.
86 XML Attribute : Format = XML* | HDF
87 Format is any supported XDMF format but usually XML | HDF.
88\*****************************************************************************/
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
92
93#include "arcane/utils/ArcanePrecomp.h"
94#include "arcane/utils/Iostream.h"
95#include "arcane/utils/StdHeader.h"
96#include "arcane/utils/HashTableMap.h"
97#include "arcane/utils/ValueConvert.h"
98#include "arcane/utils/ScopedPtr.h"
99#include "arcane/utils/ITraceMng.h"
100#include "arcane/utils/String.h"
101#include "arcane/utils/IOException.h"
102#include "arcane/utils/PlatformUtils.h"
103#include "arcane/utils/Collection.h"
104#include "arcane/utils/Enumerator.h"
105#include "arcane/utils/NotImplementedException.h"
106#include "arcane/utils/Real3.h"
107
108#include "arcane/FactoryService.h"
109#include "arcane/IMainFactory.h"
110#include "arcane/IMeshReader.h"
111#include "arcane/ISubDomain.h"
112#include "arcane/IMesh.h"
113#include "arcane/IItemFamily.h"
114#include "arcane/Item.h"
115#include "arcane/ItemEnumerator.h"
116#include "arcane/VariableTypes.h"
117#include "arcane/IVariableAccessor.h"
118#include "arcane/IParallelMng.h"
119#include "arcane/IIOMng.h"
120#include "arcane/IXmlDocumentHolder.h"
121#include "arcane/XmlNodeList.h"
122#include "arcane/XmlNode.h"
123#include "arcane/IMeshUtilities.h"
124#include "arcane/IMeshWriter.h"
125#include "arcane/BasicService.h"
126
127#include "arcane/AbstractService.h"
128
129#define XDMF_USE_ANSI_STDLIB
130#include <vtkxdmf2/Xdmf.h>
131
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135ARCANE_BEGIN_NAMESPACE
136
137using namespace xdmf2;
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
146
147public:
149 this->CurrIndent=0;
150 }
151 virtual void build(void) {}
152 virtual bool writeMeshToFile(IMesh* mesh,const String& file_name);
153
154 bool xmfWriteHead(void);
155 bool xmfWriteTail(void);
156
157 bool xmfWriteDomainHeader(void);
158 bool xmfWriteDomainFooter(void);
159
160 bool xmfWriteGridHeader(char*, char*);
161 bool xmfWriteGridFooter(void);
162
163 bool xmfWriteTopologyHeader(char*, XdmfInt32);
164 bool xmfWriteTopologyFooter(void);
165
166 bool xmfWriteGeometryHeader(char *Name, XdmfInt32 GeometryType);
167 bool xmfWriteGeometryFooter(void);
168
169 bool xmfWriteDataItemHeader(XdmfInt32[3], XdmfInt32, XdmfInt32);
170 bool xmfWriteDataItemFooter(void);
171
172 void Indent(void);
173 void IncrementIndent() { this->CurrIndent ++; }
174 void DecrementIndent() { if (this->CurrIndent >= 0) this->CurrIndent--; }
175
176private:
177 ofstream ost;
178 void _switchXmfType(Integer, Array<Integer>&);
179 int CurrIndent;
180 char *HeavyDataSetNameString;
181};
182
183
184/*---------------------------------------------------------------------------*/
185/*---------------------------------------------------------------------------*/
186ARCANE_REGISTER_SUB_DOMAIN_FACTORY(XmfMeshWriter,IMeshWriter,XmfNewMeshWriter);
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
190/*****************************************************************************\
191* [_switchXmfType] *
192\*****************************************************************************/
193void XmfMeshWriter::_switchXmfType(Integer arc_type, Array<Integer>& arcConnectivityArray){
194 if (arc_type > ItemTypeMng::nbBasicItemType()){
195 arcConnectivityArray.add(XDMF_NOTOPOLOGY);
196 return;
197 }
198
199 switch(arc_type){
200 case (IT_NullType): arcConnectivityArray.add(XDMF_NOTOPOLOGY);return;
201
202 case (IT_Vertex):
203 arcConnectivityArray.add(XDMF_POLYVERTEX);
204 arcConnectivityArray.add(1ul); return;
205
206 case (IT_Line2):
207 arcConnectivityArray.add(XDMF_POLYLINE);
208 arcConnectivityArray.add(2ul); return;
209
210 case (IT_Triangle3): arcConnectivityArray.add(XDMF_TRI); return;
211 case (IT_Quad4): arcConnectivityArray.add(XDMF_QUAD); return;
212 case (IT_Pentagon5): arcConnectivityArray.add(XDMF_POLYGON); return;
213 case (IT_Hexagon6): arcConnectivityArray.add(XDMF_POLYGON); return;
214 case (IT_Heptagon7): arcConnectivityArray.add(XDMF_POLYGON); return;
215 case (IT_Octogon8): arcConnectivityArray.add(XDMF_POLYGON); return;
216 case (IT_Tetraedron4): arcConnectivityArray.add(XDMF_TET); return;
217 case (IT_Pyramid5): arcConnectivityArray.add(XDMF_PYRAMID); return;
218 case (IT_Pentaedron6): arcConnectivityArray.add(XDMF_WEDGE); return;
219 case (IT_Hexaedron8): arcConnectivityArray.add(XDMF_HEX); return;
220 case (IT_Heptaedron10): arcConnectivityArray.add(XDMF_TET_10); return;
221
222 case (IT_Octaedron12):
223 arcConnectivityArray.add(XDMF_POLYVERTEX);
224 arcConnectivityArray.add(12ul); return;
225case (IT_Enneedron14):
226 arcConnectivityArray.add(XDMF_POLYVERTEX);
227 arcConnectivityArray.add(14ul); return;
228 case (IT_Decaedron16):
229 arcConnectivityArray.add(XDMF_POLYVERTEX);
230 arcConnectivityArray.add(16ul); return;
231 case (IT_HemiHexa7):
232 arcConnectivityArray.add(XDMF_POLYVERTEX);
233 arcConnectivityArray.add(7ul); return;
234
235 //warning IT_AntiWedgeLeft6 IT_AntiWedgeRight6 and IT_HemiHexa6 are merged
236 case (IT_HemiHexa6):
237 case (IT_AntiWedgeLeft6):
238 case (IT_AntiWedgeRight6):
239 arcConnectivityArray.add(XDMF_POLYVERTEX);
240 arcConnectivityArray.add(6ul); return;
241
242 //warning IT_HemiHexa5 and IT_DiTetra5 are merged
243 case (IT_HemiHexa5):
244 case (IT_DiTetra5):
245 arcConnectivityArray.add(XDMF_POLYVERTEX);
246 arcConnectivityArray.add(5ul); return;
247
248 case (IT_DualNode):
249 case (IT_DualEdge):
250 case (IT_DualFace):
251 case (IT_DualCell): arcConnectivityArray.add(XDMF_NOTOPOLOGY); return;
252
253 default: arcConnectivityArray.add(XDMF_NOTOPOLOGY);return;
254 }
255 arcConnectivityArray.add(XDMF_NOTOPOLOGY);
256}
257
258
259
260
261/**********************************************************************
262 * [writeMeshToFile]
263 **********************************************************************/
264bool XmfMeshWriter::writeMeshToFile(IMesh* mesh,const String& file_name){
265 info() << "[XmfMeshWriter::writeMeshToFile] nNodes=" <<mesh->nbNode() << " nCells="<< mesh->nbCell()
266 << " all=" << mesh->allNodes().size() << ", own=" << mesh->ownNodes().size();
267
268 /****************************
269 * XDMF-side initialisation *
270 ****************************/
271 XdmfRoot *xmfRoot=new XdmfRoot(); // represents the Root Element in Xdmf
272 XdmfDOM *xmfDom= new XdmfDOM();
273 if (platform::isFileReadable(file_name+".h5")==true)
274 if (platform::removeFile(file_name+".h5"))
275 throw FatalErrorException(A_FUNCINFO, "Could not remove .h5 file!");
277 if (xmfDom->SetWorkingDirectory(".")!= XDMF_SUCCESS) throw IOException("writeMeshToFile", "SetOutputFileName");
278 if (xmfDom->SetOutputFileName(xmfDomFileName.localstr())!= XDMF_SUCCESS) throw IOException("writeMeshToFile", "SetOutputFileName");
279 xmfRoot->SetDOM(xmfDom);
280 xmfRoot->Build();
281 info() << "XDMF-side initialisation done";
282
283 // Domain initialisation
285 xmfDomain->SetName(file_name.localstr());
286 xmfRoot->Insert(xmfDomain);
287 info() << "[XmfMeshWriter] Domain initialisation done";
288
289 // Grid initialisation
290 XdmfGrid *xmfGrid = new XdmfGrid();
291 xmfGrid->SetGridType(XDMF_GRID_UNIFORM);
292 info() << "[XmfMeshWriter] Grid initialisation done";
293
294 /****************************************
295 * XdmfAttribute to save Cells Unique IDs
296 ****************************************/
298 xmfCellAttribute->SetName("CellsUniqueIDs");
299 xmfCellAttribute->SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
302 String heavyDataForCellsUniqueIDs(file_name+".h5:/CellsUniqueIDs");
303 xmfCellsUniqueIDs->SetHeavyDataSetName(heavyDataForCellsUniqueIDs.localstr());
304 xmfCellsUniqueIDs->SetNumberType(XDMF_INT32_TYPE);
305 xmfCellsUniqueIDs->SetNumberOfElements(mesh->nbCell());
306 XdmfInt64 cellIndex=0;
307
308 /****************************************
309 * XdmfAttribute to save Nodes Unique IDs
310 ****************************************/
312 xmfNodeAttribute->SetName("NodesUniqueIDs");
313 xmfNodeAttribute->SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
316 String heavyDataForNodesUniqueIDs(file_name+".h5:/NodesUniqueIDs");
317 xmfNodesUniqueIDs->SetHeavyDataSetName(heavyDataForNodesUniqueIDs.localstr());
318 xmfNodesUniqueIDs->SetNumberType(XDMF_INT32_TYPE);
319 xmfNodesUniqueIDs->SetNumberOfElements(mesh->nbNode());
320 IntegerUniqueArray nodesUniqueIDs; // Unique nodes-IDs array
321
322 /***********************************
323 * XdmfAttribute to save Nodes Owners
324 \***********************************/
326 xmfOwnerAttribute->SetName("NodesOwner");
330 String heavyDataForOwners(file_name+".h5:/NodesOwners");
331 xmfNodesOwners->SetHeavyDataSetName(heavyDataForOwners.localstr());
332 xmfNodesOwners->SetNumberType(XDMF_INT32_TYPE);
333 xmfNodesOwners->SetNumberOfElements(mesh->nbNode());
336 nodesUniqueIDs.add(iNode->uniqueId().asInteger());
337 xmfNodesUniqueIDs->SetValue(nodeIndex, iNode->uniqueId().asInteger());
338 xmfNodesOwners->SetValue(nodeIndex++, iNode->owner());
339 }
340
341 // Each Grid contains a Topology,
342 info() << "[XmfMeshWriter] Focussing on the topology";
343 XdmfTopology *xmfTopology = xmfGrid->GetTopology();
344 xmfTopology->SetTopologyType(XDMF_MIXED);
345 xmfTopology->SetNumberOfElements(mesh->nbCell());
346 XdmfArray *xmfConnectivityArray= xmfTopology->GetConnectivity();
347 String heavyDataForConnections(file_name+".h5:/Connections");
348 xmfConnectivityArray->SetHeavyDataSetName(heavyDataForConnections.localstr());
349 xmfConnectivityArray->SetNumberType(XDMF_INT32_TYPE);
351 ENUMERATE_CELL(iCell,mesh->allCells()){// Scanning the cells' nodes to get type and connectivity
352 Cell cell = *iCell;
353 Integer nbNodes = cell.nbNode();
354 xmfCellsUniqueIDs->SetValue(cellIndex++, iCell->uniqueId().asInteger());
355 _switchXmfType(cell.type(), arcCellConnectivityArray);
356 Integer meshNbNodes=mesh->nbNode();
357 for( Integer j=0; j<nbNodes;++j){
358 Integer uid=cell.node(j).uniqueId();
359 for( Integer i=0; i<meshNbNodes; ++i){
360 // This is used for external viewers to be able to read our output
361 if (nodesUniqueIDs[i] != uid)
362 continue; // xmfNodesUniqueIDs->GetValueAsInt32(i) is just TOO painful to work with!
364 break;
365 }
366 }
367 }
368 xmfConnectivityArray->SetNumberOfElements(arcCellConnectivityArray.size());
369 info() << "[XmfMeshWriter] arcCellConnectivityArray.size()=" << arcCellConnectivityArray.size();
370 for(XdmfInt32 idx=0; idx<arcCellConnectivityArray.size();++idx)
372 info() << "[XmfMeshWriter] Work on grid->topology done";
373
374 // a Geometry,
375 XdmfGeometry *xmfGeometry = xmfGrid->GetGeometry();
376 xmfGeometry->SetGeometryType(XDMF_GEOMETRY_XYZ);
377 //xmfGeometry->SetNumberOfPoints(mesh->nbNode());
380 xmfNodeGeometryArray->SetHeavyDataSetName(heavyDataForGeometry.localstr());
381 xmfNodeGeometryArray->SetNumberType(XDMF_FLOAT32_TYPE);
382 xmfNodeGeometryArray->SetNumberOfElements(3*mesh->nbNode());// Number of points in this geometry
384 XdmfInt64 Index=0;
386 const Node& node = *iNode;
387 xmfNodeGeometryArray->SetValue(Index++,Convert::toDouble(nodes_coords[iNode].x));
388 xmfNodeGeometryArray->SetValue(Index++,Convert::toDouble(nodes_coords[iNode].y));
389 xmfNodeGeometryArray->SetValue(Index++,Convert::toDouble(nodes_coords[iNode].z));
390 //info() << "[writeMeshToFile] Adding node[" << iNode->uniqueId() << "]";
391 }
392 info() << "[XmfMeshWriter] Work on Geometry done";
393 xmfDomain->Insert(xmfGrid);
394
395
396 /*************************
397 * Fetching Other Groups
398 * XML Attribute : Name
399 * XML Attribute : AttributeType = Scalar* | Vector | Tensor | Tensor6 | Matrix
400 * XML Attribute : Center = Node* | Cell | Grid | Face | Edge
401 ************************/
402 info() << "[XmfMeshWriter] Working on Groups";
404 if ( (*arcGroup == mesh->cellFamily()->allItems())||(*arcGroup == mesh->nodeFamily()->allItems())||\
405 (*arcGroup == mesh->edgeFamily()->allItems())||(*arcGroup == mesh->faceFamily()->allItems())) continue;
406 info() << "[writeMeshToFile] Found a " << arcGroup->itemKind() << "-group " << arcGroup->name();
408 xmfAttribute->SetName(arcGroup->name().localstr());
409 xmfAttribute->SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
410 xmfAttribute->SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
411 XdmfArray *xmfGroup = xmfAttribute->GetValues();
412 String heavyDataForGroup(file_name+".h5:/" + arcGroup->name());
413 xmfGroup->SetHeavyDataSetName(heavyDataForGroup.localstr());
414 xmfGroup->SetNumberType(XDMF_INT32_TYPE);
415 xmfGroup->SetNumberOfElements(1+arcGroup->size());
416 XdmfInt64 Index=0;
417 xmfGroup->SetValue(Index++, arcGroup->itemKind());
419 xmfGroup->SetValue(Index++, iItem->uniqueId().asInteger());
420 }
421 xmfGrid->Insert(xmfAttribute);
422 }
423 xmfGrid->Insert(xmfCellAttribute);
424 xmfGrid->Insert(xmfNodeAttribute);
425 xmfGrid->Insert(xmfOwnerAttribute);
426 xmfGrid->Build();
427
428
429 /********************
430 * Output & cleanup *
431 ********************/
432 xmfDom->Write();
433
434 delete xmfCellAttribute;
435 delete xmfNodeAttribute;
436 delete xmfOwnerAttribute;
437 delete xmfGrid;
438 delete xmfDomain;
439 delete xmfRoot;
440 delete xmfDom;
441
442 info() << "[XmfMeshWriter] Done";
443 return false;
444}
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
449ARCANE_END_NAMESPACE
450
451/*---------------------------------------------------------------------------*/
452/*---------------------------------------------------------------------------*/
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Classe de base d'un service.
Maille d'un maillage.
Definition Item.h:1178
virtual NodeGroup ownNodes()=0
Groupe de tous les noeuds propres au domaine.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual Integer nbCell()=0
Nombre de mailles du maillage.
virtual IItemFamily * edgeFamily()=0
Retourne la famille des arêtes.
virtual Integer nbNode()=0
Nombre de noeuds du maillage.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Interface d'un service d'écriture d'un maillage.
Definition IMeshWriter.h:36
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual ItemGroupCollection groups()=0
Liste des groupes.
Exception lorsqu'une erreur d'entrée/sortie est détectée.
Definition IOException.h:32
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:768
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
Int16 type() const
Type de l'entité
Definition Item.h:232
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Noeud d'un maillage.
Definition Dom.h:204
Structure contenant les informations pour créer un service.
Ecriture des fichiers de maillage aux format xmf.
virtual void build(void)
Construction de niveau build du service.
Exception lorsqu'une erreur fatale est survenue.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).