14#include "arcane/utils/Collection.h"
15#include "arcane/utils/Enumerator.h"
16#include "arcane/utils/Iostream.h"
17#include "arcane/utils/ScopedPtr.h"
18#include "arcane/utils/StringBuilder.h"
19#include "arcane/utils/CheckedConvert.h"
20#include "arcane/utils/JSONWriter.h"
21#include "arcane/utils/IOException.h"
23#include "arcane/core/PostProcessorWriterBase.h"
24#include "arcane/core/Directory.h"
25#include "arcane/core/FactoryService.h"
26#include "arcane/core/IDataWriter.h"
27#include "arcane/core/IData.h"
28#include "arcane/core/IItemFamily.h"
29#include "arcane/core/VariableCollection.h"
30#include "arcane/core/IParallelMng.h"
31#include "arcane/core/IMesh.h"
33#include "arcane/std/KdiPostProcessor_axl.h"
35#include "arcane/core/internal/VtkCellTypes.h"
36#include "arcane/std/internal/Kdi.h"
67 void endWrite()
override;
92 bool m_is_master_io =
false;
100 KDIChunk* m_kdi_chunk_partless =
nullptr;
104 template <
typename DataType> PyArrayObject*
106 template <
typename DataType> PyArrayObject*
107 _numpyDataSet1D(
IData* data);
108 template <
typename DataType> PyArrayObject*
111 PyArrayObject* _numpyDataSetReal3D(
IData* data);
112 PyArrayObject* _numpyDataSetReal2D(
IData* data);
122 return sb.toString();
135 static bool python_initialize =
false;
136 if (!python_initialize) {
154 python_initialize =
true;
168 IParallelMng* pm = m_mesh->parallelMng();
169 const Int32 nb_rank = pm->commSize();
171 m_is_master_io =
true;
174 const bool is_first_call = (time_index < 2);
176 pwarning() <<
"The implementation in 'Kdi' format is experimental";
178 String filename = _getFileNameForTimeIndex(time_index);
185 if (time_index <= 1) {
186 if (m_is_master_io) {
187 dir.createDirectory();
191 info() <<
"KDI begin";
194 m_kdi_full_filename = full_filename.substr(0, full_filename.find_last_of(
"/\\") + 1) +
"Mesh_kdi";
197 info() <<
"KDI createBase m_kdi_base=nullptr";
200 ifstream fichier(filename.c_str());
201 if (!fichier.fail()) {
206 info() <<
"KDI createBase in file";
216 info() <<
"KDI createBase in memory";
220 info() <<
"KDI already createBase";
222 info() <<
"KDI update";
223 m_kdi_base->update(
"UnstructuredGrid",
"/mymesh");
224 info() <<
"KDI chunk";
225 double float_step =
m_times[time_index - 1];
226 Int32 my_rank = pm->commRank();
227 info() <<
"KDI chunk " << float_step <<
" " << my_rank;
229 m_kdi_chunk_partless =
m_kdi_base->chunk(float_step);
231 CellGroup all_cells = m_mesh->allCells();
232 NodeGroup all_nodes = m_mesh->allNodes();
235 const Int32 nb_node = all_nodes.size();
237 Int32 total_nb_connected_node = 0;
241 total_nb_connected_node += cell.nodeIds().size();
247 UniqueArray<Int64> cells_connectivity(total_nb_connected_node);
248 UniqueArray<Int64> cells_offset(nb_cell + 1);
249 UniqueArray<unsigned char> cells_ghost_type(nb_cell);
250 UniqueArray<unsigned char> cells_type(nb_cell);
251 UniqueArray<Int64> cells_uid(nb_cell);
254 Int32 connected_node_index = 0;
256 Int32 index = icell.index();
259 cells_uid[index] = icell->uniqueId();
262 bool is_ghost = !cell.isOwn();
264 ghost_type = VtkUtils::CellGhostTypes::DUPLICATECELL;
265 cells_ghost_type[index] = ghost_type;
267 unsigned char vtk_type = VtkUtils::arcaneToVtkCellType(cell.type());
268 cells_type[index] = vtk_type;
269 for (NodeLocalId node : cell.nodeIds()) {
270 cells_connectivity[connected_node_index] = node;
271 ++connected_node_index;
273 cells_offset[index + 1] = connected_node_index;
278 info() <<
"KDI chunk set connectivity begin";
279 info() <<
"KDI DTYPE C++ connectivity";
280 PyArrayObject* parray = _numpyDataSet1D<Int64>(cells_connectivity);
281 m_kdi_chunk->set(
"/mymesh/cells/connectivity", parray);
282 info() <<
"KDI chunk set connectivity end";
285 info() <<
"KDI chunk set cells types begin";
287 info() <<
"KDI DTYPE C++ cells types";
288 PyArrayObject* parray = _numpyDataSet1D<unsigned char>(cells_type);
290 info() <<
"KDI chunk set cells types end";
295 UniqueArray<Int64> nodes_uid(nb_node);
296 UniqueArray<unsigned char> nodes_ghost_type(nb_node);
298 UniqueArray2<Real> points;
299 points.resize(nb_node, 3);
301 Int32 index = inode.index();
304 nodes_uid[index] = inode->uniqueId();
307 bool is_ghost = !node.isOwn();
309 ghost_type = VtkUtils::PointGhostTypes::DUPLICATEPOINT;
310 nodes_ghost_type[index] = ghost_type;
312 Real3 pos = nodes_coordinates[inode];
313 points[index][0] = pos.x;
314 points[index][1] = pos.y;
315 points[index][2] = pos.z;
319 info() <<
"KDI chunk set connectivity begin";
320 PyArrayObject* parray = _numpyDataSet2D<Real>(points);
321 m_kdi_chunk->set(
"/mymesh/points/cartesianCoordinates", parray);
322 info() <<
"KDI chunk set connectivity end";
326 const std::string namefield =
m_kdi_base->update_fields(
"/mymesh/points/fields",
"GlobalNodeId");
327 assert(namefield ==
"/mymesh/points/fields/GlobalNodeId");
328 info() <<
"KDI chunk set GlobalNodeId begin";
329 info() <<
"KDI DTYPE C++ GlobalNodeId";
330 PyArrayObject* parray = _numpyDataSet1D<Int64>(nodes_uid);
332 info() <<
"KDI chunk set GlobalNodeId end";
335 const std::string namefield =
m_kdi_base->update_fields(
"/mymesh/points/fields",
"vtkGhostType");
336 assert(namefield ==
"/mymesh/points/fields/vtkGhostType");
337 info() <<
"KDI chunk set node vtkGhostType begin";
338 info() <<
"KDI DTYPE C++ node vtkGhostType";
339 PyArrayObject* parray = _numpyDataSet1D<unsigned char>(nodes_ghost_type);
341 info() <<
"KDI chunk set node vtkGhostType end";
347 const std::string namefield =
m_kdi_base->update_fields(
"/mymesh/cells/fields",
"GlobalCellId");
348 assert(namefield ==
"/mymesh/cells/fields/GlobalCellId");
349 info() <<
"KDI chunk set GlobalCellId begin";
350 info() <<
"KDI DTYPE C++ cell GlobalCellId";
351 PyArrayObject* parray = _numpyDataSet1D<Int64>(cells_uid);
353 info() <<
"KDI chunk set GlobalCellId end";
356 const std::string namefield =
m_kdi_base->update_fields(
"/mymesh/cells/fields",
"vtkGhostType");
357 assert(namefield ==
"/mymesh/cells/fields/vtkGhostType");
358 info() <<
"KDI chunk set cell vtkGhostType begin";
359 info() <<
"KDI DTYPE C++ cell vtkGhostType";
360 PyArrayObject* parray = _numpyDataSet1D<unsigned char>(cells_ghost_type);
362 info() <<
"KDI chunk set cell vtkGhostType end";
374 template <
typename DataType>
class KDITraits;
376 template <>
class KDITraits<
Int64>
382 std::cout <<
"KDI DTYPE C++ PyArray_LONG" << std::endl;
387 template <>
class KDITraits<
Int32>
393 std::cout <<
"KDI DTYPE C++ PyArray_INT" << std::endl;
398 template <>
class KDITraits<double>
404 std::cout <<
"KDI DTYPE C++ PyArray_DOUBLE" << std::endl;
409 template <>
class KDITraits<unsigned char>
415 std::cout <<
"KDI DTYPE C++ PyArray_UINT8" << std::endl;
426template <
typename DataType> PyArrayObject* KdiDataWriter::
429 info() <<
"KDI _numpyDataSet1D begin";
431 npy_intp dims[]{ values.size() };
432 const int py_type = KDITraits<DataType>::kdiType();
433 info() <<
"KDI DTYPE C++ py_type " << py_type;
434 PyArrayObject* vec_array =
reinterpret_cast<PyArrayObject*
>(PyArray_SimpleNew(1, dims, py_type));
435 DataType* vec_array_pointer =
static_cast<DataType*
>(PyArray_DATA(vec_array));
436 KTRACE(trace, vec_array_pointer);
437 std::copy(values.data(), values.data() + values.size(), vec_array_pointer);
438 info() <<
"KDI _numpyDataSet1D end";
446template <
typename DataType> PyArrayObject* KdiDataWriter::
449 info() <<
"KDI _numpyDataSet2D begin";
451 npy_intp dims[2] = { values.dim1Size(), values.dim2Size() };
452 const int py_type = KDITraits<DataType>::kdiType();
453 PyArrayObject* vec_array =
reinterpret_cast<PyArrayObject*
>(PyArray_SimpleNew(2, dims, py_type));
454 DataType* vec_array_pointer =
static_cast<DataType*
>(PyArray_DATA(vec_array));
455 KTRACE(trace, vec_array_pointer);
456 std::copy(values.data(), values.data() + values.dim1Size() * values.dim2Size(), vec_array_pointer);
457 info() <<
"KDI _numpyDataSet2D end";
500 ARCANE_UNUSED(meta_data);
511 info(4) <<
"Write Kdi var=" << var->
name();
516 ARCANE_FATAL(
"Only export of scalar item variable is implemented (name={0})", var->
name());
519 info() <<
"KDI chunk set " << var->
name() <<
" begin";
520 std::string namefield;
529 ARCANE_FATAL(
"Only export of 'Cell' or 'Node' variable is implemented (name={0})", var->
name());
532 info() <<
"KDI DTYPE C++ var->name() " << var->
name();
535 PyArrayObject* parray =
nullptr;
538 parray = _numpyDataSet1D<Real>(data);
541 parray = _numpyDataSet1D<Int64>(data);
544 parray = _numpyDataSet1D<Int32>(data);
547 parray = _numpyDataSetReal3D(data);
550 parray = _numpyDataSetReal2D(data);
553 warning() << String::format(
"Export for datatype '{0}' is not supported (var_name={1})", data_type, var->
name());
557 info() <<
"KDI chunk set " << var->
name() <<
" end";
567template <
typename DataType> PyArrayObject* KdiDataWriter::
568_numpyDataSet1D(
IData* data)
572 info() <<
"KDI _numpyDataSet1D var/data begin";
574 info() <<
"KDI _numpyDataSet1D var/data end";
582PyArrayObject* KdiDataWriter::
583_numpyDataSetReal3D(IData* data)
585 info() <<
"KDI _numpyDataSetReal3D var/data begin";
586 auto* true_data =
dynamic_cast<IArrayDataT<Real3>*
>(data);
588 SmallSpan<const Real3> values(true_data->view());
589 Int32 nb_value = values.size();
591 UniqueArray2<Real> scalar_values;
592 scalar_values.resize(nb_value, 3);
593 for (Int32 i = 0; i < nb_value; ++i) {
595 scalar_values[i][0] = v.x;
596 scalar_values[i][1] = v.y;
597 scalar_values[i][2] = v.z;
600 PyArrayObject* vec_array = _numpyDataSet2D<Real>(scalar_values);
601 info() <<
"KDI _numpyDataSetReal3D var/data end";
609PyArrayObject* KdiDataWriter::
610_numpyDataSetReal2D(
IData* data)
612 info() <<
"KDI _numpyDataSetReal3D var/data begin";
614 auto* true_data =
dynamic_cast<IArrayDataT<Real2>*
>(data);
616 SmallSpan<const Real2> values(true_data->view());
617 Int32 nb_value = values.size();
618 UniqueArray2<Real> scalar_values;
619 scalar_values.resize(nb_value, 3);
620 for (
Int32 i = 0; i < nb_value; ++i) {
622 scalar_values[i][0] = v.x;
623 scalar_values[i][1] = v.y;
624 scalar_values[i][2] = 0.0;
627 PyArrayObject* vec_array = _numpyDataSet2D<Real>(scalar_values);
628 info() <<
"KDI _numpyDataSetReal3D var/data end";
641class KdiPostProcessor
654 auto w = std::make_unique<KdiDataWriter>(
mesh(),
groups());
655 w->setTimes(
times());
657 w->setDirectoryName(dir.
file(
"kdi"));
658 m_writer = std::move(w);
668 std::unique_ptr<IDataWriter> m_writer;
674ARCANE_REGISTER_SERVICE_KDIPOSTPROCESSOR(KdiPostProcessor,
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
ArcaneKdiPostProcessorObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
Class managing a directory.
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Interface of a 1D array data item of type T.
Interface for writing variable data.
Interface of a data item.
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.
Integer size() const
Number of elements in the group.
KDIChunk * m_kdi_chunk
Output Chunk identifier (vtps, ipart) and (vtps, partless).
void write(IVariable *var, IData *data) override
Writes the data data of the variable var.
String m_directory_name
Output directory.
void setMetaData(const String &meta_data) override
Sets the metadata information.
KDIBase * m_kdi_base
KDI identifier of the output.
UniqueArray< Real > m_times
List of times.
std::string m_kdi_full_filename
Name of the current HDF file.
ItemGroupCollection m_groups
List of groups to save.
String m_full_filename
Name of the current HDF file.
void notifyBeginWrite() override
Notifies that an output is going to be performed with the current parameters.
void close() override
Closes the writer. After closing, it can no longer be used.
void notifyEndWrite() override
Notifies that an output has just been performed.
IDataWriter * dataWriter() override
Returns the writer associated with this post-processor.
ItemGroupCollection groups() override
List of groups to save.
ConstArrayView< Real > times() override
List of saved times.
const String & baseDirectoryName() override
Name of the output directory for files.
Structure containing the information to create a service.
View for a 2D array whose size is an 'Int64'.
View of an array of elements of type T.
Unicode character string constructor.
Unicode character string.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage warning() const
Flow for a warning message.
TraceMessage pwarning() const
1D data vector with value semantics (STL style).
ItemGroupT< Cell > CellGroup
Group of cells.
ItemGroupT< Node > NodeGroup
Group of nodes.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Collection< ItemGroup > ItemGroupCollection
Collection of mesh item groups.
std::int64_t Int64
Signed integer type of 64 bits.
eItemKind
Mesh entity type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
unsigned char Byte
Type of a byte.
@ DT_Int32
32-bit integer data type
@ DT_Real3
Vector 3 data type.
@ DT_Int64
64-bit integer data type
@ DT_Real2
Vector 2 data type.
@ Cell
The mesh is AMR by cell.
std::int32_t Int32
Signed integer type of 32 bits.
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.