git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15435 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
123
src/variable.cpp
123
src/variable.cpp
@ -52,7 +52,7 @@ using namespace MathConst;
|
||||
#define MYROUND(a) (( a-floor(a) ) >= .5) ? ceil(a) : floor(a)
|
||||
|
||||
enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,GETENV,
|
||||
SCALARFILE,ATOMFILE,FORMAT,EQUAL,ATOM,VECTOR,PYTHON};
|
||||
SCALARFILE,ATOMFILE,FORMAT,EQUAL,ATOM,VECTOR,PYTHON,INTERNAL};
|
||||
enum{ARG,OP};
|
||||
|
||||
// customize by adding a function
|
||||
@ -92,6 +92,7 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
|
||||
pad = NULL;
|
||||
reader = NULL;
|
||||
data = NULL;
|
||||
dvalue = NULL;
|
||||
vecs = NULL;
|
||||
|
||||
eval_in_progress = NULL;
|
||||
@ -135,6 +136,7 @@ Variable::~Variable()
|
||||
memory->destroy(pad);
|
||||
memory->sfree(reader);
|
||||
memory->sfree(data);
|
||||
memory->sfree(dvalue);
|
||||
memory->sfree(vecs);
|
||||
|
||||
memory->destroy(eval_in_progress);
|
||||
@ -483,9 +485,33 @@ void Variable::set(int narg, char **arg)
|
||||
strcpy(data[nvar][1],"(undefined)");
|
||||
}
|
||||
|
||||
// INTERNAL
|
||||
// replace pre-existing var if also style INTERNAL (allows it to be reset)
|
||||
// num = 1, for string representation of dvalue, set by retrieve()
|
||||
// dvalue = numeric initialization from 2nd arg, reset by internal_set()
|
||||
|
||||
} else if (strcmp(arg[1],"internal") == 0) {
|
||||
if (narg != 3) error->all(FLERR,"Illegal variable command");
|
||||
int ivar = find(arg[0]);
|
||||
if (ivar >= 0) {
|
||||
if (style[ivar] != INTERNAL)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
dvalue[nvar] = force->numeric(FLERR,arg[2]);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
style[nvar] = INTERNAL;
|
||||
num[nvar] = 1;
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
data[nvar][0] = new char[VALUELENGTH];
|
||||
dvalue[nvar] = force->numeric(FLERR,arg[2]);
|
||||
}
|
||||
|
||||
} else error->all(FLERR,"Illegal variable command");
|
||||
|
||||
// set name of variable, if not replacing (EQUAL/ATOM/STRING/PYTHON)
|
||||
// set name of variable, if not replacing one flagged with replaceflag
|
||||
// name must be all alphanumeric chars or underscores
|
||||
|
||||
if (replaceflag) return;
|
||||
@ -557,12 +583,13 @@ int Variable::next(int narg, char **arg)
|
||||
error->all(FLERR,"All variables in next command must be same style");
|
||||
}
|
||||
|
||||
// invalid styles: STRING, EQUAL, WORLD, ATOM, VECTOR, GETENV, FORMAT, PYTHON
|
||||
// invalid styles: STRING, EQUAL, WORLD, ATOM, VECTOR, GETENV,
|
||||
// FORMAT, PYTHON, INTERNAL
|
||||
|
||||
int istyle = style[find(arg[0])];
|
||||
if (istyle == STRING || istyle == EQUAL || istyle == WORLD ||
|
||||
istyle == GETENV || istyle == ATOM || istyle == VECTOR ||
|
||||
istyle == FORMAT || istyle == PYTHON)
|
||||
istyle == FORMAT || istyle == PYTHON || istyle == INTERNAL)
|
||||
error->all(FLERR,"Invalid variable style with next command");
|
||||
|
||||
// if istyle = UNIVERSE or ULOOP, insure all such variables are incremented
|
||||
@ -713,13 +740,13 @@ void Variable::python_command(int narg, char **arg)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return 1 if variable is EQUAL or PYTHON numeric style, 0 if not
|
||||
return 1 if variable is EQUAL or INTERNAL or PYTHON numeric style, 0 if not
|
||||
this is checked before call to compute_equal() to return a double
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::equalstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == EQUAL) return 1;
|
||||
if (style[ivar] == EQUAL || style[ivar] == INTERNAL) return 1;
|
||||
if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->variable_match(data[ivar][0],names[ivar],1);
|
||||
if (ifunc < 0) return 0;
|
||||
@ -766,6 +793,17 @@ char *Variable::pythonstyle(char *name, char *funcname)
|
||||
return data[ivar][1];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return 1 if variable is INTERNAL style, 0 if not
|
||||
this is checked before call to set_internal() to assure it can be set
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::internalstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == INTERNAL) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return ptr to the data text associated with a variable
|
||||
if INDEX or WORLD or UNIVERSE or STRING or SCALARFILE,
|
||||
@ -775,6 +813,7 @@ char *Variable::pythonstyle(char *name, char *funcname)
|
||||
if FORMAT, evaluate its variable and put formatted result in str
|
||||
if GETENV, query environment and put result in str
|
||||
if PYTHON, evaluate Python function, it will put result in str
|
||||
if INTERNAL, convert dvalue and put result in str
|
||||
if ATOM or ATOMFILE or VECTOR, return NULL
|
||||
return NULL if no variable with name, or which value is bad,
|
||||
caller must respond
|
||||
@ -835,6 +874,9 @@ 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];
|
||||
} else if (style[ivar] == INTERNAL) {
|
||||
sprintf(data[ivar][0],"%.15g",dvalue[ivar]);
|
||||
str = data[ivar][0];
|
||||
} else if (style[ivar] == ATOM || style[ivar] == ATOMFILE ||
|
||||
style[ivar] == VECTOR) return NULL;
|
||||
|
||||
@ -845,7 +887,7 @@ char *Variable::retrieve(char *name)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return result of equal-style variable evaluation
|
||||
can be EQUAL style or PYTHON numeric style
|
||||
can be EQUAL or INTERNAL style or PYTHON numeric style
|
||||
for PYTHON, don't need to check python->variable_match() error return,
|
||||
since caller will have already checked via equalstyle()
|
||||
------------------------------------------------------------------------- */
|
||||
@ -856,8 +898,9 @@ double Variable::compute_equal(int ivar)
|
||||
error->all(FLERR,"Variable has circular dependency");
|
||||
eval_in_progress[ivar] = 1;
|
||||
|
||||
double value = 0.0;
|
||||
double value;
|
||||
if (style[ivar] == EQUAL) value = evaluate(data[ivar][0],NULL);
|
||||
else if (style[ivar] == INTERNAL) value = dvalue[ivar];
|
||||
else if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->find(data[ivar][0]);
|
||||
if (ifunc < 0) error->all(FLERR,"Python variable has no function");
|
||||
@ -1001,43 +1044,12 @@ int Variable::compute_vector(int ivar, double **result)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
save copy of EQUAL style ivar formula in copy
|
||||
allocate copy here, later equal_restore() call will free it
|
||||
insure data[ivar][0] is of VALUELENGTH since will be overridden
|
||||
next 3 functions are used by create_atoms to temporarily override variables
|
||||
set value stored by INTERNAL style ivar
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::equal_save(int ivar, char *©)
|
||||
void Variable::internal_set(int ivar, double value)
|
||||
{
|
||||
int n = strlen(data[ivar][0]) + 1;
|
||||
copy = new char[n];
|
||||
strcpy(copy,data[ivar][0]);
|
||||
delete [] data[ivar][0];
|
||||
data[ivar][0] = new char[VALUELENGTH];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
restore formula string of EQUAL style ivar from copy
|
||||
then free copy, allocated in equal_save()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::equal_restore(int ivar, char *copy)
|
||||
{
|
||||
delete [] data[ivar][0];
|
||||
int n = strlen(copy) + 1;
|
||||
data[ivar][0] = new char[n];
|
||||
strcpy(data[ivar][0],copy);
|
||||
delete [] copy;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
override EQUAL style ivar formula with value converted to string
|
||||
data[ivar][0] was set to length 64 in equal_save()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::equal_override(int ivar, double value)
|
||||
{
|
||||
sprintf(data[ivar][0],"%.15g",value);
|
||||
dvalue[ivar] = value;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -1084,6 +1096,7 @@ void Variable::grow()
|
||||
for (int i = old; i < maxvar; i++) reader[i] = NULL;
|
||||
|
||||
data = (char ***) memory->srealloc(data,maxvar*sizeof(char **),"var:data");
|
||||
memory->grow(dvalue,maxvar,"var:dvalue");
|
||||
|
||||
vecs = (VecVar *) memory->srealloc(vecs,maxvar*sizeof(VecVar),"var:vecvar");
|
||||
for (int i = old; i < maxvar; i++) {
|
||||
@ -1806,10 +1819,26 @@ double Variable::evaluate(char *str, Tree **tree)
|
||||
i = ptr-str+1;
|
||||
}
|
||||
|
||||
// v_name = scalar from non atom/atomfile and non vector-style variable
|
||||
// v_name = scalar from internal-style variable
|
||||
// access value directly
|
||||
|
||||
if (nbracket == 0 && style[ivar] != ATOM && style[ivar] != ATOMFILE &&
|
||||
style[ivar] != VECTOR) {
|
||||
if (nbracket == 0 && style[ivar] == INTERNAL) {
|
||||
|
||||
value1 = dvalue[ivar];
|
||||
if (tree) {
|
||||
Tree *newtree = new Tree();
|
||||
newtree->type = VALUE;
|
||||
newtree->value = value1;
|
||||
newtree->first = newtree->second = NULL;
|
||||
newtree->nextra = 0;
|
||||
treestack[ntreestack++] = newtree;
|
||||
} else argstack[nargstack++] = value1;
|
||||
|
||||
// v_name = scalar from non atom/atomfile & non vector-style variable
|
||||
// access value via retrieve()
|
||||
|
||||
} else if (nbracket == 0 && style[ivar] != ATOM &&
|
||||
style[ivar] != ATOMFILE && style[ivar] != VECTOR) {
|
||||
|
||||
char *var = retrieve(word+2);
|
||||
if (var == NULL)
|
||||
@ -1847,8 +1876,8 @@ double Variable::evaluate(char *str, Tree **tree)
|
||||
error->all(FLERR,"Atomfile-style variable in "
|
||||
"equal-style variable formula");
|
||||
if (treetype == VECTOR)
|
||||
error->all(FLERR,
|
||||
"Atomfile-style variable in vector-style variable formula");
|
||||
error->all(FLERR,"Atomfile-style variable in "
|
||||
"vector-style variable formula");
|
||||
|
||||
Tree *newtree = new Tree();
|
||||
newtree->type = ATOMARRAY;
|
||||
|
||||
Reference in New Issue
Block a user