add output option for vector-style vars

This commit is contained in:
Steve Plimpton
2023-05-04 12:52:11 -06:00
parent 936b24e3b0
commit ccc1b200c0

View File

@ -38,6 +38,8 @@
#include "universe.h" #include "universe.h"
#include "update.h" #include "update.h"
#include "fmt/ranges.h"
#include <cctype> #include <cctype>
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
@ -72,10 +74,10 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
enum{SUM,XMIN,XMAX,AVE,TRAP,SLOPE}; enum{SUM,XMIN,XMAX,AVE,TRAP,SLOPE};
static constexpr double BIG = 1.0e20; static constexpr double BIG = 1.0e20;
// INT64_MAX cannot be represented with a double. reduce to avoid overflow when casting back. // INT64_MAX cannot be represented with a double. reduce to avoid overflow when casting back
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) #if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
static constexpr double MAXBIGINT_DOUBLE = (double) (MAXBIGINT-512); static constexpr double MAXBIGINT_DOUBLE = (double) (MAXBIGINT-512);
#else #else
@ -477,8 +479,8 @@ void Variable::set(int narg, char **arg)
// VECTOR // VECTOR
// replace pre-existing var if also style VECTOR (allows it to be reset) // replace pre-existing var if also style VECTOR (allows it to be reset)
// num = 1, which = 1st value // num = 2, which = 1st value
// data = 1 value, string to eval // data = 2 values, 1st is string to eval, 2nd is formatted output string [1,2,3]
// if formula string is [value,value,...] then // if formula string is [value,value,...] then
// immediately store it as N-length vector and set dynamic flag to 0 // immediately store it as N-length vector and set dynamic flag to 0
@ -489,24 +491,36 @@ void Variable::set(int narg, char **arg)
if (style[ivar] != VECTOR) if (style[ivar] != VECTOR)
error->all(FLERR,"Cannot redefine variable as a different style"); error->all(FLERR,"Cannot redefine variable as a different style");
delete[] data[ivar][0]; delete[] data[ivar][0];
delete[] data[ivar][1];
data[ivar][0] = utils::strdup(arg[2]); data[ivar][0] = utils::strdup(arg[2]);
if (data[ivar][0][0] == '[') { if (data[ivar][0][0] != '[')
parse_vector(ivar,data[ivar][0]); vecs[ivar].dynamic = 1;
else {
vecs[ivar].dynamic = 0; vecs[ivar].dynamic = 0;
} else vecs[ivar].dynamic = 1; parse_vector(ivar,data[ivar][0]);
std::vector <double> vec(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n);
std::string str = fmt::format("[{}]", fmt::join(vec,","));
data[ivar][1] = utils::strdup(str);
}
replaceflag = 1; replaceflag = 1;
} else { } else {
if (nvar == maxvar) grow(); if (nvar == maxvar) grow();
style[nvar] = VECTOR; style[nvar] = VECTOR;
num[nvar] = 1; num[nvar] = 2;
which[nvar] = 0; which[nvar] = 0;
pad[nvar] = 0; pad[nvar] = 0;
data[nvar] = new char*[num[nvar]]; data[nvar] = new char*[num[nvar]];
data[nvar][0] = utils::strdup(arg[2]); data[nvar][0] = utils::strdup(arg[2]);
if (data[nvar][0][0] == '[') { if (data[nvar][0][0] != '[')
parse_vector(nvar,data[nvar][0]); vecs[nvar].dynamic = 1;
else {
vecs[nvar].dynamic = 0; vecs[nvar].dynamic = 0;
} else vecs[nvar].dynamic = 1; parse_vector(nvar,data[nvar][0]);
std::vector <double> vec(vecs[nvar].values,vecs[nvar].values + vecs[nvar].n);
std::string str = fmt::format("[{}]", fmt::join(vec,","));
data[nvar][1] = utils::strdup(str);
}
} }
// PYTHON // PYTHON
@ -945,8 +959,9 @@ int Variable::internalstyle(int ivar)
if GETENV, query environment and put result in str if GETENV, query environment and put result in str
if PYTHON, evaluate Python function, it will 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 INTERNAL, convert dvalue and put result in str
if ATOM or ATOMFILE or VECTOR, return nullptr if VECTOR, return ptr to str = [value,value,...]
return nullptr if no variable with name, or which value is bad, if ATOM or ATOMFILE, return nullptr
return nullptr if no variable with name or if which value is bad,
caller must respond caller must respond
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
@ -1019,8 +1034,10 @@ char *Variable::retrieve(const char *name)
delete[] data[ivar][0]; delete[] data[ivar][0];
data[ivar][0] = utils::strdup(fmt::format("{:.15g}",dvalue[ivar])); data[ivar][0] = utils::strdup(fmt::format("{:.15g}",dvalue[ivar]));
str = data[ivar][0]; str = data[ivar][0];
} else if (style[ivar] == ATOM || style[ivar] == ATOMFILE || } else if (style[ivar] == VECTOR) {
style[ivar] == VECTOR) return nullptr; str = data[ivar][1];
} else if (style[ivar] == ATOM || style[ivar] == ATOMFILE)
return nullptr;
eval_in_progress[ivar] = 0; eval_in_progress[ivar] = 0;
@ -1203,6 +1220,14 @@ int Variable::compute_vector(int ivar, double **result)
free_tree(tree); free_tree(tree);
eval_in_progress[ivar] = 0; eval_in_progress[ivar] = 0;
// convert numeric vector to formatted string in data[ivar][1]
// this is so that retrieve() on the vector variable will work
delete[] data[ivar][1];
std::vector <double> vectmp(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n);
std::string str = fmt::format("[{}]", fmt::join(vectmp,","));
data[ivar][1] = utils::strdup(str);
*result = vec; *result = vec;
return nlen; return nlen;
} }