Merge branch 'master' of https://github.com/lammps/lammps into lammps-master
This commit is contained in:
442
src/variable.cpp
442
src/variable.cpp
@ -31,6 +31,7 @@
|
||||
#include "random_mars.h"
|
||||
#include "region.h"
|
||||
#include "thermo.h"
|
||||
#include "tokenizer.h"
|
||||
#include "universe.h"
|
||||
#include "update.h"
|
||||
|
||||
@ -38,7 +39,7 @@
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
@ -52,8 +53,6 @@ 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,INTERNAL};
|
||||
enum{ARG,OP};
|
||||
|
||||
// customize by adding a function
|
||||
@ -65,20 +64,30 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
|
||||
SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
|
||||
RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2,
|
||||
LOGFREQ3,STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,
|
||||
GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,
|
||||
GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,IS_FILE,
|
||||
VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY,VECTORARRAY};
|
||||
|
||||
// customize by adding a special function
|
||||
|
||||
enum{SUM,XMIN,XMAX,AVE,TRAP,SLOPE};
|
||||
|
||||
#define INVOKED_SCALAR 1
|
||||
#define INVOKED_VECTOR 2
|
||||
#define INVOKED_ARRAY 4
|
||||
#define INVOKED_PERATOM 8
|
||||
|
||||
#define BIG 1.0e20
|
||||
|
||||
// constants for variable expressions. customize by adding new items.
|
||||
// if needed (cf. 'version') initialize in Variable class constructor.
|
||||
|
||||
static std::unordered_map<std::string, double> constants = {
|
||||
{"PI", MY_PI },
|
||||
{"version", -1 },
|
||||
{"yes", 1 },
|
||||
{"no", 0 },
|
||||
{"on", 1 },
|
||||
{"off", 0 },
|
||||
{"true", 1 },
|
||||
{"false", 0 }
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
|
||||
@ -101,6 +110,10 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
|
||||
randomequal = nullptr;
|
||||
randomatom = nullptr;
|
||||
|
||||
// override initializer since LAMMPS class needs to be instantiated
|
||||
|
||||
constants["version"] = lmp->num_ver;
|
||||
|
||||
// customize by assigning a precedence level
|
||||
|
||||
precedence[DONE] = 0;
|
||||
@ -189,9 +202,7 @@ void Variable::set(int narg, char **arg)
|
||||
nlast = utils::inumeric(FLERR,arg[2],false,lmp);
|
||||
if (nlast <= 0) error->all(FLERR,"Illegal variable command");
|
||||
if (narg == 4 && strcmp(arg[3],"pad") == 0) {
|
||||
char digits[12];
|
||||
sprintf(digits,"%d",nlast);
|
||||
pad[nvar] = strlen(digits);
|
||||
pad[nvar] = fmt::format("{}",nlast).size();
|
||||
} else pad[nvar] = 0;
|
||||
} else if (narg == 4 || (narg == 5 && strcmp(arg[4],"pad") == 0)) {
|
||||
nfirst = utils::inumeric(FLERR,arg[2],false,lmp);
|
||||
@ -199,9 +210,7 @@ void Variable::set(int narg, char **arg)
|
||||
if (nfirst > nlast || nlast < 0)
|
||||
error->all(FLERR,"Illegal variable command");
|
||||
if (narg == 5 && strcmp(arg[4],"pad") == 0) {
|
||||
char digits[12];
|
||||
sprintf(digits,"%d",nlast);
|
||||
pad[nvar] = strlen(digits);
|
||||
pad[nvar] = fmt::format("{}",nlast).size();
|
||||
} else pad[nvar] = 0;
|
||||
} else error->all(FLERR,"Illegal variable command");
|
||||
num[nvar] = nlast;
|
||||
@ -327,13 +336,12 @@ void Variable::set(int narg, char **arg)
|
||||
}
|
||||
if (nvar == maxvar) grow();
|
||||
style[nvar] = GETENV;
|
||||
num[nvar] = 1;
|
||||
num[nvar] = 2;
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
data[nvar][1] = new char[VALUELENGTH];
|
||||
strcpy(data[nvar][1],"(undefined)");
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
data[nvar][1] = utils::strdup("(undefined)");
|
||||
|
||||
// SCALARFILE for strings or numbers
|
||||
// which = 1st value
|
||||
@ -404,7 +412,7 @@ void Variable::set(int narg, char **arg)
|
||||
if (style[ivar] != EQUAL)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete [] data[ivar][0];
|
||||
copy(1,&arg[2],data[ivar]);
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
@ -413,7 +421,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
data[nvar][1] = new char[VALUELENGTH];
|
||||
strcpy(data[nvar][1],"(undefined)");
|
||||
}
|
||||
@ -430,7 +438,7 @@ void Variable::set(int narg, char **arg)
|
||||
if (style[ivar] != ATOM)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete [] data[ivar][0];
|
||||
copy(1,&arg[2],data[ivar]);
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
@ -439,7 +447,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
}
|
||||
|
||||
// VECTOR
|
||||
@ -454,7 +462,7 @@ void Variable::set(int narg, char **arg)
|
||||
if (style[ivar] != VECTOR)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete [] data[ivar][0];
|
||||
copy(1,&arg[2],data[ivar]);
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
@ -463,7 +471,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
}
|
||||
|
||||
// PYTHON
|
||||
@ -480,7 +488,7 @@ void Variable::set(int narg, char **arg)
|
||||
if (style[ivar] != PYTHON)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete [] data[ivar][0];
|
||||
copy(1,&arg[2],data[ivar]);
|
||||
data[ivar][0] = utils::strdup(arg[2]);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
@ -489,7 +497,7 @@ void Variable::set(int narg, char **arg)
|
||||
which[nvar] = 1;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
data[nvar][0] = utils::strdup(arg[2]);
|
||||
data[nvar][1] = new char[VALUELENGTH];
|
||||
strcpy(data[nvar][1],"(undefined)");
|
||||
}
|
||||
@ -525,15 +533,10 @@ void Variable::set(int narg, char **arg)
|
||||
|
||||
if (replaceflag) return;
|
||||
|
||||
int n = strlen(arg[0]) + 1;
|
||||
names[nvar] = new char[n];
|
||||
strcpy(names[nvar],arg[0]);
|
||||
|
||||
for (int i = 0; i < n-1; i++)
|
||||
if (!isalnum(names[nvar][i]) && names[nvar][i] != '_')
|
||||
error->all(FLERR,fmt::format("Variable name '{}' must have only "
|
||||
"alphanumeric characters or underscores",
|
||||
names[nvar]));
|
||||
if (!utils::is_id(arg[0]))
|
||||
error->all(FLERR,fmt::format("Variable name '{}' must have only alphanu"
|
||||
"meric characters or underscores",arg[0]));
|
||||
names[nvar] = utils::strdup(arg[0]);
|
||||
nvar++;
|
||||
}
|
||||
|
||||
@ -581,8 +584,7 @@ int Variable::set_string(const char *name, const char *str)
|
||||
if (ivar < 0) return -1;
|
||||
if (style[ivar] != STRING) return -1;
|
||||
delete [] data[ivar][0];
|
||||
data[ivar][0] = new char[strlen(str)+1];
|
||||
strcpy(data[ivar][0],str);
|
||||
data[ivar][0] = utils::strdup(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -902,11 +904,8 @@ char *Variable::retrieve(const char *name)
|
||||
sprintf(padstr,"%%0%dd",pad[ivar]);
|
||||
sprintf(result,padstr,which[ivar]+1);
|
||||
}
|
||||
int n = strlen(result) + 1;
|
||||
delete [] data[ivar][0];
|
||||
data[ivar][0] = new char[n];
|
||||
strcpy(data[ivar][0],result);
|
||||
str = data[ivar][0];
|
||||
str = data[ivar][0] = utils::strdup(result);
|
||||
} else if (style[ivar] == EQUAL) {
|
||||
double answer = evaluate(data[ivar][0],nullptr,ivar);
|
||||
sprintf(data[ivar][1],"%.15g",answer);
|
||||
@ -921,13 +920,8 @@ char *Variable::retrieve(const char *name)
|
||||
} else if (style[ivar] == GETENV) {
|
||||
const char *result = getenv(data[ivar][0]);
|
||||
if (result == nullptr) result = (const char *) "";
|
||||
int n = strlen(result) + 1;
|
||||
if (n > VALUELENGTH) {
|
||||
delete [] data[ivar][1];
|
||||
data[ivar][1] = new char[n];
|
||||
}
|
||||
strcpy(data[ivar][1],result);
|
||||
str = data[ivar][1];
|
||||
delete [] data[ivar][1];
|
||||
str = data[ivar][1] = utils::strdup(result);
|
||||
} else if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->variable_match(data[ivar][0],name,0);
|
||||
if (ifunc < 0)
|
||||
@ -986,9 +980,12 @@ double Variable::compute_equal(int ivar)
|
||||
don't need to flag eval_in_progress since is an immediate variable
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double Variable::compute_equal(char *str)
|
||||
double Variable::compute_equal(const std::string &str)
|
||||
{
|
||||
return evaluate(str,nullptr,-1);
|
||||
char *ptr = utils::strdup(str);
|
||||
double val = evaluate(ptr,nullptr,-1);
|
||||
delete[] ptr;
|
||||
return val;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -1189,12 +1186,8 @@ void Variable::grow()
|
||||
|
||||
void Variable::copy(int narg, char **from, char **to)
|
||||
{
|
||||
int n;
|
||||
for (int i = 0; i < narg; i++) {
|
||||
n = strlen(from[i]) + 1;
|
||||
to[i] = new char[n];
|
||||
strcpy(to[i],from[i]);
|
||||
}
|
||||
for (int i = 0; i < narg; i++)
|
||||
to[i] = utils::strdup(from[i]);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -1239,6 +1232,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
int i = 0;
|
||||
int expect = ARG;
|
||||
|
||||
if (str == nullptr)
|
||||
print_var_error(FLERR,"Invalid syntax in variable formula",ivar);
|
||||
|
||||
while (1) {
|
||||
onechar = str[i];
|
||||
|
||||
@ -1255,7 +1251,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
print_var_error(FLERR,"Invalid syntax in variable formula",ivar);
|
||||
expect = OP;
|
||||
|
||||
char *contents;
|
||||
char *contents = nullptr;
|
||||
i = find_matching_paren(str,i,contents,ivar);
|
||||
i++;
|
||||
|
||||
@ -1380,9 +1376,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_scalar != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between "
|
||||
"runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_SCALAR)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||
compute->compute_scalar();
|
||||
compute->invoked_flag |= INVOKED_SCALAR;
|
||||
compute->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||
}
|
||||
|
||||
value1 = compute->scalar;
|
||||
@ -1407,9 +1403,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_vector != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between runs "
|
||||
"is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
compute->compute_vector();
|
||||
compute->invoked_flag |= INVOKED_VECTOR;
|
||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
}
|
||||
|
||||
if (compute->size_vector_variable &&
|
||||
@ -1439,9 +1435,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_array != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between runs "
|
||||
"is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_ARRAY)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
||||
compute->compute_array();
|
||||
compute->invoked_flag |= INVOKED_ARRAY;
|
||||
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
||||
}
|
||||
|
||||
if (compute->size_array_rows_variable &&
|
||||
@ -1473,9 +1469,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_vector != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between "
|
||||
"runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
compute->compute_vector();
|
||||
compute->invoked_flag |= INVOKED_VECTOR;
|
||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
}
|
||||
|
||||
Tree *newtree = new Tree();
|
||||
@ -1505,9 +1501,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_array != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between "
|
||||
"runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_ARRAY)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
||||
compute->compute_array();
|
||||
compute->invoked_flag |= INVOKED_ARRAY;
|
||||
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
||||
}
|
||||
|
||||
Tree *newtree = new Tree();
|
||||
@ -1529,9 +1525,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_peratom != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable "
|
||||
"between runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||
compute->compute_peratom();
|
||||
compute->invoked_flag |= INVOKED_PERATOM;
|
||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||
}
|
||||
|
||||
peratom2global(1,nullptr,compute->vector_atom,1,index1,
|
||||
@ -1549,9 +1545,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_peratom != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable "
|
||||
"between runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||
compute->compute_peratom();
|
||||
compute->invoked_flag |= INVOKED_PERATOM;
|
||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||
}
|
||||
|
||||
if (compute->array_atom)
|
||||
@ -1578,9 +1574,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_peratom != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable "
|
||||
"between runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||
compute->compute_peratom();
|
||||
compute->invoked_flag |= INVOKED_PERATOM;
|
||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||
}
|
||||
|
||||
Tree *newtree = new Tree();
|
||||
@ -1610,9 +1606,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
if (compute->invoked_peratom != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable "
|
||||
"between runs is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||
compute->compute_peratom();
|
||||
compute->invoked_flag |= INVOKED_PERATOM;
|
||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||
}
|
||||
|
||||
Tree *newtree = new Tree();
|
||||
@ -2071,7 +2067,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
// ----------------
|
||||
|
||||
if (str[i] == '(') {
|
||||
char *contents;
|
||||
char *contents = nullptr;
|
||||
i = find_matching_paren(str,i,contents,ivar);
|
||||
i++;
|
||||
|
||||
@ -2119,8 +2115,8 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
// constant
|
||||
// ----------------
|
||||
|
||||
} else if (is_constant(word)) {
|
||||
value1 = constant(word);
|
||||
} else if (constants.find(word) != constants.end()) {
|
||||
value1 = constants[word];
|
||||
if (tree) {
|
||||
Tree *newtree = new Tree();
|
||||
newtree->type = VALUE;
|
||||
@ -2344,7 +2340,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
||||
|
||||
double Variable::collapse_tree(Tree *tree)
|
||||
{
|
||||
double arg1,arg2;
|
||||
double arg1,arg2,arg3;
|
||||
|
||||
if (tree->type == VALUE) return tree->value;
|
||||
if (tree->type == ATOMARRAY) return 0.0;
|
||||
@ -2757,7 +2753,7 @@ double Variable::collapse_tree(Tree *tree)
|
||||
ivalue3-ivalue1+1 < ivalue2 )
|
||||
error->all(FLERR,"Invalid math function in variable formula");
|
||||
if (update->ntimestep < ivalue1) tree->value = ivalue1;
|
||||
//else if (update->ntimestep <= ivalue3){
|
||||
//else if (update->ntimestep <= ivalue3) {
|
||||
else {
|
||||
tree->value = ivalue1;
|
||||
double logsp = ivalue1;
|
||||
@ -2811,19 +2807,19 @@ double Variable::collapse_tree(Tree *tree)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (ivalue4 < ivalue1 || ivalue5 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
bigint istep;
|
||||
bigint istep, offset;
|
||||
if (update->ntimestep < ivalue1) istep = ivalue1;
|
||||
else if (update->ntimestep < ivalue2) {
|
||||
if (update->ntimestep < ivalue4 || update->ntimestep > ivalue5) {
|
||||
bigint offset = update->ntimestep - ivalue1;
|
||||
offset = update->ntimestep - ivalue1;
|
||||
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (update->ntimestep < ivalue2 && istep > ivalue4)
|
||||
tree->value = ivalue4;
|
||||
} else {
|
||||
bigint offset = update->ntimestep - ivalue4;
|
||||
offset = update->ntimestep - ivalue4;
|
||||
istep = ivalue4 + (offset/ivalue6)*ivalue6 + ivalue6;
|
||||
if (istep > ivalue5) {
|
||||
bigint offset = ivalue5 - ivalue1;
|
||||
offset = ivalue5 - ivalue1;
|
||||
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (istep > ivalue2) istep = MAXBIGINT;
|
||||
}
|
||||
@ -2834,8 +2830,8 @@ double Variable::collapse_tree(Tree *tree)
|
||||
}
|
||||
|
||||
if (tree->type == VDISPLACE) {
|
||||
double arg1 = collapse_tree(tree->first);
|
||||
double arg2 = collapse_tree(tree->second);
|
||||
arg1 = collapse_tree(tree->first);
|
||||
arg2 = collapse_tree(tree->second);
|
||||
if (tree->first->type != VALUE || tree->second->type != VALUE) return 0.0;
|
||||
tree->type = VALUE;
|
||||
double delta = update->ntimestep - update->beginstep;
|
||||
@ -2844,9 +2840,9 @@ double Variable::collapse_tree(Tree *tree)
|
||||
}
|
||||
|
||||
if (tree->type == SWIGGLE) {
|
||||
double arg1 = collapse_tree(tree->first);
|
||||
double arg2 = collapse_tree(tree->second);
|
||||
double arg3 = collapse_tree(tree->extra[0]);
|
||||
arg1 = collapse_tree(tree->first);
|
||||
arg2 = collapse_tree(tree->second);
|
||||
arg3 = collapse_tree(tree->extra[0]);
|
||||
if (tree->first->type != VALUE || tree->second->type != VALUE ||
|
||||
tree->extra[0]->type != VALUE) return 0.0;
|
||||
tree->type = VALUE;
|
||||
@ -2859,9 +2855,9 @@ double Variable::collapse_tree(Tree *tree)
|
||||
}
|
||||
|
||||
if (tree->type == CWIGGLE) {
|
||||
double arg1 = collapse_tree(tree->first);
|
||||
double arg2 = collapse_tree(tree->second);
|
||||
double arg3 = collapse_tree(tree->extra[0]);
|
||||
arg1 = collapse_tree(tree->first);
|
||||
arg2 = collapse_tree(tree->second);
|
||||
arg3 = collapse_tree(tree->extra[0]);
|
||||
if (tree->first->type != VALUE || tree->second->type != VALUE ||
|
||||
tree->extra[0]->type != VALUE) return 0.0;
|
||||
tree->type = VALUE;
|
||||
@ -3063,28 +3059,28 @@ double Variable::eval_tree(Tree *tree, int i)
|
||||
}
|
||||
|
||||
if (tree->type == STAGGER) {
|
||||
int ivalue1 = static_cast<int> (eval_tree(tree->first,i));
|
||||
int ivalue2 = static_cast<int> (eval_tree(tree->second,i));
|
||||
bigint ivalue1 = static_cast<bigint> (eval_tree(tree->first,i));
|
||||
bigint ivalue2 = static_cast<bigint> (eval_tree(tree->second,i));
|
||||
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
int lower = update->ntimestep/ivalue1 * ivalue1;
|
||||
int delta = update->ntimestep - lower;
|
||||
bigint lower = update->ntimestep/ivalue1 * ivalue1;
|
||||
bigint delta = update->ntimestep - lower;
|
||||
if (delta < ivalue2) arg = lower+ivalue2;
|
||||
else arg = lower+ivalue1;
|
||||
return arg;
|
||||
}
|
||||
|
||||
if (tree->type == LOGFREQ) {
|
||||
int ivalue1 = static_cast<int> (eval_tree(tree->first,i));
|
||||
int ivalue2 = static_cast<int> (eval_tree(tree->second,i));
|
||||
int ivalue3 = static_cast<int> (eval_tree(tree->extra[0],i));
|
||||
bigint ivalue1 = static_cast<bigint> (eval_tree(tree->first,i));
|
||||
bigint ivalue2 = static_cast<bigint> (eval_tree(tree->second,i));
|
||||
bigint ivalue3 = static_cast<bigint> (eval_tree(tree->extra[0],i));
|
||||
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (update->ntimestep < ivalue1) arg = ivalue1;
|
||||
else {
|
||||
int lower = ivalue1;
|
||||
bigint lower = ivalue1;
|
||||
while (update->ntimestep >= ivalue3*lower) lower *= ivalue3;
|
||||
int multiple = update->ntimestep/lower;
|
||||
bigint multiple = update->ntimestep/lower;
|
||||
if (multiple < ivalue2) arg = (multiple+1)*lower;
|
||||
else arg = lower*ivalue3;
|
||||
}
|
||||
@ -3092,16 +3088,16 @@ double Variable::eval_tree(Tree *tree, int i)
|
||||
}
|
||||
|
||||
if (tree->type == LOGFREQ2) {
|
||||
int ivalue1 = static_cast<int> (eval_tree(tree->first,i));
|
||||
int ivalue2 = static_cast<int> (eval_tree(tree->second,i));
|
||||
int ivalue3 = static_cast<int> (eval_tree(tree->extra[0],i));
|
||||
bigint ivalue1 = static_cast<bigint> (eval_tree(tree->first,i));
|
||||
bigint ivalue2 = static_cast<bigint> (eval_tree(tree->second,i));
|
||||
bigint ivalue3 = static_cast<bigint> (eval_tree(tree->extra[0],i));
|
||||
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 )
|
||||
error->all(FLERR,"Invalid math function in variable formula");
|
||||
if (update->ntimestep < ivalue1) arg = ivalue1;
|
||||
else {
|
||||
arg = ivalue1;
|
||||
double delta = ivalue1*(ivalue3-1.0)/ivalue2;
|
||||
int count = 0;
|
||||
bigint count = 0;
|
||||
while (update->ntimestep >= arg) {
|
||||
arg += delta;
|
||||
count++;
|
||||
@ -3113,14 +3109,14 @@ double Variable::eval_tree(Tree *tree, int i)
|
||||
}
|
||||
|
||||
if (tree->type == STRIDE) {
|
||||
int ivalue1 = static_cast<int> (eval_tree(tree->first,i));
|
||||
int ivalue2 = static_cast<int> (eval_tree(tree->second,i));
|
||||
int ivalue3 = static_cast<int> (eval_tree(tree->extra[0],i));
|
||||
bigint ivalue1 = static_cast<bigint> (eval_tree(tree->first,i));
|
||||
bigint ivalue2 = static_cast<bigint> (eval_tree(tree->second,i));
|
||||
bigint ivalue3 = static_cast<bigint> (eval_tree(tree->extra[0],i));
|
||||
if (ivalue1 < 0 || ivalue2 < 0 || ivalue3 <= 0 || ivalue1 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (update->ntimestep < ivalue1) arg = ivalue1;
|
||||
else if (update->ntimestep < ivalue2) {
|
||||
int offset = update->ntimestep - ivalue1;
|
||||
bigint offset = update->ntimestep - ivalue1;
|
||||
arg = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (arg > ivalue2) arg = (double) MAXBIGINT;
|
||||
} else arg = (double) MAXBIGINT;
|
||||
@ -3128,31 +3124,31 @@ double Variable::eval_tree(Tree *tree, int i)
|
||||
}
|
||||
|
||||
if (tree->type == STRIDE2) {
|
||||
int ivalue1 = static_cast<int> (eval_tree(tree->first,i));
|
||||
int ivalue2 = static_cast<int> (eval_tree(tree->second,i));
|
||||
int ivalue3 = static_cast<int> (eval_tree(tree->extra[0],i));
|
||||
int ivalue4 = static_cast<int> (eval_tree(tree->extra[1],i));
|
||||
int ivalue5 = static_cast<int> (eval_tree(tree->extra[2],i));
|
||||
int ivalue6 = static_cast<int> (eval_tree(tree->extra[3],i));
|
||||
bigint ivalue1 = static_cast<bigint> (eval_tree(tree->first,i));
|
||||
bigint ivalue2 = static_cast<bigint> (eval_tree(tree->second,i));
|
||||
bigint ivalue3 = static_cast<bigint> (eval_tree(tree->extra[0],i));
|
||||
bigint ivalue4 = static_cast<bigint> (eval_tree(tree->extra[1],i));
|
||||
bigint ivalue5 = static_cast<bigint> (eval_tree(tree->extra[2],i));
|
||||
bigint ivalue6 = static_cast<bigint> (eval_tree(tree->extra[3],i));
|
||||
if (ivalue1 < 0 || ivalue2 < 0 || ivalue3 <= 0 || ivalue1 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (ivalue4 < 0 || ivalue5 < 0 || ivalue6 <= 0 || ivalue4 > ivalue5)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (ivalue4 < ivalue1 || ivalue5 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
bigint istep;
|
||||
bigint istep, offset;
|
||||
if (update->ntimestep < ivalue1) istep = ivalue1;
|
||||
else if (update->ntimestep < ivalue2) {
|
||||
if (update->ntimestep < ivalue4 || update->ntimestep > ivalue5) {
|
||||
int offset = update->ntimestep - ivalue1;
|
||||
offset = update->ntimestep - ivalue1;
|
||||
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (update->ntimestep < ivalue2 && istep > ivalue4)
|
||||
tree->value = ivalue4;
|
||||
} else {
|
||||
int offset = update->ntimestep - ivalue4;
|
||||
offset = update->ntimestep - ivalue4;
|
||||
istep = ivalue4 + (offset/ivalue6)*ivalue6 + ivalue6;
|
||||
if (istep > ivalue5) {
|
||||
int offset = ivalue5 - ivalue1;
|
||||
offset = ivalue5 - ivalue1;
|
||||
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (istep > ivalue2) istep = MAXBIGINT;
|
||||
}
|
||||
@ -3291,6 +3287,7 @@ int Variable::find_matching_paren(char *str, int i, char *&contents, int ivar)
|
||||
int istop = i;
|
||||
|
||||
int n = istop - istart - 1;
|
||||
delete[] contents;
|
||||
contents = new char[n+1];
|
||||
strncpy(contents,&str[istart+1],n);
|
||||
contents[n] = '\0';
|
||||
@ -3315,7 +3312,7 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow)
|
||||
|
||||
char *start = ++ptr;
|
||||
|
||||
if (varallow && strstr(ptr,"v_") == ptr) {
|
||||
if (varallow && utils::strmatch(ptr,"^v_")) {
|
||||
varflag = 1;
|
||||
while (*ptr && *ptr != ']') {
|
||||
if (!isalnum(*ptr) && *ptr != '_')
|
||||
@ -3594,12 +3591,12 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = STAGGER;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
bigint ivalue1 = static_cast<bigint> (value1);
|
||||
bigint ivalue2 = static_cast<bigint> (value2);
|
||||
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
int lower = update->ntimestep/ivalue1 * ivalue1;
|
||||
int delta = update->ntimestep - lower;
|
||||
bigint lower = update->ntimestep/ivalue1 * ivalue1;
|
||||
bigint delta = update->ntimestep - lower;
|
||||
double value;
|
||||
if (delta < ivalue2) value = lower+ivalue2;
|
||||
else value = lower+ivalue1;
|
||||
@ -3611,17 +3608,17 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = LOGFREQ;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
int ivalue3 = static_cast<int> (values[0]);
|
||||
bigint ivalue1 = static_cast<bigint> (value1);
|
||||
bigint ivalue2 = static_cast<bigint> (value2);
|
||||
bigint ivalue3 = static_cast<bigint> (values[0]);
|
||||
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3)
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
double value;
|
||||
if (update->ntimestep < ivalue1) value = ivalue1;
|
||||
else {
|
||||
int lower = ivalue1;
|
||||
bigint lower = ivalue1;
|
||||
while (update->ntimestep >= ivalue3*lower) lower *= ivalue3;
|
||||
int multiple = update->ntimestep/lower;
|
||||
bigint multiple = update->ntimestep/lower;
|
||||
if (multiple < ivalue2) value = (multiple+1)*lower;
|
||||
else value = lower*ivalue3;
|
||||
}
|
||||
@ -3633,9 +3630,9 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = LOGFREQ2;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
int ivalue3 = static_cast<int> (values[0]);
|
||||
bigint ivalue1 = static_cast<bigint> (value1);
|
||||
bigint ivalue2 = static_cast<bigint> (value2);
|
||||
bigint ivalue3 = static_cast<bigint> (values[0]);
|
||||
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 )
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
double value;
|
||||
@ -3643,7 +3640,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
else {
|
||||
value = ivalue1;
|
||||
double delta = ivalue1*(ivalue3-1.0)/ivalue2;
|
||||
int count = 0;
|
||||
bigint count = 0;
|
||||
while (update->ntimestep >= value) {
|
||||
value += delta;
|
||||
count++;
|
||||
@ -3658,25 +3655,25 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = LOGFREQ3;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
int ivalue3 = static_cast<int> (values[0]);
|
||||
bigint ivalue1 = static_cast<bigint> (value1);
|
||||
bigint ivalue2 = static_cast<bigint> (value2);
|
||||
bigint ivalue3 = static_cast<bigint> (values[0]);
|
||||
if (ivalue1 <= 0 || ivalue2 <= 1 || ivalue3 <= 0 ||
|
||||
ivalue3-ivalue1+1 < ivalue2 )
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
double value;
|
||||
if (update->ntimestep < ivalue1) value = ivalue1;
|
||||
//else if (update->ntimestep <= ivalue3){
|
||||
//else if (update->ntimestep <= ivalue3) {
|
||||
else {
|
||||
value = ivalue1;
|
||||
double logsp = ivalue1;
|
||||
double factor = pow(((double)ivalue3)/ivalue1, 1.0/(ivalue2-1));
|
||||
int linsp = ivalue1;
|
||||
bigint linsp = ivalue1;
|
||||
while (update->ntimestep >= value) {
|
||||
logsp *= factor;
|
||||
linsp++;
|
||||
if (linsp > logsp) value = linsp;
|
||||
else value = ceil(logsp)-(((int)ceil(logsp)-1)/ivalue3);
|
||||
else value = ceil(logsp)-(((bigint)ceil(logsp)-1)/ivalue3);
|
||||
}
|
||||
}
|
||||
if (update->ntimestep > ivalue3)
|
||||
@ -3689,15 +3686,15 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = STRIDE;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
int ivalue3 = static_cast<int> (values[0]);
|
||||
bigint ivalue1 = static_cast<bigint> (value1);
|
||||
bigint ivalue2 = static_cast<bigint> (value2);
|
||||
bigint ivalue3 = static_cast<bigint> (values[0]);
|
||||
if (ivalue1 < 0 || ivalue2 < 0 || ivalue3 <= 0 || ivalue1 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
double value;
|
||||
if (update->ntimestep < ivalue1) value = ivalue1;
|
||||
else if (update->ntimestep < ivalue2) {
|
||||
int offset = update->ntimestep - ivalue1;
|
||||
bigint offset = update->ntimestep - ivalue1;
|
||||
value = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (value > ivalue2) value = (double) MAXBIGINT;
|
||||
} else value = (double) MAXBIGINT;
|
||||
@ -3709,30 +3706,30 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = STRIDE2;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
int ivalue3 = static_cast<int> (values[0]);
|
||||
int ivalue4 = static_cast<int> (values[1]);
|
||||
int ivalue5 = static_cast<int> (values[2]);
|
||||
int ivalue6 = static_cast<int> (values[3]);
|
||||
bigint ivalue1 = static_cast<bigint> (value1);
|
||||
bigint ivalue2 = static_cast<bigint> (value2);
|
||||
bigint ivalue3 = static_cast<bigint> (values[0]);
|
||||
bigint ivalue4 = static_cast<bigint> (values[1]);
|
||||
bigint ivalue5 = static_cast<bigint> (values[2]);
|
||||
bigint ivalue6 = static_cast<bigint> (values[3]);
|
||||
if (ivalue1 < 0 || ivalue2 < 0 || ivalue3 <= 0 || ivalue1 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (ivalue4 < 0 || ivalue5 < 0 || ivalue6 <= 0 || ivalue4 > ivalue5)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
if (ivalue4 < ivalue1 || ivalue5 > ivalue2)
|
||||
error->one(FLERR,"Invalid math function in variable formula");
|
||||
bigint istep;
|
||||
bigint istep, offset;
|
||||
if (update->ntimestep < ivalue1) istep = ivalue1;
|
||||
else if (update->ntimestep < ivalue2) {
|
||||
if (update->ntimestep < ivalue4 || update->ntimestep > ivalue5) {
|
||||
int offset = update->ntimestep - ivalue1;
|
||||
offset = update->ntimestep - ivalue1;
|
||||
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (update->ntimestep < ivalue4 && istep > ivalue4) istep = ivalue4;
|
||||
} else {
|
||||
int offset = update->ntimestep - ivalue4;
|
||||
offset = update->ntimestep - ivalue4;
|
||||
istep = ivalue4 + (offset/ivalue6)*ivalue6 + ivalue6;
|
||||
if (istep > ivalue5) {
|
||||
int offset = ivalue5 - ivalue1;
|
||||
offset = ivalue5 - ivalue1;
|
||||
istep = ivalue1 + (offset/ivalue3)*ivalue3 + ivalue3;
|
||||
if (istep > ivalue2) istep = MAXBIGINT;
|
||||
}
|
||||
@ -4084,7 +4081,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
strcmp(word,"gmask") && strcmp(word,"rmask") &&
|
||||
strcmp(word,"grmask") && strcmp(word,"next") &&
|
||||
strcmp(word,"is_active") && strcmp(word,"is_defined") &&
|
||||
strcmp(word,"is_available"))
|
||||
strcmp(word,"is_available") && strcmp(word,"is_file"))
|
||||
return 0;
|
||||
|
||||
// parse contents for comma-separated args
|
||||
@ -4112,13 +4109,13 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
|
||||
Compute *compute = nullptr;
|
||||
Fix *fix = nullptr;
|
||||
int ivar = -1;
|
||||
int index,nvec,nstride;
|
||||
char *ptr1,*ptr2;
|
||||
int ivar = -1;
|
||||
|
||||
// argument is compute
|
||||
|
||||
if (strstr(args[0],"c_") == args[0]) {
|
||||
if (utils::strmatch(args[0],"^c_")) {
|
||||
ptr1 = strchr(args[0],'[');
|
||||
if (ptr1) {
|
||||
ptr2 = ptr1;
|
||||
@ -4139,9 +4136,9 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
if (compute->invoked_vector != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between runs "
|
||||
"is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
compute->compute_vector();
|
||||
compute->invoked_flag |= INVOKED_VECTOR;
|
||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
}
|
||||
nvec = compute->size_vector;
|
||||
nstride = 1;
|
||||
@ -4153,9 +4150,9 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
if (compute->invoked_array != update->ntimestep)
|
||||
print_var_error(FLERR,"Compute used in variable between runs "
|
||||
"is not current",ivar);
|
||||
} else if (!(compute->invoked_flag & INVOKED_ARRAY)) {
|
||||
} else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
||||
compute->compute_array();
|
||||
compute->invoked_flag |= INVOKED_ARRAY;
|
||||
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
||||
}
|
||||
nvec = compute->size_array_rows;
|
||||
nstride = compute->size_array_cols;
|
||||
@ -4163,7 +4160,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
|
||||
// argument is fix
|
||||
|
||||
} else if (strstr(args[0],"f_") == args[0]) {
|
||||
} else if (utils::strmatch(args[0],"^f_")) {
|
||||
ptr1 = strchr(args[0],'[');
|
||||
if (ptr1) {
|
||||
ptr2 = ptr1;
|
||||
@ -4201,7 +4198,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
|
||||
// argument is vector-style variable
|
||||
|
||||
} else if (strstr(args[0],"v_") == args[0]) {
|
||||
} else if (utils::strmatch(args[0],"^v_")) {
|
||||
ptr1 = strchr(args[0],'[');
|
||||
if (ptr1) {
|
||||
ptr2 = ptr1;
|
||||
@ -4493,6 +4490,26 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
|
||||
// save value in tree or on argstack
|
||||
|
||||
if (tree) {
|
||||
Tree *newtree = new Tree();
|
||||
newtree->type = VALUE;
|
||||
newtree->value = value;
|
||||
newtree->first = newtree->second = nullptr;
|
||||
newtree->nextra = 0;
|
||||
treestack[ntreestack++] = newtree;
|
||||
} else argstack[nargstack++] = value;
|
||||
|
||||
} else if (strcmp(word,"is_file") == 0) {
|
||||
if (narg != 1)
|
||||
print_var_error(FLERR,"Invalid is_file() function in "
|
||||
"variable formula",ivar);
|
||||
|
||||
FILE *fp = fopen(args[0],"r");
|
||||
value = (fp == nullptr) ? 0.0 : 1.0;
|
||||
if (fp) fclose(fp);
|
||||
|
||||
// save value in tree or on argstack
|
||||
|
||||
if (tree) {
|
||||
Tree *newtree = new Tree();
|
||||
newtree->type = VALUE;
|
||||
@ -4752,43 +4769,6 @@ void Variable::atom_vector(char *word, Tree **tree,
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
check if word matches a constant
|
||||
return 1 if yes, else 0
|
||||
customize by adding a constant: PI, version
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::is_constant(char *word)
|
||||
{
|
||||
if (strcmp(word,"PI") == 0) return 1;
|
||||
if (strcmp(word,"version") == 0) return 1;
|
||||
if (strcmp(word,"yes") == 0) return 1;
|
||||
if (strcmp(word,"no") == 0) return 1;
|
||||
if (strcmp(word,"on") == 0) return 1;
|
||||
if (strcmp(word,"off") == 0) return 1;
|
||||
if (strcmp(word,"true") == 0) return 1;
|
||||
if (strcmp(word,"false") == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
process a constant in formula
|
||||
customize by adding a constant: PI, version
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double Variable::constant(char *word)
|
||||
{
|
||||
if (strcmp(word,"PI") == 0) return MY_PI;
|
||||
if (strcmp(word,"version") == 0) return lmp->num_ver;
|
||||
if (strcmp(word,"yes") == 0) return 1.0;
|
||||
if (strcmp(word,"no") == 0) return 0.0;
|
||||
if (strcmp(word,"on") == 0) return 1.0;
|
||||
if (strcmp(word,"off") == 0) return 0.0;
|
||||
if (strcmp(word,"true") == 0) return 1.0;
|
||||
if (strcmp(word,"false") == 0) return 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
parse string for comma-separated args
|
||||
store copy of each arg in args array
|
||||
@ -4797,18 +4777,14 @@ double Variable::constant(char *word)
|
||||
|
||||
int Variable::parse_args(char *str, char **args)
|
||||
{
|
||||
int n;
|
||||
char *ptrnext;
|
||||
|
||||
int narg = 0;
|
||||
int narg = 0;
|
||||
char *ptr = str;
|
||||
|
||||
while (ptr && narg < MAXFUNCARG) {
|
||||
ptrnext = find_next_comma(ptr);
|
||||
if (ptrnext) *ptrnext = '\0';
|
||||
n = strlen(ptr) + 1;
|
||||
args[narg] = new char[n];
|
||||
strcpy(args[narg],ptr);
|
||||
args[narg] = utils::strdup(ptr);
|
||||
narg++;
|
||||
ptr = ptrnext;
|
||||
if (ptr) ptr++;
|
||||
@ -4818,7 +4794,6 @@ int Variable::parse_args(char *str, char **args)
|
||||
return narg;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
find next comma in str
|
||||
skip commas inside one or more nested parenthesis
|
||||
@ -4917,7 +4892,7 @@ double Variable::evaluate_boolean(char *str)
|
||||
error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
expect = OP;
|
||||
|
||||
char *contents;
|
||||
char *contents = nullptr;
|
||||
i = find_matching_paren(str,i,contents,-1);
|
||||
i++;
|
||||
|
||||
@ -5152,14 +5127,13 @@ VarReader::VarReader(LAMMPS *lmp, char *name, char *file, int flag) :
|
||||
id_fix = nullptr;
|
||||
buffer = nullptr;
|
||||
|
||||
if (style == ATOMFILE) {
|
||||
if (style == Variable::ATOMFILE) {
|
||||
if (atom->map_style == Atom::MAP_NONE)
|
||||
error->all(FLERR,"Cannot use atomfile-style "
|
||||
"variable unless an atom map exists");
|
||||
|
||||
std::string cmd = name + std::string("_VARIABLE_STORE");
|
||||
id_fix = new char[cmd.size()+1];
|
||||
strcpy(id_fix,cmd.c_str());
|
||||
id_fix = utils::strdup(cmd);
|
||||
|
||||
cmd += " all STORE peratom 0 1";
|
||||
modify->add_fix(cmd);
|
||||
@ -5203,17 +5177,17 @@ int VarReader::read_scalar(char *str)
|
||||
|
||||
if (me == 0) {
|
||||
while (1) {
|
||||
if (fgets(str,MAXLINE,fp) == nullptr) n = 0;
|
||||
else n = strlen(str);
|
||||
if (n == 0) break; // end of file
|
||||
str[n-1] = '\0'; // strip newline
|
||||
if ((ptr = strchr(str,'#'))) *ptr = '\0'; // strip comment
|
||||
if (strtok(str," \t\n\r\f") == nullptr) continue; // skip if blank
|
||||
n = strlen(str) + 1;
|
||||
ptr = fgets(str,MAXLINE,fp);
|
||||
if (!ptr) { n=0; break; } // end of file
|
||||
ptr[strcspn(ptr,"#")] = '\0'; // strip comment
|
||||
ptr += strspn(ptr," \t\n\r\f"); // strip leading whitespace
|
||||
ptr[strcspn(ptr," \t\n\r\f")] = '\0'; // strip trailing whitespace
|
||||
n = strlen(ptr) + 1;
|
||||
if (n == 1) continue; // skip if blank line
|
||||
break;
|
||||
}
|
||||
memmove(str,ptr,n); // move trimmed string back
|
||||
}
|
||||
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n == 0) return 1;
|
||||
MPI_Bcast(str,n,MPI_CHAR,0,world);
|
||||
@ -5246,20 +5220,20 @@ int VarReader::read_peratom()
|
||||
char str[MAXLINE];
|
||||
if (me == 0) {
|
||||
while (1) {
|
||||
if (fgets(str,MAXLINE,fp) == nullptr) n = 0;
|
||||
else n = strlen(str);
|
||||
if (n == 0) break; // end of file
|
||||
str[n-1] = '\0'; // strip newline
|
||||
if ((ptr = strchr(str,'#'))) *ptr = '\0'; // strip comment
|
||||
if (strtok(str," \t\n\r\f") == nullptr) continue; // skip if blank
|
||||
n = strlen(str) + 1;
|
||||
ptr = fgets(str,MAXLINE,fp);
|
||||
if (!ptr) { n=0; break; } // end of file
|
||||
ptr[strcspn(ptr,"#")] = '\0'; // strip comment
|
||||
ptr += strspn(ptr," \t\n\r\f"); // strip leading whitespace
|
||||
ptr[strcspn(ptr," \t\n\r\f")] = '\0'; // strip trailing whitespace
|
||||
n = strlen(ptr) + 1;
|
||||
if (n == 1) continue; // skip if blank line
|
||||
break;
|
||||
}
|
||||
memmove(str,ptr,n); // move trimmed string back
|
||||
}
|
||||
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n == 0) return 1;
|
||||
|
||||
MPI_Bcast(str,n,MPI_CHAR,0,world);
|
||||
bigint nlines = utils::bnumeric(FLERR,str,false,lmp);
|
||||
tagint map_tag_max = atom->map_tag_max;
|
||||
@ -5267,16 +5241,24 @@ int VarReader::read_peratom()
|
||||
bigint nread = 0;
|
||||
while (nread < nlines) {
|
||||
nchunk = MIN(nlines-nread,CHUNK);
|
||||
eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
|
||||
eof = utils::read_lines_from_file(fp,nchunk,MAXLINE,buffer,me,world);
|
||||
if (eof) return 1;
|
||||
|
||||
char *buf = buffer;
|
||||
for (i = 0; i < nchunk; i++) {
|
||||
next = strchr(buf,'\n');
|
||||
*next = '\0';
|
||||
int rv = sscanf(buf,TAGINT_FORMAT " %lg",&tag,&value);
|
||||
if (tag <= 0 || tag > map_tag_max || rv != 2)
|
||||
error->one(FLERR,"Invalid atom ID in variable file");
|
||||
try {
|
||||
ValueTokenizer words(buf);
|
||||
tag = words.next_bigint();
|
||||
value = words.next_double();
|
||||
} catch (TokenizerException &e) {
|
||||
error->all(FLERR,fmt::format("Invalid atomfile line '{}': {}",
|
||||
buf,e.what()));
|
||||
}
|
||||
if ((tag <= 0) || (tag > map_tag_max))
|
||||
error->all(FLERR,fmt::format("Invalid atom ID {} in variable "
|
||||
"file", tag));
|
||||
if ((m = atom->map(tag)) >= 0) vstore[m] = value;
|
||||
buf = next + 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user