modernize fix vector
This commit is contained in:
@ -1,4 +1,3 @@
|
||||
// clang-format off
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
@ -26,41 +25,34 @@
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
enum{ONE,RUNNING,WINDOW};
|
||||
enum{SCALAR,VECTOR};
|
||||
|
||||
enum { ONE, RUNNING, WINDOW };
|
||||
enum { SCALAR, VECTOR };
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg),
|
||||
nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), ids(nullptr), vector(nullptr), array(nullptr)
|
||||
Fix(lmp, narg, arg), vector(nullptr), array(nullptr)
|
||||
{
|
||||
if (narg < 5) error->all(FLERR,"Illegal fix vector command");
|
||||
if (narg < 5) utils::missing_cmd_args(FLERR, "fix vector", error);
|
||||
|
||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||
if (nevery <= 0) error->all(FLERR,"Illegal fix vector command");
|
||||
nevery = utils::inumeric(FLERR, arg[3], false, lmp);
|
||||
if (nevery <= 0) error->all(FLERR, "Invalid fix vector every argument: {}", nevery);
|
||||
|
||||
nvalues = narg-4;
|
||||
which = new int[nvalues];
|
||||
argindex = new int[nvalues];
|
||||
value2index = new int[nvalues];
|
||||
ids = new char*[nvalues];
|
||||
|
||||
nvalues = 0;
|
||||
values.clear();
|
||||
for (int iarg = 4; iarg < narg; iarg++) {
|
||||
ArgInfo argi(arg[iarg]);
|
||||
|
||||
which[nvalues] = argi.get_type();
|
||||
argindex[nvalues] = argi.get_index1();
|
||||
ids[nvalues] = argi.copy_name();
|
||||
value_t val;
|
||||
val.which = argi.get_type();
|
||||
val.argindex = argi.get_index1();
|
||||
val.id = argi.get_name();
|
||||
val.val.c = nullptr;
|
||||
|
||||
if ((argi.get_type() == ArgInfo::UNKNOWN)
|
||||
|| (argi.get_type() == ArgInfo::NONE)
|
||||
|| (argi.get_dim() > 1))
|
||||
error->all(FLERR,"Illegal fix vector command");
|
||||
if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_type() == ArgInfo::NONE) ||
|
||||
(argi.get_dim() > 1))
|
||||
error->all(FLERR, "Invalid fix vector argument: {}", arg[iarg]);
|
||||
|
||||
nvalues++;
|
||||
values.push_back(val);
|
||||
}
|
||||
|
||||
// setup and error check
|
||||
@ -68,59 +60,70 @@ FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
// this fix produces either a global vector or array
|
||||
// intensive/extensive flags set by compute,fix,variable that produces value
|
||||
|
||||
int value,finalvalue;
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
if (which[i] == ArgInfo::COMPUTE) {
|
||||
auto icompute = modify->get_compute_by_id(ids[i]);
|
||||
if (!icompute) error->all(FLERR,"Compute ID {} for fix vector does not exist",ids[i]);
|
||||
if (argindex[i] == 0 && icompute->scalar_flag == 0)
|
||||
error->all(FLERR,"Fix vector compute {} does not calculate a scalar",ids[i]);
|
||||
if (argindex[i] && icompute->vector_flag == 0)
|
||||
error->all(FLERR,"Fix vector compute {} does not calculate a vector",ids[i]);
|
||||
if (argindex[i] && argindex[i] > icompute->size_vector)
|
||||
error->all(FLERR,"Fix vector compute {} vector is accessed out-of-range",ids[i]);
|
||||
int value, finalvalue;
|
||||
bool first = true;
|
||||
for (auto &val : values) {
|
||||
if (val.which == ArgInfo::COMPUTE) {
|
||||
auto icompute = modify->get_compute_by_id(val.id);
|
||||
if (!icompute) error->all(FLERR, "Compute ID {} for fix vector does not exist", val.id);
|
||||
if (val.argindex == 0 && icompute->scalar_flag == 0)
|
||||
error->all(FLERR, "Fix vector compute {} does not calculate a scalar", val.id);
|
||||
if (val.argindex && icompute->vector_flag == 0)
|
||||
error->all(FLERR, "Fix vector compute {} does not calculate a vector", val.id);
|
||||
if (val.argindex && (val.argindex > icompute->size_vector))
|
||||
error->all(FLERR, "Fix vector compute {} vector is accessed out-of-range", val.id);
|
||||
|
||||
if (argindex[i] == 0) value = icompute->extscalar;
|
||||
else if (icompute->extvector >= 0) value = icompute->extvector;
|
||||
else value = icompute->extlist[argindex[i]-1];
|
||||
if (val.argindex == 0)
|
||||
value = icompute->extscalar;
|
||||
else if (icompute->extvector >= 0)
|
||||
value = icompute->extvector;
|
||||
else
|
||||
value = icompute->extlist[val.argindex - 1];
|
||||
val.val.c = icompute;
|
||||
|
||||
} else if (which[i] == ArgInfo::FIX) {
|
||||
auto ifix = modify->get_fix_by_id(ids[i]);
|
||||
if (!ifix) error->all(FLERR,"Fix ID {} for fix vector does not exist",ids[i]);
|
||||
if (argindex[i] == 0 && ifix->scalar_flag == 0)
|
||||
error->all(FLERR,"Fix vector fix {} does not calculate a scalar",ids[i]);
|
||||
if (argindex[i] && ifix->vector_flag == 0)
|
||||
error->all(FLERR,"Fix vector fix {} does not calculate a vector",ids[i]);
|
||||
if (argindex[i] && argindex[i] > ifix->size_vector)
|
||||
error->all(FLERR,"Fix vector fix {} vector is accessed out-of-range",ids[i]);
|
||||
} else if (val.which == ArgInfo::FIX) {
|
||||
auto ifix = modify->get_fix_by_id(val.id);
|
||||
if (!ifix) error->all(FLERR, "Fix ID {} for fix vector does not exist", val.id);
|
||||
if (val.argindex == 0 && ifix->scalar_flag == 0)
|
||||
error->all(FLERR, "Fix vector fix {} does not calculate a scalar", val.id);
|
||||
if (val.argindex && ifix->vector_flag == 0)
|
||||
error->all(FLERR, "Fix vector fix {} does not calculate a vector", val.id);
|
||||
if (val.argindex && val.argindex > ifix->size_vector)
|
||||
error->all(FLERR, "Fix vector fix {} vector is accessed out-of-range", val.id);
|
||||
if (nevery % ifix->global_freq)
|
||||
error->all(FLERR,"Fix for fix {} vector not computed at compatible time",ids[i]);
|
||||
error->all(FLERR, "Fix for fix {} vector not computed at compatible time", val.id);
|
||||
|
||||
if (argindex[i] == 0) value = ifix->extvector;
|
||||
else value = ifix->extarray;
|
||||
if (val.argindex == 0)
|
||||
value = ifix->extvector;
|
||||
else
|
||||
value = ifix->extarray;
|
||||
val.val.f = ifix;
|
||||
|
||||
} else if (which[i] == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(ids[i]);
|
||||
} else if (val.which == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(val.id.c_str());
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Variable name {} for fix vector does not exist",ids[i]);
|
||||
if (argindex[i] == 0 && input->variable->equalstyle(ivariable) == 0)
|
||||
error->all(FLERR,"Fix vector variable {} is not equal-style variable",ids[i]);
|
||||
if (argindex[i] && input->variable->vectorstyle(ivariable) == 0)
|
||||
error->all(FLERR,"Fix vector variable {} is not vector-style variable",ids[i]);
|
||||
error->all(FLERR, "Variable name {} for fix vector does not exist", val.id);
|
||||
if (val.argindex == 0 && input->variable->equalstyle(ivariable) == 0)
|
||||
error->all(FLERR, "Fix vector variable {} is not equal-style variable", val.id);
|
||||
if (val.argindex && input->variable->vectorstyle(ivariable) == 0)
|
||||
error->all(FLERR, "Fix vector variable {} is not vector-style variable", val.id);
|
||||
value = 0;
|
||||
val.val.v = ivariable;
|
||||
}
|
||||
|
||||
if (i == 0) finalvalue = value;
|
||||
else if (value != finalvalue)
|
||||
error->all(FLERR,"Fix vector cannot set output array intensive/extensive from these inputs");
|
||||
if (first) {
|
||||
finalvalue = value;
|
||||
first = false;
|
||||
} else if (value != finalvalue)
|
||||
error->all(FLERR, "Fix vector cannot set output array intensive/extensive from these inputs");
|
||||
}
|
||||
|
||||
if (nvalues == 1) {
|
||||
if (values.size() == 1) {
|
||||
vector_flag = 1;
|
||||
extvector = finalvalue;
|
||||
} else {
|
||||
array_flag = 1;
|
||||
size_array_cols = nvalues;
|
||||
size_array_cols = values.size();
|
||||
extarray = finalvalue;
|
||||
}
|
||||
|
||||
@ -132,15 +135,17 @@ FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
vector = nullptr;
|
||||
array = nullptr;
|
||||
ncount = ncountmax = 0;
|
||||
if (nvalues == 1) size_vector = 0;
|
||||
else size_array_rows = 0;
|
||||
if (values.size() == 1)
|
||||
size_vector = 0;
|
||||
else
|
||||
size_array_rows = 0;
|
||||
|
||||
// nextstep = next step on which end_of_step does something
|
||||
// add nextstep to all computes that store invocation times
|
||||
// since don't know a priori which are invoked by this fix
|
||||
// once in end_of_step() can set timestep for ones actually invoked
|
||||
|
||||
nextstep = (update->ntimestep/nevery)*nevery;
|
||||
nextstep = (update->ntimestep / nevery) * nevery;
|
||||
if (nextstep < update->ntimestep) nextstep += nevery;
|
||||
modify->addstep_compute_all(nextstep);
|
||||
|
||||
@ -153,12 +158,7 @@ FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
FixVector::~FixVector()
|
||||
{
|
||||
delete [] which;
|
||||
delete [] argindex;
|
||||
delete [] value2index;
|
||||
for (int i = 0; i < nvalues; i++) delete [] ids[i];
|
||||
delete [] ids;
|
||||
|
||||
values.clear();
|
||||
memory->destroy(vector);
|
||||
memory->destroy(array);
|
||||
}
|
||||
@ -178,22 +178,19 @@ void FixVector::init()
|
||||
{
|
||||
// set current indices for all computes,fixes,variables
|
||||
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
if (which[i] == ArgInfo::COMPUTE) {
|
||||
int icompute = modify->find_compute(ids[i]);
|
||||
if (icompute < 0) error->all(FLERR,"Compute ID {} for fix vector does not exist",id[i]);
|
||||
value2index[i] = icompute;
|
||||
for (auto &val : values) {
|
||||
if (val.which == ArgInfo::COMPUTE) {
|
||||
val.val.c = modify->get_compute_by_id(val.id);
|
||||
if (!val.val.c) error->all(FLERR, "Compute ID {} for fix vector does not exist", val.id);
|
||||
|
||||
} else if (which[i] == ArgInfo::FIX) {
|
||||
int ifix = modify->find_fix(ids[i]);
|
||||
if (ifix < 0) error->all(FLERR,"Fix ID {} for fix vector does not exist",id[i]);
|
||||
value2index[i] = ifix;
|
||||
} else if (val.which == ArgInfo::FIX) {
|
||||
val.val.f = modify->get_fix_by_id(val.id);
|
||||
if (!val.val.f) error->all(FLERR, "Fix ID {} for fix vector does not exist", val.id);
|
||||
|
||||
} else if (which[i] == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(ids[i]);
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Variable name for fix vector does not exist");
|
||||
value2index[i] = ivariable;
|
||||
} else if (val.which == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(val.id.c_str());
|
||||
if (ivariable < 0) error->all(FLERR, "Variable name for fix vector does not exist");
|
||||
val.val.v = ivariable;
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,11 +198,13 @@ void FixVector::init()
|
||||
// use endstep to allow for subsequent runs with "pre no"
|
||||
// nsize = # of entries from initialstep to finalstep
|
||||
|
||||
bigint finalstep = update->endstep/nevery * nevery;
|
||||
bigint finalstep = update->endstep / nevery * nevery;
|
||||
if (finalstep > update->endstep) finalstep -= nevery;
|
||||
ncountmax = (finalstep-initialstep)/nevery + 1;
|
||||
if (nvalues == 1) memory->grow(vector,ncountmax,"vector:vector");
|
||||
else memory->grow(array,ncountmax,nvalues,"vector:array");
|
||||
ncountmax = (finalstep - initialstep) / nevery + 1;
|
||||
if (values.size() == 1)
|
||||
memory->grow(vector, ncountmax, "vector:vector");
|
||||
else
|
||||
memory->grow(array, ncountmax, values.size(), "vector:array");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -224,61 +223,64 @@ void FixVector::end_of_step()
|
||||
// skip if not step which requires doing something
|
||||
|
||||
if (update->ntimestep != nextstep) return;
|
||||
if (ncount == ncountmax)
|
||||
error->all(FLERR,"Overflow of allocated fix vector storage");
|
||||
if (ncount == ncountmax) error->all(FLERR, "Overflow of allocated fix vector storage");
|
||||
|
||||
// accumulate results of computes,fixes,variables to local copy
|
||||
// compute/fix/variable may invoke computes so wrap with clear/add
|
||||
|
||||
double *result;
|
||||
if (nvalues == 1) result = &vector[ncount];
|
||||
else result = array[ncount];
|
||||
if (values.size() == 1)
|
||||
result = &vector[ncount];
|
||||
else
|
||||
result = array[ncount];
|
||||
|
||||
modify->clearstep_compute();
|
||||
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
int m = value2index[i];
|
||||
int i = 0;
|
||||
for (auto &val : values) {
|
||||
|
||||
// invoke compute if not previously invoked
|
||||
|
||||
if (which[i] == ArgInfo::COMPUTE) {
|
||||
auto compute = modify->get_compute_by_index(m);
|
||||
if (val.which == ArgInfo::COMPUTE) {
|
||||
|
||||
if (argindex[i] == 0) {
|
||||
if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||
compute->compute_scalar();
|
||||
compute->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||
if (val.argindex == 0) {
|
||||
if (!(val.val.c->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||
val.val.c->compute_scalar();
|
||||
val.val.c->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||
}
|
||||
result[i] = compute->scalar;
|
||||
result[i] = val.val.c->scalar;
|
||||
} else {
|
||||
if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
compute->compute_vector();
|
||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
if (!(val.val.c->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
val.val.c->compute_vector();
|
||||
val.val.c->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
}
|
||||
result[i] = compute->vector[argindex[i]-1];
|
||||
result[i] = val.val.c->vector[val.argindex - 1];
|
||||
}
|
||||
|
||||
// access fix fields, guaranteed to be ready
|
||||
// access fix fields, guaranteed to be ready
|
||||
|
||||
} else if (which[i] == ArgInfo::FIX) {
|
||||
if (argindex[i] == 0)
|
||||
result[i] = modify->get_fix_by_index(m)->compute_scalar();
|
||||
} else if (val.which == ArgInfo::FIX) {
|
||||
if (val.argindex == 0)
|
||||
result[i] = val.val.f->compute_scalar();
|
||||
else
|
||||
result[i] = modify->get_fix_by_index(m)->compute_vector(argindex[i]-1);
|
||||
result[i] = val.val.f->compute_vector(val.argindex - 1);
|
||||
|
||||
// evaluate equal-style or vector-style variable
|
||||
// evaluate equal-style or vector-style variable
|
||||
|
||||
} else if (which[i] == ArgInfo::VARIABLE) {
|
||||
if (argindex[i] == 0)
|
||||
result[i] = input->variable->compute_equal(m);
|
||||
} else if (val.which == ArgInfo::VARIABLE) {
|
||||
if (val.argindex == 0)
|
||||
result[i] = input->variable->compute_equal(val.val.v);
|
||||
else {
|
||||
double *varvec;
|
||||
int nvec = input->variable->compute_vector(m,&varvec);
|
||||
int index = argindex[i];
|
||||
if (nvec < index) result[i] = 0.0;
|
||||
else result[i] = varvec[index-1];
|
||||
int nvec = input->variable->compute_vector(val.val.v, &varvec);
|
||||
int index = val.argindex;
|
||||
if (nvec < index)
|
||||
result[i] = 0.0;
|
||||
else
|
||||
result[i] = varvec[index - 1];
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// trigger computes on next needed step
|
||||
@ -289,8 +291,10 @@ void FixVector::end_of_step()
|
||||
// update size of vector or array
|
||||
|
||||
ncount++;
|
||||
if (nvalues == 1) size_vector++;
|
||||
else size_array_rows++;
|
||||
if (values.size() == 1)
|
||||
size_vector++;
|
||||
else
|
||||
size_array_rows++;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user