Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Kdi.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* Kdi.h (C) 2000-2024 */
9/* */
10/* Post-traitement avec l'outil KDI. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_STD_INTERNAL_KDI_H
13#define ARCANE_STD_INTERNAL_KDI_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#define Py_LIMITED_API 0x03100000
18#define PY_SSIZE_T_CLEAN
19#define NPY_NO_DEPRECATED_API NPY_1_23_API_VERSION
20#include <Python.h>
21
22#include <numpy/arrayobject.h>
23
24#include <iostream>
25#include <map>
26#include <string>
27#include <vector>
28
29#define KASSERT(cnd) \
30 if (!(cnd)) { \
31 ARCANE_FATAL("KDI ASSERT"); \
32 }
33#define KTRACE(trace, msg) \
34 if (trace) { \
35 std::cout << msg << std::endl; \
36 }
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
42{
43 private:
44
45 const PyObject* m_pInstanceChunk;
46 const bool m_trace;
47
48 public:
49
50 KDIChunk(const PyObject* _pInstanceChunk, bool _trace = false)
51 : m_pInstanceChunk(_pInstanceChunk)
52 , m_trace(_trace)
53 {
54 KTRACE(m_trace, "KDIChunk::KDIChunk IN/OUT");
55 }
56
57 ~KDIChunk()
58 {
59 KTRACE(m_trace, "KDIChunk::~KDIChunk IN");
60 if (m_pInstanceChunk)
61 Py_DECREF(m_pInstanceChunk);
62 KTRACE(m_trace, "KDIChunk::~KDIChunk OUT");
63 }
64
65 private:
66
67 PyObject* _simple_call(const std::string _method, PyObject* _pArgs)
68 {
69 KTRACE(m_trace, "KDIChunk:_simple_call IN");
70 PyObject* pValue = PyUnicode_FromString("pykdi");
71 KASSERT(pValue);
72 PyObject* pModule = PyImport_Import(pValue);
73 KASSERT(pModule);
74 PyObject* pClass = PyObject_GetAttrString(pModule, "KDIAgreementStepPartChunk");
75 KASSERT(pClass);
76 PyObject* pMethod = PyObject_GetAttrString(pClass, _method.c_str());
77 KASSERT(pMethod);
78 KASSERT(PyCallable_Check(pMethod));
79 KASSERT(_pArgs);
80 PyObject* pResult = PyObject_CallObject(pMethod, _pArgs);
81 Py_DECREF(pMethod);
82 Py_DECREF(pClass);
83 Py_DECREF(pModule);
84 Py_DECREF(pValue);
85 KTRACE(m_trace, "KDIChunk:_simple_call OUT");
86 return pResult;
87 }
88
89 public:
90
91 void dump()
92 {
93 KTRACE(m_trace, "KDIChunk:dump IN");
94 KASSERT(m_pInstanceChunk);
95 PyObject* pArgs = Py_BuildValue("(O)", m_pInstanceChunk);
96 _simple_call("dump", pArgs);
97 Py_DECREF(pArgs);
98 KTRACE(m_trace, "KDIChunk:dump OUT");
99 }
100
101 void set(const std::string _absname, PyArrayObject* _array)
102 {
103 KTRACE(m_trace, "KDIChunk:set IN");
104 KASSERT(m_pInstanceChunk);
105 PyObject* pArgs = Py_BuildValue("(O, z, O)", m_pInstanceChunk, _absname.c_str(), _array);
106 _simple_call("set", pArgs);
107 Py_DECREF(pArgs);
108 KTRACE(m_trace, "KDIChunk:set OUT");
109 }
110
111 void saveVTKHDF(const std::string _absfilename)
112 {
113 // TODO On pourrait vérifier que l'on est partless au moins en 0.4.0
114 KTRACE(m_trace, "KDIChunk:saveVTKHDF (...) IN");
115 // TODO Verifier que l'on est bien partless
116 KASSERT(m_pInstanceChunk);
117 PyObject* pArgs = Py_BuildValue("(O, z)", m_pInstanceChunk, _absfilename.c_str());
118 KASSERT(pArgs);
119 _simple_call("saveVTKHDF", pArgs);
120 Py_DECREF(pArgs);
121 KTRACE(m_trace, "KDIChunk:saveVTKHDF OUT");
122 }
123
124 void saveVTKHDFCompute(const std::string _absfilename)
125 {
126 KTRACE(m_trace, "KDI KDIChunk saveVTKHDFCompute " << _absfilename);
127 // TODO On pourrait vérifier que l'on est partless au moins en 0.4.0
128 // TODO ON pourrait trouver une facon plus elegante d'activté des traitements ici KDIComputeMultiMilieux
129 KTRACE(m_trace, "KDIChunk:saveVTKHDFCompute (...) IN");
130 // TODO Verifier que l'on est bien partless
131 KASSERT(m_pInstanceChunk);
132 PyObject* pArgs = Py_BuildValue("(O, z)", m_pInstanceChunk, _absfilename.c_str());
133 KASSERT(pArgs);
134 _simple_call("saveVTKHDFCompute", pArgs);
135 Py_DECREF(pArgs);
136 KTRACE(m_trace, "KDI KDIChunk saveVTKHDFCompute");
137 }
138};
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
144{
145 private:
146
147 const PyObject* m_pInstanceBase;
148 const bool m_trace;
149
150 public:
151
152 KDIBase(const PyObject* _pInstanceBase, const bool _trace)
153 : m_pInstanceBase(_pInstanceBase)
154 , m_trace(_trace)
155 {
156 KTRACE(m_trace, "KDIBase::KDIBase IN/OUT");
157 }
158
159 ~KDIBase()
160 {
161 KTRACE(m_trace, "KDIBase::~KDIBase IN");
162 if (m_pInstanceBase)
163 Py_DECREF(m_pInstanceBase);
164 KTRACE(m_trace, "KDIBase::~KDIBase OUT");
165 }
166
167 private:
168
169 PyObject* _simple_call(const std::string _method, PyObject* _pArgs)
170 {
171 KTRACE(m_trace, "KDIBase:_simple_call IN");
172 PyObject* pValue = PyUnicode_FromString("pykdi");
173 KASSERT(pValue);
174 PyObject* pModule = PyImport_Import(pValue);
175 KASSERT(pModule);
176 PyObject* pClass = PyObject_GetAttrString(pModule, "KDIAgreementStepPartBase");
177 KASSERT(pClass);
178 PyObject* pMethod = PyObject_GetAttrString(pClass, _method.c_str());
179 KASSERT(pMethod);
180 KASSERT(PyCallable_Check(pMethod));
181 KASSERT(_pArgs);
182 PyObject* pResult = PyObject_CallObject(pMethod, _pArgs);
183 Py_DECREF(pMethod);
184 Py_DECREF(pClass);
185 Py_DECREF(pModule);
186 Py_DECREF(pValue);
187 KTRACE(m_trace, "KDIBase:_simple_call OUT");
188 return pResult;
189 }
190
191 public:
192
193 void dump()
194 {
195 KTRACE(m_trace, "KDIBase:dump IN");
196 KASSERT(m_pInstanceBase);
197 PyObject* pArgs = Py_BuildValue("(O)", m_pInstanceBase);
198 _simple_call("dump", pArgs);
199 Py_DECREF(pArgs);
200 KTRACE(m_trace, "KDIBase:dump OUT");
201 }
202
203 void update(const std::string& _typename, const std::string& _absname)
204 {
205 KTRACE(m_trace, "KDIBase:update IN");
206 KASSERT(m_pInstanceBase);
207 PyObject* pArgs = Py_BuildValue("(O, z, z)", m_pInstanceBase, _typename.c_str(), _absname.c_str());
208 KASSERT(pArgs);
209 _simple_call("update", pArgs);
210 Py_DECREF(pArgs);
211 KTRACE(m_trace, "KDIBase:update OUT");
212 }
213
214 const std::string update_fields(const std::string& _nameParentMesh, const std::string& _nameField)
215 {
216 KTRACE(m_trace, "KDIBase:update_fields IN");
217 KASSERT(m_pInstanceBase);
218 PyObject* pArgs = Py_BuildValue("(O, z, z)", m_pInstanceBase, _nameParentMesh.c_str(), _nameField.c_str());
219 KASSERT(pArgs);
220 _simple_call("update_fields", pArgs);
221 Py_DECREF(pArgs);
222 KTRACE(m_trace, "KDIBase:update_fields OUT");
223 // TODO Ceci est une verole... il serait preferable que ce soit le retour de la fonction Python qui soit exploitee
224 return _nameParentMesh + "/" + _nameField;
225 }
226
227 const std::string update_sub(const std::string& _nameParentMesh, const std::string& _nameSubMesh)
228 {
229 KTRACE(m_trace, "KDIBase:update_sub IN");
230 KASSERT(m_pInstanceBase);
231 KASSERT(_nameParentMesh[0] == '/');
232 KASSERT(_nameSubMesh[0] == '/');
233 PyObject* pArgs = Py_BuildValue("(O, z, z)", m_pInstanceBase, _nameParentMesh.c_str(), _nameSubMesh.c_str());
234 KASSERT(pArgs);
235 _simple_call("update_sub", pArgs);
236 Py_DECREF(pArgs);
237 KTRACE(m_trace, "KDIBase:update_sub OUT");
238 // TODO Ceci est une verole... il serait preferable que ce soit le retour de la fonction Python qui soit exploitee
239 return _nameParentMesh + "/submeshes" + _nameSubMesh;
240 }
241
242 private:
243
244 KDIChunk* _chunk(PyObject* pArgs)
245 {
246 KTRACE(m_trace, "KDIBase:_chunk IN");
247 PyObject* pResult = _simple_call("chunk", pArgs);
248 Py_DECREF(pArgs);
249 KDIChunk* chunk = new KDIChunk(pResult, m_trace);
250 KTRACE(m_trace, "KDIBase:_chunk OUT");
251 return chunk;
252 }
253
254 public:
255
256 KDIChunk* chunk()
257 {
258 KTRACE(m_trace, "KDIBase:chunk IN");
259 KASSERT(m_pInstanceBase);
260 PyObject* pArgs = Py_BuildValue("(O)", m_pInstanceBase);
261 KDIChunk* chunk = _chunk(pArgs);
262 Py_DECREF(pArgs);
263 KTRACE(m_trace, "KDIBase:chunk OUT (" << chunk << ")");
264 return chunk;
265 }
266
267 KDIChunk* chunk(double _vstep)
268 {
269 KTRACE(m_trace, "KDIBase:chunk (" << _vstep << ") IN");
270 KASSERT(m_pInstanceBase);
271 PyObject* pArgs = Py_BuildValue("(O, f)", m_pInstanceBase, _vstep);
272 KDIChunk* chunk = _chunk(pArgs);
273 Py_DECREF(pArgs);
274 KTRACE(m_trace, "KDIBase:chunk OUT (" << chunk << ")");
275 return chunk;
276 }
277
278 KDIChunk* chunk(double _vstep, int _ipart)
279 {
280 KTRACE(m_trace, "KDIBase:chunk (" << _vstep << ") IN");
281 KASSERT(m_pInstanceBase);
282 PyObject* pArgs = Py_BuildValue("(O, f, i)", m_pInstanceBase, _vstep, _ipart);
283 KDIChunk* chunk = _chunk(pArgs);
284 Py_DECREF(pArgs);
285 KTRACE(m_trace, "KDIBase:chunk OUT (" << chunk << ")");
286 return chunk;
287 }
288};
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
292
293KDIBase*
294createBase(unsigned int _nb_parts, bool _trace = false)
295{
296 KTRACE(_trace, "KDI C++ createBase (" << _nb_parts << ") IN");
297 PyObject* pValue = PyUnicode_FromString("pykdi");
298 KASSERT(pValue);
299 KTRACE(_trace, "KDI FromString pValue=" << pValue);
300 KTRACE(_trace, "KDI Getenv PYTHONPATH=" << getenv("PYTHONPATH"));
301 KTRACE(_trace, "KDI Getenv KDI_DICTIONARY_PATH=" << getenv("KDI_DICTIONARY_PATH"));
302 // Si on a un plantage, c'est parce que les commandes :
303 // Py_Initialize();
304 // import_array();
305 // n'ont pas été exécutées avant.
306 PyObject* pModule = PyImport_Import(pValue);
307 KTRACE(_trace, "KDI Import ?");
308 KTRACE(_trace, "KDI pModule=" << pModule);
309 KASSERT(pModule);
310 KTRACE(_trace, "KDI Import");
311 PyObject* pClass = PyObject_GetAttrString(pModule, "KDIAgreementStepPartBase");
312 KASSERT(pClass);
313 KTRACE(_trace, "KDI GetAttrString");
314 KASSERT(PyCallable_Check(pClass));
315 KTRACE(_trace, "KDI Check");
316 PyObject* pArgs = Py_BuildValue("(i)", (int)_nb_parts);
317 KASSERT(pArgs);
318 KTRACE(_trace, "KDI BuildValue");
319 PyObject* pResult = PyObject_CallObject(pClass, pArgs);
320 KASSERT(pResult);
321 KTRACE(_trace, "KDI CallObject");
322 Py_DECREF(pArgs);
323 Py_DECREF(pClass);
324 Py_DECREF(pModule);
325 Py_DECREF(pValue);
326 KDIBase* base = new KDIBase(pResult, _trace);
327 KTRACE(_trace, "KDI C++ createBase OUT");
328 return base;
329}
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333
334KDIBase*
335loadVTKHDF(const std::string _absfilename, bool _trace = false)
336{
337 KTRACE(_trace, "loadBase () IN");
338 PyObject* pValue = PyUnicode_FromString("pykdi");
339 KASSERT(pValue);
340 PyObject* pModule = PyImport_Import(pValue);
341 KASSERT(pModule);
342 PyObject* pClass = PyObject_GetAttrString(pModule, "KDIAgreementStepPartBase");
343 KASSERT(pClass);
344 KASSERT(PyCallable_Check(pClass));
345 PyObject* pArgs = Py_BuildValue("(z)", _absfilename.c_str());
346 KASSERT(pArgs);
347 PyObject* pResult = PyObject_CallObject(pClass, pArgs);
348 KASSERT(pResult);
349 Py_DECREF(pArgs);
350 Py_DECREF(pClass);
351 Py_DECREF(pModule);
352 Py_DECREF(pValue);
353 KDIBase* base = new KDIBase(pResult, _trace);
354 KTRACE(_trace, "loadVTKHDF OUT");
355 return base;
356}
357
358/*---------------------------------------------------------------------------*/
359/*---------------------------------------------------------------------------*/
372template <typename T>
373static PyArrayObject* vector_to_nparray(const std::vector<std::vector<T>>& vec, int type_num = NPY_FLOAT64)
374{
375
376 // rows not empty
377 if (!vec.empty()) {
378
379 // column not empty
380 if (!vec[0].empty()) {
381
382 size_t nRows = vec.size();
383 size_t nCols = vec[0].size();
384 npy_intp dims[2] = { nRows, nCols };
385 PyArrayObject* vec_array = (PyArrayObject*)PyArray_SimpleNew(2, dims, type_num);
386
387 T* vec_array_pointer = (T*)PyArray_DATA(vec_array);
388
389 // copy vector line by line ... maybe could be done at one
390 for (size_t iRow = 0; iRow < vec.size(); ++iRow) {
391
392 if (vec[iRow].size() != nCols) {
393 Py_DECREF(vec_array); // delete
394 throw(std::string("Can not convert vector<vector<T>> to np.array, since c++ matrix shape is not uniform."));
395 }
396
397 copy(vec[iRow].begin(), vec[iRow].end(), vec_array_pointer + iRow * nCols);
398 }
399
400 return vec_array;
401
402 // Empty columns
403 }
404 else {
405 npy_intp dims[2] = { vec.size(), 0 };
406 return (PyArrayObject*)PyArray_ZEROS(2, dims, NPY_FLOAT64, 0);
407 }
408
409 // no data at all
410 }
411 else {
412 npy_intp dims[2] = { 0, 0 };
413 return (PyArrayObject*)PyArray_ZEROS(2, dims, NPY_FLOAT64, 0);
414 }
415}
416
432template <typename T>
433static PyArrayObject* vector_to_nparray(const std::vector<T>& vec, int type_num = NPY_FLOAT64, int comp_num = 1)
434{
435 bool trace{ true };
436
437 // rows not empty
438 if (!vec.empty()) {
439 PyArrayObject* vec_array = nullptr;
440 if (comp_num == 1) {
441 int nd = 1;
442 npy_intp dims[]{ vec.size() };
443 vec_array = (PyArrayObject*)PyArray_SimpleNew(nd, dims, type_num);
444 }
445 else {
446 int nd = 2;
447 npy_intp dims[]{ int(vec.size() / comp_num), comp_num };
448 vec_array = (PyArrayObject*)PyArray_SimpleNew(nd, dims, type_num);
449 }
450 T* vec_array_pointer = (T*)PyArray_DATA(vec_array);
451 KTRACE(trace, vec_array_pointer);
452 // A bannir
453 copy(vec.begin(), vec.end(), vec_array_pointer);
454 return vec_array;
455
456 // no data at all
457 }
458 else {
459 npy_intp dims[1] = { 0 };
460 return (PyArrayObject*)PyArray_ZEROS(1, dims, NPY_FLOAT64, 0);
461 }
462}
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467#endif
468
469/*---------------------------------------------------------------------------*/
470/*---------------------------------------------------------------------------*/
Definition Kdi.h:144
Definition Kdi.h:42
char * copy(char *to, const char *from)
Copie from dans to.