forked from lijiext/lammps
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15435 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
677da2ea52
commit
0bffc1711e
|
@ -230,7 +230,6 @@ void CreateAtoms::command(int narg, char **arg)
|
|||
}
|
||||
|
||||
// error check and further setup for variable test
|
||||
// save local copy of each equal variable string so can restore at end
|
||||
|
||||
if (!vstr && (xstr || ystr || zstr))
|
||||
error->all(FLERR,"Incomplete use of variables in create_atoms command");
|
||||
|
@ -248,25 +247,22 @@ void CreateAtoms::command(int narg, char **arg)
|
|||
xvar = input->variable->find(xstr);
|
||||
if (xvar < 0)
|
||||
error->all(FLERR,"Variable name for create_atoms does not exist");
|
||||
if (!input->variable->equalstyle(xvar))
|
||||
if (!input->variable->internalstyle(xvar))
|
||||
error->all(FLERR,"Variable for create_atoms is invalid style");
|
||||
input->variable->equal_save(xvar,xstr_copy);
|
||||
}
|
||||
if (ystr) {
|
||||
yvar = input->variable->find(ystr);
|
||||
if (yvar < 0)
|
||||
error->all(FLERR,"Variable name for create_atoms does not exist");
|
||||
if (!input->variable->equalstyle(yvar))
|
||||
if (!input->variable->internalstyle(yvar))
|
||||
error->all(FLERR,"Variable for create_atoms is invalid style");
|
||||
input->variable->equal_save(yvar,ystr_copy);
|
||||
}
|
||||
if (zstr) {
|
||||
zvar = input->variable->find(zstr);
|
||||
if (zvar < 0)
|
||||
error->all(FLERR,"Variable name for create_atoms does not exist");
|
||||
if (!input->variable->equalstyle(zvar))
|
||||
if (!input->variable->internalstyle(zvar))
|
||||
error->all(FLERR,"Variable for create_atoms is invalid style");
|
||||
input->variable->equal_save(zvar,zstr_copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,23 +373,17 @@ void CreateAtoms::command(int narg, char **arg)
|
|||
for (int i = nlocal_previous; i < nlocal; i++)
|
||||
fix->set_arrays(i);
|
||||
}
|
||||
|
||||
for (int m = 0; m < modify->ncompute; m++) {
|
||||
Compute *compute = modify->compute[m];
|
||||
if (compute->create_attribute)
|
||||
for (int i = nlocal_previous; i < nlocal; i++)
|
||||
compute->set_arrays(i);
|
||||
}
|
||||
|
||||
for (int i = nlocal_previous; i < nlocal; i++)
|
||||
input->variable->set_arrays(i);
|
||||
|
||||
// restore each equal variable string previously saved
|
||||
|
||||
if (varflag) {
|
||||
if (xstr) input->variable->equal_restore(xvar,xstr_copy);
|
||||
if (ystr) input->variable->equal_restore(yvar,ystr_copy);
|
||||
if (zstr) input->variable->equal_restore(zvar,zstr_copy);
|
||||
}
|
||||
|
||||
// set new total # of atoms and error check
|
||||
|
||||
bigint nblocal = atom->nlocal;
|
||||
|
@ -853,16 +843,17 @@ void CreateAtoms::add_molecule(double *center, double *quat_user)
|
|||
|
||||
/* ----------------------------------------------------------------------
|
||||
test a generated atom position against variable evaluation
|
||||
first plug in x,y,z values as requested
|
||||
first set x,y,z values in internal variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int CreateAtoms::vartest(double *x)
|
||||
{
|
||||
if (xstr) input->variable->equal_override(xvar,x[0]);
|
||||
if (ystr) input->variable->equal_override(yvar,x[1]);
|
||||
if (zstr) input->variable->equal_override(zvar,x[2]);
|
||||
if (xstr) input->variable->internal_set(xvar,x[0]);
|
||||
if (ystr) input->variable->internal_set(yvar,x[1]);
|
||||
if (zstr) input->variable->internal_set(zvar,x[2]);
|
||||
|
||||
double value = input->variable->compute_equal(vvar);
|
||||
|
||||
if (value == 0.0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -829,7 +829,6 @@ void Dump::modify_params(int narg, char **arg)
|
|||
format_float_user = NULL;
|
||||
// pass format none to child classes which may use it
|
||||
// not an error if they don't
|
||||
printf("CALL %d %s\n",narg-iarg,arg[iarg]);
|
||||
int n = modify_param(narg-iarg,&arg[iarg]);
|
||||
iarg += 2;
|
||||
continue;
|
||||
|
|
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;
|
||||
|
|
|
@ -37,19 +37,18 @@ class Variable : protected Pointers {
|
|||
int atomstyle(int);
|
||||
int vectorstyle(int);
|
||||
char *pythonstyle(char *, char *);
|
||||
int internalstyle(int);
|
||||
|
||||
char *retrieve(char *);
|
||||
double compute_equal(int);
|
||||
double compute_equal(char *);
|
||||
void compute_atom(int, int, double *, int, int);
|
||||
int compute_vector(int, double **);
|
||||
void internal_set(int, double);
|
||||
|
||||
tagint int_between_brackets(char *&, int);
|
||||
double evaluate_boolean(char *);
|
||||
|
||||
void equal_save(int, char *&);
|
||||
void equal_restore(int, char *);
|
||||
void equal_override(int, double);
|
||||
|
||||
unsigned int data_mask(int ivar);
|
||||
unsigned int data_mask(char *str);
|
||||
|
||||
|
@ -64,6 +63,7 @@ class Variable : protected Pointers {
|
|||
int *pad; // 1 = pad loop/uloop variables with 0s, 0 = no pad
|
||||
class VarReader **reader; // variable that reads from file
|
||||
char ***data; // str value of each variable's values
|
||||
double *dvalue; // single numeric value for internal variables
|
||||
|
||||
struct VecVar {
|
||||
int n,nmax;
|
||||
|
|
Loading…
Reference in New Issue