forked from lijiext/lammps
added length keyword to python command
This commit is contained in:
parent
f509f133af
commit
e364b80724
|
@ -14,7 +14,7 @@ python func keyword args ... :pre
|
|||
|
||||
func = name of Python function :ulb,l
|
||||
one or more keyword/args pairs must be appended :l
|
||||
keyword = {invoke} or {input} or {return} or {format} or {file} or {here} or {exists}
|
||||
keyword = {invoke} or {input} or {return} or {format} or {length} or {file} or {here} or {exists}
|
||||
{invoke} arg = none = invoke the previously defined Python function
|
||||
{input} args = N i1 i2 ... iN
|
||||
N = # of inputs to function
|
||||
|
@ -29,6 +29,8 @@ keyword = {invoke} or {input} or {return} or {format} or {file} or {here} or {ex
|
|||
M = N+1 if there is a return value
|
||||
fstring = each character (i,f,s,p) corresponds in order to an input or return value
|
||||
'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF
|
||||
{length} arg = Nlen
|
||||
Nlen = max length of string returned from Python function
|
||||
{file} arg = filename
|
||||
filename = file of Python code, which defines func
|
||||
{here} arg = inline
|
||||
|
@ -165,6 +167,17 @@ equal-style variable as an argument, but only if the output of the
|
|||
Python function is flagged as a numeric value ("i" or "f") via the
|
||||
{format} keyword.
|
||||
|
||||
If the {return} keyword is used and the {format} keyword specifies the
|
||||
output as a string, then the default maximum length of that string is
|
||||
63 characters (64-1 for the string terminator). If you want to return
|
||||
a longer string, the {length} keyword can be specified with its {Nlen}
|
||||
value set to a larger number (the code allocates space for Nlen+1 to
|
||||
include the string terminator). If the Python function generates a
|
||||
string longer than the default 63 or the specified {Nlen}, it will be
|
||||
trunctated.
|
||||
|
||||
:line
|
||||
|
||||
Either the {file}, {here}, or {exists} keyword must be used, but only
|
||||
one of them. These keywords specify what Python code to load into the
|
||||
Python interpreter. The {file} keyword gives the name of a file,
|
||||
|
|
|
@ -89,6 +89,7 @@ void Python::command(int narg, char **arg)
|
|||
istr = NULL;
|
||||
ostr = NULL;
|
||||
format = NULL;
|
||||
length_longstr = 0;
|
||||
char *pyfile = NULL;
|
||||
char *herestr = NULL;
|
||||
int existflag = 0;
|
||||
|
@ -115,6 +116,11 @@ void Python::command(int narg, char **arg)
|
|||
format = new char[n];
|
||||
strcpy(format,arg[iarg+1]);
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"length") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
length_longstr = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (length_longstr <= 0) error->all(FLERR,"Invalid python command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"file") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
delete[] pyfile;
|
||||
|
@ -249,6 +255,7 @@ void Python::invoke_function(int ifunc, char *result)
|
|||
|
||||
// function returned a value
|
||||
// assign it to result string stored by python-style variable
|
||||
// or if user specified a length, assign it to longstr
|
||||
|
||||
if (pfuncs[ifunc].noutput) {
|
||||
int otype = pfuncs[ifunc].otype;
|
||||
|
@ -258,7 +265,9 @@ void Python::invoke_function(int ifunc, char *result)
|
|||
sprintf(result,"%.15g",PyFloat_AsDouble(pValue));
|
||||
} else if (otype == STRING) {
|
||||
char *pystr = PyString_AsString(pValue);
|
||||
strncpy(result,pystr,VALUELENGTH-1);
|
||||
if (pfuncs[ifunc].longstr)
|
||||
strncpy(pfuncs[ifunc].longstr,pystr,pfuncs[ifunc].length_longstr);
|
||||
else strncpy(result,pystr,VALUELENGTH-1);
|
||||
}
|
||||
Py_DECREF(pValue);
|
||||
}
|
||||
|
@ -287,6 +296,13 @@ int Python::variable_match(char *name, char *varname, int numeric)
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
char *Python::long_string(int ifunc)
|
||||
{
|
||||
return pfuncs[ifunc].longstr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int Python::create_entry(char *name)
|
||||
{
|
||||
// ifunc = index to entry by name in pfuncs vector, can be old or new
|
||||
|
@ -370,6 +386,7 @@ int Python::create_entry(char *name)
|
|||
// process output as value or variable
|
||||
|
||||
pfuncs[ifunc].ovarname = NULL;
|
||||
pfuncs[ifunc].longstr = NULL;
|
||||
if (!noutput) return ifunc;
|
||||
|
||||
char type = format[ninput];
|
||||
|
@ -378,6 +395,14 @@ int Python::create_entry(char *name)
|
|||
else if (type == 's') pfuncs[ifunc].otype = STRING;
|
||||
else error->all(FLERR,"Invalid python command");
|
||||
|
||||
if (length_longstr) {
|
||||
if (pfuncs[ifunc].otype != STRING)
|
||||
error->all(FLERR,"Python command length keyword "
|
||||
"cannot be used unless output is a string");
|
||||
pfuncs[ifunc].length_longstr = length_longstr;
|
||||
pfuncs[ifunc].longstr = new char[length_longstr+1];
|
||||
}
|
||||
|
||||
if (strstr(ostr,"v_") != ostr) error->all(FLERR,"Invalid python command");
|
||||
int n = strlen(&ostr[2]) + 1;
|
||||
pfuncs[ifunc].ovarname = new char[n];
|
||||
|
@ -398,4 +423,5 @@ void Python::deallocate(int i)
|
|||
delete [] pfuncs[i].svalue[j];
|
||||
delete [] pfuncs[i].svalue;
|
||||
delete [] pfuncs[i].ovarname;
|
||||
delete [] pfuncs[i].longstr;
|
||||
}
|
||||
|
|
|
@ -28,9 +28,10 @@ class Python : protected Pointers {
|
|||
void invoke_function(int, char *);
|
||||
int find(char *);
|
||||
int variable_match(char *, char *, int);
|
||||
char *long_string(int);
|
||||
|
||||
private:
|
||||
int ninput,noutput;
|
||||
int ninput,noutput,length_longstr;
|
||||
char **istr;
|
||||
char *ostr,*format;
|
||||
void *pyMain;
|
||||
|
@ -44,6 +45,8 @@ class Python : protected Pointers {
|
|||
char **svalue;
|
||||
int otype;
|
||||
char *ovarname;
|
||||
char *longstr;
|
||||
int length_longstr;
|
||||
void *pFunc;
|
||||
};
|
||||
|
||||
|
|
|
@ -325,8 +325,6 @@ void FixIntel::init()
|
|||
error->all(FLERR,
|
||||
"Currently, cannot use more than one intel style with hybrid.");
|
||||
|
||||
neighbor->fix_intel = (void *)this;
|
||||
|
||||
check_neighbor_intel();
|
||||
if (_precision_mode == PREC_MODE_SINGLE)
|
||||
_single_buffers->zero_ev();
|
||||
|
|
|
@ -526,7 +526,7 @@ double FixShearHistory::memory_usage()
|
|||
{
|
||||
int nmax = atom->nmax;
|
||||
double bytes = nmax * sizeof(int);
|
||||
bytes += nmax * sizeof(int *);
|
||||
bytes += nmax * sizeof(tagint *);
|
||||
bytes += nmax * sizeof(double *);
|
||||
|
||||
int nmypage = comm->nthreads;
|
||||
|
|
|
@ -875,6 +875,10 @@ char *Variable::retrieve(char *name)
|
|||
error->all(FLERR,"Python variable does not match Python function");
|
||||
python->invoke_function(ifunc,data[ivar][1]);
|
||||
str = data[ivar][1];
|
||||
// if Python func returns a string longer than VALUELENGTH
|
||||
// then the Python class stores the result, query it via long_string()
|
||||
char *strlong = python->long_string(ifunc);
|
||||
if (strlong) str = strlong;
|
||||
} else if (style[ivar] == INTERNAL) {
|
||||
sprintf(data[ivar][0],"%.15g",dvalue[ivar]);
|
||||
str = data[ivar][0];
|
||||
|
|
Loading…
Reference in New Issue