Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
DumpWUCD.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/* DumpWUCD.cc (C) 2000-2021 */
9/* */
10/* Exporting files in UCD format. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/String.h"
15#include "arcane/utils/Enumerator.h"
16#include "arcane/utils/Iterator.h"
17#include "arcane/utils/List.h"
18#include "arcane/utils/PlatformUtils.h"
19#include "arcane/utils/Iostream.h"
20#include "arcane/utils/OStringStream.h"
21#include "arcane/utils/ArcanePrecomp.h"
22
23#include "arcane/core/Item.h"
25#include "arcane/core/IVariable.h"
26#include "arcane/core/ISubDomain.h"
27#include "arcane/core/IMesh.h"
28#include "arcane/core/IMeshSubMeshTransition.h"
29#include "arcane/core/StdNum.h"
30#include "arcane/core/ItemGroup.h"
31#include "arcane/core/IParallelMng.h"
32#include "arcane/core/Directory.h"
33#include "arcane/core/PostProcessorWriterBase.h"
34#include "arcane/core/Service.h"
35#include "arcane/core/SimpleProperty.h"
36#include "arcane/core/FactoryService.h"
37#include "arcane/core/VariableCollection.h"
38
39#include "arcane/std/DumpW.h"
40
41#include <string>
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46namespace Arcane
47{
48// NOTE: This format only works in sequential mode
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53namespace
54{
55 Integer code_hex[8] = { 0, 3, 2, 1, 4, 7, 6, 5 };
56 Integer code_prism[6] = { 2, 1, 0, 5, 4, 3 };
57 Integer code_pyr[5] = { 4, 1, 2, 3, 0 };
58 Integer code_tet[4] = { 0, 1, 3, 2 };
59} // namespace
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
67class DumpWUCD
68: public TraceAccessor
69, public DumpW
70{
71 public:
72
73 DumpWUCD(ISubDomain* sd, IMesh* mesh, const String& filename,
74 RealConstArrayView times, VariableCollection variables);
75 ~DumpWUCD();
76
77 void setMetaData(const String& meta_data) override
78 {
79 ARCANE_UNUSED(meta_data);
80 }
81 String metaData() const { return String(); }
82
85 void writeVal(IVariable&, ConstArrayView<Real2>) override {}
86 void writeVal(IVariable&, ConstArrayView<Real3>) override;
87 void writeVal(IVariable&, ConstArrayView<Int64>) override {}
88 void writeVal(IVariable&, ConstArrayView<Int32>) override {}
89 void writeVal(IVariable&, ConstArrayView<Real2x2>) override {}
90 void writeVal(IVariable&, ConstArrayView<Real3x3>) override {}
91 void writeVal(IVariable&, ConstArrayView<String>) override {}
92
93 void writeVal(IVariable&, ConstArray2View<Byte>) override {}
94 void writeVal(IVariable&, ConstArray2View<Real>) override {}
95 void writeVal(IVariable&, ConstArray2View<Int64>) override {}
96 void writeVal(IVariable&, ConstArray2View<Int32>) override {}
97 void writeVal(IVariable&, ConstArray2View<Real2>) override {}
98 void writeVal(IVariable&, ConstArray2View<Real3>) override {}
99 void writeVal(IVariable&, ConstArray2View<Real2x2>) override {}
100 void writeVal(IVariable&, ConstArray2View<Real3x3>) override {}
101
102 void writeVal(IVariable&, ConstMultiArray2View<Byte>) override {}
103 void writeVal(IVariable&, ConstMultiArray2View<Real>) override {}
104 void writeVal(IVariable&, ConstMultiArray2View<Int64>) override {}
105 void writeVal(IVariable&, ConstMultiArray2View<Int32>) override {}
106 void writeVal(IVariable&, ConstMultiArray2View<Real2>) override {}
107 void writeVal(IVariable&, ConstMultiArray2View<Real3>) override {}
108 void writeVal(IVariable&, ConstMultiArray2View<Real2x2>) override {}
109 void writeVal(IVariable&, ConstMultiArray2View<Real3x3>) override {}
110
111 void beginWrite() override;
112 void endWrite() override;
113
114 private:
115
116 static constexpr Integer m_max_digit = 5;
117 // Number of significant figures for displaying real numbers.
118 static constexpr Integer MAX_FLOAT_DIGIT = FloatInfo<Real>::maxDigit() + 1;
119
120 ISubDomain* m_sub_domain;
124 VariableList m_save_variables;
125
129};
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
134DumpWUCD::
135DumpWUCD(ISubDomain* sd, IMesh* mesh, const String& filename, RealConstArrayView times,
136 VariableCollection variables)
137: TraceAccessor(mesh->traceMng())
138, m_sub_domain(sd)
139, m_mesh(mesh)
140, m_base_directory(filename)
141, m_times(times)
142, m_save_variables(variables.clone())
143{
145
146 // filtrage des cellules
147 // ne sont gardees que les mailles dont le type est reconnue dans UCD
149 Cell cell = *it;
150 const int type = cell.type();
151 if (type == IT_Vertex || type == IT_Line2 || type == IT_Triangle3 || type == IT_Quad4 || type == IT_Hexaedron8 || type == IT_Pyramid5 || type == IT_Pentagon5 || type == IT_Tetraedron4)
152 m_managed_cells.add(cell);
153 else
154 info() << "** Warning: cell type " << cell.uniqueId()
155 << " is unknown in UCD format. Cell will be ignored.";
156 }
157
158 Integer nb_cell_var = m_managed_cells.size();
159 Integer nb_node_var = m_mesh->nbNode();
160 m_cell_streams.resize(nb_cell_var);
161 m_node_streams.resize(nb_node_var);
162 for (Integer i = 0; i < nb_cell_var; ++i) {
163 m_cell_streams[i] = makeRef(new OStringStream());
164 m_cell_streams[i]->stream().precision(MAX_FLOAT_DIGIT);
165 m_cell_streams[i]->stream().flags(std::ios::scientific);
166 }
167 for (Integer i = 0; i < nb_node_var; ++i) {
168 m_node_streams[i] = makeRef(new OStringStream());
169 m_node_streams[i]->stream().precision(MAX_FLOAT_DIGIT);
170 m_node_streams[i]->stream().flags(std::ios::scientific);
171 }
172
173 debug() << "DumpWUCD::DumpWUCD - "
174 << m_mesh->nbCell() << " cells among which "
175 << m_managed_cells.size() << " have a known type";
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
181DumpWUCD::
182~DumpWUCD()
183{
184}
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
196{
197 info() << "** HERE dump Real variable " << v.name();
198
199 Integer size;
200 switch (v.itemKind()) {
201 case (IK_Node):
202 size = ptr.size();
203 for (Integer i = 0; i < size; i++)
204 m_node_streams[i]->stream() << " " << ptr[i];
205 break;
206 case (IK_Cell):
207 size = m_managed_cells.size();
208 for (Integer i = 0; i < size; i++) {
209 const Cell& cell = m_managed_cells[i];
210 m_cell_streams[i]->stream() << " " << ptr[cell.localId()];
211 }
212 break;
213 default:
214 info() << "Variable not managed by UCD writer: " << v.name();
215 }
216}
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220
228{
229 info() << "** HERE dump Real3 variable " << v.name();
230
231 Integer size;
232 switch (v.itemKind()) {
233 case (IK_Node):
234 size = ptr.size();
235 for (Integer i = 0; i < size; i++) {
236 m_node_streams[i]->stream() << " " << ptr[i].x
237 << " " << ptr[i].y
238 << " " << ptr[i].z;
239 }
240 break;
241 case (IK_Cell):
242 size = m_managed_cells.size();
243 for (Integer i = 0; i < size; i++) {
244 const Cell cell = m_managed_cells[i];
245 Integer id = cell.localId();
246 m_cell_streams[i]->stream() << " " << ptr[id].x
247 << " " << ptr[id].y
248 << " " << ptr[id].z;
249 }
250 break;
251 default:
252 info() << "Variable not managed by UCD writer: " << v.name();
253 }
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
271{
272 info() << "** Entering method DumpWUCD::writeBegin";
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
283endWrite()
284{
285 info() << "** Entering method DumpWUCD::writeEnd";
286
287 // Creation du nom de fichier UCD : UCD_<no_iteration>
288 OStringStream ostr;
289 ostr() << "UCD_";
290 ostr().fill('0');
291 ostr().width(m_max_digit);
292 ostr() << m_times.size() - 1;
293 ostr() << ".inp\0";
294 String buf = m_base_directory.file(ostr.str());
295 std::ofstream ucd_file(buf.localstr());
296
297 // Adding the file header
298 // Counting the number of data for nodes and cells and their
299 // sizes. The only implemented "write" methods are:
300 // - void writeVal(IVariable& v,ConstArrayView<Real3> a)
301 // - void writeVal(IVariable& v,ConstArrayView<Real> a)
302 // Consequently, the only variables considered are of type
303 // "Real" and "Real3" and of dimension 1.
304 IMesh* mesh = m_mesh;
305 Integer nb_comp_node_data = 0;
306 Integer nb_comp_cell_data = 0;
307 Integer comp_node_data_size = 0;
308 Integer comp_cell_data_size = 0;
309 OStringStream ndata_size_stream, cdata_size_stream;
310 OStringStream ndata_name_stream, cdata_name_stream;
311 ndata_size_stream().precision(MAX_FLOAT_DIGIT);
312 ndata_name_stream().precision(MAX_FLOAT_DIGIT);
313 cdata_size_stream().precision(MAX_FLOAT_DIGIT);
314 cdata_name_stream().precision(MAX_FLOAT_DIGIT);
315
316 ndata_size_stream().flags(std::ios::scientific);
317 ndata_name_stream().flags(std::ios::scientific);
318 cdata_size_stream().flags(std::ios::scientific);
319 cdata_name_stream().flags(std::ios::scientific);
320
321 for (VariableList::Enumerator i(m_save_variables); ++i;) {
322 IVariable* var = *i;
323
324 if (var->dimension() == 1) {
325 eDataType type = var->dataType();
326 eItemKind kind = var->itemKind();
327 String name = var->name();
328 if (type == DT_Real) {
329 if (kind == IK_Node) {
330 debug() << " Variable " << name
331 << " kind = IK_Node, type = DT_Real";
332 nb_comp_node_data++;
333 comp_node_data_size++;
334 ndata_size_stream() << " 1"; // 1 = size of Real
335 ndata_name_stream() << name << ", Unknown" << '\n';
336 }
337 else if (kind == IK_Cell) {
338 debug() << " Variable " << name
339 << " kind = IK_Cell, type = DT_Real";
340 nb_comp_cell_data++;
341 comp_cell_data_size++;
342 cdata_size_stream() << " 1"; // 1 = size of Real1
343 cdata_name_stream() << name << ", Unknown" << '\n';
344 }
345 }
346 else if (type == DT_Real3) {
347 if (kind == IK_Node) {
348 debug() << " Variable " << name
349 << " kind = IK_Node, type = DT_Real3";
350 nb_comp_node_data++;
351 comp_node_data_size += 3;
352 ndata_size_stream() << " 3"; // 3 = size of Real3
353 ndata_name_stream() << name << ", Unknown" << '\n';
354 }
355 else if (kind == IK_Cell) {
356 debug() << " Variable " << name
357 << " kind = IK_Cell, type = DT_Real3";
358 nb_comp_cell_data++;
359 comp_cell_data_size += 3;
360 cdata_size_stream() << " 3"; // 3 = size of Real3
361 cdata_name_stream() << name << ", Unknown" << '\n';
362 }
363 }
364 }
365 }
366
367 Integer nb_node = mesh->nbNode();
368 Integer nb_managed_cell = m_managed_cells.size();
369 ucd_file << nb_node << " "
370 << nb_managed_cell << " "
371 << comp_node_data_size << " "
372 << comp_cell_data_size << " 0" << '\n';
373
374 // adding node coordinates
375 ConstArrayView<Real3> node_coords = mesh->toPrimaryMesh()->nodesCoordinates().asArray();
376 for (Integer i = 0; i < nb_node; i++) {
377 const Real3 node_coord = node_coords[i];
378 ucd_file << i + 1 << " "
379 << node_coord.x << " "
380 << node_coord.y << " "
381 << node_coord.z << '\n';
382 }
383
384 // adding cell description
385 for (Integer iz = 0; iz < nb_managed_cell; ++iz) {
386 const Cell cell = m_managed_cells[iz];
387 Integer id = cell.localId();
388 ucd_file << id + 1 << " 1 ";
389 Integer nb_cell_node = cell.nbNode();
390 switch (cell.type()) {
391 case (IT_Vertex):
392 ucd_file << "pt";
393 ucd_file << " " << cell.node(0).localId() + 1;
394 break;
395 case (IT_Line2):
396 ucd_file << "line";
397 for (Integer i = 0; i < nb_cell_node; i++)
398 ucd_file << " " << cell.node(i).localId() + 1;
399 break;
400 case (IT_Triangle3):
401 ucd_file << "tri";
402 for (Integer i = 0; i < nb_cell_node; i++)
403 ucd_file << " " << cell.node(i).localId() + 1;
404 break;
405 case (IT_Quad4):
406 ucd_file << "quad";
407 for (Integer i = 0; i < nb_cell_node; i++)
408 ucd_file << " " << cell.node(i).localId() + 1;
409 break;
410 case (IT_Hexaedron8):
411 ucd_file << "hex";
412 for (Integer i = 0; i < nb_cell_node; i++)
413 ucd_file << " " << cell.node(code_hex[i]).localId() + 1;
414 break;
415 case (IT_Pyramid5):
416 ucd_file << "pyr";
417 for (Integer i = 0; i < nb_cell_node; i++)
418 ucd_file << " " << cell.node(code_pyr[i]).localId() + 1;
419 break;
420 case (IT_Pentagon5):
421 ucd_file << "prism";
422 for (Integer i = 0; i < nb_cell_node; i++)
423 ucd_file << " " << cell.node(code_prism[i]).localId() + 1;
424 break;
425 case (IT_Tetraedron4):
426 ucd_file << "tet";
427 for (Integer i = 0; i < nb_cell_node; i++)
428 ucd_file << " " << cell.node(code_tet[i]).localId() + 1;
429 break;
430 default:
431 // this case cannot happen because of filtering in the constructor
432 break;
433 }
434
435 ucd_file << '\n';
436 }
437
438 // adding the number of node data, their size, their name
439 // and the variable values
440 if (nb_comp_node_data) {
441 ucd_file << nb_comp_node_data
442 << ndata_size_stream.str()
443 << '\n'
444 << ndata_name_stream.str();
445 for (Integer i = 0; i < nb_node; i++)
446 ucd_file << i + 1 << m_node_streams[i]->str() << '\n';
447 }
448
449 // same for cells
450 if (nb_comp_cell_data) {
451 ucd_file << nb_comp_cell_data
452 << cdata_size_stream.str()
453 << '\n'
454 << cdata_name_stream.str();
455 for (Integer i = 0; i < nb_managed_cell; i++) {
456 const Cell& cell = m_managed_cells[i];
457 ucd_file << cell.localId() + 1 << m_cell_streams[i]->str() << '\n';
458 }
459 }
460
461 OStringStream code_ostr;
462 code_ostr() << "U_";
463 code_ostr().fill('0');
464 code_ostr().width(m_max_digit);
465 code_ostr() << m_times.size() - 1;
466 code_ostr() << '\0';
467 buf = m_base_directory.file(code_ostr.str());
468 std::ofstream code_file(buf.localstr());
469 code_file << m_sub_domain->commonVariables().globalIteration() << '\n'
470 << m_times[m_times.size() - 1] << '\n'
471 << "3" << '\n'
472 << "1" << '\n'
473 << "7" << '\n'
474 << "Unknown" << '\n'
475 << comp_node_data_size << '\n'
476 << comp_cell_data_size << '\n';
477 for (Integer i = 0; i < comp_node_data_size; i++)
478 code_file << "1" << '\n';
479 for (Integer i = 0; i < comp_cell_data_size; i++)
480 code_file << "1" << '\n';
481}
482
483/*---------------------------------------------------------------------------*/
484/*---------------------------------------------------------------------------*/
485
486/*---------------------------------------------------------------------------*/
487/*---------------------------------------------------------------------------*/
488
492class UCDPostProcessorService
493: public PostProcessorWriterBase
494{
495 public:
496
497 explicit UCDPostProcessorService(const ServiceBuildInfo& sbi)
498 : PostProcessorWriterBase(sbi)
499 , m_writer(nullptr)
500 {}
501 IDataWriter* dataWriter() override { return m_writer; }
502 void notifyBeginWrite() override;
503 void notifyEndWrite() override;
504 void close() override {}
505
506 private:
507
508 DumpW* m_writer;
509};
510
511/*---------------------------------------------------------------------------*/
512/*---------------------------------------------------------------------------*/
513
516{
517 m_writer = new DumpWUCD(subDomain(), subDomain()->defaultMesh(),
519}
520
523{
524 delete m_writer;
525 m_writer = 0;
526}
527
528/*---------------------------------------------------------------------------*/
529/*---------------------------------------------------------------------------*/
530
532
534
535/*---------------------------------------------------------------------------*/
536/*---------------------------------------------------------------------------*/
537
538} // End namespace Arcane
539
540/*---------------------------------------------------------------------------*/
541/*---------------------------------------------------------------------------*/
Types and macros for iterating over mesh entities.
#define ENUMERATE_CELL(name, group)
Generic enumerator for a cell group.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
#define ARCANE_REGISTER_CASE_OPTIONS_NOAXL_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
Cell of a mesh.
Definition Item.h:1300
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Class managing a directory.
Definition Directory.h:36
bool createDirectory() const override
Creates the directory.
Definition Directory.cc:102
Writing in UCD format.
Definition DumpWUCD.cc:70
VariableList m_save_variables
List of variables to export.
Definition DumpWUCD.cc:124
UniqueArray< Ref< OStringStream > > m_cell_streams
Variable values at cells.
Definition DumpWUCD.cc:126
IMesh * m_mesh
Mesh.
Definition DumpWUCD.cc:121
UniqueArray< Ref< OStringStream > > m_node_streams
Variable values at nodes.
Definition DumpWUCD.cc:127
void writeVal(IVariable &, ConstArrayView< Byte >) override
Writing for variable v of array a.
Definition DumpWUCD.cc:83
RealUniqueArray m_times
List of time instances.
Definition DumpWUCD.cc:123
Directory m_base_directory
Storage directory name.
Definition DumpWUCD.cc:122
UniqueArray< Cell > m_managed_cells
List of managed cells.
Definition DumpWUCD.cc:128
void beginWrite() override
Creation of the UCD file (named UCD_<no_iteration>) and its header. This header contains:
Definition DumpWUCD.cc:270
void endWrite() override
Concatenation of the stream containing cell data to the main file.
Definition DumpWUCD.cc:283
void setMetaData(const String &meta_data) override
Sets metadata information.
Definition DumpWUCD.cc:77
wrapper transforming calls to the IDataWriter interface into IDumpW
Definition DumpW.h:46
DumpW()
Constructor.
Definition DumpW.cc:155
Interface for writing variable data.
Definition IDataWriter.h:45
virtual Integer nbNode()=0
Number of mesh nodes.
virtual CellGroup allCells()=0
Group of all cells.
Interface for a writer for post-processing information.
Interface of the subdomain manager.
Definition ISubDomain.h:75
Interface of a variable.
Definition IVariable.h:40
virtual eDataType dataType() const =0
Data type managed by the variable (Real, Integer, ...).
virtual eItemKind itemKind() const =0
Kind of mesh entities on which the variable is based.
virtual Integer dimension() const =0
Dimension of the variable.
virtual String name() const =0
Variable name.
Node node(Int32 i) const
i-th node of the entity
Definition Item.h:840
Int32 nbNode() const
Number of nodes of the entity.
Definition Item.h:837
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
Int16 type() const
Entity type.
Definition Item.h:255
Output stream linked to a String.
VariableCollection variables() override
List of variables to save.
ConstArrayView< Real > times() override
List of saved times.
const String & baseDirectoryName() override
Name of the output directory for files.
Class managing a 3-dimensional real vector.
Definition Real3.h:132
Structure containing the information to create a service.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
Post-processing in UCD format.
Definition DumpWUCD.cc:494
void notifyBeginWrite() override
Notifies that an output is going to be performed with the current parameters.
Definition DumpWUCD.cc:515
IDataWriter * dataWriter() override
Returns the writer associated with this post-processor.
Definition DumpWUCD.cc:501
void close() override
Closes the writer. After closing, it can no longer be used.
Definition DumpWUCD.cc:504
void notifyEndWrite() override
Notifies that an output has just been performed.
Definition DumpWUCD.cc:522
1D data vector with value semantics (STL style).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
UniqueArray< Real > RealUniqueArray
Dynamic 1D array of reals.
Definition UtilsTypes.h:349
eItemKind
Mesh entity type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
eDataType
Data type.
Definition DataTypes.h:41
@ DT_Real3
Vector 3 data type.
Definition DataTypes.h:49
@ DT_Real
Real data type.
Definition DataTypes.h:43
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.
Definition UtilsTypes.h:488
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35