1#ifndef PRECICE_NO_PYTHON
14#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
15#include <numpy/arrayobject.h>
28 PyObject *ptype, *pvalue, *ptraceback;
29 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
30 if (ptype ==
nullptr) {
31 return "<no error available>";
36 Py_XDECREF(ptraceback);
38 if (pvalue ==
nullptr) {
39 return "<no error message available>";
41 wchar_t *wmessage = PyUnicode_AsWideCharString(pvalue,
nullptr);
49 return "<fetching error message failed>";
63 _modulePath(
std::move(modulePath)),
64 _moduleName(
std::move(moduleName))
67 "The module path of the python action \"{}\" does not exist. The configured path is \"{}\".",
69 if (targetDataID != -1) {
73 if (sourceDataID != -1) {
101 for (
auto &targetStample :
_targetData->stamples()) {
104 PyObject *pythonTime = PyFloat_FromDouble(targetStample.timestamp);
105 PyTuple_SetItem(dataArgs, 0, pythonTime);
109 _sourceData->values() = sourceStample.sample.values;
110 PRECICE_CHECK(
math::equals(sourceStample.timestamp, targetStample.timestamp),
"Trying to perform python action on samples with different timestamps: {} for source data and {} for target data. Time mesh of source data and target data must agree.", sourceStample.timestamp, targetStample.timestamp);
112 npy_intp sourceDim[] = {
_sourceData->values().size()};
113 double * sourceValues =
_sourceData->values().data();
114 _sourceValues = PyArray_SimpleNewFromData(1, sourceDim, NPY_DOUBLE, sourceValues);
115 PRECICE_CHECK(
_sourceValues !=
nullptr,
"Creating python source values failed. Please check that the source data name is used by the mesh in action:python.");
119 _targetData->values() = targetStample.sample.values;
120 npy_intp targetDim[] = {
_targetData->values().size()};
121 double * targetValues =
_targetData->values().data();
123 _targetValues = PyArray_SimpleNewFromData(1, targetDim, NPY_DOUBLE, targetValues);
124 PRECICE_CHECK(
_targetValues !=
nullptr,
"Creating python target values failed. Please check that the target data name is used by the mesh in action:python.");
130 "Error occurred during call of function performAction() in python module \"{}\". "
131 "The error message is: {}",
146 PyRun_SimpleString(
"import sys");
148 PyRun_SimpleString(appendPathCommand.
c_str());
152 "An error occurred while loading python module \"{}\": {}",
_moduleName, python_error_as_string());
156 if (PyErr_Occurred()) {
165 static bool importedAlready =
false;
169 importedAlready =
true;
#define PRECICE_WARN(...)
#define PRECICE_TRACE(...)
#define PRECICE_CHECK(check,...)
#define PRECICE_ASSERT(...)
Abstract base class for configurable actions on data and/or meshes.
Timing
Defines the time and place of application of the action.
const mesh::PtrMesh & getMesh() const
Returns the mesh carrying the data used in the action.
mesh::PtrData _sourceData
PyObject * _moduleNameObject
int makeNumPyArraysAvailable()
PythonAction(Timing timing, std::string modulePath, std::string moduleName, const mesh::PtrMesh &mesh, int targetDataID, int sourceDataID)
virtual void performAction() final override
Performs the action, to be overwritten by subclasses.
PyObject * _performAction
mesh::PtrData _targetData
T is_directory(T... args)
contains actions to modify exchanged data.
constexpr bool equals(const Eigen::MatrixBase< DerivedA > &A, const Eigen::MatrixBase< DerivedB > &B, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares two Eigen::MatrixBase for equality up to tolerance.
std::string truncate_wstring_to_string(std::wstring wstr, char fill)