OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
cpp_python_funct.h
Go to the documentation of this file.
1//Copyright> OpenRadioss
2//Copyright> Copyright (C) 1986-2025 Altair Engineering Inc.
3//Copyright>
4//Copyright> This program is free software: you can redistribute it and/or modify
5//Copyright> it under the terms of the GNU Affero General Public License as published by
6//Copyright> the Free Software Foundation, either version 3 of the License, or
7//Copyright> (at your option) any later version.
8//Copyright>
9//Copyright> This program is distributed in the hope that it will be useful,
10//Copyright> but WITHOUT ANY WARRANTY; without even the implied warranty of
11//Copyright> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12//Copyright> GNU Affero General Public License for more details.
13//Copyright>
14//Copyright> You should have received a copy of the GNU Affero General Public License
15//Copyright> along with this program. If not, see <https://www.gnu.org/licenses/>.
16//Copyright>
17//Copyright>
18//Copyright> Commercial Alternative: Altair Radioss Software
19//Copyright>
20//Copyright> As an alternative to this open-source version, Altair also offers Altair Radioss
21//Copyright> software under a commercial license. Contact Altair to discuss further if the
22//Copyright> commercial version may interest you: https://www.altair.com/radioss/.
23
24// the maximum length of a line of code of python function
25#include <iostream>
26#include <string>
27#include <regex>
28#include <array>
29#include <set>
30#include <array>
31#include <set>
32#include <utility>
33#include <vector>
34#include <limits>
35#include <cmath>
36
37
38#include <stdio.h>
39
40#if defined(_WIN64)
41#include <BaseTsd.h>
42typedef SSIZE_T My_ssize_t;
43#else
44#include <stddef.h>
45typedef ssize_t My_ssize_t;
46#endif
47
48#define max_line_length 500
49// the maximum number of lines of python function
50#define max_num_lines 1000
51#define max_code_length max_line_length *max_num_lines
52#define max_variable_length 100
53
54constexpr int sensor_result_size = 2;
55
56typedef void *PyObject;
57// Corrected typedefs for Python C API function pointers
58typedef PyObject *(*T_PyDict_GetItemString)(PyObject *, const char *);
59typedef int (*T_PyCallable_Check)(PyObject *);
60typedef PyObject *(*T_PyTuple_New)(My_ssize_t); // Use Py_ssize_t for size
61typedef PyObject *(*T_PyFloat_FromDouble)(double);
62typedef PyObject *(*T_PyObject_CallObject)(PyObject *, PyObject *);
63typedef void (*T_Py_Initialize)();
64typedef void (*T_Py_Finalize)();
65typedef PyObject *(*T_PyImport_AddModule)(const char *);
66typedef PyObject *(*T_PyModule_GetDict)(PyObject *);
67typedef int (*T_PyRun_SimpleString)(const char *);
68typedef int (*T_PyTuple_SetItem)(PyObject *, My_ssize_t, PyObject *); // Use Py_ssize_t for index
70typedef void (*T_Py_DecRef)(PyObject *);
71typedef void (*T_Py_IncRef)(PyObject *);
72typedef double (*T_PyFloat_AsDouble)(PyObject *);
73typedef int (*T_PyDict_SetItemString)(PyObject *, const char *, PyObject *);
74typedef void (*T_PyErr_Fetch)(PyObject **, PyObject **, PyObject **);
75typedef void (*T_PyErr_Display)(PyObject *, PyObject *, PyObject *);
76typedef PyObject *(*T_PyErr_Occurred)();
77typedef int (*T_Py_IsInitialized)();
78typedef PyObject *(*T_PyObject_Str)(PyObject *);
79typedef const char *(*T_PyUnicode_AsUTF8)(PyObject *);
80typedef PyObject *(*T_PyDict_New)();
81typedef PyObject *(*T_PyList_New)(My_ssize_t); // Use Py_ssize_t for size
82typedef void (*T_PyErr_Clear)();
83typedef PyObject *(*T_PyLong_FromLong)(long int);
84typedef PyObject *(*T_PyLong_FromVoidPtr)(void *);
85typedef PyObject *(*T_PyUnicode_FromString)(const char *); // Added this line to declare the function pointer
86
87struct _ts; // Forward declaration for PyThreadState
88typedef struct _ts PyThreadState;
89typedef int PyGILState_STATE;
90
91typedef PyThreadState *(*T_PyEval_SaveThread)();
95
96
97
98// Python library handle
99#ifdef _WIN32
100template <typename T>
101void load_function(HMODULE handle, const std::string &func_name, T &func_ptr, bool &python_initialized)
102{
103 func_ptr = reinterpret_cast<T>(GetProcAddress(handle, func_name.c_str()));
104 if (func_ptr == nullptr)
105 {
106 // std::cout << "Could not load " << func_name << ": " << GetLastError() << std::endl;
107 python_initialized = false;
108 }
109}
110
111#else
112
113template <typename T>
114void load_function(void *h, const std::string &func_name, T &func_ptr, bool &python_initialized)
115{
116 func_ptr = reinterpret_cast<T>(dlsym(h, func_name.c_str()));
117 if (func_ptr == nullptr)
118 {
119 const char *dlsym_error = dlerror();
120 std::cout << "Could not load " << func_name << ": " << dlsym_error << std::endl;
121 python_initialized = false;
122 }
123}
124#endif
125
152T_PyLong_FromVoidPtr MyLong_FromVoidPtr; // Added this line to declare the function pointer
153T_PyUnicode_FromString MyUnicode_FromString; // Added this line to declare the function pointer
158
159
160constexpr std::array<const char*, 89> ELEMENT_KEYWORDS = {
161"ALPHA",
162"AMS",
163"BFRAC",
164"BULK",
165"COLOR",
166"DAM1",
167"DAM2",
168"DAM3",
169"DAMA",
170"DAMG",
171"DAMINI",
172"DENS",
173"DOMAIN",
174"DT",
175"EINT",
176"EINTM",
177"EINTV",
178"ENER",
179"ENTH",
180"ENTHM",
181"ENTHV",
182"EPSD",
183"EPSP",
184"FAIL",
185"FAILURE",
186"FILL",
187"FLAY",
188"FLDF",
189"FLDZ",
190"GROUP",
191"HC_DSSE_F",
192"HC_DSSE_Z",
193"HOURGLASS",
194"K",
195"M151DENS",
196"M151ENER",
197"M151PRES",
198"M151VFRAC",
199"MACH",
200"MASS",
201"MOMX",
202"MOMXY",
203"MOMXZ",
204"MOMY",
205"MOMYZ",
206"MOMZ",
207"NL_EPSD",
208"NL_EPSP",
209"NXTF",
210"OFF",
211"P",
212"PHI",
213"SCHLIEREN",
214"SIGEQ",
215"SIGX",
216"SIGXY",
217"SIGY",
218"SIGYZ",
219"SIGZ",
220"SIGZX",
221"SSP",
222"TDEL",
223"TDET",
224"TEMP",
225"THICK",
226"THIN",
227"TILLOTSON",
228"TSAIWU",
229"TVIS",
230"VDAM1",
231"VDAM2",
232"VDAM3",
233"VELX",
234"VELXY",
235"VELXZ",
236"VELY",
237"VELYZ",
238"VELZ",
239"VFRAC1",
240"VFRAC2",
241"VFRAC3",
242"VFRAC4",
243"VOLU",
244"VONM",
245"VORT",
246"VORTX",
247"VORTY",
248"VORTZ",
249"WPLA"
250};
251
252using KeywordPair = std::pair<int, const char*>;
253// Comparator for the set to order pairs by keyword and id
255 bool operator() (const KeywordPair& lhs, const KeywordPair& rhs) const {
256 if (lhs.second == rhs.second) {
257 return lhs.first < rhs.first;
258 }
259 return std::string(lhs.second) < std::string(rhs.second);
260 }
261};
262using KeywordPairs = std::set<std::pair<int, const char*>, ComparePairs>;
263
264// Get a pair of keyword, id from an index: is inefficient but called only at initialization
265KeywordPair get_keyword_pair(const KeywordPairs& keywordPairs, size_t n) {
266 if (n >= keywordPairs.size()) {
267 std::cout<<"ERROR: Out of range access in elemental value for Python function."<<std::endl;
268 std::cout<<"Index: "<<n<<" Size: "<<keywordPairs.size()<<std::endl;
269 }
270 auto it = std::next(keywordPairs.begin(), n);
271 return *it;
272}
273
274
275// Utility function to add a key-value pair to a dictionary with proper reference counting
276//static int add_to_dict(PyObject* dict, PyObject* key, PyObject* value) {
277// int result = MyDict_SetItem(dict, key, value);
278// My_DecRef(key); // PyDict_SetItem doesn't steal references
279// My_DecRef(value); // so we need to decrease them ourselves
280// return result;
281//}
282
283// Utility function to format a key with the array name
284//static PyObject* create_key(const char* array_name, const char* suffix) {
285// return MyUnicode_FromFormat("%s_%s", array_name, suffix);
286//}
287
288// Utility function to check if a Python object is a valid dictionary
289//static int check_context(PyObject* context) {
290// if (!context || !MyDict_Check(context)) {
291// std::cerr << "Error: Invalid context pointer" << std::endl;
292// return -1;
293// }
294// return 0;
295//}
296
297
298
void * handle
bool python_initialized
T_PyEval_RestoreThread MyEval_RestoreThread
PyObject *(* T_PyUnicode_FromString)(const char *)
int(* T_PyRun_SimpleString)(const char *)
T_PyModule_GetDict MyModule_GetDict
PyObject *(* T_PyFloat_FromDouble)(double)
T_PyList_New MyList_New
PyGILState_STATE(* T_PyGILState_Ensure)()
PyObject *(* T_PyLong_FromLong)(long int)
T_PyGILState_Release MyGILState_Release
T_PyErr_Display MyErr_Display
PyThreadState *(* T_PyEval_SaveThread)()
double(* T_PyFloat_AsDouble)(PyObject *)
PyObject *(* T_PyErr_Occurred)()
T_Py_DecRef My_DecRef
int(* T_PyTuple_SetItem)(PyObject *, My_ssize_t, PyObject *)
void(* T_Py_IncRef)(PyObject *)
void(* T_PyGILState_Release)(PyGILState_STATE)
int PyGILState_STATE
T_PyTuple_SetItem MyTuple_SetItem
T_PyCallable_Check MyCallable_Check
ssize_t My_ssize_t
T_PyLong_FromLong MyLong_FromLong
T_PyDict_New MyDict_New
PyObject *(* T_PyDict_GetItemString)(PyObject *, const char *)
void * PyObject
T_PyLong_FromVoidPtr MyLong_FromVoidPtr
PyObject *(* T_PyModule_GetDict)(PyObject *)
void(* T_PyErr_Display)(PyObject *, PyObject *, PyObject *)
void(* T_Py_Initialize)()
int(* T_Py_IsInitialized)()
int(* T_PyCallable_Check)(PyObject *)
PyObject *(* T_PyList_New)(My_ssize_t)
constexpr std::array< const char *, 89 > ELEMENT_KEYWORDS
T_PyUnicode_FromString MyUnicode_FromString
T_PyUnicode_AsUTF8 MyUnicode_AsUTF8
T_PyDict_GetItemString MyDict_GetItemString
void(* T_PyErr_Fetch)(PyObject **, PyObject **, PyObject **)
PyObject *(* T_PyTuple_New)(My_ssize_t)
KeywordPair get_keyword_pair(const KeywordPairs &keywordPairs, size_t n)
T_PyErr_Clear MyErr_Clear
void(* T_Py_Finalize)()
std::pair< int, const char * > KeywordPair
T_PyGILState_Ensure MyGILState_Ensure
int(* T_PyDict_SetItemString)(PyObject *, const char *, PyObject *)
T_PyErr_Occurred MyErr_Occurred
T_Py_IsInitialized My_IsInitialized
int(* T_PyList_SetItem)(PyObject *, My_ssize_t, PyObject *)
T_Py_Initialize My_Initialize
void(* T_Py_DecRef)(PyObject *)
PyObject *(* T_PyImport_AddModule)(const char *)
struct _ts PyThreadState
T_PyErr_Fetch MyErr_Fetch
T_Py_Finalize My_Finalize
T_Py_IncRef My_IncRef
PyObject *(* T_PyDict_New)()
T_PyFloat_AsDouble MyFloat_AsDouble
T_PyImport_AddModule MyImport_AddModule
void(* T_PyErr_Clear)()
constexpr int sensor_result_size
std::set< std::pair< int, const char * >, ComparePairs > KeywordPairs
PyObject *(* T_PyObject_Str)(PyObject *)
void load_function(void *h, const std::string &func_name, T &func_ptr, bool &python_initialized)
PyObject *(* T_PyLong_FromVoidPtr)(void *)
T_PyDict_SetItemString MyDict_SetItemString
T_PyTuple_New MyTuple_New
const char *(* T_PyUnicode_AsUTF8)(PyObject *)
T_PyRun_SimpleString MyRun_SimpleString
T_PyList_SetItem MyList_SetItem
PyObject *(* T_PyObject_CallObject)(PyObject *, PyObject *)
T_PyObject_CallObject MyObject_CallObject
T_PyObject_Str MyObject_Str
void(* T_PyEval_RestoreThread)(PyThreadState *)
T_PyFloat_FromDouble MyFloat_FromDouble
T_PyEval_SaveThread MyEval_SaveThread
n
bool operator()(const KeywordPair &lhs, const KeywordPair &rhs) const