diff --git a/src/compute_chunk_spread_atom.cpp b/src/compute_chunk_spread_atom.cpp index ce91644c0e..e7237bb2d6 100644 --- a/src/compute_chunk_spread_atom.cpp +++ b/src/compute_chunk_spread_atom.cpp @@ -63,8 +63,7 @@ ComputeChunkSpreadAtom(LAMMPS *lmp, int narg, char **arg) : val.id = argi.get_name(); val.val.c = nullptr; - if ((val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) - || (argi.get_dim() > 1)) + if ((val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi.get_dim() > 1)) error->all(FLERR,"Illegal compute chunk/spread/atom argument: {}", arg[iarg]); values.push_back(val); diff --git a/src/compute_reduce_chunk.cpp b/src/compute_reduce_chunk.cpp index 11604998c8..2f8212bc0a 100644 --- a/src/compute_reduce_chunk.cpp +++ b/src/compute_reduce_chunk.cpp @@ -30,19 +30,17 @@ using namespace LAMMPS_NS; -enum{SUM,MINN,MAXX}; - +enum{ SUM, MINN, MAXX }; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - which(nullptr), argindex(nullptr), value2index(nullptr), idchunk(nullptr), ids(nullptr), - vlocal(nullptr), vglobal(nullptr), alocal(nullptr), aglobal(nullptr), varatom(nullptr) + Compute(lmp, narg, arg), idchunk(nullptr), vlocal(nullptr), vglobal(nullptr), + alocal(nullptr), aglobal(nullptr), varatom(nullptr), cchunk(nullptr), ichunk(nullptr) { - if (narg < 6) error->all(FLERR,"Illegal compute reduce/chunk command"); + if (narg < 6) utils::missing_cmd_args(FLERR,"compute reduce/chunk", error); // ID of compute chunk/atom @@ -54,7 +52,7 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[4],"sum") == 0) mode = SUM; else if (strcmp(arg[4],"min") == 0) mode = MINN; else if (strcmp(arg[4],"max") == 0) mode = MAXX; - else error->all(FLERR,"Illegal compute reduce/chunk command"); + else error->all(FLERR,"Unknown compute reduce/chunk mode: {}", arg[4]); int iarg = 5; @@ -67,30 +65,22 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : if (earg != &arg[iarg]) expand = 1; arg = earg; - // parse values until one isn't recognized - - which = new int[nargnew]; - argindex = new int[nargnew]; - ids = new char*[nargnew]; - value2index = new int[nargnew]; - for (int i=0; i < nargnew; ++i) { - which[i] = argindex[i] = value2index[i] = ArgInfo::UNKNOWN; - ids[i] = nullptr; - } - nvalues = 0; + // parse values until + values.clear(); for (iarg = 0; iarg < nargnew; 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 ((which[nvalues] == ArgInfo::UNKNOWN) || (which[nvalues] == ArgInfo::NONE) - || (argi.get_dim() > 1)) - error->all(FLERR,"Illegal compute reduce/chunk command"); + if ((val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi.get_dim() > 1)) + error->all(FLERR,"Illegal compute reduce/chunk argument: {}", arg[iarg]); - nvalues++; + values.push_back(val); } // if wildcard expansion occurred, free earg memory from expand_args() @@ -102,58 +92,55 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : // error check - 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 compute reduce/chunk does not exist"); - if (!modify->compute[icompute]->peratom_flag) - error->all(FLERR,"Compute reduce/chunk compute does not " - "calculate per-atom values"); - if (argindex[i] == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Compute reduce/chunk compute does not " - "calculate a per-atom vector"); - if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR,"Compute reduce/chunk compute does not " - "calculate a per-atom array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, - "Compute reduce/chunk compute array is accessed out-of-range"); + 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 compute reduce/chunk does not exist", val.id); + if (!val.val.c->peratom_flag) + error->all(FLERR,"Compute reduce/chunk compute {} does not calculate per-atom values", + val.id); + if ((val.argindex == 0) && (val.val.c->size_peratom_cols != 0)) + error->all(FLERR,"Compute reduce/chunk compute {} does not calculate a per-atom vector", + val.id); + if (val.argindex && (val.val.c->size_peratom_cols == 0)) + error->all(FLERR,"Compute reduce/chunk compute {} does not calculate a per-atom array", + val.id); + if (val.argindex && (val.argindex > val.val.c->size_peratom_cols)) + error->all(FLERR, "Compute reduce/chunk compute array {} is accessed out-of-range", val.id); - } else if (which[i] == ArgInfo::FIX) { - auto ifix = modify->get_fix_by_id(ids[i]); - if (!ifix) - error->all(FLERR,"Fix ID {} for compute reduce/chunk does not exist", ids[i]); - if (!ifix->peratom_flag) - error->all(FLERR,"Compute reduce/chunk fix {} does not calculate per-atom values", ids[i]); - if ((argindex[i] == 0) && (ifix->size_peratom_cols != 0)) - error->all(FLERR,"Compute reduce/chunk fix {} does not calculate a per-atom vector", ids[i]); - if (argindex[i] && (ifix->size_peratom_cols == 0)) - error->all(FLERR,"Compute reduce/chunk fix {} does not calculate a per-atom array", ids[i]); - if (argindex[i] && (argindex[i] > ifix->size_peratom_cols)) - error->all(FLERR,"Compute reduce/chunk fix {} array is accessed out-of-range", ids[i]); + } 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 compute reduce/chunk does not exist", val.id); + if (!val.val.f->peratom_flag) + error->all(FLERR,"Compute reduce/chunk fix {} does not calculate per-atom values", val.id); + if ((val.argindex == 0) && (val.val.f->size_peratom_cols != 0)) + error->all(FLERR,"Compute reduce/chunk fix {} does not calculate a per-atom vector", val.id); + if (val.argindex && (val.val.f->size_peratom_cols == 0)) + error->all(FLERR,"Compute reduce/chunk fix {} does not calculate a per-atom array", val.id); + if (val.argindex && (val.argindex > val.val.f->size_peratom_cols)) + error->all(FLERR,"Compute reduce/chunk fix {} array is accessed out-of-range", val.id); - } else if (which[i] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name for compute reduce/chunk does not exist"); - if (input->variable->atomstyle(ivariable) == 0) + } else if (val.which == ArgInfo::VARIABLE) { + val.val.v = input->variable->find(val.id.c_str()); + if (val.val.v < 0) + error->all(FLERR,"Variable name {} for compute reduce/chunk does not exist", val.id); + if (input->variable->atomstyle(val.val.v) == 0) error->all(FLERR,"Compute reduce/chunk variable is not atom-style variable"); } } // this compute produces either a vector or array - if (nvalues == 1) { + if (values.size() == 1) { vector_flag = 1; size_vector_variable = 1; extvector = 0; } else { array_flag = 1; size_array_rows_variable = 1; - size_array_cols = nvalues; + size_array_cols = values.size(); extarray = 0; } @@ -175,13 +162,7 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : ComputeReduceChunk::~ComputeReduceChunk() { - delete [] idchunk; - - delete [] which; - delete [] argindex; - for (int m = 0; m < nvalues; m++) delete [] ids[m]; - delete [] ids; - delete [] value2index; + delete[] idchunk; memory->destroy(vlocal); memory->destroy(vglobal); @@ -199,24 +180,21 @@ void ComputeReduceChunk::init() // set indices of all computes,fixes,variables - for (int m = 0; m < nvalues; m++) { - if (which[m] == ArgInfo::COMPUTE) { - int icompute = modify->find_compute(ids[m]); - if (icompute < 0) - error->all(FLERR,"Compute ID for compute reduce/chunk does not exist"); - value2index[m] = 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 compute reduce/chunk does not exist", val.id); - } else if (which[m] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[m]); - if (ifix < 0) - error->all(FLERR,"Fix ID for compute reduce/chunk does not exist"); - value2index[m] = 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 compute reduce/chunk does not exist", val.id); - } else if (which[m] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[m]); - if (ivariable < 0) - error->all(FLERR,"Variable name for compute reduce/chunk does not exist"); - value2index[m] = ivariable; + } else if (val.which == ArgInfo::VARIABLE) { + val.val.v = input->variable->find(val.id.c_str()); + if (val.val.v < 0) + error->all(FLERR,"Variable name {} for compute reduce/chunk does not exist", val.id); } } } @@ -225,13 +203,10 @@ void ComputeReduceChunk::init() void ComputeReduceChunk::init_chunk() { - int icompute = modify->find_compute(idchunk); - if (icompute < 0) - error->all(FLERR,"Chunk/atom compute does not exist for " - "compute reduce/chunk"); - cchunk = dynamic_cast(modify->compute[icompute]); - if (strcmp(cchunk->style,"chunk/atom") != 0) - error->all(FLERR,"Compute reduce/chunk does not use chunk/atom compute"); + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (!cchunk) + error->all(FLERR,"Compute chunk/atom {} does not exist or is incorrect style for " + "compute reduce/chunk", idchunk); } /* ---------------------------------------------------------------------- */ @@ -295,26 +270,23 @@ void ComputeReduceChunk::compute_array() memory->destroy(alocal); memory->destroy(aglobal); maxchunk = nchunk; - memory->create(alocal,maxchunk,nvalues,"reduce/chunk:alocal"); - memory->create(aglobal,maxchunk,nvalues,"reduce/chunk:aglobal"); + memory->create(alocal,maxchunk,values.size(),"reduce/chunk:alocal"); + memory->create(aglobal,maxchunk,values.size(),"reduce/chunk:aglobal"); array = aglobal; } // perform local reduction of all peratom values - for (int m = 0; m < nvalues; m++) compute_one(m,&alocal[0][m],nvalues); + for (std::size_t m = 0; m < values.size(); m++) compute_one(m,&alocal[0][m],values.size()); // reduce the per-chunk values across all procs if (mode == SUM) - MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*nvalues, - MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*values.size(),MPI_DOUBLE,MPI_SUM,world); else if (mode == MINN) - MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*nvalues, - MPI_DOUBLE,MPI_MIN,world); + MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*values.size(),MPI_DOUBLE,MPI_MIN,world); else if (mode == MAXX) - MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*nvalues, - MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*values.size(),MPI_DOUBLE,MPI_MAX,world); } /* ---------------------------------------------------------------------- */ @@ -323,7 +295,7 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) { // initialize per-chunk values in accumulation vector - for (int i = 0; i < nvalues*nchunk; i += nstride) vchunk[i] = initvalue; + for (std::size_t i = 0; i < values.size()*nchunk; i += nstride) vchunk[i] = initvalue; // loop over my atoms // use peratom input and chunk ID of each atom to update vector @@ -331,27 +303,22 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) int *mask = atom->mask; int nlocal = atom->nlocal; + auto &val = values[m]; int index = -1; - int vidx = value2index[m]; // initialization in case it has not yet been run, e.g. when // the compute was invoked right after it has been created - if (vidx == ArgInfo::UNKNOWN) { - init(); - vidx = value2index[m]; - } + if (val.val.c == nullptr) init(); - if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[vidx]; - - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + if (val.which == ArgInfo::COMPUTE) { + if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + val.val.c->compute_peratom(); + val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } - if (argindex[m] == 0) { - double *vcompute = compute->vector_atom; + if (val.argindex == 0) { + double *vcompute = val.val.c->vector_atom; for (int i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; index = ichunk[i]-1; @@ -359,8 +326,8 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) combine(vchunk[index*nstride],vcompute[i]); } } else { - double **acompute = compute->array_atom; - int argindexm1 = argindex[m] - 1; + double **acompute = val.val.c->array_atom; + int argindexm1 = val.argindex - 1; for (int i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; index = ichunk[i]-1; @@ -371,13 +338,12 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) // access fix fields, check if fix frequency is a match - } else if (which[m] == ArgInfo::FIX) { - Fix *fix = modify->fix[vidx]; - if (update->ntimestep % fix->peratom_freq) + } else if (val.which == ArgInfo::FIX) { + if (update->ntimestep % val.val.f->peratom_freq) error->all(FLERR,"Fix used in compute reduce/chunk not computed at compatible time"); - if (argindex[m] == 0) { - double *vfix = fix->vector_atom; + if (val.argindex == 0) { + double *vfix = val.val.f->vector_atom; for (int i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; index = ichunk[i]-1; @@ -385,8 +351,8 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) combine(vchunk[index*nstride],vfix[i]); } } else { - double **afix = fix->array_atom; - int argindexm1 = argindex[m] - 1; + double **afix = val.val.f->array_atom; + int argindexm1 = val.argindex - 1; for (int i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; index = ichunk[i]-1; @@ -397,14 +363,14 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) // evaluate atom-style variable - } else if (which[m] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { if (atom->nmax > maxatom) { memory->destroy(varatom); maxatom = atom->nmax; memory->create(varatom,maxatom,"reduce/chunk:varatom"); } - input->variable->compute_atom(vidx,igroup,varatom,1,0); + input->variable->compute_atom(val.val.v,igroup,varatom,1,0); for (int i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; index = ichunk[i]-1; @@ -449,11 +415,8 @@ void ComputeReduceChunk::lock_enable() void ComputeReduceChunk::lock_disable() { - int icompute = modify->find_compute(idchunk); - if (icompute >= 0) { - cchunk = dynamic_cast(modify->compute[icompute]); - cchunk->lockcount--; - } + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (cchunk) cchunk->lockcount--; } /* ---------------------------------------------------------------------- @@ -491,7 +454,7 @@ void ComputeReduceChunk::unlock(Fix *fixptr) double ComputeReduceChunk::memory_usage() { double bytes = (bigint) maxatom * sizeof(double); - if (nvalues == 1) bytes += (double) maxchunk * 2 * sizeof(double); - else bytes += (double) maxchunk * nvalues * 2 * sizeof(double); + if (values.size() == 1) bytes += (double) maxchunk * 2 * sizeof(double); + else bytes += (double) maxchunk * values.size() * 2 * sizeof(double); return bytes; } diff --git a/src/compute_reduce_chunk.h b/src/compute_reduce_chunk.h index 4c83093c6b..543a471705 100644 --- a/src/compute_reduce_chunk.h +++ b/src/compute_reduce_chunk.h @@ -41,12 +41,21 @@ class ComputeReduceChunk : public Compute { double memory_usage() override; private: - int mode, nvalues; - int *which, *argindex, *value2index; - char *idchunk; - 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; - int nchunk; + char *idchunk; + + int mode, nchunk; int maxchunk, maxatom; double initvalue; double *vlocal, *vglobal; @@ -60,8 +69,6 @@ class ComputeReduceChunk : public Compute { void compute_one(int, double *, int); void combine(double &, double); }; - } // namespace LAMMPS_NS - #endif #endif