"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Functions/F_Python.cpp" between
getdp-3.4.0-source.tgz and getdp-3.5.0-source.tgz

About: GetDP is a general finite element solver using mixed elements to discretize de Rham-type complexes in one, two and three dimensions.

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

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)