finish changes to variables

This commit is contained in:
Steve Plimpton
2023-08-18 13:18:50 -06:00
parent 91d826a5d6
commit 6e1529ddff
2 changed files with 338 additions and 306 deletions

View File

@ -1174,19 +1174,19 @@ The various allowed compute references in the variable formulas for
equal-, vector-, and atom-style variables are listed in the following
table:
+--------+------------+--------------------------------------------+
+--------+------------+------------------------------------------+
| equal | c_ID | global scalar |
| equal | c_ID[I] | element of global vector |
| equal | c_ID[I][J] | element of global array |
| equal | C_ID[I] | element of per-atom vector, I = ID of atom |
| equal | C_ID{i}[J] | element of per-atom array, I = ID of atom |
+--------+------------+--------------------------------------------|
| equal | C_ID[I] | element of per-atom vector (I = atom ID) |
| equal | C_ID{i}[J] | element of per-atom array (I = atom ID) |
+--------+------------+------------------------------------------+
| vector | c_ID | global vector |
| vector | c_ID[I] | column of global array |
---------+------------+--------------------------------------------+
---------+------------+------------------------------------------+
| atom | c_ID | per-atom vector |
| atom | c_ID[I] | column of per-atom array |
+--------+------------+--------------------------------------------+
+--------+------------+------------------------------------------+
Note that if an equal-style variable formula wishes to access per-atom
data from a compute, it must use capital "C" as the ID prefix and not
@ -1235,23 +1235,22 @@ Atom-style variables can use scalar values (same as for equal-style
varaibles), or per-atom vectors of values. The latter can also be a
column of a per-atom array.
The various allowed fix references in the variable formulas for
equal-, vector-, and atom-style variables are listed in the following
table:
The allowed fix references in variable formulas for equal-, vector-,
and atom-style variables are listed in the following table:
+--------+------------+--------------------------------------------+
+--------+------------+------------------------------------------+
| equal | f_ID | global scalar |
| equal | f_ID[I] | element of global vector |
| equal | f_ID[I][J] | element of global array |
| equal | F_ID[I] | element of per-atom vector, I = ID of atom |
| equal | F_ID{i}[J] | element of per-atom array, I = ID of atom |
+--------+------------+--------------------------------------------|
| equal | F_ID[I] | element of per-atom vector (I = atom ID) |
| equal | F_ID{i}[J] | element of per-atom array (I = atom ID) |
+--------+------------+------------------------------------------+
| vector | f_ID | global vector |
| vector | f_ID[I] | column of global array |
---------+------------+--------------------------------------------+
---------+------------+------------------------------------------+
| atom | f_ID | per-atom vector |
| atom | f_ID[I] | column of per-atom array |
+--------+------------+--------------------------------------------+
+--------+------------+------------------------------------------+
Note that if an equal-style variable formula wishes to access per-atom
data from a fix, it must use capital "F" as the ID prefix and not
@ -1312,21 +1311,27 @@ including other atom-style or atomfile-style variables. If it uses a
vector-style variable, a subscript must be used to access a single
value from the vector-style variable.
Examples of different kinds of variable references are as follows.
There is no ambiguity as to what a reference means, since variables
produce only a global scalar or global vector or per-atom vector.
The allowed variable references in variable formulas for equal-,
vector-, and atom-style variables are listed in the following table.
Note that there is no ambiguity as to what a reference means, since
referenced variables produce only a global scalar or global vector or
per-atom vector.
+------------+----------------------------------------------------------------------+
| v_name | global scalar from equal-style variable |
+------------+----------------------------------------------------------------------+
| v_name | global vector from vector-style variable |
+------------+----------------------------------------------------------------------+
| v_name | per-atom vector from atom-style or atomfile-style variable |
+------------+----------------------------------------------------------------------+
| v_name[I] | Ith element of a global vector from vector-style variable |
+------------+----------------------------------------------------------------------+
| v_name[I] | value of atom with ID = I from atom-style or atomfile-style variable |
+------------+----------------------------------------------------------------------+
+--------+-----------+-----------------------------------------------------------------------------------+
| equal | v_name | global scalar from an equal-style variable |
| equal | v_name[I] | element of global vector from a vector-style variable |
| equal | v_name[I] | element of per-atom vector (I = atom ID) from an atom- or atomfile-style variable |
+--------+-----------+-----------------------------------------------------------------------------------+
| vector | v_name | global scalar from an equal-style variable |
| vector | v_name | global vector from a vector-style variable |
| vector | v_name[I] | element of global vector from a vector-style variable |
| vector | v_name[I] | element of per-atom vector (I = atom ID) from an atom- or atomfile-style variable |
+--------+-----------+-----------------------------------------------------------------------------------+
| atom | v_name | global scalar from an equal-style variable |
| atom | v_name | per-atom vector from an atom-style or atomfile-style variable |
| atom | v_name[I] | element of global vector from a vector-style variable |
| atom | v_name[I] | element of per-atom vector (I = atom ID) from an atom- or atomfile-style variable |
+--------+-----------+-----------------------------------------------------------------------------------+
For the I index, an integer can be specified or a variable name,
specified as v_name, where name is the name of the variable. The

