F_Python.cpp (getdp-3.4.0-source.tgz) | : | F_Python.cpp (getdp-3.5.0-source.tgz) | ||
---|---|---|---|---|
// GetDP - Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege | // GetDP - Copyright (C) 1997-2022 P. Dular and C. Geuzaine, University of Liege | |||
// | // | |||
// See the LICENSE.txt file for license information. Please report all | // See the LICENSE.txt file for license information. Please report all | |||
// issues on https://gitlab.onelab.info/getdp/getdp/issues. | // issues on https://gitlab.onelab.info/getdp/getdp/issues. | |||
#include "GetDPConfig.h" | #include "GetDPConfig.h" | |||
#include "ProData.h" | #include "ProData.h" | |||
#include "F.h" | #include "F.h" | |||
#include "Message.h" | #include "Message.h" | |||
extern struct CurrentData Current ; | extern struct CurrentData Current; | |||
#if defined(HAVE_KERNEL) | #if defined(HAVE_KERNEL) | |||
extern char *Name_Path ; | extern char *Name_Path; | |||
#else | #else | |||
static const char *Name_Path = ""; | static const char *Name_Path = ""; | |||
#endif | #endif | |||
// This file defines a simple interface to Python. | // This file defines a simple interface to Python. | |||
// | // | |||
// * The Python interpreter will be initialized when GetDP is started; you can | // * The Python interpreter will be initialized when GetDP is started; you can | |||
// then use the Python[argument_list]{string} function in the same way as | // then use the Python[argument_list]{string} function in the same way as | |||
// other GetDP functions: | // other GetDP functions: | |||
// | // | |||
skipping to change at line 52 | skipping to change at line 52 | |||
// Evaluate[ my_python_precomputation[] ] | // Evaluate[ my_python_precomputation[] ] | |||
// | // | |||
// in the Operation field of a Resolution before Generate[] is called. | // in the Operation field of a Resolution before Generate[] is called. | |||
#if defined(HAVE_PYTHON) | #if defined(HAVE_PYTHON) | |||
#include <Python.h> | #include <Python.h> | |||
void F_Python(F_ARG) | void F_Python(F_ARG) | |||
{ | { | |||
if(!Fct->String){ | if(!Fct->String) { | |||
Message::Error("Missing Python expression: use Python[arguments]{\"expressio | Message::Error( | |||
n\"}"); | "Missing Python expression: use Python[arguments]{\"expression\"}"); | |||
for (int k = 0; k < Current.NbrHar; k++) | for(int k = 0; k < Current.NbrHar; k++) V->Val[MAX_DIM * k] = 0.; | |||
V->Val[MAX_DIM * k] = 0. ; | ||||
V->Type = SCALAR; | V->Type = SCALAR; | |||
return; | return; | |||
} | } | |||
// we could do this more efficiently by directly storing the values in python | // we could do this more efficiently by directly storing the values in python | |||
// (instead of parsing) | // (instead of parsing) | |||
std::string expr = "input = ["; | std::string expr = "input = ["; | |||
for(int i = 0; i < Fct->NbrArguments; i++){ | for(int i = 0; i < Fct->NbrArguments; i++) { | |||
char tmp[256]; | char tmp[256]; | |||
if((A + i)->Type == SCALAR){ | if((A + i)->Type == SCALAR) { | |||
if(Current.NbrHar == 2) | if(Current.NbrHar == 2) | |||
sprintf(tmp, "%.16g+%.16gj", | sprintf(tmp, "%.16g+%.16gj", (A + i)->Val[0], (A + i)->Val[MAX_DIM]); | |||
(A + i)->Val[0], (A + i)->Val[MAX_DIM]); | ||||
else | else | |||
sprintf(tmp, "%.16g", (A + i)->Val[0]); | sprintf(tmp, "%.16g", (A + i)->Val[0]); | |||
} | } | |||
else if((A + i)->Type == VECTOR){ | else if((A + i)->Type == VECTOR) { | |||
strcpy(tmp, "["); | strcpy(tmp, "["); | |||
char tmp2[256]; | char tmp2[256]; | |||
for(int j = 0; j < 3; j++){ | for(int j = 0; j < 3; j++) { | |||
if(Current.NbrHar == 2) | if(Current.NbrHar == 2) | |||
sprintf(tmp2, "%.16g+%.16gj", | sprintf(tmp2, "%.16g+%.16gj", (A + i)->Val[j], | |||
(A + i)->Val[j], (A + i)->Val[MAX_DIM + j]); | (A + i)->Val[MAX_DIM + j]); | |||
else | else | |||
sprintf(tmp2, "%.16g", (A + i)->Val[j]); | sprintf(tmp2, "%.16g", (A + i)->Val[j]); | |||
if(j != 2) strcat(tmp2, ","); | if(j != 2) strcat(tmp2, ","); | |||
strcat(tmp, tmp2); | strcat(tmp, tmp2); | |||
} | } | |||
strcat(tmp, "]"); | strcat(tmp, "]"); | |||
} | } | |||
else{ | else { | |||
Message::Error("Unsupported Python argument (should be scalar or vector"); | Message::Error("Unsupported Python argument (should be scalar or vector"); | |||
} | } | |||
if(i) expr += ","; | if(i) expr += ","; | |||
expr += tmp; | expr += tmp; | |||
} | } | |||
expr += std::string("];"); | expr += std::string("];"); | |||
std::string str(Fct->String); | std::string str(Fct->String); | |||
if(str.size() > 3 && str.substr(str.size() - 3) == ".py"){ | if(str.size() > 3 && str.substr(str.size() - 3) == ".py") { | |||
PyRun_SimpleString(expr.c_str()); | PyRun_SimpleString(expr.c_str()); | |||
std::string file = std::string(Name_Path) + str; | std::string file = std::string(Name_Path) + str; | |||
FILE *fp = fopen(file.c_str(), "r"); | FILE *fp = fopen(file.c_str(), "r"); | |||
if(fp){ | if(fp) { | |||
PyRun_SimpleFile(fp, file.c_str()); | PyRun_SimpleFile(fp, file.c_str()); | |||
fclose(fp); | fclose(fp); | |||
} | } | |||
else{ | else { | |||
Message::Error("Could not open file `%s'", file.c_str()); | Message::Error("Could not open file `%s'", file.c_str()); | |||
} | } | |||
} | } | |||
else{ | else { | |||
expr += std::string(Fct->String); | expr += std::string(Fct->String); | |||
PyRun_SimpleString(expr.c_str()); | PyRun_SimpleString(expr.c_str()); | |||
} | } | |||
for (int k = 0; k < Current.NbrHar; k++) | for(int k = 0; k < Current.NbrHar; k++) | |||
for (int j = 0; j < 9; j++) | for(int j = 0; j < 9; j++) V->Val[MAX_DIM * k + j] = 0.; | |||
V->Val[MAX_DIM * k + j] = 0. ; | ||||
V->Type = SCALAR; | V->Type = SCALAR; | |||
PyObject* dict = PyModule_GetDict(PyImport_AddModule("__main__")); | PyObject *dict = PyModule_GetDict(PyImport_AddModule("__main__")); | |||
if(dict){ | if(dict) { | |||
PyObject* out = PyDict_GetItemString(dict, "output"); | PyObject *out = PyDict_GetItemString(dict, "output"); | |||
if(out){ | if(out) { | |||
if(PyList_Check(out)){ | if(PyList_Check(out)) { | |||
Py_ssize_t size = PyList_Size(out); | Py_ssize_t size = PyList_Size(out); | |||
if(size == 1 || size == 3 || size == 9){ | if(size == 1 || size == 3 || size == 9) { | |||
for(int i = 0; i < size; i++){ | for(int i = 0; i < size; i++) { | |||
PyObject *item = PyList_GetItem(out, i); | PyObject *item = PyList_GetItem(out, i); | |||
if(PyComplex_Check(item)){ | if(PyComplex_Check(item)) { | |||
double re = PyComplex_RealAsDouble(item); | double re = PyComplex_RealAsDouble(item); | |||
double im = PyComplex_ImagAsDouble(item); | double im = PyComplex_ImagAsDouble(item); | |||
V->Val[i] = re; | V->Val[i] = re; | |||
V->Val[MAX_DIM + i] = im; | V->Val[MAX_DIM + i] = im; | |||
} | } | |||
else if(PyNumber_Check(item)){ | else if(PyNumber_Check(item)) { | |||
V->Val[i] = PyFloat_AsDouble(item); | V->Val[i] = PyFloat_AsDouble(item); | |||
} | } | |||
else{ | else { | |||
Message::Error("Unknown type of Python output list item"); | Message::Error("Unknown type of Python output list item"); | |||
} | } | |||
} | } | |||
V->Type = (size == 1) ? SCALAR : (size == 3) ? VECTOR : TENSOR; | V->Type = (size == 1) ? SCALAR : (size == 3) ? VECTOR : TENSOR; | |||
} | } | |||
else{ | else { | |||
Message::Error("Wrong number of components in Python output list " | Message::Error("Wrong number of components in Python output list " | |||
"(%d != 1, 3 or 9)", size); | "(%d != 1, 3 or 9)", | |||
size); | ||||
} | } | |||
} | } | |||
else if(PyComplex_Check(out)){ | else if(PyComplex_Check(out)) { | |||
double re = PyComplex_RealAsDouble(out); | double re = PyComplex_RealAsDouble(out); | |||
double im = PyComplex_ImagAsDouble(out); | double im = PyComplex_ImagAsDouble(out); | |||
V->Val[0] = re; | V->Val[0] = re; | |||
V->Val[MAX_DIM] = im; | V->Val[MAX_DIM] = im; | |||
} | } | |||
else if(PyNumber_Check(out)){ | else if(PyNumber_Check(out)) { | |||
V->Val[0] = PyFloat_AsDouble(out); | V->Val[0] = PyFloat_AsDouble(out); | |||
} | } | |||
else{ | else { | |||
Message::Error("Unknown type of Python output value"); | Message::Error("Unknown type of Python output value"); | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
#else | #else | |||
void F_Python(F_ARG) | void F_Python(F_ARG) | |||
{ | { | |||
Message::Error("You need to compile GetDP with Python support to use Python fu | Message::Error( | |||
nctions"); | "You need to compile GetDP with Python support to use Python functions"); | |||
V->Val[0] = 0. ; | V->Val[0] = 0.; | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
} | } | |||
#endif | #endif | |||
End of changes. 27 change blocks. | ||||
43 lines changed or deleted | 41 lines changed or added |