git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15435 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2016-08-04 16:39:15 +00:00
parent 677da2ea52
commit 0bffc1711e
4 changed files with 90 additions and 71 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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 *&copy)
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;

View File

@ -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;