View File

@ -1509,7 +1509,6 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
if (!compute->scalar_flag)
print_var_error(FLERR,"Mismatched compute in variable formula",ivar);
if (!compute->is_initialized())
print_var_error(FLERR,"Variable formula compute cannot be invoked before "
"initialization by a run",ivar);
@ -1567,7 +1566,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
else value1 = compute->array[index1-1][index2-1];
argstack[nargstack++] = value1;
// C_ID[i] = scalar element of per-atom vector
// C_ID[i] = scalar element of per-atom vector, note uppercase "C"
} else if (!lowercase && nbracket == 1) {
@ -1586,7 +1585,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
peratom2global(1,nullptr,compute->vector_atom,1,index1,tree,
treestack,ntreestack,argstack,nargstack);
// C_ID[i][j] = scalar element of per-atom array
// C_ID[i][j] = scalar element of per-atom array, note uppercase "C"
} else if (!lowercase && nbracket == 2) {
@ -1729,12 +1728,6 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
} else print_var_error(FLERR,"Mismatched compute in variable formula",ivar);
}
// ----------------
// fix
// ----------------
@ -1753,7 +1746,6 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
if (!fix)
print_var_error(FLERR,fmt::format("Invalid fix ID '{}' in variable formula",word+2),ivar);
// parse zero or one or two trailing brackets
// point i beyond last bracket
// nbracket = # of bracket pairs
@ -1775,25 +1767,28 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
}
}
// f_ID = scalar from global scalar, must be lowercase
// equal-style variable is being evaluated
if (nbracket == 0 && fix->scalar_flag && lowercase) {
if (style[ivar] == EQUAL) {
// f_ID = scalar from global scalar
if (lowercase && nbracket == 0) {
if (!fix->scalar_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
value1 = fix->compute_scalar();
if (tree) {
auto newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
argstack[nargstack++] = value1;
// f_ID[i] = scalar from global vector, must be lowercase
// f_ID[i] = scalar from global vector
} else if (nbracket == 1 && fix->vector_flag && lowercase) {
} else if (lowercase && nbracket == 1) {
if (!fix->vector_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (index1 > fix->size_vector &&
fix->size_vector_variable == 0)
print_var_error(FLERR,"Variable formula fix vector is accessed out-of-range",ivar,0);
@ -1801,17 +1796,14 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
value1 = fix->compute_vector(index1-1);
if (tree) {
auto newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
argstack[nargstack++] = value1;
// f_ID[i][j] = scalar from global array, must be lowercase
// f_ID[i][j] = scalar from global array
} else if (nbracket == 2 && fix->array_flag && lowercase) {
} else if (lowercase && nbracket == 2) {
if (!fix->array_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (index1 > fix->size_array_rows &&
fix->size_array_rows_variable == 0)
print_var_error(FLERR,"Variable formula fix array is accessed out-of-range",ivar,0);
@ -1821,25 +1813,62 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
value1 = fix->compute_array(index1-1,index2-1);
if (tree) {
auto newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
argstack[nargstack++] = value1;
// f_ID = vector from global vector, lowercase or uppercase
// F_ID[i] = scalar element of per-atom vector, note uppercase "F"
} else if (nbracket == 0 && fix->vector_flag) {
} else if (!lowercase && nbracket == 1) {
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
print_var_error(FLERR,"Fix in variable not computed at compatible time",ivar);
if (tree == nullptr)
print_var_error(FLERR,"Fix global vector in equal-style variable formula",ivar);
if (treetype == ATOM)
print_var_error(FLERR,"Fix global vector in atom-style variable formula",ivar);
if (!fix->peratom_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (fix->size_peratom_cols)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
peratom2global(1,nullptr,fix->vector_atom,1,index1,tree,
treestack,ntreestack,argstack,nargstack);
// F_ID[i][j] = scalar element of per-atom array, note uppercase "F"
} else if (!lowercase && nbracket == 2) {
if (!fix->peratom_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (!fix->size_peratom_cols)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (index2 > fix->size_peratom_cols)
print_var_error(FLERR,"Variable formula fix array is accessed out-of-range",ivar,0);
if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
if (fix->array_atom)
peratom2global(1,nullptr,&fix->array_atom[0][index2-1],
fix->size_peratom_cols,index1,
tree,treestack,ntreestack,argstack,nargstack);
else
peratom2global(1,nullptr,nullptr,fix->size_peratom_cols,index1,
tree,treestack,ntreestack,argstack,nargstack);
// no other possibilities for equal-style variable, so error
} else print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
// vector-style variable is being evaluated
} else if (style[ivar] == VECTOR) {
// f_ID = vector from global vector
if (lowercase && nbracket == 0) {
if (!fix->vector_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (fix->size_vector == 0)
print_var_error(FLERR,"Variable formula fix vector is zero length",ivar);
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
print_var_error(FLERR,"Fix in variable not computed at compatible time",ivar);
int nvec = fix->size_vector;
double *vec;
@ -1855,18 +1884,18 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
newtree->selfalloc = 1;
treestack[ntreestack++] = newtree;
// f_ID[i] = vector from global array, lowercase or uppercase
// f_ID[i] = vector from global array
} else if (nbracket == 1 && fix->array_flag) {
} else if (lowercase && nbracket == 1) {
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
if (tree == nullptr)
print_var_error(FLERR,"Fix global vector in equal-style variable formula",ivar);
if (treetype == ATOM)
print_var_error(FLERR,"Fix global vector in atom-style variable formula",ivar);
if (!fix->array_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (fix->size_array_rows == 0)
print_var_error(FLERR,"Variable formula fix array is zero length",ivar);
if (index1 > fix->size_array_cols)
print_var_error(FLERR,"Variable formula fix array is accessed out-of-range",ivar,0);
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
int nvec = fix->size_array_rows;
double *vec;
@ -1882,45 +1911,23 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
newtree->selfalloc = 1;
treestack[ntreestack++] = newtree;
// f_ID[i] = scalar from per-atom vector
// no other possibilities for vector-style variable, so error
} else if (nbracket == 1 && fix->peratom_flag &&
fix->size_peratom_cols == 0) {
} else print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
// atom-style variable is being evaluated
peratom2global(1,nullptr,fix->vector_atom,1,index1,
tree,treestack,ntreestack,argstack,nargstack);
// f_ID[i][j] = scalar from per-atom array
} else if (nbracket == 2 && fix->peratom_flag &&
fix->size_peratom_cols > 0) {
if (index2 > fix->size_peratom_cols)
print_var_error(FLERR,"Variable formula fix array is accessed out-of-range",ivar,0);
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
print_var_error(FLERR,"Fix in variable not computed at a compatible time",ivar);
if (fix->array_atom)
peratom2global(1,nullptr,&fix->array_atom[0][index2-1],fix->size_peratom_cols,index1,
tree,treestack,ntreestack,argstack,nargstack);
else
peratom2global(1,nullptr,nullptr,fix->size_peratom_cols,index1,
tree,treestack,ntreestack,argstack,nargstack);
} else if (style[ivar] == ATOM) {
// f_ID = vector from per-atom vector
} else if (nbracket == 0 && fix->peratom_flag &&
fix->size_peratom_cols == 0) {
if (lowercase && nbracket == 0) {
if (tree == nullptr)
print_var_error(FLERR,"Per-atom fix in equal-style variable formula",ivar);
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
if (!fix->peratom_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (fix->size_peratom_cols)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq)
print_var_error(FLERR,"Fix in variable not computed at compatible time",ivar);
auto newtree = new Tree();
@ -1931,25 +1938,29 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
// f_ID[i] = vector from per-atom array
} else if (nbracket == 1 && fix->peratom_flag &&
fix->size_peratom_cols > 0) {
} else if (lowercase && nbracket == 1) {
if (tree == nullptr)
print_var_error(FLERR,"Per-atom fix in equal-style variable formula",ivar);
if (!fix->peratom_flag)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (!fix->size_peratom_cols)
print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
if (index1 > fix->size_peratom_cols)
print_var_error(FLERR,"Variable formula fix array is accessed out-of-range",ivar,0);
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
if (update->whichflag > 0 && update->ntimestep % fix->peratom_freq)
print_var_error(FLERR,"Fix in variable not computed at compatible time",ivar);
auto newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = nullptr;
if (fix->array_atom)
newtree->array = &fix->array_atom[0][index1-1];
newtree->nstride = fix->size_peratom_cols;
treestack[ntreestack++] = newtree;
// no other possibilities for atom-style variable, so error
} else print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
}
// ----------------
// variable
@ -1979,10 +1990,14 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
i = ptr-str+1;
}
// v_name = scalar from internal-style variable
// vname with no bracket
if (nbracket == 0) {
// scalar from internal-style variable
// access value directly
if (nbracket == 0 && style[ivar] == INTERNAL) {
if (style[ivar] = INTERNAL) {
value1 = dvalue[ivar];
if (tree) {
@ -1992,57 +2007,27 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// v_name = scalar from non atom/atomfile & non vector-style variable
// scalar from any style variable except VECTOR, ATOM, ATOMFILE
// access value via retrieve()
} else if (nbracket == 0 && style[ivar] != ATOM &&
style[ivar] != ATOMFILE && style[ivar] != VECTOR) {
} else if (style[ivar] != ATOM && style[ivar] != ATOMFILE && style[ivar] != VECTOR) {
char *var = retrieve(word+2);
if (var == nullptr)
print_var_error(FLERR,"Invalid variable evaluation in variable formula",ivar);
if (utils::is_double(var)) {
if (!utils::is_double(var))
print_var_error(FLERR,"Non-numeric variable value in variable formula",ivar);
if (tree) {
auto newtree = new Tree();
newtree->type = VALUE;
newtree->value = atof(var);
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = atof(var);
} else print_var_error(FLERR,"Non-numeric variable value in variable formula",ivar);
// v_name = per-atom vector from atom-style variable
// evaluate the atom-style variable as newtree
} else if (nbracket == 0 && style[ivar] == ATOM) {
if (tree == nullptr)
print_var_error(FLERR,"Atom-style variable in equal-style variable formula",ivar);
if (treetype == VECTOR)
print_var_error(FLERR,"Atom-style variable in vector-style variable formula",ivar);
Tree *newtree = nullptr;
evaluate(data[ivar][0],&newtree,ivar);
treestack[ntreestack++] = newtree;
// v_name = per-atom vector from atomfile-style variable
} else if (nbracket == 0 && style[ivar] == ATOMFILE) {
if (tree == nullptr)
print_var_error(FLERR,"Atomfile-style variable in equal-style variable formula",ivar);
if (treetype == VECTOR)
print_var_error(FLERR,"Atomfile-style variable in vector-style variable formula",ivar);
auto newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = reader[ivar]->fixstore->vstore;
newtree->nstride = 1;
treestack[ntreestack++] = newtree;
// v_name = vector from vector-style variable
// vector from vector-style variable
// evaluate the vector-style variable, put result in newtree
} else if (nbracket == 0 && style[ivar] == VECTOR) {
} else if (style[ivar] == VECTOR) {
if (tree == nullptr)
print_var_error(FLERR,"Vector-style variable in equal-style variable formula",ivar);
@ -2059,29 +2044,48 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
newtree->nstride = 1;
treestack[ntreestack++] = newtree;
// v_name[N] = scalar from atom-style variable
// compute the per-atom variable in result
// use peratom2global to extract single value from result
// vector from atom-style variable
// evaluate the atom-style variable as newtree
} else if (nbracket && style[ivar] == ATOM) {
} else if (style[ivar] == ATOM) {
double *result;
memory->create(result,atom->nlocal,"variable:result");
compute_atom(ivar,0,result,1,0);
peratom2global(1,nullptr,result,1,index,tree,treestack,ntreestack,argstack,nargstack);
memory->destroy(result);
if (tree == nullptr)
print_var_error(FLERR,"Atom-style variable in equal-style variable formula",ivar);
if (treetype == VECTOR)
print_var_error(FLERR,"Atom-style variable in vector-style variable formula",ivar);
// v_name[N] = scalar from atomfile-style variable
Tree *newtree = nullptr;
evaluate(data[ivar][0],&newtree,ivar);
treestack[ntreestack++] = newtree;
} else if (nbracket && style[ivar] == ATOMFILE) {
// vector from atomfile-style variable
// point to the values in FixStore instance
peratom2global(1,nullptr,reader[ivar]->fixstore->vstore,1,index,
tree,treestack,ntreestack,argstack,nargstack);
} else if (style[ivar] == ATOMFILE) {
// v_name[N] = scalar from vector-style variable
if (tree == nullptr)
print_var_error(FLERR,"Atomfile-style variable in equal-style variable formula",ivar);
if (treetype == VECTOR)
print_var_error(FLERR,"Atomfile-style variable in vector-style variable formula",ivar);
auto newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = reader[ivar]->fixstore->vstore;
newtree->nstride = 1;
treestack[ntreestack++] = newtree;
// no other possibilities for variable with no bracket
} else print_var_error(FLERR,"Mismatched variable in variable formula",ivar);
// vname[i] with one bracket
} else if (nbracket == 1) {
// scalar from vector-style variable
// compute the vector-style variable, extract single value
} else if (nbracket && style[ivar] == VECTOR) {
if (style[ivar] == VECTOR) {
double *vec;
int nvec = compute_vector(ivar,&vec);
@ -2096,7 +2100,30 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = vec[m-1];
// scalar from atom-style variable
// compute the per-atom variable in result
// use peratom2global to extract single value from result
} else if (style[ivar] == ATOM) {
double *result;
memory->create(result,atom->nlocal,"variable:result");
compute_atom(ivar,0,result,1,0);
peratom2global(1,nullptr,result,1,index,tree,treestack,ntreestack,argstack,nargstack);
memory->destroy(result);
// scalar from atomfile-style variable
// use peratom2global to extract single value from FixStore instance
} else if (style[ivar] == ATOMFILE) {
peratom2global(1,nullptr,reader[ivar]->fixstore->vstore,1,index,
tree,treestack,ntreestack,argstack,nargstack);
// no other possibilities for variable with one bracket
} else print_var_error(FLERR,"Mismatched variable in variable formula",ivar);
}
// ----------------
// math/group/special/labelmap function or atom value/vector or