diff --git a/src/fix_vector.cpp b/src/fix_vector.cpp index e916b8e9fe..38169bfcff 100644 --- a/src/fix_vector.cpp +++ b/src/fix_vector.cpp @@ -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++; } /* ---------------------------------------------------------------------- diff --git a/src/fix_vector.h b/src/fix_vector.h index 6d0db294c6..3c2f69b21b 100644 --- a/src/fix_vector.h +++ b/src/fix_vector.h @@ -36,9 +36,17 @@ class FixVector : public Fix { double compute_array(int, int) override; private: - int nvalues; - int *which, *argindex, *value2index; - char **ids; + struct value_t { + int which; + int argindex; + std::string id; + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; bigint nextstep, initialstep; @@ -47,8 +55,6 @@ class FixVector : public Fix { double *vector; double **array; }; - } // namespace LAMMPS_NS - #endif #endif