From 93841b939eeac542c547fd055e91274295df58d4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 4 Oct 2022 21:24:59 -0400 Subject: [PATCH 01/20] add test for compute chunk/spread/atom and compute global/atom --- unittest/commands/test_compute_chunk.cpp | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/unittest/commands/test_compute_chunk.cpp b/unittest/commands/test_compute_chunk.cpp index 5792ee725d..21018da5e6 100644 --- a/unittest/commands/test_compute_chunk.cpp +++ b/unittest/commands/test_compute_chunk.cpp @@ -314,6 +314,39 @@ TEST_F(ComputeChunkTest, ChunkComputes) EXPECT_NEAR(ctmp[4], -0.06062938, EPSILON); EXPECT_NEAR(ctmp[5], -0.09219489, EPSILON); } + +TEST_F(ComputeChunkTest, ChunkSpreadGlobal) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("pair_style lj/cut/coul/cut 10.0"); + command("pair_coeff * * 0.01 3.0"); + command("bond_style harmonic"); + command("bond_coeff * 100.0 1.5"); + command("compute gyr all gyration/chunk mols"); + command("compute spr all chunk/spread/atom mols c_gyr"); + command("compute glb all global/atom c_mols c_gyr"); + command("variable odd atom ((id+1)%2)+1"); + command("compute odd all global/atom v_odd c_gyr"); + command("fix ave all ave/atom 1 1 1 c_spr c_glb c_odd"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + const int natoms = lammps_get_natoms(lmp); + + auto cgyr = get_vector("gyr"); + auto cspr = get_peratom("spr"); + auto cglb = get_peratom("glb"); + auto codd = get_peratom("odd"); + auto ctag = get_peratom("tags"); + + for (int i = 0; i < natoms; ++i) { + EXPECT_EQ(cspr[i], cgyr[chunkmol[(int)ctag[i]] - 1]); + EXPECT_EQ(cglb[i], cgyr[chunkmol[(int)ctag[i]] - 1]); + EXPECT_EQ(codd[i], cgyr[(((int)ctag[i] + 1) % 2)]); + } +} } // namespace LAMMPS_NS int main(int argc, char **argv) From 874e1522e76f74c861d589b16808da8c4f58a503 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 4 Oct 2022 21:38:28 -0400 Subject: [PATCH 02/20] add test for compute reduce/chunk --- unittest/commands/test_compute_chunk.cpp | 29 ++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/unittest/commands/test_compute_chunk.cpp b/unittest/commands/test_compute_chunk.cpp index 21018da5e6..78cfe014da 100644 --- a/unittest/commands/test_compute_chunk.cpp +++ b/unittest/commands/test_compute_chunk.cpp @@ -246,8 +246,8 @@ TEST_F(ComputeChunkTest, ChunkComputes) command("compute trq all torque/chunk mols"); command("compute vcm all vcm/chunk mols"); command("fix hist1 all ave/time 1 1 1 c_ang[*] c_com[*] c_dip[*] c_gyr c_mom[*] c_omg[*] " - "c_trq[*] c_vcm[*] mode vector file all_chunk.dat format %15.8f"); - command("fix hist2 all ave/time 1 1 1 c_tmp mode vector file vec_chunk.dat format %15.8f"); + "c_trq[*] c_vcm[*] mode vector"); + command("fix hist2 all ave/time 1 1 1 c_tmp mode vector"); command("run 0 post no"); END_HIDE_OUTPUT(); auto cang = get_array("ang"); @@ -347,6 +347,31 @@ TEST_F(ComputeChunkTest, ChunkSpreadGlobal) EXPECT_EQ(codd[i], cgyr[(((int)ctag[i] + 1) % 2)]); } } + +TEST_F(ComputeChunkTest, ChunkReduce) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("pair_style lj/cut/coul/cut 10.0"); + command("pair_coeff * * 0.01 3.0"); + command("bond_style harmonic"); + command("bond_coeff * 100.0 1.5"); + command("compute prp all property/chunk mols count"); + command("variable one atom 1"); + command("compute red all reduce/chunk mols sum v_one"); + command("fix ave all ave/time 1 1 1 c_prp c_red mode vector"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + const int nchunks = get_scalar("mols"); + + auto cprp = get_vector("prp"); + auto cred = get_vector("red"); + + for (int i = 0; i < nchunks; ++i) + EXPECT_EQ(cprp[i], cred[i]); +} } // namespace LAMMPS_NS int main(int argc, char **argv) From 2bc0825e4aa16f9ec5ebeb2d6740d7a5d0d9b90b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 5 Oct 2022 06:33:08 -0400 Subject: [PATCH 03/20] refactor compute global/atom to use array of struct --- src/compute_chunk_spread_atom.cpp | 2 +- src/compute_global_atom.cpp | 406 ++++++++++++-------------- src/compute_global_atom.h | 18 +- unittest/formats/test_atom_styles.cpp | 1 - 4 files changed, 203 insertions(+), 224 deletions(-) diff --git a/src/compute_chunk_spread_atom.cpp b/src/compute_chunk_spread_atom.cpp index c34da3e2c0..ce91644c0e 100644 --- a/src/compute_chunk_spread_atom.cpp +++ b/src/compute_chunk_spread_atom.cpp @@ -153,7 +153,7 @@ void ComputeChunkSpreadAtom::init() { init_chunk(); - // set indices of all computes,fixes,variables + // store references of all computes and fixes for (auto &val : values) { if (val.which == ArgInfo::COMPUTE) { diff --git a/src/compute_global_atom.cpp b/src/compute_global_atom.cpp index b72f5a28f6..de7f744149 100644 --- a/src/compute_global_atom.cpp +++ b/src/compute_global_atom.cpp @@ -26,19 +26,12 @@ using namespace LAMMPS_NS; -enum{VECTOR,ARRAY}; - - -#define BIG 1.0e20 - /* ---------------------------------------------------------------------- */ ComputeGlobalAtom::ComputeGlobalAtom(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - idref(nullptr), which(nullptr), argindex(nullptr), value2index(nullptr), ids(nullptr), - indices(nullptr), varatom(nullptr), vecglobal(nullptr) + Compute(lmp, narg, arg), indices(nullptr), varatom(nullptr), vecglobal(nullptr) { - if (narg < 5) error->all(FLERR,"Illegal compute global/atom command"); + if (narg < 5) utils::missing_cmd_args(FLERR,"compute global/atom", error); peratom_flag = 1; @@ -47,13 +40,13 @@ ComputeGlobalAtom::ComputeGlobalAtom(LAMMPS *lmp, int narg, char **arg) : int iarg = 3; ArgInfo argi(arg[iarg]); - whichref = argi.get_type(); - indexref = argi.get_index1(); - idref = argi.copy_name(); + reference.which = argi.get_type(); + reference.argindex = argi.get_index1(); + reference.id = argi.get_name(); - if ((whichref == ArgInfo::UNKNOWN) || (whichref == ArgInfo::NONE) + if ((reference.which == ArgInfo::UNKNOWN) || (reference.which == ArgInfo::NONE) || (argi.get_dim() > 1)) - error->all(FLERR,"Illegal compute global/atom command"); + error->all(FLERR,"Illegal compute global/atom index property: {}", arg[iarg]); iarg++; @@ -68,24 +61,21 @@ ComputeGlobalAtom::ComputeGlobalAtom(LAMMPS *lmp, int narg, char **arg) : // parse values until one isn't recognized - which = new int[nargnew]; - argindex = new int[nargnew]; - ids = new char*[nargnew]; - value2index = new int[nargnew]; - nvalues = 0; + values.clear(); for (iarg = 0; iarg < nargnew; iarg++) { ArgInfo argi2(arg[iarg]); - which[nvalues] = argi2.get_type(); - argindex[nvalues] = argi2.get_index1(); - ids[nvalues] = argi2.copy_name(); + value_t val; + val.which = argi2.get_type(); + val.argindex = argi2.get_index1(); + val.id = argi2.get_name(); - if ((which[nvalues] == ArgInfo::UNKNOWN) || (which[nvalues] == ArgInfo::NONE) + if ((val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi2.get_dim() > 1)) - error->all(FLERR,"Illegal compute slice command"); + error->all(FLERR,"Illegal compute global/atom global property: {}", arg[iarg]); - nvalues++; + values.push_back(val); } // if wildcard expansion occurred, free earg memory from expand_args() @@ -95,94 +85,97 @@ ComputeGlobalAtom::ComputeGlobalAtom(LAMMPS *lmp, int narg, char **arg) : memory->sfree(earg); } - // setup and error check both index arg and values + // setup and error check for both, index arg and values - if (whichref == ArgInfo::COMPUTE) { - int icompute = modify->find_compute(idref); - if (icompute < 0) - error->all(FLERR,"Compute ID for compute global/atom does not exist"); + if (reference.which == ArgInfo::COMPUTE) { + reference.val.c = modify->get_compute_by_id(reference.id); + if (!reference.val.c) + error->all(FLERR,"Compute ID {} for compute global/atom index", reference.id); - if (!modify->compute[icompute]->peratom_flag) - error->all(FLERR,"Compute global/atom compute does not " - "calculate a per-atom vector or array"); - if (indexref == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Compute global/atom compute does not " - "calculate a per-atom vector"); - if (indexref && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR,"Compute global/atom compute does not " - "calculate a per-atom array"); - if (indexref && indexref > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, - "Compute global/atom compute array is accessed out-of-range"); + if (!reference.val.c->peratom_flag) + error->all(FLERR,"Compute global/atom compute {} does not calculate a per-atom " + "vector or array", reference.id); + if ((reference.argindex == 0) && (reference.val.c->size_peratom_cols != 0)) + error->all(FLERR,"Compute global/atom compute {} does not calculate a per-atom " + "vector", reference.id); + if (reference.argindex && (reference.val.c->size_peratom_cols == 0)) + error->all(FLERR,"Compute global/atom compute does not calculate a per-atom " + "array", reference.id); + if (reference.argindex && (reference.argindex > reference.val.c->size_peratom_cols)) + error->all(FLERR, "Compute global/atom compute array {} is accessed out-of-range", + reference.id); - } else if (whichref == ArgInfo::FIX) { - auto ifix = modify->get_fix_by_id(idref); - if (!ifix) - error->all(FLERR,"Fix ID {} for compute global/atom does not exist", idref); - if (!ifix->peratom_flag) - error->all(FLERR,"Compute global/atom fix {} does not calculate a per-atom vector or array", idref); - if (indexref == 0 && (ifix->size_peratom_cols != 0)) - error->all(FLERR,"Compute global/atom fix {} does not calculate a per-atom vector", idref); - if (indexref && (ifix->size_peratom_cols == 0)) - error->all(FLERR,"Compute global/atom fix {} does not calculate a per-atom array", idref); - if (indexref && indexref > ifix->size_peratom_cols) - error->all(FLERR, "Compute global/atom fix {} array is accessed out-of-range", idref); + } else if (reference.which == ArgInfo::FIX) { + reference.val.f =modify->get_fix_by_id(reference.id); + if (!reference.val.f) + error->all(FLERR,"Fix ID {} for compute global/atom does not exist", reference.id); + if (!reference.val.f->peratom_flag) + error->all(FLERR,"Compute global/atom fix {} does not calculate a per-atom vector " + "or array", reference.id); + if (reference.argindex == 0 && (reference.val.f->size_peratom_cols != 0)) + error->all(FLERR,"Compute global/atom fix {} does not calculate a per-atom vector", + reference.id); + if (reference.argindex && (reference.val.f->size_peratom_cols == 0)) + error->all(FLERR,"Compute global/atom fix {} does not calculate a per-atom array", + reference.id); + if (reference.argindex && (reference.argindex > reference.val.f->size_peratom_cols)) + error->all(FLERR, "Compute global/atom fix {} array is accessed out-of-range", reference.id); - } else if (whichref == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(idref); - if (ivariable < 0) - error->all(FLERR,"Variable name for compute global/atom does not exist"); - if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Compute global/atom variable is not " - "atom-style variable"); + } else if (reference.which == ArgInfo::VARIABLE) { + reference.val.v = input->variable->find(reference.id.c_str()); + if (reference.val.v < 0) + error->all(FLERR,"Variable name {} for compute global/atom index does not exist", + reference.id); + if (input->variable->atomstyle(reference.val.v) == 0) + error->all(FLERR,"Compute global/atom index variable {} is not atom-style variable", + reference.id); } - 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 global/atom does not exist"); - if (argindex[i] == 0) { - if (!modify->compute[icompute]->vector_flag) - error->all(FLERR,"Compute global/atom compute does not " - "calculate a global vector"); + 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 global/atom does not exist", val.id); + if (val.argindex == 0) { + if (!val.val.c->vector_flag) + error->all(FLERR,"Compute ID {} for global/atom compute does not calculate " + "a global vector", val.id); } else { - if (!modify->compute[icompute]->array_flag) - error->all(FLERR,"Compute global/atom compute does not " - "calculate a global array"); - if (argindex[i] > modify->compute[icompute]->size_array_cols) - error->all(FLERR,"Compute global/atom compute array is " - "accessed out-of-range"); + if (!val.val.c->array_flag) + error->all(FLERR,"Compute ID {} for global/atom compute does not calculate " + "a global array", val.id); + if (val.argindex > val.val.c->size_array_cols) + error->all(FLERR,"Compute global/atom 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 global/atom does not exist"); - if (argindex[i] == 0) { - if (!ifix->vector_flag) - error->all(FLERR,"Compute global/atom fix {} does not calculate a global vector", 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 global/atom does not exist", val.id); + if (val.argindex == 0) { + if (!val.val.f->vector_flag) + error->all(FLERR,"Fix ID {} for compute global/atom compute does not calculate " + "a global vector", val.id); } else { - if (!ifix->array_flag) - error->all(FLERR,"Compute global/atom fix {} does not calculate a global array", ids[i]); - if (argindex[i] > ifix->size_array_cols) - error->all(FLERR,"Compute global/atom fix {} array is accessed out-of-range", ids[i]); + if (!val.val.f->array_flag) + error->all(FLERR,"Fix ID {} for compute global/atom compute does not calculate " + "a global array", val.id); + if (val.argindex > val.val.f->size_array_cols) + error->all(FLERR,"Compute global/atom 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 global/atom does not exist"); - if (input->variable->vectorstyle(ivariable) == 0) - error->all(FLERR,"Compute global/atom variable is not vector-style variable"); + } 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 global/atom does not exist", val.id); + if (input->variable->vectorstyle(val.val.v) == 0) + error->all(FLERR,"Compute global/atom variable {} is not vector-style variable", val.id); } } // this compute produces either a peratom vector or array - if (nvalues == 1) size_peratom_cols = 0; - else size_peratom_cols = nvalues; + if (values.size() == 1) size_peratom_cols = 0; + else size_peratom_cols = values.size(); nmax = maxvector = 0; vector_atom = nullptr; @@ -193,14 +186,6 @@ ComputeGlobalAtom::ComputeGlobalAtom(LAMMPS *lmp, int narg, char **arg) : ComputeGlobalAtom::~ComputeGlobalAtom() { - delete [] idref; - - delete [] which; - delete [] argindex; - for (int m = 0; m < nvalues; m++) delete [] ids[m]; - delete [] ids; - delete [] value2index; - memory->destroy(indices); memory->destroy(varatom); memory->destroy(vecglobal); @@ -212,44 +197,38 @@ ComputeGlobalAtom::~ComputeGlobalAtom() void ComputeGlobalAtom::init() { - // set indices of all computes,fixes,variables + // store references of all computes, fixes, or variables - if (whichref == ArgInfo::COMPUTE) { - int icompute = modify->find_compute(idref); - if (icompute < 0) - error->all(FLERR,"Compute ID for compute global/atom does not exist"); - ref2index = icompute; - } else if (whichref == ArgInfo::FIX) { - int ifix = modify->find_fix(idref); - if (ifix < 0) - error->all(FLERR,"Fix ID for compute global/atom does not exist"); - ref2index = ifix; - } else if (whichref == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(idref); - if (ivariable < 0) - error->all(FLERR,"Variable name for compute global/atom does not exist"); - ref2index = ivariable; + if (reference.which == ArgInfo::COMPUTE) { + reference.val.c = modify->get_compute_by_id(reference.id); + if (!reference.val.c) + error->all(FLERR,"Compute ID {} for compute global/atom index does not exist", reference.id); + } else if (reference.which == ArgInfo::FIX) { + reference.val.f = modify->get_fix_by_id(reference.id); + if (reference.val.f) + error->all(FLERR,"Fix ID {} for compute global/atom index does not exist", reference.id); + } else if (reference.which == ArgInfo::VARIABLE) { + reference.val.v = input->variable->find(reference.id.c_str()); + if (reference.val.v < 0) + error->all(FLERR,"Variable name {} for compute global/atom index does not exist", + reference.id); } - 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 global/atom 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 global/atom 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 global/atom 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 global/atom 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 global/atom " - "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 global/atom does not exist", val.id); } } } @@ -258,8 +237,6 @@ void ComputeGlobalAtom::init() void ComputeGlobalAtom::compute_peratom() { - int i,j; - invoked_peratom = update->ntimestep; // grow indices and output vector or array if necessary @@ -268,16 +245,16 @@ void ComputeGlobalAtom::compute_peratom() nmax = atom->nmax; memory->destroy(indices); memory->create(indices,nmax,"global/atom:indices"); - if (whichref == ArgInfo::VARIABLE) { + if (reference.which == ArgInfo::VARIABLE) { memory->destroy(varatom); memory->create(varatom,nmax,"global/atom:varatom"); } - if (nvalues == 1) { + if (values.size() == 1) { memory->destroy(vector_atom); memory->create(vector_atom,nmax,"global/atom:vector_atom"); } else { memory->destroy(array_atom); - memory->create(array_atom,nmax,nvalues,"global/atom:array_atom"); + memory->create(array_atom,nmax,values.size(),"global/atom:array_atom"); } } @@ -286,81 +263,79 @@ void ComputeGlobalAtom::compute_peratom() // indices are decremented from 1 to N -> 0 to N-1 int *mask = atom->mask; - int nlocal = atom->nlocal; + const int nlocal = atom->nlocal; - if (whichref == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[ref2index]; + if (reference.which == ArgInfo::COMPUTE) { - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + if (!(reference.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + reference.val.c->compute_peratom(); + reference.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } - if (indexref == 0) { - double *compute_vector = compute->vector_atom; - for (i = 0; i < nlocal; i++) + if (reference.argindex == 0) { + double *compute_vector = reference.val.c->vector_atom; + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) indices[i] = static_cast (compute_vector[i]) - 1; } else { - double **compute_array = compute->array_atom; - int im1 = indexref - 1; - for (i = 0; i < nlocal; i++) + double **compute_array = reference.val.c->array_atom; + int im1 = reference.argindex - 1; + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) indices[i] = static_cast (compute_array[i][im1]) - 1; } - } else if (whichref == ArgInfo::FIX) { - if (update->ntimestep % modify->fix[ref2index]->peratom_freq) - error->all(FLERR,"Fix used in compute global/atom not " - "computed at compatible time"); - Fix *fix = modify->fix[ref2index]; + } else if (reference.which == ArgInfo::FIX) { + if (update->ntimestep % reference.val.f->peratom_freq) + error->all(FLERR,"Fix {} used in compute global/atom not computed at compatible time", + reference.id); - if (indexref == 0) { - double *fix_vector = fix->vector_atom; - for (i = 0; i < nlocal; i++) + if (reference.argindex == 0) { + double *fix_vector = reference.val.f->vector_atom; + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) indices[i] = static_cast (fix_vector[i]) - 1; } else { - double **fix_array = fix->array_atom; - int im1 = indexref - 1; - for (i = 0; i < nlocal; i++) + double **fix_array = reference.val.f->array_atom; + int im1 = reference.argindex - 1; + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) indices[i] = static_cast (fix_array[i][im1]) - 1; } - } else if (whichref == ArgInfo::VARIABLE) { - input->variable->compute_atom(ref2index,igroup,varatom,1,0); - for (i = 0; i < nlocal; i++) + } else if (reference.which == ArgInfo::VARIABLE) { + input->variable->compute_atom(reference.val.v, igroup, varatom, 1, 0); + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) indices[i] = static_cast (varatom[i]) - 1; } // loop over values to fill output vector or array - for (int m = 0; m < nvalues; m++) { + int m = 0; + for (auto &val : values) { // output = vector - if (argindex[m] == 0) { + if (val.argindex == 0) { int vmax; double *source; - if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[value2index[m]]; + if (val.which == ArgInfo::COMPUTE) { - 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; } - source = compute->vector; - vmax = compute->size_vector; + source = val.val.c->vector; + vmax = val.val.c->size_vector; - } else if (which[m] == ArgInfo::FIX) { - if (update->ntimestep % modify->fix[value2index[m]]->peratom_freq) - error->all(FLERR,"Fix used in compute global/atom not computed at compatible time"); - Fix *fix = modify->fix[value2index[m]]; - vmax = fix->size_vector; + } else if (val.which == ArgInfo::FIX) { + if (update->ntimestep % val.val.f->peratom_freq) + error->all(FLERR,"Fix {} used in compute global/atom not computed at compatible time", + val.id); + vmax = reference.val.f->size_vector; if (vmax > maxvector) { maxvector = vmax; @@ -368,28 +343,28 @@ void ComputeGlobalAtom::compute_peratom() memory->create(vecglobal,maxvector,"global/atom:vecglobal"); } - for (i = 0; i < vmax; i++) - vecglobal[i] = fix->compute_vector(i); + for (int i = 0; i < vmax; i++) + vecglobal[i] = val.val.f->compute_vector(i); source = vecglobal; - } else if (which[m] == ArgInfo::VARIABLE) { - vmax = input->variable->compute_vector(value2index[m],&source); + } else if (val.which == ArgInfo::VARIABLE) { + vmax = input->variable->compute_vector(val.val.v, &source); } - if (nvalues == 1) { - for (i = 0; i < nlocal; i++) { + if (values.size() == 1) { + for (int i = 0; i < nlocal; i++) { vector_atom[i] = 0.0; if (mask[i] & groupbit) { - j = indices[i]; + int j = indices[i]; if (j >= 0 && j < vmax) vector_atom[i] = source[j]; } } } else { - for (i = 0; i < nlocal; i++) { + for (int i = 0; i < nlocal; i++) { array_atom[i][m] = 0.0; if (mask[i] & groupbit) { - j = indices[i]; + int j = indices[i]; if (j >= 0 && j < vmax) array_atom[i][m] = source[j]; } } @@ -400,18 +375,17 @@ void ComputeGlobalAtom::compute_peratom() } else { int vmax; double *source; - int col = argindex[m] - 1; + int col = val.argindex - 1; - if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[value2index[m]]; + if (val.which == ArgInfo::COMPUTE) { - if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { - compute->compute_array(); - compute->invoked_flag |= Compute::INVOKED_ARRAY; + if (!(val.val.c->invoked_flag & Compute::INVOKED_ARRAY)) { + val.val.c->compute_array(); + val.val.c->invoked_flag |= Compute::INVOKED_ARRAY; } - double **compute_array = compute->array; - vmax = compute->size_array_rows; + double **compute_array = val.val.c->array; + vmax = val.val.c->size_array_rows; if (vmax > maxvector) { maxvector = vmax; @@ -419,17 +393,16 @@ void ComputeGlobalAtom::compute_peratom() memory->create(vecglobal,maxvector,"global/atom:vecglobal"); } - for (i = 0; i < vmax; i++) + for (int i = 0; i < vmax; i++) vecglobal[i] = compute_array[i][col]; source = vecglobal; - } else if (which[m] == ArgInfo::FIX) { - if (update->ntimestep % modify->fix[value2index[m]]->peratom_freq) - error->all(FLERR,"Fix used in compute global/atom not " - "computed at compatible time"); - Fix *fix = modify->fix[value2index[m]]; - vmax = fix->size_array_rows; + } else if (val.which == ArgInfo::FIX) { + if (update->ntimestep % val.val.f->peratom_freq) + error->all(FLERR,"Fix {} used in compute global/atom not computed at compatible time", + val.id); + vmax = val.val.f->size_array_rows; if (vmax > maxvector) { maxvector = vmax; @@ -437,34 +410,35 @@ void ComputeGlobalAtom::compute_peratom() memory->create(vecglobal,maxvector,"global/atom:vecglobal"); } - for (i = 0; i < vmax; i++) - vecglobal[i] = fix->compute_array(i,col); + for (int i = 0; i < vmax; i++) + vecglobal[i] = val.val.f->compute_array(i,col); source = vecglobal; - } else if (which[m] == ArgInfo::VARIABLE) { - vmax = input->variable->compute_vector(value2index[m],&source); + } else if (val.which == ArgInfo::VARIABLE) { + vmax = input->variable->compute_vector(val.val.v, &source); } - if (nvalues == 1) { - for (i = 0; i < nlocal; i++) { + if (values.size() == 1) { + for (int i = 0; i < nlocal; i++) { vector_atom[i] = 0.0; if (mask[i] & groupbit) { - j = indices[i]; + int j = indices[i]; if (j >= 0 && j < vmax) vector_atom[i] = source[j]; } } } else { - for (i = 0; i < nlocal; i++) { + for (int i = 0; i < nlocal; i++) { array_atom[i][m] = 0.0; if (mask[i] & groupbit) { - j = indices[i]; + int j = indices[i]; if (j >= 0 && j < vmax) array_atom[i][m] = source[j]; } } } } } + ++m; } /* ---------------------------------------------------------------------- @@ -473,7 +447,7 @@ void ComputeGlobalAtom::compute_peratom() double ComputeGlobalAtom::memory_usage() { - double bytes = (double)nmax*nvalues * sizeof(double); + double bytes = (double)nmax*values.size() * sizeof(double); bytes += (double)nmax * sizeof(int); // indices if (varatom) bytes += (double)nmax * sizeof(double); // varatom bytes += (double)maxvector * sizeof(double); // vecglobal diff --git a/src/compute_global_atom.h b/src/compute_global_atom.h index 67b499dc3c..ee1c5fc5f1 100644 --- a/src/compute_global_atom.h +++ b/src/compute_global_atom.h @@ -33,12 +33,18 @@ class ComputeGlobalAtom : public Compute { double memory_usage() override; protected: - int whichref, indexref, ref2index; - char *idref; - - 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; + value_t reference; int nmax, maxvector; int *indices; diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index 4b726bb030..d3fbe9c286 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -648,7 +648,6 @@ TEST_F(AtomStyleTest, atomic) END_HIDE_OUTPUT(); ASSERT_EQ(lmp->atom->map_tag_max, 16); x = lmp->atom->x; - tag = lmp->atom->tag; EXPECT_NEAR(x[GETIDX(1)][0], -2.0, EPSILON); EXPECT_NEAR(x[GETIDX(1)][1], 2.0, EPSILON); EXPECT_NEAR(x[GETIDX(1)][2], 0.1, EPSILON); From cf4e133a2c1838065ee5ea83e5d9d88c76fa431e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 5 Oct 2022 14:03:35 -0400 Subject: [PATCH 04/20] refactor compute reduce/chunk --- src/compute_chunk_spread_atom.cpp | 3 +- src/compute_reduce_chunk.cpp | 231 +++++++++++++----------------- src/compute_reduce_chunk.h | 21 ++- 3 files changed, 112 insertions(+), 143 deletions(-) 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 From 0124cc4194eab79549d7bf79ca6b099ed5a98f91 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 6 Oct 2022 19:21:07 -0400 Subject: [PATCH 05/20] fix bug in thermo_modify format column check --- src/thermo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thermo.cpp b/src/thermo.cpp index 518deab618..df07e7c87b 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -691,7 +691,7 @@ void Thermo::modify_params(int narg, char **arg) icol = -1; } } - if (icol < 0 || icol >= nfield_initial + 1) + if ((icol < 0) || (icol >= nfield_initial)) error->all(FLERR, "Invalid thermo_modify format argument: {}", arg[iarg + 1]); format_column_user[icol] = arg[iarg + 2]; } From 0fc84753830f281373d1bc970e6410e4ea9358b3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 6 Oct 2022 22:10:56 -0400 Subject: [PATCH 06/20] refactor compute reduce and compute reduce/region --- src/compute_reduce.cpp | 395 ++++++++++++++++------------------ src/compute_reduce.h | 22 +- src/compute_reduce_chunk.cpp | 2 +- src/compute_reduce_region.cpp | 151 +++++++------ 4 files changed, 274 insertions(+), 296 deletions(-) diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp index c8426673ab..41a1831dc8 100644 --- a/src/compute_reduce.cpp +++ b/src/compute_reduce.cpp @@ -15,6 +15,7 @@ #include "arg_info.h" #include "atom.h" +#include "comm.h" #include "domain.h" #include "error.h" #include "fix.h" @@ -34,16 +35,15 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), nvalues(0), which(nullptr), argindex(nullptr), flavor(nullptr), - value2index(nullptr), ids(nullptr), onevec(nullptr), replace(nullptr), indices(nullptr), + Compute(lmp, narg, arg), nvalues(0), onevec(nullptr), replace(nullptr), indices(nullptr), owner(nullptr), idregion(nullptr), region(nullptr), varatom(nullptr) { int iarg = 0; if (strcmp(style, "reduce") == 0) { - if (narg < 5) error->all(FLERR, "Illegal compute reduce command"); + if (narg < 5) utils::missing_cmd_args(FLERR, "compute reduce", error); iarg = 3; } else if (strcmp(style, "reduce/region") == 0) { - if (narg < 6) error->all(FLERR, "Illegal compute reduce/region command"); + if (narg < 6) utils::missing_cmd_args(FLERR, "compute reduce/region", error); if (!domain->get_region_by_id(arg[3])) error->all(FLERR, "Region {} for compute reduce/region does not exist", arg[3]); idregion = utils::strdup(arg[3]); @@ -67,11 +67,9 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg], "aveabs") == 0) mode = AVEABS; else - error->all(FLERR, "Illegal compute {} operation {}", style, arg[iarg]); + error->all(FLERR, "Unknown compute {} mode: {}", style, arg[iarg]); iarg++; - MPI_Comm_rank(world, &me); - // expand args if any have wildcard character "*" int expand = 0; @@ -81,95 +79,92 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : if (earg != &arg[iarg]) expand = 1; arg = earg; - // parse values until one isn't recognized + // parse values - which = new int[nargnew]; - argindex = new int[nargnew]; - flavor = new int[nargnew]; - ids = new char *[nargnew]; - value2index = new int[nargnew]; - for (int i = 0; i < nargnew; ++i) { - which[i] = argindex[i] = flavor[i] = value2index[i] = ArgInfo::UNKNOWN; - ids[i] = nullptr; - } + values.clear(); nvalues = 0; + for (int iarg = 0; iarg < nargnew; ++iarg) { + value_t val; - iarg = 0; - while (iarg < nargnew) { - ids[nvalues] = nullptr; + val.id = ""; + val.flavor = 0; + val.val.c = nullptr; if (strcmp(arg[iarg], "x") == 0) { - which[nvalues] = ArgInfo::X; - argindex[nvalues++] = 0; + val.which = ArgInfo::X; + val.argindex = 0; } else if (strcmp(arg[iarg], "y") == 0) { - which[nvalues] = ArgInfo::X; - argindex[nvalues++] = 1; + val.which = ArgInfo::X; + val.argindex = 1; } else if (strcmp(arg[iarg], "z") == 0) { - which[nvalues] = ArgInfo::X; - argindex[nvalues++] = 2; + val.which = ArgInfo::X; + val.argindex = 2; } else if (strcmp(arg[iarg], "vx") == 0) { - which[nvalues] = ArgInfo::V; - argindex[nvalues++] = 0; + val.which = ArgInfo::V; + val.argindex = 0; } else if (strcmp(arg[iarg], "vy") == 0) { - which[nvalues] = ArgInfo::V; - argindex[nvalues++] = 1; + val.which = ArgInfo::V; + val.argindex = 1; } else if (strcmp(arg[iarg], "vz") == 0) { - which[nvalues] = ArgInfo::V; - argindex[nvalues++] = 2; + val.which = ArgInfo::V; + val.argindex = 2; } else if (strcmp(arg[iarg], "fx") == 0) { - which[nvalues] = ArgInfo::F; - argindex[nvalues++] = 0; + val.which = ArgInfo::F; + val.argindex = 0; } else if (strcmp(arg[iarg], "fy") == 0) { - which[nvalues] = ArgInfo::F; - argindex[nvalues++] = 1; + val.which = ArgInfo::F; + val.argindex = 1; } else if (strcmp(arg[iarg], "fz") == 0) { - which[nvalues] = ArgInfo::F; - argindex[nvalues++] = 2; + val.which = ArgInfo::F; + val.argindex = 2; } else { ArgInfo argi(arg[iarg]); - which[nvalues] = argi.get_type(); - argindex[nvalues] = argi.get_index1(); - ids[nvalues] = argi.copy_name(); + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); - if ((which[nvalues] == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) - error->all(FLERR, "Illegal compute reduce command"); + if ((val.which == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) + error->all(FLERR, "Illegal compute {} argument: {}", style, arg[iarg]); - if (which[nvalues] == ArgInfo::NONE) break; - nvalues++; + if (val.which == ArgInfo::NONE) break; } - - iarg++; + values.push_back(val); } // optional args + nvalues = values.size(); replace = new int[nvalues]; - for (int i = 0; i < nvalues; i++) replace[i] = -1; + for (int i = 0; i < nvalues; ++i) replace[i] = -1; + std::string mycmd = "compute "; + mycmd += style; - while (iarg < nargnew) { + for (int iarg = nvalues; iarg < nargnew; iarg++) { if (strcmp(arg[iarg], "replace") == 0) { - if (iarg + 3 > narg) error->all(FLERR, "Illegal compute reduce command"); + if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, mycmd + " replace", error); if (mode != MINN && mode != MAXX) - error->all(FLERR, "Compute reduce replace requires min or max mode"); + error->all(FLERR, "Compute {} replace requires min or max mode", style); int col1 = utils::inumeric(FLERR, arg[iarg + 1], false, lmp) - 1; int col2 = utils::inumeric(FLERR, arg[iarg + 2], false, lmp) - 1; - if (col1 < 0 || col1 >= nvalues || col2 < 0 || col2 >= nvalues) - error->all(FLERR, "Illegal compute reduce command"); - if (col1 == col2) error->all(FLERR, "Illegal compute reduce command"); - if (replace[col1] >= 0 || replace[col2] >= 0) - error->all(FLERR, "Invalid replace values in compute reduce"); + if ((col1 < 0) || (col1 >= nvalues)) + error->all(FLERR, "Invalid compute {} replace first column index {}", style, col1); + if ((col2 < 0) || (col2 >= nvalues)) + error->all(FLERR, "Invalid compute {} replace second column index {}", style, col2); + if (col1 == col2) error->all(FLERR, "Compute {} replace columns must be different"); + if ((replace[col1] >= 0) || (replace[col2] >= 0)) + error->all(FLERR, "Compute {} replace column already used for another replacement"); replace[col1] = col2; - iarg += 3; + iarg += 2; } else - error->all(FLERR, "Illegal compute reduce command"); + error->all(FLERR, "Unknown compute {} keyword: {}", style, arg[iarg]); } - // delete replace if not set + // delete replace list if not set int flag = 0; for (int i = 0; i < nvalues; i++) @@ -188,68 +183,67 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : // setup and error check - for (int i = 0; i < nvalues; i++) { - if (which[i] == ArgInfo::X || which[i] == ArgInfo::V || which[i] == ArgInfo::F) - flavor[i] = PERATOM; + for (auto &val : values) { + if (val.which == ArgInfo::X || val.which == ArgInfo::V || val.which == ArgInfo::F) + val.flavor = PERATOM; - else if (which[i] == ArgInfo::COMPUTE) { - int icompute = modify->find_compute(ids[i]); - if (icompute < 0) error->all(FLERR, "Compute ID for compute reduce does not exist"); - if (modify->compute[icompute]->peratom_flag) { - flavor[i] = PERATOM; - if (argindex[i] == 0 && modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR, - "Compute reduce compute does not " - "calculate a per-atom vector"); - if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR, - "Compute reduce compute does not " - "calculate a per-atom array"); - if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, "Compute reduce compute array is accessed out-of-range"); - } else if (modify->compute[icompute]->local_flag) { - flavor[i] = LOCAL; - if (argindex[i] == 0 && modify->compute[icompute]->size_local_cols != 0) - error->all(FLERR, - "Compute reduce compute does not " - "calculate a local vector"); - if (argindex[i] && modify->compute[icompute]->size_local_cols == 0) - error->all(FLERR, - "Compute reduce compute does not " - "calculate a local array"); - if (argindex[i] && argindex[i] > modify->compute[icompute]->size_local_cols) - error->all(FLERR, "Compute reduce compute array is accessed out-of-range"); + else 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 {} does not exist", val.id, style); + if (val.val.c->peratom_flag) { + val.flavor = PERATOM; + if (val.argindex == 0 && val.val.c->size_peratom_cols != 0) + error->all(FLERR, "Compute {} compute {} does not calculate a per-atom vector", style, + val.id); + if (val.argindex && val.val.c->size_peratom_cols == 0) + error->all(FLERR, "Compute {} compute {} does not calculate a per-atom array", style, + val.id); + if (val.argindex && val.argindex > val.val.c->size_peratom_cols) + error->all(FLERR, "Compute {} compute {} array is accessed out-of-range", style, val.id); + } else if (val.val.c->local_flag) { + val.flavor = LOCAL; + if (val.argindex == 0 && val.val.c->size_local_cols != 0) + error->all(FLERR, "Compute {} compute {} does not calculate a local vector", style, + val.id); + if (val.argindex && val.val.c->size_local_cols == 0) + error->all(FLERR, "Compute {} compute {} does not calculate a local array", style, + val.id); + if (val.argindex && val.argindex > val.val.c->size_local_cols) + error->all(FLERR, "Compute {} compute {} array is accessed out-of-range", style, val.id); } else - error->all(FLERR, "Compute reduce compute calculates global values"); + error->all(FLERR, "Compute {} compute {} calculates global values", style, 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 does not exist", ids[i]); - if (ifix->peratom_flag) { - flavor[i] = PERATOM; - if (argindex[i] == 0 && (ifix->size_peratom_cols != 0)) - error->all(FLERR, "Compute reduce fix {} does not calculate a per-atom vector", ids[i]); - if (argindex[i] && (ifix->size_peratom_cols == 0)) - error->all(FLERR, "Compute reduce fix {} does not calculate a per-atom array", ids[i]); - if (argindex[i] && (argindex[i] > ifix->size_peratom_cols)) - error->all(FLERR, "Compute reduce fix {} array is accessed out-of-range", ids[i]); - } else if (ifix->local_flag) { - flavor[i] = LOCAL; - if (argindex[i] == 0 && (ifix->size_local_cols != 0)) - error->all(FLERR, "Compute reduce fix {} does not calculate a local vector", ids[i]); - if (argindex[i] && (ifix->size_local_cols == 0)) - error->all(FLERR, "Compute reduce fix {} does not calculate a local array", ids[i]); - if (argindex[i] && (argindex[i] > ifix->size_local_cols)) - error->all(FLERR, "Compute reduce 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 {} does not exist", val.id, style); + if (val.val.f->peratom_flag) { + val.flavor = PERATOM; + if (val.argindex == 0 && (val.val.f->size_peratom_cols != 0)) + error->all(FLERR, "Compute {} fix {} does not calculate a per-atom vector", style, + val.id); + if (val.argindex && (val.val.f->size_peratom_cols == 0)) + error->all(FLERR, "Compute {} fix {} does not calculate a per-atom array", style, val.id); + if (val.argindex && (val.argindex > val.val.f->size_peratom_cols)) + error->all(FLERR, "Compute {} fix {} array is accessed out-of-range", style, val.id); + } else if (val.val.f->local_flag) { + val.flavor = LOCAL; + if (val.argindex == 0 && (val.val.f->size_local_cols != 0)) + error->all(FLERR, "Compute {} fix {} does not calculate a local vector", style, val.id); + if (val.argindex && (val.val.f->size_local_cols == 0)) + error->all(FLERR, "Compute {} fix {} does not calculate a local array", style, val.id); + if (val.argindex && (val.argindex > val.val.f->size_local_cols)) + error->all(FLERR, "Compute {} fix {} array is accessed out-of-range", style, val.id); } else - error->all(FLERR, "Compute reduce fix {} calculates global values", ids[i]); + error->all(FLERR, "Compute {} fix {} calculates global values", style, 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 does not exist"); - if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR, "Compute reduce variable is not atom-style variable"); - flavor[i] = PERATOM; + } 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 {} does not exist", val.id, style); + if (input->variable->atomstyle(val.val.v) == 0) + error->all(FLERR, "Compute {} variable {} is not atom-style variable", style, val.id); + val.flavor = PERATOM; } } @@ -284,12 +278,6 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : ComputeReduce::~ComputeReduce() { - delete[] which; - delete[] argindex; - delete[] flavor; - for (int m = 0; m < nvalues; m++) delete[] ids[m]; - delete[] ids; - delete[] value2index; delete[] replace; delete[] idregion; @@ -307,24 +295,21 @@ void ComputeReduce::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 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 {} does not exist", val.id, style); - } else if (which[m] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[m]); - if (ifix < 0) error->all(FLERR, "Fix ID for compute reduce 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 {} does not exist", val.id, style); - } else if (which[m] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[m]); - if (ivariable < 0) error->all(FLERR, "Variable name for compute reduce does not exist"); - value2index[m] = ivariable; - - } else - value2index[m] = ArgInfo::UNKNOWN; + } 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 {} does not exist", val.id, style); + } } // set index and check validity of region @@ -383,14 +368,14 @@ void ComputeReduce::compute_vector() for (int m = 0; m < nvalues; m++) if (replace[m] < 0) { pairme.value = onevec[m]; - pairme.proc = me; + pairme.proc = comm->me; MPI_Allreduce(&pairme, &pairall, 1, MPI_DOUBLE_INT, MPI_MINLOC, world); vector[m] = pairall.value; owner[m] = pairall.proc; } for (int m = 0; m < nvalues; m++) if (replace[m] >= 0) { - if (me == owner[replace[m]]) vector[m] = compute_one(m, indices[replace[m]]); + if (comm->me == owner[replace[m]]) vector[m] = compute_one(m, indices[replace[m]]); MPI_Bcast(&vector[m], 1, MPI_DOUBLE, owner[replace[m]], world); } } @@ -404,14 +389,14 @@ void ComputeReduce::compute_vector() for (int m = 0; m < nvalues; m++) if (replace[m] < 0) { pairme.value = onevec[m]; - pairme.proc = me; + pairme.proc = comm->me; MPI_Allreduce(&pairme, &pairall, 1, MPI_DOUBLE_INT, MPI_MAXLOC, world); vector[m] = pairall.value; owner[m] = pairall.proc; } for (int m = 0; m < nvalues; m++) if (replace[m] >= 0) { - if (me == owner[replace[m]]) vector[m] = compute_one(m, indices[replace[m]]); + if (comm->me == owner[replace[m]]) vector[m] = compute_one(m, indices[replace[m]]); MPI_Bcast(&vector[m], 1, MPI_DOUBLE, owner[replace[m]], world); } } @@ -436,24 +421,21 @@ void ComputeReduce::compute_vector() double ComputeReduce::compute_one(int m, int flag) { - int i; - // invoke the appropriate attribute,compute,fix,variable // for flag = -1, compute scalar quantity by scanning over atom properties // only include atoms in group for atom properties and per-atom quantities index = -1; - int vidx = value2index[m]; + auto &val = values[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.which == ArgInfo::COMPUTE) || (val.which == ArgInfo::FIX)) { + if (val.val.c == nullptr) init(); } - int aidx = argindex[m]; + int aidx = val.argindex; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -461,77 +443,76 @@ double ComputeReduce::compute_one(int m, int flag) if (mode == MINN) one = BIG; if (mode == MAXX) one = -BIG; - if (which[m] == ArgInfo::X) { + if (val.which == ArgInfo::X) { double **x = atom->x; if (flag < 0) { - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) combine(one, x[i][aidx], i); } else one = x[flag][aidx]; - } else if (which[m] == ArgInfo::V) { + } else if (val.which == ArgInfo::V) { double **v = atom->v; if (flag < 0) { - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) combine(one, v[i][aidx], i); } else one = v[flag][aidx]; - } else if (which[m] == ArgInfo::F) { + } else if (val.which == ArgInfo::F) { double **f = atom->f; if (flag < 0) { - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) combine(one, f[i][aidx], i); } else one = f[flag][aidx]; // invoke compute if not previously invoked - } else if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[vidx]; + } else if (val.which == ArgInfo::COMPUTE) { - if (flavor[m] == PERATOM) { - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + if (val.flavor == PERATOM) { + if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + val.val.c->compute_peratom(); + val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } if (aidx == 0) { - double *comp_vec = compute->vector_atom; + double *comp_vec = val.val.c->vector_atom; int n = nlocal; if (flag < 0) { - for (i = 0; i < n; i++) + for (int i = 0; i < n; i++) if (mask[i] & groupbit) combine(one, comp_vec[i], i); } else one = comp_vec[flag]; } else { - double **carray_atom = compute->array_atom; + double **carray_atom = val.val.c->array_atom; int n = nlocal; int aidxm1 = aidx - 1; if (flag < 0) { - for (i = 0; i < n; i++) + for (int i = 0; i < n; i++) if (mask[i] & groupbit) combine(one, carray_atom[i][aidxm1], i); } else one = carray_atom[flag][aidxm1]; } - } else if (flavor[m] == LOCAL) { - if (!(compute->invoked_flag & Compute::INVOKED_LOCAL)) { - compute->compute_local(); - compute->invoked_flag |= Compute::INVOKED_LOCAL; + } else if (val.flavor == LOCAL) { + if (!(val.val.c->invoked_flag & Compute::INVOKED_LOCAL)) { + val.val.c->compute_local(); + val.val.c->invoked_flag |= Compute::INVOKED_LOCAL; } if (aidx == 0) { - double *comp_vec = compute->vector_local; - int n = compute->size_local_rows; + double *comp_vec = val.val.c->vector_local; + int n = val.val.c->size_local_rows; if (flag < 0) - for (i = 0; i < n; i++) combine(one, comp_vec[i], i); + for (int i = 0; i < n; i++) combine(one, comp_vec[i], i); else one = comp_vec[flag]; } else { - double **carray_local = compute->array_local; - int n = compute->size_local_rows; + double **carray_local = val.val.c->array_local; + int n = val.val.c->size_local_rows; int aidxm1 = aidx - 1; if (flag < 0) - for (i = 0; i < n; i++) combine(one, carray_local[i][aidxm1], i); + for (int i = 0; i < n; i++) combine(one, carray_local[i][aidxm1], i); else one = carray_local[flag][aidxm1]; } @@ -539,46 +520,43 @@ double ComputeReduce::compute_one(int m, int flag) // access fix fields, check if fix frequency is a match - } else if (which[m] == ArgInfo::FIX) { - if (update->ntimestep % modify->fix[vidx]->peratom_freq) - error->all(FLERR, - "Fix used in compute reduce not " - "computed at compatible time"); - Fix *fix = modify->fix[vidx]; + } else if (val.which == ArgInfo::FIX) { + if (update->ntimestep % val.val.f->peratom_freq) + error->all(FLERR, "Fix {} used in compute {} not computed at compatible time", val.id, style); - if (flavor[m] == PERATOM) { + if (val.flavor == PERATOM) { if (aidx == 0) { - double *fix_vector = fix->vector_atom; + double *fix_vector = val.val.f->vector_atom; int n = nlocal; if (flag < 0) { - for (i = 0; i < n; i++) + for (int i = 0; i < n; i++) if (mask[i] & groupbit) combine(one, fix_vector[i], i); } else one = fix_vector[flag]; } else { - double **fix_array = fix->array_atom; + double **fix_array = val.val.f->array_atom; int aidxm1 = aidx - 1; if (flag < 0) { - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) combine(one, fix_array[i][aidxm1], i); } else one = fix_array[flag][aidxm1]; } - } else if (flavor[m] == LOCAL) { + } else if (val.flavor == LOCAL) { if (aidx == 0) { - double *fix_vector = fix->vector_local; - int n = fix->size_local_rows; + double *fix_vector = val.val.f->vector_local; + int n = val.val.f->size_local_rows; if (flag < 0) - for (i = 0; i < n; i++) combine(one, fix_vector[i], i); + for (int i = 0; i < n; i++) combine(one, fix_vector[i], i); else one = fix_vector[flag]; } else { - double **fix_array = fix->array_local; - int n = fix->size_local_rows; + double **fix_array = val.val.f->array_local; + int n = val.val.f->size_local_rows; int aidxm1 = aidx - 1; if (flag < 0) - for (i = 0; i < n; i++) combine(one, fix_array[i][aidxm1], i); + for (int i = 0; i < n; i++) combine(one, fix_array[i][aidxm1], i); else one = fix_array[flag][aidxm1]; } @@ -586,16 +564,16 @@ double ComputeReduce::compute_one(int m, int flag) // evaluate atom-style variable - } else if (which[m] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { if (atom->nmax > maxatom) { maxatom = atom->nmax; memory->destroy(varatom); memory->create(varatom, maxatom, "reduce:varatom"); } - input->variable->compute_atom(vidx, igroup, varatom, 1, 0); + input->variable->compute_atom(val.val.v, igroup, varatom, 1, 0); if (flag < 0) { - for (i = 0; i < nlocal; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) combine(one, varatom[i], i); } else one = varatom[flag]; @@ -608,31 +586,28 @@ double ComputeReduce::compute_one(int m, int flag) bigint ComputeReduce::count(int m) { - int vidx = value2index[m]; - - if (which[m] == ArgInfo::X || which[m] == ArgInfo::V || which[m] == ArgInfo::F) + auto &val = values[m]; + if ((val.which == ArgInfo::X) || (val.which == ArgInfo::V) || (val.which == ArgInfo::F)) return group->count(igroup); - else if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[vidx]; - if (flavor[m] == PERATOM) { + else if (val.which == ArgInfo::COMPUTE) { + if (val.flavor == PERATOM) { return group->count(igroup); - } else if (flavor[m] == LOCAL) { - bigint ncount = compute->size_local_rows; + } else if (val.flavor == LOCAL) { + bigint ncount = val.val.c->size_local_rows; bigint ncountall; MPI_Allreduce(&ncount, &ncountall, 1, MPI_LMP_BIGINT, MPI_SUM, world); return ncountall; } - } else if (which[m] == ArgInfo::FIX) { - Fix *fix = modify->fix[vidx]; - if (flavor[m] == PERATOM) { + } else if (val.which == ArgInfo::FIX) { + if (val.flavor == PERATOM) { return group->count(igroup); - } else if (flavor[m] == LOCAL) { - bigint ncount = fix->size_local_rows; + } else if (val.flavor == LOCAL) { + bigint ncount = val.val.f->size_local_rows; bigint ncountall; MPI_Allreduce(&ncount, &ncountall, 1, MPI_LMP_BIGINT, MPI_SUM, world); return ncountall; } - } else if (which[m] == ArgInfo::VARIABLE) + } else if (val.which == ArgInfo::VARIABLE) return group->count(igroup); bigint dummy = 0; diff --git a/src/compute_reduce.h b/src/compute_reduce.h index dc4ee1ef2c..bfaa1e2a72 100644 --- a/src/compute_reduce.h +++ b/src/compute_reduce.h @@ -37,30 +37,38 @@ class ComputeReduce : public Compute { double memory_usage() override; protected: - int me; int mode, nvalues; - int *which, *argindex, *flavor, *value2index; - char **ids; + struct value_t { + int which; + int argindex; + std::string id; + int flavor; + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; double *onevec; int *replace, *indices, *owner; + int index; char *idregion; class Region *region; int maxatom; double *varatom; - struct Pair { + struct valpair { double value; int proc; }; - Pair pairme, pairall; + valpair pairme, pairall; virtual double compute_one(int, int); virtual bigint count(int); void combine(double &, double, int); }; - } // namespace LAMMPS_NS - #endif #endif diff --git a/src/compute_reduce_chunk.cpp b/src/compute_reduce_chunk.cpp index 2f8212bc0a..f3bb57d33d 100644 --- a/src/compute_reduce_chunk.cpp +++ b/src/compute_reduce_chunk.cpp @@ -65,7 +65,7 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : if (earg != &arg[iarg]) expand = 1; arg = earg; - // parse values until + // parse values values.clear(); for (iarg = 0; iarg < nargnew; iarg++) { diff --git a/src/compute_reduce_region.cpp b/src/compute_reduce_region.cpp index f8a92c7bf3..81d0f1acf5 100644 --- a/src/compute_reduce_region.cpp +++ b/src/compute_reduce_region.cpp @@ -55,62 +55,58 @@ double ComputeReduceRegion::compute_one(int m, int flag) // only include atoms in group index = -1; + auto &val = values[m]; + + // initialization in case it has not yet been run, e.g. when + // the compute was invoked right after it has been created + if ((val.which == ArgInfo::COMPUTE) || (val.which == ArgInfo::FIX)) { + if (val.val.c == nullptr) init(); + } + + int aidx = val.argindex; double **x = atom->x; int *mask = atom->mask; int nlocal = atom->nlocal; - int n = value2index[m]; - - // initialization in case it has not yet been run, - // e.g. when invoked - if (n == ArgInfo::UNKNOWN) { - init(); - n = value2index[m]; - } - - int j = argindex[m]; - double one = 0.0; if (mode == MINN) one = BIG; if (mode == MAXX) one = -BIG; - if (which[m] == ArgInfo::X) { + if (val.which == ArgInfo::X) { if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) - combine(one, x[i][j], i); + combine(one, x[i][aidx], i); } else - one = x[flag][j]; - } else if (which[m] == ArgInfo::V) { + one = x[flag][aidx]; + } else if (val.which == ArgInfo::V) { double **v = atom->v; if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) - combine(one, v[i][j], i); + combine(one, v[i][aidx], i); } else - one = v[flag][j]; - } else if (which[m] == ArgInfo::F) { + one = v[flag][aidx]; + } else if (val.which == ArgInfo::F) { double **f = atom->f; if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) - combine(one, f[i][j], i); + combine(one, f[i][aidx], i); } else - one = f[flag][j]; + one = f[flag][aidx]; // invoke compute if not previously invoked - } else if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[n]; - - if (flavor[m] == PERATOM) { - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + } else if (val.which == ArgInfo::COMPUTE) { + if (val.flavor == PERATOM) { + if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + val.val.c->compute_peratom(); + val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } - if (j == 0) { - double *compute_vector = compute->vector_atom; + if (aidx == 0) { + double *compute_vector = val.val.c->vector_atom; if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) @@ -118,48 +114,48 @@ double ComputeReduceRegion::compute_one(int m, int flag) } else one = compute_vector[flag]; } else { - double **compute_array = compute->array_atom; - int jm1 = j - 1; + double **compute_array = val.val.c->array_atom; + int aidxm1 = aidx - 1; if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) - combine(one, compute_array[i][jm1], i); + combine(one, compute_array[i][aidxm1], i); } else - one = compute_array[flag][jm1]; + one = compute_array[flag][aidxm1]; } - } else if (flavor[m] == LOCAL) { - if (!(compute->invoked_flag & Compute::INVOKED_LOCAL)) { - compute->compute_local(); - compute->invoked_flag |= Compute::INVOKED_LOCAL; + } else if (val.flavor == LOCAL) { + if (!(val.val.c->invoked_flag & Compute::INVOKED_LOCAL)) { + val.val.c->compute_local(); + val.val.c->invoked_flag |= Compute::INVOKED_LOCAL; } - if (j == 0) { - double *compute_vector = compute->vector_local; + if (aidx == 0) { + double *compute_vector = val.val.c->vector_local; if (flag < 0) - for (int i = 0; i < compute->size_local_rows; i++) combine(one, compute_vector[i], i); + for (int i = 0; i < val.val.c->size_local_rows; i++) combine(one, compute_vector[i], i); else one = compute_vector[flag]; } else { - double **compute_array = compute->array_local; - int jm1 = j - 1; + double **compute_array = val.val.c->array_local; + int aidxm1 = aidx - 1; if (flag < 0) - for (int i = 0; i < compute->size_local_rows; i++) combine(one, compute_array[i][jm1], i); + for (int i = 0; i < val.val.c->size_local_rows; i++) + combine(one, compute_array[i][aidxm1], i); else - one = compute_array[flag][jm1]; + one = compute_array[flag][aidxm1]; } } // check if fix frequency is a match - } else if (which[m] == ArgInfo::FIX) { - if (update->ntimestep % modify->fix[n]->peratom_freq) - error->all(FLERR, "Fix used in compute reduce not computed at compatible time"); - Fix *fix = modify->fix[n]; + } else if (val.which == ArgInfo::FIX) { + if (update->ntimestep % val.val.f->peratom_freq) + error->all(FLERR, "Fix {} used in compute {} not computed at compatible time", val.id, style); - if (flavor[m] == PERATOM) { - if (j == 0) { - double *fix_vector = fix->vector_atom; + if (val.flavor == PERATOM) { + if (aidx == 0) { + double *fix_vector = val.val.f->vector_atom; if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) @@ -167,43 +163,44 @@ double ComputeReduceRegion::compute_one(int m, int flag) } else one = fix_vector[flag]; } else { - double **fix_array = fix->array_atom; - int jm1 = j - 1; + double **fix_array = val.val.f->array_atom; + int aidxm1 = aidx - 1; if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) - combine(one, fix_array[i][jm1], i); + combine(one, fix_array[i][aidxm1], i); } else - one = fix_array[flag][jm1]; + one = fix_array[flag][aidxm1]; } - } else if (flavor[m] == LOCAL) { - if (j == 0) { - double *fix_vector = fix->vector_local; + } else if (val.flavor == LOCAL) { + if (aidx == 0) { + double *fix_vector = val.val.f->vector_local; if (flag < 0) - for (int i = 0; i < fix->size_local_rows; i++) combine(one, fix_vector[i], i); + for (int i = 0; i < val.val.f->size_local_rows; i++) combine(one, fix_vector[i], i); else one = fix_vector[flag]; } else { - double **fix_array = fix->array_local; - int jm1 = j - 1; + double **fix_array = val.val.f->array_local; + int aidxm1 = aidx - 1; if (flag < 0) - for (int i = 0; i < fix->size_local_rows; i++) combine(one, fix_array[i][jm1], i); + for (int i = 0; i < val.val.f->size_local_rows; i++) + combine(one, fix_array[i][aidxm1], i); else - one = fix_array[flag][jm1]; + one = fix_array[flag][aidxm1]; } } // evaluate atom-style variable - } else if (which[m] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { if (atom->nmax > maxatom) { maxatom = atom->nmax; memory->destroy(varatom); memory->create(varatom, maxatom, "reduce/region:varatom"); } - input->variable->compute_atom(n, igroup, varatom, 1, 0); + input->variable->compute_atom(val.val.v, igroup, varatom, 1, 0); if (flag < 0) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) @@ -219,31 +216,29 @@ double ComputeReduceRegion::compute_one(int m, int flag) bigint ComputeReduceRegion::count(int m) { - int n = value2index[m]; + auto &val = values[m]; - if (which[m] == ArgInfo::X || which[m] == ArgInfo::V || which[m] == ArgInfo::F) + if (val.which == ArgInfo::X || val.which == ArgInfo::V || val.which == ArgInfo::F) return group->count(igroup, region); - else if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[n]; - if (flavor[m] == PERATOM) { + else if (val.which == ArgInfo::COMPUTE) { + if (val.flavor == PERATOM) { return group->count(igroup, region); - } else if (flavor[m] == LOCAL) { - bigint ncount = compute->size_local_rows; + } else if (val.flavor == LOCAL) { + bigint ncount = val.val.c->size_local_rows; bigint ncountall; MPI_Allreduce(&ncount, &ncountall, 1, MPI_DOUBLE, MPI_SUM, world); return ncountall; } - } else if (which[m] == ArgInfo::FIX) { - Fix *fix = modify->fix[n]; - if (flavor[m] == PERATOM) { + } else if (val.which == ArgInfo::FIX) { + if (val.flavor == PERATOM) { return group->count(igroup, region); - } else if (flavor[m] == LOCAL) { - bigint ncount = fix->size_local_rows; + } else if (val.flavor == LOCAL) { + bigint ncount = val.val.f->size_local_rows; bigint ncountall; MPI_Allreduce(&ncount, &ncountall, 1, MPI_DOUBLE, MPI_SUM, world); return ncountall; } - } else if (which[m] == ArgInfo::VARIABLE) + } else if (val.which == ArgInfo::VARIABLE) return group->count(igroup, region); bigint dummy = 0; From 68482ffe146f828bab8aa7584d4d9dfc919d90c8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 7 Oct 2022 04:26:51 -0400 Subject: [PATCH 07/20] convert compute slice --- src/compute_slice.cpp | 336 +++++++++++++++++++----------------------- src/compute_slice.h | 16 +- 2 files changed, 164 insertions(+), 188 deletions(-) diff --git a/src/compute_slice.cpp b/src/compute_slice.cpp index f37bff1e17..53f79a3275 100644 --- a/src/compute_slice.cpp +++ b/src/compute_slice.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -27,96 +26,84 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), ids(nullptr) +ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 7) error->all(FLERR,"Illegal compute slice command"); + if (narg < 7) utils::missing_cmd_args(FLERR, "compute slice", error); - MPI_Comm_rank(world,&me); + nstart = utils::inumeric(FLERR, arg[3], false, lmp); + nstop = utils::inumeric(FLERR, arg[4], false, lmp); + nskip = utils::inumeric(FLERR, arg[5], false, lmp); - nstart = utils::inumeric(FLERR,arg[3],false,lmp); - nstop = utils::inumeric(FLERR,arg[4],false,lmp); - nskip = utils::inumeric(FLERR,arg[5],false,lmp); + if (nstart < 1) error->all(FLERR, "Invalid compute slice nstart value {} < 1", nstart); + if (nstop < nstart) error->all(FLERR, "Invalid compute slice nstop value {} < {}", nstop, nstart); + if (nskip < 1) error->all(FLERR, "Invalid compute slice nskip value < 1: {}", nskip); - if (nstart < 1 || nstop < nstart || nskip < 1) - error->all(FLERR,"Illegal compute slice command"); - - // parse remaining values until one isn't recognized - - which = new int[narg-6]; - argindex = new int[narg-6]; - ids = new char*[narg-6]; - value2index = new int[narg-6]; - nvalues = 0; + // parse values + values.clear(); for (int iarg = 6; 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 ((which[nvalues] == ArgInfo::UNKNOWN) || (which[nvalues] == ArgInfo::NONE) - || (argi.get_dim() > 1)) - error->all(FLERR,"Illegal compute slice command"); + if ((val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi.get_dim() > 1)) + error->all(FLERR, "Illegal compute slice argument: {}", arg[iarg]); - nvalues++; + values.push_back(val); } // setup and 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 slice does not exist"); - if (modify->compute[icompute]->vector_flag) { - if (argindex[i]) - error->all(FLERR,"Compute slice compute does not " - "calculate a global array"); - if (nstop > modify->compute[icompute]->size_vector) - error->all(FLERR,"Compute slice compute vector is " - "accessed out-of-range"); - } else if (modify->compute[icompute]->array_flag) { - if (argindex[i] == 0) - error->all(FLERR,"Compute slice compute does not " - "calculate a global vector"); - if (argindex[i] > modify->compute[icompute]->size_array_cols) - error->all(FLERR,"Compute slice compute array is " - "accessed out-of-range"); - if (nstop > modify->compute[icompute]->size_array_rows) - error->all(FLERR,"Compute slice compute array is " - "accessed out-of-range"); - } else error->all(FLERR,"Compute slice compute does not calculate " - "global vector or array"); - - } else if (which[i] == ArgInfo::FIX) { - auto ifix = modify->get_fix_by_id(ids[i]); - if (!ifix) - error->all(FLERR,"Fix ID {} for compute slice does not exist", ids[i]); - if (ifix->vector_flag) { - if (argindex[i]) - error->all(FLERR,"Compute slice fix {} does not calculate a global array", ids[i]); - if (nstop > ifix->size_vector) - error->all(FLERR,"Compute slice fix {} vector is accessed out-of-range", ids[i]); - } else if (ifix->array_flag) { - if (argindex[i] == 0) - error->all(FLERR,"Compute slice fix {} does not calculate a global vector", ids[i]); - if (argindex[i] > ifix->size_array_cols) - error->all(FLERR,"Compute slice fix {} array is accessed out-of-range", ids[i]); - if (nstop > ifix->size_array_rows) - error->all(FLERR,"Compute slice fix {} array is accessed out-of-range", ids[i]); - } else error->all(FLERR,"Compute slice fix {} does not calculate global vector or array", ids[i]); - - } else if (which[i] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name for compute slice does not exist"); - if (argindex[i] == 0 && input->variable->vectorstyle(ivariable) == 0) - error->all(FLERR,"Compute slice variable is not vector-style variable"); - if (argindex[i]) - error->all(FLERR,"Compute slice vector variable cannot be indexed"); + 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 slice does not exist", val.id); + if (val.val.c->vector_flag) { + if (val.argindex) + error->all(FLERR, "Compute slice compute {} does not calculate a global array", val.id); + if (nstop > val.val.c->size_vector) + error->all(FLERR, "Compute slice compute {} vector is accessed out-of-range", val.id); + } else if (val.val.c->array_flag) { + if (val.argindex == 0) + error->all(FLERR, "Compute slice compute {} does not calculate a global vector", val.id); + if (val.argindex > val.val.c->size_array_cols) + error->all(FLERR, "Compute slice compute {} array is accessed out-of-range", val.id); + if (nstop > val.val.c->size_array_rows) + error->all(FLERR, "Compute slice compute {} array is accessed out-of-range", val.id); + } else { + error->all(FLERR, "Compute slice compute {} does not calculate global vector or array", + val.id); + } + } 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 slice does not exist", val.id); + if (val.val.f->vector_flag) { + if (val.argindex) + error->all(FLERR, "Compute slice fix {} does not calculate a global array", val.id); + if (nstop > val.val.f->size_vector) + error->all(FLERR, "Compute slice fix {} vector is accessed out-of-range", val.id); + } else if (val.val.f->array_flag) { + if (val.argindex == 0) + error->all(FLERR, "Compute slice fix {} does not calculate a global vector", val.id); + if (val.argindex > val.val.f->size_array_cols) + error->all(FLERR, "Compute slice fix {} array is accessed out-of-range", val.id); + if (nstop > val.val.f->size_array_rows) + error->all(FLERR, "Compute slice fix {} array is accessed out-of-range", val.id); + } else { + error->all(FLERR, "Compute slice fix {} does not calculate global vector or array", val.id); + } + } 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 slice does not exist", val.id); + if (val.argindex == 0 && input->variable->vectorstyle(val.val.v) == 0) + error->all(FLERR, "Compute slice variable {} is not vector-style variable", val.id); + if (val.argindex) + error->all(FLERR, "Compute slice vector variable {} cannot be indexed", val.id); } } @@ -124,68 +111,65 @@ ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : // for vector, set intensive/extensive to mirror input values // for array, set intensive if all input values are intensive, else extensive - if (nvalues == 1) { + if (values.size() == 1) { + auto &val = values[0]; vector_flag = 1; - size_vector = (nstop-nstart) / nskip; - memory->create(vector,size_vector,"slice:vector"); + size_vector = (nstop - nstart) / nskip; + memory->create(vector, size_vector, "slice:vector"); - if (which[0] == ArgInfo::COMPUTE) { - int icompute = modify->find_compute(ids[0]); - if (argindex[0] == 0) { - extvector = modify->compute[icompute]->extvector; - if (modify->compute[icompute]->extvector == -1) { + if (val.which == ArgInfo::COMPUTE) { + if (val.argindex == 0) { + extvector = val.val.c->extvector; + if (val.val.c->extvector == -1) { extlist = new int[size_vector]; int j = 0; - for (int i = nstart; i < nstop; i += nskip) - extlist[j++] = modify->compute[icompute]->extlist[i-1]; + for (int i = nstart; i < nstop; i += nskip) extlist[j++] = val.val.c->extlist[i - 1]; } - } else extvector = modify->compute[icompute]->extarray; - } else if (which[0] == ArgInfo::FIX) { - auto ifix = modify->get_fix_by_id(ids[0]); - if (argindex[0] == 0) { - extvector = ifix->extvector; - if (ifix->extvector == -1) { + } else + extvector = val.val.c->extarray; + } else if (val.which == ArgInfo::FIX) { + if (val.argindex == 0) { + extvector = val.val.f->extvector; + if (val.val.f->extvector == -1) { extlist = new int[size_vector]; int j = 0; - for (int i = nstart; i < nstop; i += nskip) - extlist[j++] = ifix->extlist[i-1]; + for (int i = nstart; i < nstop; i += nskip) extlist[j++] = val.val.f->extlist[i - 1]; } - } else extvector = ifix->extarray; - } else if (which[0] == ArgInfo::VARIABLE) { + } else + extvector = val.val.f->extarray; + } else if (val.which == ArgInfo::VARIABLE) { extvector = 0; } } else { array_flag = 1; - size_array_rows = (nstop-nstart) / nskip; - size_array_cols = nvalues; - memory->create(array,size_array_rows,size_array_cols,"slice:array"); + size_array_rows = (nstop - nstart) / nskip; + size_array_cols = values.size(); + memory->create(array, size_array_rows, size_array_cols, "slice:array"); extarray = 0; - for (int i = 0; i < nvalues; i++) { - if (which[i] == ArgInfo::COMPUTE) { - int icompute = modify->find_compute(ids[i]); - if (argindex[i] == 0) { - if (modify->compute[icompute]->extvector == 1) extarray = 1; - if (modify->compute[icompute]->extvector == -1) { - for (int j = 0; j < modify->compute[icompute]->size_vector; j++) - if (modify->compute[icompute]->extlist[j]) extarray = 1; + for (auto &val : values) { + if (val.which == ArgInfo::COMPUTE) { + if (val.argindex == 0) { + if (val.val.c->extvector == 1) extarray = 1; + if (val.val.c->extvector == -1) { + for (int j = 0; j < val.val.c->size_vector; j++) + if (val.val.c->extlist[j]) extarray = 1; } } else { - if (modify->compute[icompute]->extarray) extarray = 1; + if (val.val.c->extarray) extarray = 1; } - } else if (which[i] == ArgInfo::FIX) { - auto ifix = modify->get_fix_by_id(ids[i]); - if (argindex[i] == 0) { - if (ifix->extvector == 1) extarray = 1; - if (ifix->extvector == -1) { - for (int j = 0; j < ifix->size_vector; j++) - if (ifix->extlist[j]) extarray = 1; + } else if (val.which == ArgInfo::FIX) { + if (val.argindex == 0) { + if (val.val.f->extvector == 1) extarray = 1; + if (val.val.f->extvector == -1) { + for (int j = 0; j < val.val.f->size_vector; j++) + if (val.val.f->extlist[j]) extarray = 1; } } else { - if (ifix->extarray) extarray = 1; + if (val.val.f->extarray) extarray = 1; } - } else if (which[i] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { // variable is always intensive, does not change extarray } } @@ -196,12 +180,7 @@ ComputeSlice::ComputeSlice(LAMMPS *lmp, int narg, char **arg) : ComputeSlice::~ComputeSlice() { - delete [] which; - delete [] argindex; - for (int m = 0; m < nvalues; m++) delete [] ids[m]; - delete [] ids; - delete [] value2index; - delete [] extlist; + delete[] extlist; memory->destroy(vector); memory->destroy(array); @@ -213,22 +192,17 @@ void ComputeSlice::init() { // set indices and check validity of all computes,fixes - 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 slice does not exist"); - value2index[m] = icompute; - } else if (which[m] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[m]); - if (ifix < 0) - error->all(FLERR,"Fix ID for compute slice does not exist"); - value2index[m] = ifix; - } else if (which[m] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[m]); - if (ivariable < 0) - error->all(FLERR,"Variable name for compute slice does not exist"); - value2index[m] = ivariable; + 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 slice does not exist", val.id); + } 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 slice does not exist", val.id); + } 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 slice does not exist", val.id); } } } @@ -239,7 +213,7 @@ void ComputeSlice::compute_vector() { invoked_vector = update->ntimestep; - extract_one(0,vector,1); + extract_one(0, vector, 1); } /* ---------------------------------------------------------------------- */ @@ -248,8 +222,7 @@ void ComputeSlice::compute_array() { invoked_array = update->ntimestep; - for (int m = 0; m < nvalues; m++) - extract_one(0,&array[m][0],nvalues); + for (int m = 0; m < values.size(); m++) extract_one(0, &array[m][0], values.size()); } /* ---------------------------------------------------------------------- @@ -259,72 +232,67 @@ void ComputeSlice::compute_array() void ComputeSlice::extract_one(int m, double *vec, int stride) { - int i,j; + auto &val = values[m]; // invoke the appropriate compute if needed - if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[value2index[m]]; - - if (argindex[m] == 0) { - if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { - compute->compute_vector(); - compute->invoked_flag |= Compute::INVOKED_VECTOR; + if (val.which == ArgInfo::COMPUTE) { + if (val.argindex == 0) { + if (!(val.val.c->invoked_flag & Compute::INVOKED_VECTOR)) { + val.val.c->compute_vector(); + val.val.c->invoked_flag |= Compute::INVOKED_VECTOR; } - double *cvector = compute->vector; - j = 0; - for (i = nstart; i < nstop; i += nskip) { - vec[j] = cvector[i-1]; + double *cvector = val.val.c->vector; + int j = 0; + for (int i = nstart; i < nstop; i += nskip) { + vec[j] = cvector[i - 1]; j += stride; } } else { - if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { - compute->compute_array(); - compute->invoked_flag |= Compute::INVOKED_ARRAY; + if (!(val.val.c->invoked_flag & Compute::INVOKED_ARRAY)) { + val.val.c->compute_array(); + val.val.c->invoked_flag |= Compute::INVOKED_ARRAY; } - double **carray = compute->array; - int icol = argindex[m]-1; - j = 0; - for (i = nstart; i < nstop; i += nskip) { - vec[j] = carray[i-1][icol]; + double **carray = val.val.c->array; + int icol = val.argindex - 1; + int j = 0; + for (int i = nstart; i < nstop; i += nskip) { + vec[j] = carray[i - 1][icol]; j += stride; } } - // access fix fields, check if fix frequency is a match + // access fix fields, check if fix frequency is a match - } else if (which[m] == ArgInfo::FIX) { - if (update->ntimestep % modify->fix[value2index[m]]->global_freq) - error->all(FLERR,"Fix used in compute slice not " - "computed at compatible time"); - Fix *fix = modify->fix[value2index[m]]; + } else if (val.which == ArgInfo::FIX) { + if (update->ntimestep % val.val.f->global_freq) + error->all(FLERR, "Fix {} used in compute slice not computed at compatible time", val.id); - if (argindex[m] == 0) { - j = 0; - for (i = nstart; i < nstop; i += nskip) { - vec[j] = fix->compute_vector(i-1); + if (val.argindex == 0) { + int j = 0; + for (int i = nstart; i < nstop; i += nskip) { + vec[j] = val.val.f->compute_vector(i - 1); j += stride; } } else { - int icol = argindex[m]-1; - j = 0; - for (i = nstart; i < nstop; i += nskip) { - vec[j] = fix->compute_array(i-1,icol); + int icol = val.argindex - 1; + int j = 0; + for (int i = nstart; i < nstop; i += nskip) { + vec[j] = val.val.f->compute_array(i - 1, icol); j += stride; } } // invoke vector-style variable - } else if (which[m] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { double *varvec; - int nvec = input->variable->compute_vector(value2index[m],&varvec); - if (nvec < nstop) - error->all(FLERR,"Compute slice variable is not long enough"); - j = 0; - for (i = nstart; i < nstop; i += nskip) { - vec[j] = varvec[i-1]; + int nvec = input->variable->compute_vector(val.val.v, &varvec); + if (nvec < nstop) error->all(FLERR, "Compute slice variable {} is not long enough", val.id); + int j = 0; + for (int i = nstart; i < nstop; i += nskip) { + vec[j] = varvec[i - 1]; j += stride; } } diff --git a/src/compute_slice.h b/src/compute_slice.h index fd82df2d4e..fb090f1c4f 100644 --- a/src/compute_slice.h +++ b/src/compute_slice.h @@ -33,10 +33,18 @@ class ComputeSlice : public Compute { void compute_array() override; private: - int me; - int nstart, nstop, nskip, 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; + int nstart, nstop, nskip; void extract_one(int, double *, int); }; From c312bf97aee1fb721040af95fba0fa824a9e46df Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 7 Oct 2022 07:33:42 -0400 Subject: [PATCH 08/20] convert fix store/state --- src/compute_reduce.cpp | 3 +- src/fix_store_state.cpp | 621 ++++++++++++++++++++-------------------- src/fix_store_state.h | 25 +- 3 files changed, 322 insertions(+), 327 deletions(-) diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp index 41a1831dc8..3df85d629f 100644 --- a/src/compute_reduce.cpp +++ b/src/compute_reduce.cpp @@ -527,9 +527,8 @@ double ComputeReduce::compute_one(int m, int flag) if (val.flavor == PERATOM) { if (aidx == 0) { double *fix_vector = val.val.f->vector_atom; - int n = nlocal; if (flag < 0) { - for (int i = 0; i < n; i++) + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) combine(one, fix_vector[i], i); } else one = fix_vector[flag]; diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index cd29e785ec..664aac841a 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -35,175 +35,188 @@ using namespace FixConst; /* ---------------------------------------------------------------------- */ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), - ids(nullptr), values(nullptr), - vbuf(nullptr), pack_choice(nullptr) + Fix(lmp, narg, arg), avalues(nullptr), vbuf(nullptr) { - if (narg < 5) error->all(FLERR,"Illegal fix store/state command"); + if (narg < 5) utils::missing_cmd_args(FLERR,"fix store/state", error); restart_peratom = 1; peratom_freq = 1; nevery = utils::inumeric(FLERR,arg[3],false,lmp); - if (nevery < 0) error->all(FLERR,"Illegal fix store/state command"); + if (nevery < 0) error->all(FLERR,"Invalid fix store/state never value {}", nevery); - // parse values until one isn't recognized + // parse values // customize a new keyword by adding to if statement - pack_choice = new FnPtrPack[narg-4]; - which = new int[narg-4]; - argindex = new int[narg-4]; - ids = new char*[narg-4]; - value2index = new int[narg-4]; - nvalues = 0; + values.clear(); cfv_any = 0; int iarg = 4; while (iarg < narg) { - which[nvalues] = ArgInfo::KEYWORD; - ids[nvalues] = nullptr; + + value_t val; + val.which = ArgInfo::KEYWORD; + val.argindex = -1; + val.id = ""; + val.val.c = nullptr; + val.pack_choice = nullptr; if (strcmp(arg[iarg],"id") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_id; + val.pack_choice = &FixStoreState::pack_id; } else if (strcmp(arg[iarg],"mol") == 0) { if (!atom->molecule_flag) - error->all(FLERR, - "Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_molecule; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_molecule; } else if (strcmp(arg[iarg],"type") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_type; + val.pack_choice = &FixStoreState::pack_type; } else if (strcmp(arg[iarg],"mass") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_mass; + val.pack_choice = &FixStoreState::pack_mass; } else if (strcmp(arg[iarg],"x") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_x; + val.pack_choice = &FixStoreState::pack_x; } else if (strcmp(arg[iarg],"y") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_y; + val.pack_choice = &FixStoreState::pack_y; } else if (strcmp(arg[iarg],"z") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_z; + val.pack_choice = &FixStoreState::pack_z; } else if (strcmp(arg[iarg],"xs") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_xs_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_xs; + val.pack_choice = &FixStoreState::pack_xs_triclinic; + else val.pack_choice = &FixStoreState::pack_xs; } else if (strcmp(arg[iarg],"ys") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_ys_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_ys; + val.pack_choice = &FixStoreState::pack_ys_triclinic; + else val.pack_choice = &FixStoreState::pack_ys; } else if (strcmp(arg[iarg],"zs") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_zs_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_zs; + val.pack_choice = &FixStoreState::pack_zs_triclinic; + else val.pack_choice = &FixStoreState::pack_zs; } else if (strcmp(arg[iarg],"xu") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_xu_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_xu; + val.pack_choice = &FixStoreState::pack_xu_triclinic; + else val.pack_choice = &FixStoreState::pack_xu; } else if (strcmp(arg[iarg],"yu") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_yu_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_yu; + val.pack_choice = &FixStoreState::pack_yu_triclinic; + else val.pack_choice = &FixStoreState::pack_yu; } else if (strcmp(arg[iarg],"zu") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_zu_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_zu; + val.pack_choice = &FixStoreState::pack_zu_triclinic; + else val.pack_choice = &FixStoreState::pack_zu; } else if (strcmp(arg[iarg],"xsu") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_xsu_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_xsu; + val.pack_choice = &FixStoreState::pack_xsu_triclinic; + else val.pack_choice = &FixStoreState::pack_xsu; } else if (strcmp(arg[iarg],"ysu") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_ysu_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_ysu; + val.pack_choice = &FixStoreState::pack_ysu_triclinic; + else val.pack_choice = &FixStoreState::pack_ysu; } else if (strcmp(arg[iarg],"zsu") == 0) { if (domain->triclinic) - pack_choice[nvalues++] = &FixStoreState::pack_zsu_triclinic; - else pack_choice[nvalues++] = &FixStoreState::pack_zsu; + val.pack_choice = &FixStoreState::pack_zsu_triclinic; + else val.pack_choice = &FixStoreState::pack_zsu; } else if (strcmp(arg[iarg],"ix") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_ix; + val.pack_choice = &FixStoreState::pack_ix; } else if (strcmp(arg[iarg],"iy") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_iy; + val.pack_choice = &FixStoreState::pack_iy; } else if (strcmp(arg[iarg],"iz") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_iz; + val.pack_choice = &FixStoreState::pack_iz; } else if (strcmp(arg[iarg],"vx") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_vx; + val.pack_choice = &FixStoreState::pack_vx; } else if (strcmp(arg[iarg],"vy") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_vy; + val.pack_choice = &FixStoreState::pack_vy; } else if (strcmp(arg[iarg],"vz") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_vz; + val.pack_choice = &FixStoreState::pack_vz; } else if (strcmp(arg[iarg],"fx") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_fx; + val.pack_choice = &FixStoreState::pack_fx; } else if (strcmp(arg[iarg],"fy") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_fy; + val.pack_choice = &FixStoreState::pack_fy; } else if (strcmp(arg[iarg],"fz") == 0) { - pack_choice[nvalues++] = &FixStoreState::pack_fz; + val.pack_choice = &FixStoreState::pack_fz; } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_q; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_mux; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_muy; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_muz; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_muz; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_mu; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_mu; } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_radius; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_radius; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_diameter; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_diameter; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_omegax; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_omegay; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_omegaz; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_angmomx; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_angmomy; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_angmomz; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_angmomz; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_tqx; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_tqy; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Fix store/state for atom property that isn't allocated"); - pack_choice[nvalues++] = &FixStoreState::pack_tqz; + error->all(FLERR, "Cannot use fix store/state {} for atom style {}", + arg[iarg], atom->get_style()); + val.pack_choice = &FixStoreState::pack_tqz; // compute or fix or variable or custom per-atom vector or array @@ -211,16 +224,15 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : ArgInfo argi(arg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE |ArgInfo::DNAME|ArgInfo::INAME); - if (argi.get_type() == ArgInfo::NONE) break; - if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) - error->all(FLERR,"Illegal fix store/state command"); + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); - which[nvalues] = argi.get_type(); - argindex[nvalues] = argi.get_index1(); - ids[nvalues] = argi.copy_name(); - nvalues++; + if (val.which == ArgInfo::NONE) break; + if ((val.which == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) + error->all(FLERR,"Illegal fix store/state argument: {}", arg[iarg]); } - + values.push_back(val); iarg++; } @@ -230,94 +242,79 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"com") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix store/state command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR,"fix store/state com", error); comflag = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; - } else error->all(FLERR,"Illegal fix store/state command"); + } else error->all(FLERR,"Unknown fix store/state keyword: {}", arg[iarg]); } // 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 fix store/state does not exist"); - if (modify->compute[icompute]->peratom_flag == 0) - error->all(FLERR,"Fix store/state compute does not calculate per-atom values"); - if (argindex[i] == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Fix store/state compute does not calculate a per-atom vector"); - if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR, - "Fix store/state compute does not calculate a per-atom array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, - "Fix store/state 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 fix store/state does not exist", val.id); + if (val.val.c->peratom_flag == 0) + error->all(FLERR,"Fix store/state compute {} does not calculate per-atom values", val.id); + if (val.argindex == 0 && + val.val.c->size_peratom_cols != 0) + error->all(FLERR,"Fix store/state compute {} does not calculate per-atom vector", val.id); + if (val.argindex && val.val.c->size_peratom_cols == 0) + error->all(FLERR, "Fix store/state compute {} does not calculate per-atom array", val.id); + if (val.argindex && (val.argindex > val.val.c->size_peratom_cols)) + error->all(FLERR, "Fix store/state compute array {} is accessed out-of-range", 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 store/state does not exist"); - if (modify->fix[ifix]->peratom_flag == 0) - error->all(FLERR, - "Fix store/state fix does not calculate per-atom values"); - if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all(FLERR, - "Fix store/state fix does not calculate a per-atom vector"); - if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all(FLERR, - "Fix store/state fix does not calculate a per-atom array"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all(FLERR, - "Fix store/state fix array is accessed out-of-range"); - if (nevery % modify->fix[ifix]->peratom_freq) - error->all(FLERR, - "Fix for fix store/state not computed at compatible time"); + } 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 store/state does not exist", val.id); + if (val.val.f->peratom_flag == 0) + error->all(FLERR, "Fix store/state fix {} does not calculate per-atom values", val.id); + if (val.argindex == 0 && val.val.f->size_peratom_cols != 0) + error->all(FLERR, "Fix store/state fix {} does not calculate per-atom vector", val.id); + if (val.argindex && val.val.f->size_peratom_cols == 0) + error->all(FLERR, "Fix store/state fix {} does not calculate per-atom array", val.id); + if (val.argindex && (val.argindex > val.val.f->size_peratom_cols)) + error->all(FLERR, "Fix store/state fix {} array is accessed out-of-range", val.id); + if (nevery % val.val.f->peratom_freq) + error->all(FLERR, "Fix {} for fix store/state not computed at compatible time", 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 store/state does not exist"); - if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Fix store/state variable is not atom-style variable"); + } 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 fix store/state does not exist", val.id); + if (input->variable->atomstyle(val.val.v) == 0) + error->all(FLERR,"Fix store/state variable {} is not atom-style variable", val.id); - } else if (which[i] == ArgInfo::DNAME) { - int icustom,iflag,icol; - icustom = atom->find_custom(ids[i],iflag,icol); - if (icustom < 0) - error->all(FLERR,"Custom vector/array for fix store/state does not exist"); - if (argindex[i] == 0) { + } else if (val.which == ArgInfo::DNAME) { + int iflag,icol; + val.val.d = atom->find_custom(val.id.c_str(),iflag,icol); + if (val.val.d < 0) + error->all(FLERR,"Custom vector/array {} for fix store/state does not exist", val.id); + if (val.argindex == 0) { if (!iflag || icol) - error->all(FLERR, - "Custom double vector for fix store/state does not exist"); + error->all(FLERR, "Custom property {} for fix store/state is not double vector", val.id); } else { if (!iflag || !icol) - error->all(FLERR, - "Custom double array for fix store/state does not exist"); - if (argindex[i] > atom->dcols[icustom]) - error->all(FLERR, - "Fix store/state custom array is accessed out-of-range"); + error->all(FLERR, "Custom property {} for fix store/state is not double array", val.id); + if (val.argindex > atom->dcols[val.val.d]) + error->all(FLERR, "Fix store/state custom array {} is accessed out-of-range", val.id); } - } else if (which[i] == ArgInfo::INAME) { - int icustom,iflag,icol; - icustom = atom->find_custom(ids[i],iflag,icol); - if (icustom < 0) - error->all(FLERR,"Custom vector/array for fix store/state does not exist"); - if (argindex[i] == 0) { + } else if (val.which == ArgInfo::INAME) { + int iflag,icol; + val.val.i = atom->find_custom(val.id.c_str(),iflag,icol); + if (val.val.i < 0) + error->all(FLERR, "Custom vector/array {} for fix store/state does not exist", val.id); + if (val.argindex == 0) { if (iflag || icol) - error->all(FLERR, - "Custom integer vector for fix store/state does not exist"); + error->all(FLERR, "Custom property {} for fix store/state is not integer vector", val.id); } else { if (iflag || !icol) - error->all(FLERR, - "Custom integer array for fix store/state does not exist"); - if (argindex[i] > atom->icols[icustom]) - error->all(FLERR, - "Fix store/state custom array is accessed out-of-range"); + error->all(FLERR, "Custom property {} for fix store/state is not integer array", val.id); + if (val.argindex > atom->icols[val.val.i]) + error->all(FLERR, "Fix store/state custom array {} is accessed out-of-range", val.id); } } } @@ -325,13 +322,13 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : // this fix produces either a per-atom vector or array peratom_flag = 1; - if (nvalues == 1) size_peratom_cols = 0; - else size_peratom_cols = nvalues; + if (values.size() == 1) size_peratom_cols = 0; + else size_peratom_cols = values.size(); // perform initial allocation of atom-based array // register with Atom class - values = nullptr; + avalues = nullptr; FixStoreState::grow_arrays(atom->nmax); atom->add_callback(Atom::GROW); atom->add_callback(Atom::RESTART); @@ -341,8 +338,8 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - for (int m = 0; m < nvalues; m++) - values[i][m] = 0.0; + for (int m = 0; m < values.size(); m++) + avalues[i][m] = 0.0; // store current values for keywords but not for compute, fix, variable @@ -361,14 +358,7 @@ FixStoreState::~FixStoreState() atom->delete_callback(id,Atom::GROW); atom->delete_callback(id,Atom::RESTART); - delete [] which; - delete [] argindex; - for (int m = 0; m < nvalues; m++) delete [] ids[m]; - delete [] ids; - delete [] value2index; - delete [] pack_choice; - - memory->destroy(values); + memory->destroy(avalues); } /* ---------------------------------------------------------------------- */ @@ -389,31 +379,33 @@ void FixStoreState::init() if (!firstflag && nevery == 0) return; - 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 fix store/state 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 fix store/state 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 fix store/state 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 fix store/state 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 fix store/state 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 fix store/state does not exist", val.id); - } else if (which[m] == ArgInfo::INAME || which[m] == ArgInfo::DNAME) { - int icustom,iflag,cols; - icustom = atom->find_custom(ids[m],iflag,cols); - if (icustom < 0) - error->all(FLERR,"Custom vector/array for fix store/state does not exist"); - value2index[m] = icustom; + } else if (val.which == ArgInfo::DNAME) { + int iflag,cols; + val.val.d = atom->find_custom(val.id.c_str(), iflag, cols); + if (val.val.d < 0) + error->all(FLERR,"Custom vector/array {} for fix store/state does not exist", val.id); + + } else if (val.which == ArgInfo::INAME) { + int iflag,cols; + val.val.i = atom->find_custom(val.id.c_str(), iflag, cols); + if (val.val.i < 0) + error->all(FLERR,"Custom vector/array {} for fix store/state does not exist", val.id); } } } @@ -437,8 +429,6 @@ void FixStoreState::setup(int /*vflag*/) void FixStoreState::end_of_step() { - int i,j,n; - // compute com if comflag set if (comflag) { @@ -452,86 +442,85 @@ void FixStoreState::end_of_step() // fill vector or array with per-atom values - if (values) vbuf = &values[0][0]; + if (avalues) vbuf = &avalues[0][0]; else vbuf = nullptr; - for (int m = 0; m < nvalues; m++) { - if (which[m] == ArgInfo::KEYWORD && kflag) (this->*pack_choice[m])(m); + int m = 0; + for (auto &val : values) { + if (val.which == ArgInfo::KEYWORD && kflag) + (this->*val.pack_choice)(m); else if (cfv_flag) { - n = value2index[m]; - j = argindex[m]; int *mask = atom->mask; int nlocal = atom->nlocal; - // invoke compute if not previously invoked + // invoke compute if not previously invoked, then access fields - if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[n]; - 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 (j == 0) { - double *compute_vector = compute->vector_atom; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = compute_vector[i]; + if (val.argindex == 0) { + double *compute_vector = val.val.c->vector_atom; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = compute_vector[i]; } else { - int jm1 = j - 1; - double **compute_array = compute->array_atom; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = compute_array[i][jm1]; + int jm1 = val.argindex - 1; + double **compute_array = val.val.c->array_atom; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = compute_array[i][jm1]; } // access fix fields, guaranteed to be ready - } else if (which[m] == ArgInfo::FIX) { - if (j == 0) { - double *fix_vector = modify->fix[n]->vector_atom; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = fix_vector[i]; + } else if (val.which == ArgInfo::FIX) { + if (val.argindex == 0) { + double *fix_vector = val.val.f->vector_atom; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = fix_vector[i]; } else { - int jm1 = j - 1; - double **fix_array = modify->fix[n]->array_atom; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = fix_array[i][jm1]; + int jm1 = val.argindex - 1; + double **fix_array = val.val.f->array_atom; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = fix_array[i][jm1]; } // evaluate atom-style variable - } else if (which[m] == ArgInfo::VARIABLE) { - input->variable->compute_atom(n,igroup,&values[0][m],nvalues,0); - + } else if (val.which == ArgInfo::VARIABLE) { + input->variable->compute_atom(val.val.v, igroup, &avalues[0][m], values.size(),0); // access custom atom vector/array fields - } else if (which[m] == ArgInfo::DNAME) { - if (j == 0) { - double *dvector = atom->dvector[n]; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = dvector[i]; + } else if (val.which == ArgInfo::DNAME) { + if (val.argindex == 0) { + double *dvector = atom->dvector[val.val.d]; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = dvector[i]; } else { - double **darray = atom->darray[n]; - int jm1 = j - 1; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = darray[i][jm1]; + double **darray = atom->darray[val.val.d]; + int jm1 = val.argindex - 1; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = darray[i][jm1]; } - } else if (which[m] == ArgInfo::INAME) { - if (j == 0) { - int *ivector = atom->ivector[n]; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = ivector[i]; + } else if (val.which == ArgInfo::INAME) { + if (val.argindex == 0) { + int *ivector = atom->ivector[val.val.i]; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = ivector[i]; } else { - int **iarray = atom->iarray[n]; - int jm1 = j - 1; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) values[i][m] = iarray[i][jm1]; + int **iarray = atom->iarray[val.val.i]; + int jm1 = val.argindex - 1; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) avalues[i][m] = iarray[i][jm1]; } } } + ++m; } // if any compute/fix/variable and nevery, wrap with clear/add @@ -548,7 +537,7 @@ void FixStoreState::end_of_step() double FixStoreState::memory_usage() { - double bytes = (double)atom->nmax*nvalues * sizeof(double); + double bytes = (double)atom->nmax*values.size() * sizeof(double); return bytes; } @@ -558,11 +547,11 @@ double FixStoreState::memory_usage() void FixStoreState::grow_arrays(int nmax) { - memory->grow(values,nmax,nvalues,"store/state:values"); - if (nvalues == 1) { - if (nmax) vector_atom = &values[0][0]; + memory->grow(avalues,nmax,values.size(),"store/state:avalues"); + if (values.size() == 1) { + if (nmax) vector_atom = &avalues[0][0]; else vector_atom = nullptr; - } else array_atom = values; + } else array_atom = avalues; } /* ---------------------------------------------------------------------- @@ -571,7 +560,7 @@ void FixStoreState::grow_arrays(int nmax) void FixStoreState::copy_arrays(int i, int j, int /*delflag*/) { - for (int m = 0; m < nvalues; m++) values[j][m] = values[i][m]; + for (int m = 0; m < values.size(); m++) avalues[j][m] = avalues[i][m]; } /* ---------------------------------------------------------------------- @@ -580,8 +569,8 @@ void FixStoreState::copy_arrays(int i, int j, int /*delflag*/) int FixStoreState::pack_exchange(int i, double *buf) { - for (int m = 0; m < nvalues; m++) buf[m] = values[i][m]; - return nvalues; + for (int m = 0; m < values.size(); m++) buf[m] = avalues[i][m]; + return values.size(); } /* ---------------------------------------------------------------------- @@ -590,8 +579,8 @@ int FixStoreState::pack_exchange(int i, double *buf) int FixStoreState::unpack_exchange(int nlocal, double *buf) { - for (int m = 0; m < nvalues; m++) values[nlocal][m] = buf[m]; - return nvalues; + for (int m = 0; m < values.size(); m++) avalues[nlocal][m] = buf[m]; + return values.size(); } /* ---------------------------------------------------------------------- @@ -601,9 +590,9 @@ int FixStoreState::unpack_exchange(int nlocal, double *buf) int FixStoreState::pack_restart(int i, double *buf) { // pack buf[0] this way because other fixes unpack it - buf[0] = nvalues+1; - for (int m = 0; m < nvalues; m++) buf[m+1] = values[i][m]; - return nvalues+1; + buf[0] = values.size()+1; + for (int m = 0; m < values.size(); m++) buf[m+1] = avalues[i][m]; + return values.size()+1; } /* ---------------------------------------------------------------------- @@ -621,7 +610,7 @@ void FixStoreState::unpack_restart(int nlocal, int nth) for (int i = 0; i < nth; i++) m += static_cast (extra[nlocal][m]); m++; - for (int i = 0; i < nvalues; i++) values[nlocal][i] = extra[nlocal][m++]; + for (int i = 0; i < values.size(); i++) avalues[nlocal][i] = extra[nlocal][m++]; } /* ---------------------------------------------------------------------- @@ -630,7 +619,7 @@ void FixStoreState::unpack_restart(int nlocal, int nth) int FixStoreState::maxsize_restart() { - return nvalues+1; + return values.size()+1; } /* ---------------------------------------------------------------------- @@ -639,12 +628,12 @@ int FixStoreState::maxsize_restart() int FixStoreState::size_restart(int /*nlocal*/) { - return nvalues+1; + return values.size()+1; } /* ---------------------------------------------------------------------- one method for every keyword fix store/state can archive - the atom property is packed into buf starting at n with stride nvalues + the atom property is packed into buf starting at n with stride values.size() customize a new keyword by adding a method ------------------------------------------------------------------------- */ @@ -659,7 +648,7 @@ void FixStoreState::pack_id(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = tag[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -674,7 +663,7 @@ void FixStoreState::pack_molecule(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = molecule[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -689,7 +678,7 @@ void FixStoreState::pack_type(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = type[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -707,13 +696,13 @@ void FixStoreState::pack_mass(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = rmass[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } else { for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = mass[type[i]]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } } @@ -729,7 +718,7 @@ void FixStoreState::pack_x(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = x[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -744,7 +733,7 @@ void FixStoreState::pack_y(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = x[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -759,7 +748,7 @@ void FixStoreState::pack_z(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = x[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -777,7 +766,7 @@ void FixStoreState::pack_xs(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = (x[i][0] - boxxlo) * invxprd; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -795,7 +784,7 @@ void FixStoreState::pack_ys(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = (x[i][1] - boxylo) * invyprd; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -813,7 +802,7 @@ void FixStoreState::pack_zs(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = (x[i][2] - boxzlo) * invzprd; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -833,7 +822,7 @@ void FixStoreState::pack_xs_triclinic(int n) vbuf[n] = h_inv[0]*(x[i][0]-boxlo[0]) + h_inv[5]*(x[i][1]-boxlo[1]) + h_inv[4]*(x[i][2]-boxlo[2]); else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -852,7 +841,7 @@ void FixStoreState::pack_ys_triclinic(int n) if (mask[i] & groupbit) vbuf[n] = h_inv[1]*(x[i][1]-boxlo[1]) + h_inv[3]*(x[i][2]-boxlo[2]); else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -871,7 +860,7 @@ void FixStoreState::pack_zs_triclinic(int n) if (mask[i] & groupbit) vbuf[n] = h_inv[2]*(x[i][2]-boxlo[2]); else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -891,7 +880,7 @@ void FixStoreState::pack_xu(int n) vbuf[n] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd; if (comflag) vbuf[n] -= cm[0]; } else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -911,7 +900,7 @@ void FixStoreState::pack_yu(int n) vbuf[n] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd; if (comflag) vbuf[n] -= cm[1]; } else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -931,7 +920,7 @@ void FixStoreState::pack_zu(int n) vbuf[n] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd; if (comflag) vbuf[n] -= cm[2]; } else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -955,7 +944,7 @@ void FixStoreState::pack_xu_triclinic(int n) vbuf[n] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox; if (comflag) vbuf[n] -= cm[0]; } else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -978,7 +967,7 @@ void FixStoreState::pack_yu_triclinic(int n) vbuf[n] = x[i][1] + h[1]*ybox + h[3]*zbox; if (comflag) vbuf[n] -= cm[1]; } else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1000,7 +989,7 @@ void FixStoreState::pack_zu_triclinic(int n) vbuf[n] = x[i][2] + h[2]*zbox; if (comflag) vbuf[n] -= cm[2]; } else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1020,7 +1009,7 @@ void FixStoreState::pack_xsu(int n) if (mask[i] & groupbit) vbuf[n] = (x[i][0]-boxxlo)*invxprd + ((image[i] & IMGMASK) - IMGMAX); else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1041,7 +1030,7 @@ void FixStoreState::pack_ysu(int n) vbuf[n] = (x[i][1]-boxylo)*invyprd + (image[i] >> IMGBITS & IMGMASK) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1061,7 +1050,7 @@ void FixStoreState::pack_zsu(int n) if (mask[i] & groupbit) vbuf[n] = (x[i][2]-boxzlo)*invzprd + (image[i] >> IMG2BITS) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1082,7 +1071,7 @@ void FixStoreState::pack_xsu_triclinic(int n) vbuf[n] = h_inv[0]*(x[i][0]-boxlo[0]) + h_inv[5]*(x[i][1]-boxlo[1]) + h_inv[4]*(x[i][2]-boxlo[2]) + (image[i] & IMGMASK) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1103,7 +1092,7 @@ void FixStoreState::pack_ysu_triclinic(int n) vbuf[n] = h_inv[1]*(x[i][1]-boxlo[1]) + h_inv[3]*(x[i][2]-boxlo[2]) + (image[i] >> IMGBITS & IMGMASK) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1123,7 +1112,7 @@ void FixStoreState::pack_zsu_triclinic(int n) if (mask[i] & groupbit) vbuf[n] = h_inv[2]*(x[i][2]-boxlo[2]) + (image[i] >> IMG2BITS) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1138,7 +1127,7 @@ void FixStoreState::pack_ix(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = (image[i] & IMGMASK) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1154,7 +1143,7 @@ void FixStoreState::pack_iy(int n) if (mask[i] & groupbit) vbuf[n] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1169,7 +1158,7 @@ void FixStoreState::pack_iz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = (image[i] >> IMG2BITS) - IMGMAX; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1184,7 +1173,7 @@ void FixStoreState::pack_vx(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = v[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1199,7 +1188,7 @@ void FixStoreState::pack_vy(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = v[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1214,7 +1203,7 @@ void FixStoreState::pack_vz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = v[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1229,7 +1218,7 @@ void FixStoreState::pack_fx(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = f[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1244,7 +1233,7 @@ void FixStoreState::pack_fy(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = f[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1259,7 +1248,7 @@ void FixStoreState::pack_fz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = f[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1274,7 +1263,7 @@ void FixStoreState::pack_q(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = q[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1289,7 +1278,7 @@ void FixStoreState::pack_mux(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = mu[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1304,7 +1293,7 @@ void FixStoreState::pack_muy(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = mu[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1319,7 +1308,7 @@ void FixStoreState::pack_muz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = mu[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1334,7 +1323,7 @@ void FixStoreState::pack_mu(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = mu[i][3]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1349,7 +1338,7 @@ void FixStoreState::pack_radius(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = radius[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1364,7 +1353,7 @@ void FixStoreState::pack_diameter(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = 2.0*radius[i]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1379,7 +1368,7 @@ void FixStoreState::pack_omegax(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = omega[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1394,7 +1383,7 @@ void FixStoreState::pack_omegay(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = omega[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1409,7 +1398,7 @@ void FixStoreState::pack_omegaz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = omega[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1424,7 +1413,7 @@ void FixStoreState::pack_angmomx(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = angmom[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1439,7 +1428,7 @@ void FixStoreState::pack_angmomy(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = angmom[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1454,7 +1443,7 @@ void FixStoreState::pack_angmomz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = angmom[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1469,7 +1458,7 @@ void FixStoreState::pack_tqx(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = torque[i][0]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1484,7 +1473,7 @@ void FixStoreState::pack_tqy(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = torque[i][1]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } @@ -1499,6 +1488,6 @@ void FixStoreState::pack_tqz(int n) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) vbuf[n] = torque[i][2]; else vbuf[n] = 0.0; - n += nvalues; + n += values.size(); } } diff --git a/src/fix_store_state.h b/src/fix_store_state.h index 245d54c8e5..19821d55ef 100644 --- a/src/fix_store_state.h +++ b/src/fix_store_state.h @@ -44,10 +44,22 @@ class FixStoreState : public Fix { int maxsize_restart() override; private: - int nvalues; - int *which, *argindex, *value2index; - char **ids; - double **values; // archived atom properties + struct value_t { + int which; + int argindex; + std::string id; + union { + class Compute *c; + class Fix *f; + int v; + int d; + int i; + } val; + void (FixStoreState::* pack_choice)(int); // ptr to pack function + }; + std::vector values; + + double **avalues; // archived atom properties double *vbuf; // 1d ptr to values int comflag; @@ -56,9 +68,6 @@ class FixStoreState : public Fix { int kflag, cfv_flag, firstflag; int cfv_any; // 1 if any compute/fix/variable specified - typedef void (FixStoreState::*FnPtrPack)(int); - FnPtrPack *pack_choice; // ptrs to pack functions - void pack_id(int); void pack_molecule(int); void pack_type(int); @@ -113,8 +122,6 @@ class FixStoreState : public Fix { void pack_tqy(int); void pack_tqz(int); }; - } // namespace LAMMPS_NS - #endif #endif From b3557b81c14cddac04524f96726332dda3ec7b52 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 14 Oct 2022 17:49:56 -0400 Subject: [PATCH 09/20] convert fix ave/histo and fix ave/histo/weight --- src/fix_ave_histo.cpp | 644 +++++++++++++++-------------------- src/fix_ave_histo.h | 18 +- src/fix_ave_histo_weight.cpp | 326 +++++++++--------- 3 files changed, 442 insertions(+), 546 deletions(-) diff --git a/src/fix_ave_histo.cpp b/src/fix_ave_histo.cpp index c2acd652ad..46c26acad7 100644 --- a/src/fix_ave_histo.cpp +++ b/src/fix_ave_histo.cpp @@ -16,6 +16,7 @@ #include "arg_info.h" #include "atom.h" +#include "comm.h" #include "compute.h" #include "error.h" #include "input.h" @@ -29,29 +30,24 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{ONE,RUNNING}; -enum{SCALAR,VECTOR,WINDOW}; -enum{DEFAULT,GLOBAL,PERATOM,LOCAL}; -enum{IGNORE,END,EXTRA}; - +enum { ONE, RUNNING }; +enum { SCALAR, VECTOR, WINDOW }; +enum { DEFAULT, GLOBAL, PERATOM, LOCAL }; +enum { IGNORE, END, EXTRA }; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), - ids(nullptr), fp(nullptr), stats_list(nullptr), - bin(nullptr), bin_total(nullptr), bin_all(nullptr), bin_list(nullptr), - coord(nullptr), vector(nullptr) + Fix(lmp, narg, arg), nvalues(0), fp(nullptr), stats_list(nullptr), bin(nullptr), + bin_total(nullptr), bin_all(nullptr), bin_list(nullptr), coord(nullptr), vector(nullptr) { - if (narg < 10) error->all(FLERR,"Illegal fix ave/histo command"); + auto mycmd = fmt::format("fix {}", style); + if (narg < 10) utils::missing_cmd_args(FLERR, mycmd, error); - MPI_Comm_rank(world,&me); - - nevery = utils::inumeric(FLERR,arg[3],false,lmp); - nrepeat = utils::inumeric(FLERR,arg[4],false,lmp); - nfreq = utils::inumeric(FLERR,arg[5],false,lmp); + nevery = utils::inumeric(FLERR, arg[3], false, lmp); + nrepeat = utils::inumeric(FLERR, arg[4], false, lmp); + nfreq = utils::inumeric(FLERR, arg[5], false, lmp); global_freq = nfreq; vector_flag = 1; @@ -63,9 +59,9 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : dynamic_group_allow = 1; time_depend = 1; - lo = utils::numeric(FLERR,arg[6],false,lmp); - hi = utils::numeric(FLERR,arg[7],false,lmp); - nbins = utils::inumeric(FLERR,arg[8],false,lmp); + lo = utils::numeric(FLERR, arg[6], false, lmp); + hi = utils::numeric(FLERR, arg[7], false, lmp); + nbins = utils::inumeric(FLERR, arg[8], false, lmp); // scan values to count them // then read options so know mode = SCALAR/VECTOR before re-reading values @@ -91,7 +87,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : } else break; } - if (nvalues == 0) error->all(FLERR,"No values in fix ave/histo command"); + if (nvalues == 0) error->all(FLERR,"No values in {} command", mycmd); options(iarg,narg,arg); @@ -100,70 +96,65 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : int expand = 0; char **earg; - nvalues = utils::expand_args(FLERR,nvalues,&arg[9],mode,earg,lmp); + nvalues = utils::expand_args(FLERR, nvalues, &arg[9], mode, earg, lmp); if (earg != &arg[9]) expand = 1; arg = earg; // parse values - which = new int[nvalues]; - argindex = new int[nvalues]; - value2index = new int[nvalues]; - ids = new char*[nvalues]; + values.clear(); for (int i = 0; i < nvalues; i++) { + value_t val; + val.id = ""; + val.val.c = nullptr; + if (strcmp(arg[i],"x") == 0) { - which[i] = ArgInfo::X; - argindex[i] = 0; - ids[i] = nullptr; + val.which = ArgInfo::X; + val.argindex = 0; } else if (strcmp(arg[i],"y") == 0) { - which[i] = ArgInfo::X; - argindex[i] = 1; - ids[i] = nullptr; + val.which = ArgInfo::X; + val.argindex = 1; } else if (strcmp(arg[i],"z") == 0) { - which[i] = ArgInfo::X; - argindex[i] = 2; - ids[i] = nullptr; + val.which = ArgInfo::X; + val.argindex = 2; } else if (strcmp(arg[i],"vx") == 0) { - which[i] = ArgInfo::V; - argindex[i] = 0; - ids[i] = nullptr; + val.which = ArgInfo::V; + val.argindex = 0; } else if (strcmp(arg[i],"vy") == 0) { - which[i] = ArgInfo::V; - argindex[i] = 1; - ids[i] = nullptr; + val.which = ArgInfo::V; + val.argindex = 1; } else if (strcmp(arg[i],"vz") == 0) { - which[i] = ArgInfo::V; - argindex[i] = 2; - ids[i] = nullptr; + val.which = ArgInfo::V; + val.argindex = 2; } else if (strcmp(arg[i],"fx") == 0) { - which[i] = ArgInfo::F; - argindex[i] = 0; - ids[i] = nullptr; + val.which = ArgInfo::F; + val.argindex = 0; } else if (strcmp(arg[i],"fy") == 0) { - which[i] = ArgInfo::F; - argindex[i] = 1; - ids[i] = nullptr; + val.which = ArgInfo::F; + val.argindex = 1; } else if (strcmp(arg[i],"fz") == 0) { - which[i] = ArgInfo::F; - argindex[i] = 2; - ids[i] = nullptr; + val.which = ArgInfo::F; + val.argindex = 2; } else { ArgInfo argi(arg[i]); if (argi.get_type() == ArgInfo::NONE) break; if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) - error->all(FLERR,"Invalid fix ave/histo command"); + error->all(FLERR,"Invalid {} argument: {}", mycmd, arg[i]); - which[i] = argi.get_type(); - argindex[i] = argi.get_index1(); - ids[i] = argi.copy_name(); + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); } + values.push_back(val); } + if (nvalues != (int)values.size()) + error->all(FLERR, "Could not parse value data consistently for {}", mycmd); // if wildcard expansion occurred, free earg memory from expand_args() @@ -175,69 +166,67 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : // check input args for kind consistency // all inputs must all be global, per-atom, or local - if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all(FLERR,"Illegal fix ave/histo command"); + if (nevery <= 0) + error->all(FLERR,"Illegal {} nevery value: {}", mycmd, nevery); + if (nrepeat <= 0) + error->all(FLERR,"Illegal {} nrepeat value: {}", mycmd, nrepeat); + if (nfreq <= 0) + error->all(FLERR,"Illegal {} nfreq value: {}", mycmd, nfreq); if (nfreq % nevery || nrepeat*nevery > nfreq) - error->all(FLERR,"Illegal fix ave/histo command"); - if (lo >= hi) error->all(FLERR,"Illegal fix ave/histo command"); - if (nbins <= 0) error->all(FLERR,"Illegal fix ave/histo command"); + error->all(FLERR,"Inconsistent {} nevery/nrepeat/nfreq values", mycmd); if (ave != RUNNING && overwrite) - error->all(FLERR,"Illegal fix ave/histo command"); + error->all(FLERR,"{} overwrite keyword requires ave running setting", mycmd); int kindglobal,kindperatom,kindlocal; - - for (int i = 0; i < nvalues; i++) { + for (auto &val : values) { kindglobal = kindperatom = kindlocal = 0; - if ((which[i] == ArgInfo::X) || (which[i] == ArgInfo::V) - || (which[i] == ArgInfo::F)) { + if ((val.which == ArgInfo::X) || (val.which == ArgInfo::V) || (val.which == ArgInfo::F)) { kindperatom = 1; - } else if (which[i] == ArgInfo::COMPUTE) { - int c_id = modify->find_compute(ids[i]); - if (c_id < 0) error->all(FLERR,"Fix ave/histo input is invalid compute"); - Compute *compute = modify->compute[c_id]; + } else 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 {} does not exist", val.id, mycmd); // computes can produce multiple kinds of output - if (compute->scalar_flag || compute->vector_flag || compute->array_flag) + if (val.val.c->scalar_flag || val.val.c->vector_flag || val.val.c->array_flag) kindglobal = 1; - if (compute->peratom_flag) kindperatom = 1; - if (compute->local_flag) kindlocal = 1; + if (val.val.c->peratom_flag) kindperatom = 1; + if (val.val.c->local_flag) kindlocal = 1; - } else if (which[i] == ArgInfo::FIX) { - int f_id = modify->find_fix(ids[i]); - if (f_id < 0) error->all(FLERR,"Fix ave/histo input is invalid fix"); - Fix *fix = modify->fix[f_id]; + } 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 {} does not exist", val.id, mycmd); // fixes can produce multiple kinds of output - if (fix->scalar_flag || fix->vector_flag || fix->array_flag) + if (val.val.f->scalar_flag || val.val.f->vector_flag || val.val.f->array_flag) kindglobal = 1; - if (fix->peratom_flag) kindperatom = 1; - if (fix->local_flag) kindlocal = 1; + if (val.val.f->peratom_flag) kindperatom = 1; + if (val.val.f->local_flag) kindlocal = 1; - } else if (which[i] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Fix ave/histo input is invalid variable"); + } 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 {} does not exist", val.id, mycmd); // variables only produce one kind of output - if (input->variable->equalstyle(ivariable)) kindglobal = 1; - else if (input->variable->atomstyle(ivariable)) kindperatom = 1; - else error->all(FLERR,"Fix ave/histo input is invalid kind of variable"); + if (input->variable->equalstyle(val.val.v)) kindglobal = 1; + else if (input->variable->atomstyle(val.val.v)) kindperatom = 1; + else error->all(FLERR,"{} variable {} is incompatible style", mycmd, val.id); } if (kind == DEFAULT) { if (kindglobal + kindperatom + kindlocal > 1) - error->all(FLERR,"Fix ave/histo input kind is ambiguous"); + error->all(FLERR,"{} input kind is ambiguous", mycmd); if (kindglobal) kind = GLOBAL; if (kindperatom) kind = PERATOM; if (kindlocal) kind = LOCAL; } else if (kind == GLOBAL) { if (!kindglobal) - error->all(FLERR,"Fix ave/histo input kind is invalid"); + error->all(FLERR,"{} input kind is not global", mycmd); } else if (kind == PERATOM) { if (!kindperatom) - error->all(FLERR,"Fix ave/histo input kind is invalid"); + error->all(FLERR,"{} input kind is not peratom", mycmd); } else if (kind == LOCAL) { if (!kindlocal) - error->all(FLERR,"Fix ave/histo input kind is invalid"); + error->all(FLERR,"{} input kind is not local", mycmd); } } @@ -245,183 +234,112 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : // for fix inputs, check that fix frequency is acceptable if (kind == PERATOM && mode == SCALAR) - error->all(FLERR, - "Fix ave/histo cannot input per-atom values in scalar mode"); + error->all(FLERR, "{} cannot process per-atom values in scalar mode", mycmd); if (kind == LOCAL && mode == SCALAR) - error->all(FLERR,"Fix ave/histo cannot input local values in scalar mode"); + error->all(FLERR,"{} cannot process local values in scalar mode", mycmd); - for (int i = 0; i < nvalues; i++) { - if (which[i] == ArgInfo::COMPUTE && kind == GLOBAL && mode == SCALAR) { - int icompute = modify->find_compute(ids[i]); - if (icompute < 0) - error->all(FLERR,"Compute ID for fix ave/histo does not exist"); - if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) - error->all(FLERR, - "Fix ave/histo compute does not calculate a global scalar"); - if (argindex[i] && modify->compute[icompute]->vector_flag == 0) - error->all(FLERR, - "Fix ave/histo compute does not calculate a global vector"); - if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) - error->all(FLERR, - "Fix ave/histo compute vector is accessed out-of-range"); + for (auto &val : values) { + if (val.which == ArgInfo::COMPUTE && kind == GLOBAL && mode == SCALAR) { + if (val.argindex == 0 && val.val.c->scalar_flag == 0) + error->all(FLERR, "{} compute {} does not calculate a global scalar", mycmd, val.id); + if (val.argindex && val.val.c->vector_flag == 0) + error->all(FLERR, "{} compute {} does not calculate a global vector", mycmd, val.id); + if (val.argindex && val.argindex > val.val.c->size_vector) + error->all(FLERR, "{} compute {} vector is accessed out-of-range", mycmd, val.id); - } else if (which[i] == ArgInfo::COMPUTE && kind == GLOBAL && mode == VECTOR) { - int icompute = modify->find_compute(ids[i]); - if (icompute < 0) - error->all(FLERR,"Compute ID for fix ave/histo does not exist"); - if (argindex[i] == 0 && modify->compute[icompute]->vector_flag == 0) - error->all(FLERR, - "Fix ave/histo compute does not calculate a global vector"); - if (argindex[i] && modify->compute[icompute]->array_flag == 0) - error->all(FLERR, - "Fix ave/histo compute does not calculate a global array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_array_cols) - error->all(FLERR, - "Fix ave/histo compute array is accessed out-of-range"); + } else if (val.which == ArgInfo::COMPUTE && kind == GLOBAL && mode == VECTOR) { + if (val.argindex == 0 && val.val.c->vector_flag == 0) + error->all(FLERR, "{} compute {} does not calculate a global vector", mycmd, val.id); + if (val.argindex && val.val.c->array_flag == 0) + error->all(FLERR, "{} compute {} does not calculate a global array", mycmd, val.id); + if (val.argindex && val.argindex > val.val.c->size_array_cols) + error->all(FLERR, "{} compute {} array is accessed out-of-range", mycmd, val.id); - } else if (which[i] == ArgInfo::COMPUTE && kind == PERATOM) { - int icompute = modify->find_compute(ids[i]); - if (icompute < 0) - error->all(FLERR,"Compute ID for fix ave/histo does not exist"); - if (modify->compute[icompute]->peratom_flag == 0) - error->all(FLERR, - "Fix ave/histo compute does not calculate per-atom values"); - if (argindex[i] == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Fix ave/histo compute does not " - "calculate a per-atom vector"); - if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR,"Fix ave/histo compute does not " - "calculate a per-atom array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, - "Fix ave/histo compute array is accessed out-of-range"); + } else if (val.which == ArgInfo::COMPUTE && kind == PERATOM) { + if (val.val.c->peratom_flag == 0) + error->all(FLERR, "{} compute {} does not calculate per-atom values", mycmd, val.id); + if (val.argindex == 0 && val.val.c->size_peratom_cols != 0) + error->all(FLERR, "{} compute {} does not calculate a per-atom vector", mycmd, val.id); + if (val.argindex && val.val.c->size_peratom_cols == 0) + error->all(FLERR, "{} compute {} does not calculate a per-atom array", mycmd, val.id); + if (val.argindex && val.argindex > val.val.c->size_peratom_cols) + error->all(FLERR, "{} compute {} array is accessed out-of-range", mycmd, val.id); - } else if (which[i] == ArgInfo::COMPUTE && kind == LOCAL) { - int icompute = modify->find_compute(ids[i]); - if (icompute < 0) - error->all(FLERR,"Compute ID for fix ave/histo does not exist"); - if (modify->compute[icompute]->local_flag == 0) - error->all(FLERR, - "Fix ave/histo compute does not calculate local values"); - if (argindex[i] == 0 && - modify->compute[icompute]->size_local_cols != 0) - error->all(FLERR,"Fix ave/histo compute does not " - "calculate a local vector"); - if (argindex[i] && modify->compute[icompute]->size_local_cols == 0) - error->all(FLERR,"Fix ave/histo compute does not " - "calculate a local array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_local_cols) - error->all(FLERR, - "Fix ave/histo compute array is accessed out-of-range"); + } else if (val.which == ArgInfo::COMPUTE && kind == LOCAL) { + if (val.val.c->local_flag == 0) + error->all(FLERR, "{} compute {} does not calculate local values", mycmd, val.id); + if (val.argindex == 0 && val.val.c->size_local_cols != 0) + error->all(FLERR, "{} compute {} does not calculate a local vector", mycmd, val.id); + if (val.argindex && val.val.c->size_local_cols == 0) + error->all(FLERR, "{} compute {} does not calculate a local array", mycmd, val.id); + if (val.argindex && val.argindex > val.val.c->size_local_cols) + error->all(FLERR, "{} compute {} array is accessed out-of-range", mycmd, val.id); - } else if (which[i] == ArgInfo::FIX && kind == GLOBAL && mode == SCALAR) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/histo does not exist"); - if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) - error->all(FLERR, - "Fix ave/histo fix does not calculate a global scalar"); - if (argindex[i] && modify->fix[ifix]->vector_flag == 0) - error->all(FLERR, - "Fix ave/histo fix does not calculate a global vector"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) - error->all(FLERR,"Fix ave/histo fix vector is accessed out-of-range"); - if (nevery % modify->fix[ifix]->global_freq) - error->all(FLERR, - "Fix for fix ave/histo not computed at compatible time"); + } else if (val.which == ArgInfo::FIX && kind == GLOBAL && mode == SCALAR) { + if (val.argindex == 0 && val.val.f->scalar_flag == 0) + error->all(FLERR, "{} fix {} does not calculate a global scalar", mycmd, val.id); + if (val.argindex && val.val.f->vector_flag == 0) + error->all(FLERR, "{} fix {} does not calculate a global vector", mycmd, val.id); + if (val.argindex && val.argindex > val.val.f->size_vector) + error->all(FLERR, "{} fix {} vector is accessed out-of-range", mycmd, val.id); + if (nevery % val.val.f->global_freq) + error->all(FLERR, "Fix {} for {} not computed at compatible time", val.id, mycmd); - } else if (which[i] == ArgInfo::FIX && kind == GLOBAL && mode == VECTOR) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/histo does not exist"); - if (argindex[i] == 0 && modify->fix[ifix]->vector_flag == 0) - error->all(FLERR, - "Fix ave/histo fix does not calculate a global vector"); - if (argindex[i] && modify->fix[ifix]->array_flag == 0) - error->all(FLERR,"Fix ave/histo fix does not calculate a global array"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_array_cols) - error->all(FLERR,"Fix ave/histo fix array is accessed out-of-range"); - if (nevery % modify->fix[ifix]->global_freq) - error->all(FLERR, - "Fix for fix ave/histo not computed at compatible time"); + } else if (val.which == ArgInfo::FIX && kind == GLOBAL && mode == VECTOR) { + if (val.argindex == 0 && val.val.f->vector_flag == 0) + error->all(FLERR, "{} fix {} does not calculate a global vector", mycmd, val.id); + if (val.argindex && val.val.f->array_flag == 0) + error->all(FLERR, "{} fix {} does not calculate a global array", mycmd, val.id); + if (val.argindex && val.argindex > val.val.f->size_array_cols) + error->all(FLERR, "{} fix {} array is accessed out-of-range", mycmd, val.id); + if (nevery % val.val.f->global_freq) + error->all(FLERR, "Fix {} for {} not computed at compatible time", val.id, mycmd); - } else if (which[i] == ArgInfo::FIX && kind == PERATOM) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/histo does not exist"); - if (modify->fix[ifix]->peratom_flag == 0) - error->all(FLERR, - "Fix ave/histo fix does not calculate per-atom values"); - if (argindex[i] == 0 && - modify->fix[ifix]->size_peratom_cols != 0) - error->all(FLERR,"Fix ave/histo fix does not " - "calculate a per-atom vector"); - if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all(FLERR,"Fix ave/histo fix does not " - "calculate a per-atom array"); - if (argindex[i] && - argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all(FLERR,"Fix ave/histo fix array is accessed out-of-range"); - if (nevery % modify->fix[ifix]->global_freq) - error->all(FLERR, - "Fix for fix ave/histo not computed at compatible time"); + } else if (val.which == ArgInfo::FIX && kind == PERATOM) { + if (val.val.f->peratom_flag == 0) + error->all(FLERR, "{} fix {} does not calculate per-atom values", mycmd, val.id); + if (val.argindex == 0 && val.val.f->size_peratom_cols != 0) + error->all(FLERR," {} fix {} does not calculate a per-atom vector", mycmd, val.id); + if (val.argindex && val.val.f->size_peratom_cols == 0) + error->all(FLERR, "{} fix {} does not ""calculate a per-atom array", mycmd, val.id); + if (val.argindex && val.argindex > val.val.f->size_peratom_cols) + error->all(FLERR, "{} fix {} array is accessed out-of-range", mycmd, val.id); + if (nevery % val.val.f->global_freq) + error->all(FLERR, "Fix {} for {} not computed at compatible time", val.id, mycmd); - } else if (which[i] == ArgInfo::FIX && kind == LOCAL) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/histo does not exist"); - if (modify->fix[ifix]->local_flag == 0) - error->all(FLERR,"Fix ave/histo fix does not calculate local values"); - if (argindex[i] == 0 && - modify->fix[ifix]->size_local_cols != 0) - error->all(FLERR,"Fix ave/histo fix does not " - "calculate a local vector"); - if (argindex[i] && modify->fix[ifix]->size_local_cols == 0) - error->all(FLERR,"Fix ave/histo fix does not " - "calculate a local array"); - if (argindex[i] && - argindex[i] > modify->fix[ifix]->size_local_cols) - error->all(FLERR,"Fix ave/histo fix array is accessed out-of-range"); - if (nevery % modify->fix[ifix]->global_freq) - error->all(FLERR, - "Fix for fix ave/histo not computed at compatible time"); + } else if (val.which == ArgInfo::FIX && kind == LOCAL) { + if (val.val.f->local_flag == 0) + error->all(FLERR, "{} fix {} does not calculate local values", mycmd, val.id); + if (val.argindex == 0 && val.val.f->size_local_cols != 0) + error->all(FLERR, "{} fix {} does not calculate a local vector", mycmd, val.id); + if (val.argindex && val.val.f->size_local_cols == 0) + error->all(FLERR, "{} fix does not calculate a local array", mycmd, val.id); + if (val.argindex && val.argindex > val.val.f->size_local_cols) + error->all(FLERR, "{} fix {} array is accessed out-of-range", mycmd, val.id); + if (nevery % val.val.f->global_freq) + error->all(FLERR, "Fix {} for {} not computed at compatible time", val.id, mycmd); - } else if (which[i] == ArgInfo::VARIABLE && kind == GLOBAL && mode == SCALAR) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name for fix ave/histo does not exist"); - if (argindex[i] == 0 && input->variable->equalstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/histo variable is not equal-style variable"); - if (argindex[i] && input->variable->vectorstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/histo variable is not vector-style variable"); + } else if (val.which == ArgInfo::VARIABLE && kind == GLOBAL && mode == SCALAR) { + if (val.argindex == 0 && input->variable->equalstyle(val.val.v) == 0) + error->all(FLERR,"{} variable {} is not equal-style variable", mycmd, val.id); + if (val.argindex && input->variable->vectorstyle(val.val.v) == 0) + error->all(FLERR,"{} variable {} is not vector-style variable" , mycmd, val.id); - } else if (which[i] == ArgInfo::VARIABLE && kind == GLOBAL && mode == VECTOR) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name for fix ave/histo does not exist"); - if (argindex[i] == 0 && input->variable->vectorstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/histo variable is not vector-style variable"); - if (argindex[i]) - error->all(FLERR,"Fix ave/histo variable cannot be indexed"); + } else if (val.which == ArgInfo::VARIABLE && kind == GLOBAL && mode == VECTOR) { + if (val.argindex == 0 && input->variable->vectorstyle(val.val.v) == 0) + error->all(FLERR,"{} variable {} is not vector-style variable", mycmd, val.id); + if (val.argindex) error->all(FLERR,"{} variable {} cannot be indexed", mycmd, val.id); - } else if (which[i] == ArgInfo::VARIABLE && kind == PERATOM) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name for fix ave/histo does not exist"); - if (argindex[i] == 0 && input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/histo variable is not atom-style variable"); - if (argindex[i]) - error->all(FLERR,"Fix ave/histo variable cannot be indexed"); + } else if (val.which == ArgInfo::VARIABLE && kind == PERATOM) { + if (val.argindex == 0 && input->variable->atomstyle(val.val.v) == 0) + error->all(FLERR,"{} variable {} is not atom-style variable", mycmd, val.id); + if (val.argindex) error->all(FLERR,"{} variable {} cannot be indexed", mycmd, val.id); } } // print file comment lines - if (fp && me == 0) { + if (fp && comm->me == 0) { clearerr(fp); if (title1) fprintf(fp,"%s\n",title1); else fprintf(fp,"# Histogrammed data for fix %s\n",id); @@ -431,9 +349,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : if (title3) fprintf(fp,"%s\n",title3); else fprintf(fp,"# Bin Coord Count Count/Total\n"); - if (ferror(fp)) - error->one(FLERR,"Error writing file header"); - + if (ferror(fp)) error->one(FLERR,"Error writing file header: {}", utils::getsyserror()); filepos = platform::ftell(fp); } @@ -502,13 +418,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : FixAveHisto::~FixAveHisto() { - delete[] which; - delete[] argindex; - delete[] value2index; - for (int i = 0; i < nvalues; i++) delete[] ids[i]; - delete[] ids; - - if (fp && me == 0) fclose(fp); + if (fp && comm->me == 0) fclose(fp); delete[] bin; delete[] bin_total; @@ -532,26 +442,20 @@ int FixAveHisto::setmask() void FixAveHisto::init() { - // set current indices for all computes,fixes,variables + auto mycmd = fmt::format("fix {}", style); - 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 ave/histo does not exist"); - value2index[i] = icompute; + // update indices/pointers for all computes,fixes,variables - } else if (which[i] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/histo does not exist"); - value2index[i] = ifix; - - } else if (which[i] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name for fix ave/histo does not exist"); - value2index[i] = ivariable; + 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 {} does not exist", val.id, mycmd); + } 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 {} does not exist", val.id, mycmd); + } 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 {} does not exist", val.id, mycmd); } } @@ -577,8 +481,6 @@ void FixAveHisto::setup(int /*vflag*/) void FixAveHisto::end_of_step() { - int i,j,m; - // skip if not step which requires doing something bigint ntimestep = update->ntimestep; @@ -591,7 +493,7 @@ void FixAveHisto::end_of_step() stats[0] = stats[1] = 0.0; stats[2] = BIG; stats[3] = -BIG; - for (i = 0; i < nbins; i++) bin[i] = 0.0; + for (int i = 0; i < nbins; i++) bin[i] = 0.0; } // accumulate results of computes,fixes,variables to local copy @@ -599,132 +501,128 @@ void FixAveHisto::end_of_step() modify->clearstep_compute(); - for (i = 0; i < nvalues; i++) { - m = value2index[i]; - j = argindex[i]; + for (auto &val : values) { + int j = val.argindex; // atom attributes - if (which[i] == ArgInfo::X) + if (val.which == ArgInfo::X) bin_atoms(&atom->x[0][j],3); - else if (which[i] == ArgInfo::V) + else if (val.which == ArgInfo::V) bin_atoms(&atom->v[0][j],3); - else if (which[i] == ArgInfo::F) + else if (val.which == ArgInfo::F) bin_atoms(&atom->f[0][j],3); // invoke compute if not previously invoked - if (which[i] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[m]; + if (val.which == ArgInfo::COMPUTE) { if (kind == GLOBAL && mode == SCALAR) { if (j == 0) { - if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) { - compute->compute_scalar(); - compute->invoked_flag |= Compute::INVOKED_SCALAR; + if (!(val.val.c->invoked_flag & Compute::INVOKED_SCALAR)) { + val.val.c->compute_scalar(); + val.val.c->invoked_flag |= Compute::INVOKED_SCALAR; } - bin_one(compute->scalar); + bin_one(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; } - bin_one(compute->vector[j-1]); + bin_one(val.val.c->vector[j-1]); } } else if (kind == GLOBAL && mode == VECTOR) { if (j == 0) { - 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; } - bin_vector(compute->size_vector,compute->vector,1); + bin_vector(val.val.c->size_vector,val.val.c->vector,1); } else { - if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { - compute->compute_array(); - compute->invoked_flag |= Compute::INVOKED_ARRAY; + if (!(val.val.c->invoked_flag & Compute::INVOKED_ARRAY)) { + val.val.c->compute_array(); + val.val.c->invoked_flag |= Compute::INVOKED_ARRAY; } - if (compute->array) - bin_vector(compute->size_array_rows,&compute->array[0][j-1], - compute->size_array_cols); + if (val.val.c->array) + bin_vector(val.val.c->size_array_rows,&val.val.c->array[0][j-1], + val.val.c->size_array_cols); } } else if (kind == PERATOM) { - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + val.val.c->compute_peratom(); + val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } if (j == 0) - bin_atoms(compute->vector_atom,1); - else if (compute->array_atom) - bin_atoms(&compute->array_atom[0][j-1],compute->size_peratom_cols); + bin_atoms(val.val.c->vector_atom,1); + else if (val.val.c->array_atom) + bin_atoms(&val.val.c->array_atom[0][j-1],val.val.c->size_peratom_cols); } else if (kind == LOCAL) { - if (!(compute->invoked_flag & Compute::INVOKED_LOCAL)) { - compute->compute_local(); - compute->invoked_flag |= Compute::INVOKED_LOCAL; + if (!(val.val.c->invoked_flag & Compute::INVOKED_LOCAL)) { + val.val.c->compute_local(); + val.val.c->invoked_flag |= Compute::INVOKED_LOCAL; } if (j == 0) - bin_vector(compute->size_local_rows,compute->vector_local,1); - else if (compute->array_local) - bin_vector(compute->size_local_rows,&compute->array_local[0][j-1], - compute->size_local_cols); + bin_vector(val.val.c->size_local_rows,val.val.c->vector_local,1); + else if (val.val.c->array_local) + bin_vector(val.val.c->size_local_rows,&val.val.c->array_local[0][j-1], + val.val.c->size_local_cols); } // access fix fields, guaranteed to be ready - } else if (which[i] == ArgInfo::FIX) { - - Fix *fix = modify->fix[m]; + } else if (val.which == ArgInfo::FIX) { if (kind == GLOBAL && mode == SCALAR) { - if (j == 0) bin_one(fix->compute_scalar()); - else bin_one(fix->compute_vector(j-1)); + if (j == 0) bin_one(val.val.f->compute_scalar()); + else bin_one(val.val.f->compute_vector(j-1)); } else if (kind == GLOBAL && mode == VECTOR) { if (j == 0) { - int n = fix->size_vector; - for (i = 0; i < n; i++) bin_one(fix->compute_vector(i)); + int n = val.val.f->size_vector; + for (int i = 0; i < n; i++) bin_one(val.val.f->compute_vector(i)); } else { - int n = fix->size_vector; - for (i = 0; i < n; i++) bin_one(fix->compute_array(i,j-1)); + int n = val.val.f->size_vector; + for (int i = 0; i < n; i++) bin_one(val.val.f->compute_array(i,j-1)); } } else if (kind == PERATOM) { - if (j == 0) bin_atoms(fix->vector_atom,1); - else if (fix->array_atom) - bin_atoms(fix->array_atom[j-1],fix->size_peratom_cols); + if (j == 0) bin_atoms(val.val.f->vector_atom,1); + else if (val.val.f->array_atom) + bin_atoms(val.val.f->array_atom[j-1],val.val.f->size_peratom_cols); } else if (kind == LOCAL) { - if (j == 0) bin_vector(fix->size_local_rows,fix->vector_local,1); - else if (fix->array_local) - bin_vector(fix->size_local_rows,&fix->array_local[0][j-1], - fix->size_local_cols); + if (j == 0) bin_vector(val.val.f->size_local_rows,val.val.f->vector_local,1); + else if (val.val.f->array_local) + bin_vector(val.val.f->size_local_rows,&val.val.f->array_local[0][j-1], + val.val.f->size_local_cols); } // evaluate equal-style or vector-style or atom-style variable - } else if (which[i] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { if (kind == GLOBAL && mode == SCALAR) { - if (j == 0) bin_one(input->variable->compute_equal(m)); + if (j == 0) bin_one(input->variable->compute_equal(val.val.v)); else { double *varvec; - int nvec = input->variable->compute_vector(m,&varvec); + int nvec = input->variable->compute_vector(val.val.v,&varvec); if (nvec < j) bin_one(0.0); else bin_one(varvec[j-1]); } } else if (kind == GLOBAL && mode == VECTOR) { double *varvec; - int nvec = input->variable->compute_vector(m,&varvec); + int nvec = input->variable->compute_vector(val.val.v,&varvec); bin_vector(nvec,varvec,1); - } else if (which[i] == ArgInfo::VARIABLE && kind == PERATOM) { + } else if (val.which == ArgInfo::VARIABLE && kind == PERATOM) { if (atom->nmax > maxatom) { memory->destroy(vector); maxatom = atom->nmax; memory->create(vector,maxatom,"ave/histo:vector"); } - input->variable->compute_atom(m,igroup,vector,1,0); + input->variable->compute_atom(val.val.v,igroup,vector,1,0); bin_atoms(vector,1); } } @@ -756,7 +654,7 @@ void FixAveHisto::end_of_step() stats[1] = stats_all[1]; stats[2] = stats_all[2]; stats[3] = stats_all[3]; - for (i = 0; i < nbins; i++) bin[i] = bin_all[i]; + for (int i = 0; i < nbins; i++) bin[i] = bin_all[i]; } // if ave = ONE, only single Nfreq timestep value is needed @@ -768,16 +666,17 @@ void FixAveHisto::end_of_step() stats_total[1] = stats[1]; stats_total[2] = stats[2]; stats_total[3] = stats[3]; - for (i = 0; i < nbins; i++) bin_total[i] = bin[i]; + for (int i = 0; i < nbins; i++) bin_total[i] = bin[i]; } else if (ave == RUNNING) { stats_total[0] += stats[0]; stats_total[1] += stats[1]; stats_total[2] = MIN(stats_total[2],stats[2]); stats_total[3] = MAX(stats_total[3],stats[3]); - for (i = 0; i < nbins; i++) bin_total[i] += bin[i]; + for (int i = 0; i < nbins; i++) bin_total[i] += bin[i]; } else if (ave == WINDOW) { + int m; stats_total[0] += stats[0]; if (window_limit) stats_total[0] -= stats_list[iwindow][0]; stats_list[iwindow][0] = stats[0]; @@ -790,14 +689,14 @@ void FixAveHisto::end_of_step() stats_list[iwindow][2] = stats[2]; stats_total[2] = stats_list[0][2]; - for (i = 1; i < m; i++) + for (int i = 1; i < m; i++) stats_total[2] = MIN(stats_total[2],stats_list[i][2]); stats_list[iwindow][3] = stats[3]; stats_total[3] = stats_list[0][3]; - for (i = 1; i < m; i++) + for (int i = 1; i < m; i++) stats_total[3] = MAX(stats_total[3],stats_list[i][3]); - for (i = 0; i < nbins; i++) { + for (int i = 0; i < nbins; i++) { bin_total[i] += bin[i]; if (window_limit) bin_total[i] -= bin_list[iwindow][i]; bin_list[iwindow][i] = bin[i]; @@ -812,17 +711,17 @@ void FixAveHisto::end_of_step() // output result to file - if (fp && me == 0) { + if (fp && comm->me == 0) { clearerr(fp); if (overwrite) platform::fseek(fp,filepos); fmt::print(fp,"{} {} {} {} {} {}\n",ntimestep,nbins, stats_total[0],stats_total[1],stats_total[2],stats_total[3]); if (stats_total[0] != 0.0) - for (i = 0; i < nbins; i++) + for (int i = 0; i < nbins; i++) fprintf(fp,"%d %g %g %g\n", i+1,coord[i],bin_total[i],bin_total[i]/stats_total[0]); else - for (i = 0; i < nbins; i++) + for (int i = 0; i < nbins; i++) fprintf(fp,"%d %g %g %g\n",i+1,coord[i],0.0,0.0); if (ferror(fp)) @@ -937,73 +836,74 @@ void FixAveHisto::options(int iarg, int narg, char **arg) title3 = nullptr; // optional args - + auto mycmd = fmt::format("fix {}", style); + while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); - if (me == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " file", error); + if (comm->me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == nullptr) - error->one(FLERR,"Cannot open fix ave/histo file {}: {}", - arg[iarg+1], utils::getsyserror()); + error->one(FLERR, "Cannot open fix ave/histo file {}: {}", + arg[iarg+1], utils::getsyserror()); } iarg += 2; } else if (strcmp(arg[iarg],"kind") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " kind", error); if (strcmp(arg[iarg+1],"global") == 0) kind = GLOBAL; else if (strcmp(arg[iarg+1],"peratom") == 0) kind = PERATOM; else if (strcmp(arg[iarg+1],"local") == 0) kind = LOCAL; - else error->all(FLERR,"Illegal fix ave/histo command"); + else error->all(FLERR,"Unknown fix ave/histo kind option: {}", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " ave", error); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW; - else error->all(FLERR,"Illegal fix ave/histo command"); + else error->all(FLERR,"Unknown fix ave/histo ave option: {}", arg[iarg+1]); if (ave == WINDOW) { - if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, mycmd + " ave window", error); nwindow = utils::inumeric(FLERR,arg[iarg+2],false,lmp); - if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/histo command"); + if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/histo ave window size: {}", nwindow); } iarg += 2; if (ave == WINDOW) iarg++; } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " start", error); startstep = utils::inumeric(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"mode") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " mode", error); if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR; else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR; - else error->all(FLERR,"Illegal fix ave/histo command"); + else error->all(FLERR,"Unknown fix ave/histo mode option: {}", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"beyond") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " beyond", error); if (strcmp(arg[iarg+1],"ignore") == 0) beyond = IGNORE; else if (strcmp(arg[iarg+1],"end") == 0) beyond = END; else if (strcmp(arg[iarg+1],"extra") == 0) beyond = EXTRA; - else error->all(FLERR,"Illegal fix ave/histo command"); + else error->all(FLERR,"Unknown fix ave/histo beyond option: {}", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"overwrite") == 0) { overwrite = 1; iarg += 1; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " title1", error); delete[] title1; title1 = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " title2", error); delete[] title2; title2 = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " title3", error); delete[] title3; title3 = utils::strdup(arg[iarg+1]); iarg += 2; - } else error->all(FLERR,"Illegal fix ave/histo command"); + } else error->all(FLERR,"Unknown {} option: {}", mycmd, arg[iarg]); } } diff --git a/src/fix_ave_histo.h b/src/fix_ave_histo.h index ed64c8562d..620fb3b321 100644 --- a/src/fix_ave_histo.h +++ b/src/fix_ave_histo.h @@ -36,11 +36,21 @@ class FixAveHisto : public Fix { double compute_array(int, int) override; protected: - int me, nvalues; - int nrepeat, nfreq, irepeat; + struct value_t { + int which; // type of data: COMPUTE, FIX, VARIABLE + int argindex; // 1-based index if data is vector, else 0 + std::string id; // compute/fix/variable ID + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; + + int nvalues, nrepeat, nfreq, irepeat; bigint nvalid, nvalid_last; - int *which, *argindex, *value2index; - char **ids; + FILE *fp; double lo, hi, binsize, bininv; int kind, beyond, overwrite; diff --git a/src/fix_ave_histo_weight.cpp b/src/fix_ave_histo_weight.cpp index f90551b52f..8051d93b7c 100644 --- a/src/fix_ave_histo_weight.cpp +++ b/src/fix_ave_histo_weight.cpp @@ -19,6 +19,7 @@ #include "arg_info.h" #include "atom.h" +#include "comm.h" #include "compute.h" #include "error.h" #include "fix.h" @@ -31,68 +32,61 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{ONE,RUNNING}; -enum{SCALAR,VECTOR,WINDOW}; -enum{DEFAULT,GLOBAL,PERATOM,LOCAL}; -enum{IGNORE,END,EXTRA}; -enum{SINGLE,VALUE}; +enum { ONE, RUNNING }; +enum { SCALAR, VECTOR, WINDOW }; +enum { DEFAULT, GLOBAL, PERATOM, LOCAL }; +enum { IGNORE, END, EXTRA }; +enum { SINGLE, VALUE }; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ FixAveHistoWeight::FixAveHistoWeight(LAMMPS *lmp, int narg, char **arg) : - FixAveHisto(lmp, narg, arg) + FixAveHisto(lmp, narg, arg) { // nvalues = 2 required for histo/weight - if (nvalues != 2) error->all(FLERR,"Illegal fix ave/histo/weight command"); + if (nvalues != 2) + error->all(FLERR, "Illegal fix ave/histo/weight command: must have two data arguments"); // check that length of 2 values is the same - int size[2] = {0,0}; + int size[2] = {0, 0}; for (int i = 0; i < nvalues; i++) { - if (which[i] == ArgInfo::X || which[i] == ArgInfo::V || which[i] == ArgInfo::F) { + auto &val = values[i]; + if (val.which == ArgInfo::X || val.which == ArgInfo::V || val.which == ArgInfo::F) { size[i] = atom->nlocal; - } else if (which[i] == ArgInfo::COMPUTE && kind == GLOBAL && mode == SCALAR) { - int icompute = modify->find_compute(ids[i]); - size[i] = modify->compute[icompute]->size_vector; - } else if (which[i] == ArgInfo::COMPUTE && kind == GLOBAL && mode == VECTOR) { - int icompute = modify->find_compute(ids[i]); - size[i] = modify->compute[icompute]->size_array_rows; - } else if (which[i] == ArgInfo::COMPUTE && kind == PERATOM) { + } else if (val.which == ArgInfo::COMPUTE && kind == GLOBAL && mode == SCALAR) { + size[i] = val.val.c->size_vector; + } else if (val.which == ArgInfo::COMPUTE && kind == GLOBAL && mode == VECTOR) { + size[i] = val.val.c->size_array_rows; + } else if (val.which == ArgInfo::COMPUTE && kind == PERATOM) { size[i] = atom->nlocal; - } else if (which[i] == ArgInfo::COMPUTE && kind == LOCAL) { - int icompute = modify->find_compute(ids[i]); - size[i] = modify->compute[icompute]->size_local_rows; - } else if (which[i] == ArgInfo::FIX && kind == GLOBAL && mode == SCALAR) { - int ifix = modify->find_fix(ids[i]); - size[i] = modify->fix[ifix]->size_vector; - } else if (which[i] == ArgInfo::FIX && kind == GLOBAL && mode == VECTOR) { - int ifix = modify->find_fix(ids[i]); - size[i]= modify->fix[ifix]->size_array_rows; - } else if (which[i] == ArgInfo::FIX && kind == PERATOM) { + } else if (val.which == ArgInfo::COMPUTE && kind == LOCAL) { + size[i] = val.val.c->size_local_rows; + } else if (val.which == ArgInfo::FIX && kind == GLOBAL && mode == SCALAR) { + size[i] = val.val.f->size_vector; + } else if (val.which == ArgInfo::FIX && kind == GLOBAL && mode == VECTOR) { + size[i]= val.val.f->size_array_rows; + } else if (val.which == ArgInfo::FIX && kind == PERATOM) { size[i] = atom->nlocal; - } else if (which[i] == ArgInfo::FIX && kind == LOCAL) { - int ifix = modify->find_fix(ids[i]); - size[i] = modify->fix[ifix]->size_local_rows; - } else if (which[i] == ArgInfo::VARIABLE && kind == PERATOM) { + } else if (val.which == ArgInfo::FIX && kind == LOCAL) { + size[i] = val.val.f->size_local_rows; + } else if (val.which == ArgInfo::VARIABLE && kind == PERATOM) { size[i] = atom->nlocal; } } if (size[0] != size[1]) - error->all(FLERR,"Fix ave/histo/weight value and weight vector " - "lengths do not match"); + error->all(FLERR,"Fix ave/histo/weight value and weight vector lengths do not match"); } /* ---------------------------------------------------------------------- */ void FixAveHistoWeight::end_of_step() { - int i,j,m; - // skip if not step which requires doing something bigint ntimestep = update->ntimestep; @@ -105,7 +99,7 @@ void FixAveHistoWeight::end_of_step() stats[0] = stats[1] = 0.0; stats[2] = BIG; stats[3] = -BIG; - for (i = 0; i < nbins; i++) bin[i] = 0.0; + for (int i = 0; i < nbins; i++) bin[i] = 0.0; } // first calculate weight factors, then bin single value @@ -119,265 +113,256 @@ void FixAveHistoWeight::end_of_step() double weight = 0.0; double *weights = nullptr; int stride = 0; - i = 1; - - m = value2index[i]; - j = argindex[i]; + auto &val = values[1]; + int j = val.argindex; // atom attributes - if (which[i] == ArgInfo::X) { + if (val.which == ArgInfo::X) { weights = &atom->x[0][j]; stride = 3; - } else if (which[i] == ArgInfo::V) { + } else if (val.which == ArgInfo::V) { weights = &atom->v[0][j]; stride = 3; bin_atoms(&atom->v[0][j],3); - } else if (which[i] == ArgInfo::F) { + } else if (val.which == ArgInfo::F) { weights = &atom->f[0][j]; stride = 3; } // invoke compute if not previously invoked - if (which[i] == ArgInfo::COMPUTE) { - - Compute *compute = modify->compute[m]; + if (val.which == ArgInfo::COMPUTE) { if (kind == GLOBAL && mode == SCALAR) { if (j == 0) { - if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) { - compute->compute_scalar(); - compute->invoked_flag |= Compute::INVOKED_SCALAR; + if (!(val.val.c->invoked_flag & Compute::INVOKED_SCALAR)) { + val.val.c->compute_scalar(); + val.val.c->invoked_flag |= Compute::INVOKED_SCALAR; } - weight = compute->scalar; + weight = 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; } - weight = compute->vector[j-1]; + weight = val.val.c->vector[j-1]; } } else if (kind == GLOBAL && mode == VECTOR) { if (j == 0) { - 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; } - weights = compute->vector; + weights = val.val.c->vector; stride = 1; } else { - if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { - compute->compute_array(); - compute->invoked_flag |= Compute::INVOKED_ARRAY; + if (!(val.val.c->invoked_flag & Compute::INVOKED_ARRAY)) { + val.val.c->compute_array(); + val.val.c->invoked_flag |= Compute::INVOKED_ARRAY; } - if (compute->array) weights = &compute->array[0][j-1]; - stride = compute->size_array_cols; + if (val.val.c->array) weights = &val.val.c->array[0][j-1]; + stride = val.val.c->size_array_cols; } } else if (kind == PERATOM) { - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + val.val.c->compute_peratom(); + val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } if (j == 0) { - weights = compute->vector_atom; + weights = val.val.c->vector_atom; stride = 1; - } else if (compute->array_atom) { - weights = &compute->array_atom[0][j-1]; - stride = compute->size_peratom_cols; + } else if (val.val.c->array_atom) { + weights = &val.val.c->array_atom[0][j-1]; + stride = val.val.c->size_peratom_cols; } } else if (kind == LOCAL) { - if (!(compute->invoked_flag & Compute::INVOKED_LOCAL)) { - compute->compute_local(); - compute->invoked_flag |= Compute::INVOKED_LOCAL; + if (!(val.val.c->invoked_flag & Compute::INVOKED_LOCAL)) { + val.val.c->compute_local(); + val.val.c->invoked_flag |= Compute::INVOKED_LOCAL; } if (j == 0) { - weights = compute->vector_local; + weights = val.val.c->vector_local; stride = 1; - } else if (compute->array_local) { - weights = &compute->array_local[0][j-1]; - stride = compute->size_local_cols; + } else if (val.val.c->array_local) { + weights = &val.val.c->array_local[0][j-1]; + stride = val.val.c->size_local_cols; } } // access fix fields, guaranteed to be ready - } else if (which[i] == ArgInfo::FIX) { - - Fix *fix = modify->fix[m]; + } else if (val.which == ArgInfo::FIX) { if (kind == GLOBAL && mode == SCALAR) { - if (j == 0) weight = fix->compute_scalar(); - else weight = fix->compute_vector(j-1); + if (j == 0) weight = val.val.f->compute_scalar(); + else weight = val.val.f->compute_vector(j-1); } else if (kind == GLOBAL && mode == VECTOR) { error->all(FLERR,"Fix ave/histo/weight option not yet supported"); // NOTE: need to allocate local storage if (j == 0) { - int n = fix->size_vector; - for (i = 0; i < n; i++) weights[n] = fix->compute_vector(i); + int n = val.val.f->size_vector; + for (int i = 0; i < n; i++) weights[n] = val.val.f->compute_vector(i); } else { - int n = fix->size_vector; - for (i = 0; i < n; i++) weights[n] = fix->compute_array(i,j-1); + int n = val.val.f->size_vector; + for (int i = 0; i < n; i++) weights[n] = val.val.f->compute_array(i,j-1); } } else if (kind == PERATOM) { if (j == 0) { - weights = fix->vector_atom; + weights = val.val.f->vector_atom; stride = 1; - } else if (fix->array_atom) { - weights = fix->array_atom[j-1]; - stride = fix->size_peratom_cols; + } else if (val.val.f->array_atom) { + weights = val.val.f->array_atom[j-1]; + stride = val.val.f->size_peratom_cols; } } else if (kind == LOCAL) { if (j == 0) { - weights = fix->vector_local; + weights = val.val.f->vector_local; stride = 1; - } else if (fix->array_local) { - weights = &fix->array_local[0][j-1]; - stride = fix->size_local_cols; + } else if (val.val.f->array_local) { + weights = &val.val.f->array_local[0][j-1]; + stride = val.val.f->size_local_cols; } } // evaluate equal-style variable - } else if (which[i] == ArgInfo::VARIABLE && kind == GLOBAL) { - weight = input->variable->compute_equal(m); + } else if (val.which == ArgInfo::VARIABLE && kind == GLOBAL) { + weight = input->variable->compute_equal(val.val.v); - } else if (which[i] == ArgInfo::VARIABLE && kind == PERATOM) { + } else if (val.which == ArgInfo::VARIABLE && kind == PERATOM) { if (atom->nmax > maxatom) { memory->destroy(vector); maxatom = atom->nmax; memory->create(vector,maxatom,"ave/histo/weight:vector"); } - input->variable->compute_atom(m,igroup,vector,1,0); + input->variable->compute_atom(val.val.v,igroup,vector,1,0); weights = vector; stride = 1; } // bin values using weights, values are 1st value (i = 0) - i = 0; - m = value2index[i]; - j = argindex[i]; + val = values[0]; + j = val.argindex; // atom attributes - if (which[i] == ArgInfo::X && weights != nullptr) + if (val.which == ArgInfo::X && weights != nullptr) bin_atoms_weights(&atom->x[0][j],3,weights,stride); - else if (which[i] == ArgInfo::V && weights != nullptr) + else if (val.which == ArgInfo::V && weights != nullptr) bin_atoms_weights(&atom->v[0][j],3,weights,stride); - else if (which[i] == ArgInfo::F && weights != nullptr) + else if (val.which == ArgInfo::F && weights != nullptr) bin_atoms_weights(&atom->f[0][j],3,weights,stride); // invoke compute if not previously invoked - if (which[i] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[m]; + if (val.which == ArgInfo::COMPUTE) { + if (kind == GLOBAL && mode == SCALAR) { if (j == 0) { - if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) { - compute->compute_scalar(); - compute->invoked_flag |= Compute::INVOKED_SCALAR; + if (!(val.val.c->invoked_flag & Compute::INVOKED_SCALAR)) { + val.val.c->compute_scalar(); + val.val.c->invoked_flag |= Compute::INVOKED_SCALAR; } - bin_one_weights(compute->scalar,weight); + bin_one_weights(val.val.c->scalar,weight); } 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; } - bin_one_weights(compute->vector[j-1],weight); + bin_one_weights(val.val.c->vector[j-1],weight); } } else if (kind == GLOBAL && mode == VECTOR) { if (j == 0) { - 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; } - bin_vector_weights(compute->size_vector,compute->vector,1, + bin_vector_weights(val.val.c->size_vector,val.val.c->vector,1, weights,stride); } else { - if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { - compute->compute_array(); - compute->invoked_flag |= Compute::INVOKED_ARRAY; + if (!(val.val.c->invoked_flag & Compute::INVOKED_ARRAY)) { + val.val.c->compute_array(); + val.val.c->invoked_flag |= Compute::INVOKED_ARRAY; } - if (compute->array) - bin_vector_weights(compute->size_array_rows,&compute->array[0][j-1], - compute->size_array_cols,weights,stride); + if (val.val.c->array) + bin_vector_weights(val.val.c->size_array_rows,&val.val.c->array[0][j-1], + val.val.c->size_array_cols,weights,stride); } } else if (kind == PERATOM) { - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + if (!(val.val.c->invoked_flag & Compute::INVOKED_PERATOM)) { + val.val.c->compute_peratom(); + val.val.c->invoked_flag |= Compute::INVOKED_PERATOM; } if (j == 0) - bin_atoms_weights(compute->vector_atom,1,weights, stride); - else if (compute->array_atom) - bin_atoms_weights(&compute->array_atom[0][j-1], - compute->size_peratom_cols,weights,stride); + bin_atoms_weights(val.val.c->vector_atom,1,weights, stride); + else if (val.val.c->array_atom) + bin_atoms_weights(&val.val.c->array_atom[0][j-1], + val.val.c->size_peratom_cols,weights,stride); } else if (kind == LOCAL) { - if (!(compute->invoked_flag & Compute::INVOKED_LOCAL)) { - compute->compute_local(); - compute->invoked_flag |= Compute::INVOKED_LOCAL; + if (!(val.val.c->invoked_flag & Compute::INVOKED_LOCAL)) { + val.val.c->compute_local(); + val.val.c->invoked_flag |= Compute::INVOKED_LOCAL; } if (j == 0) - bin_vector_weights(compute->size_local_rows, - compute->vector_local,1,weights,stride); - else if (compute->array_local) - bin_vector_weights(compute->size_local_rows, - &compute->array_local[0][j-1], - compute->size_local_cols,weights,stride); + bin_vector_weights(val.val.c->size_local_rows, + val.val.c->vector_local,1,weights,stride); + else if (val.val.c->array_local) + bin_vector_weights(val.val.c->size_local_rows, + &val.val.c->array_local[0][j-1], + val.val.c->size_local_cols,weights,stride); } // access fix fields, guaranteed to be ready - } else if (which[i] == ArgInfo::FIX) { - - Fix *fix = modify->fix[m]; + } else if (val.which == ArgInfo::FIX) { if (kind == GLOBAL && mode == SCALAR) { - if (j == 0) bin_one_weights(fix->compute_scalar(),weight); - else bin_one_weights(fix->compute_vector(j-1),weight); + if (j == 0) bin_one_weights(val.val.f->compute_scalar(),weight); + else bin_one_weights(val.val.f->compute_vector(j-1),weight); } else if (kind == GLOBAL && mode == VECTOR) { if (j == 0) { - int n = fix->size_vector; - for (i = 0; i < n; i++) - bin_one_weights(fix->compute_vector(i),weights[i*stride]); + int n = val.val.f->size_vector; + for (int i = 0; i < n; i++) + bin_one_weights(val.val.f->compute_vector(i),weights[i*stride]); } else { - int n = fix->size_vector; - for (i = 0; i < n; i++) - bin_one_weights(fix->compute_array(i,j-1),weights[i*stride]); + int n = val.val.f->size_vector; + for (int i = 0; i < n; i++) + bin_one_weights(val.val.f->compute_array(i,j-1),weights[i*stride]); } } else if (kind == PERATOM) { if (j == 0) - bin_atoms_weights(fix->vector_atom,1,weights,stride); - else if (fix->array_atom) - bin_atoms_weights(fix->array_atom[j-1],fix->size_peratom_cols, + bin_atoms_weights(val.val.f->vector_atom,1,weights,stride); + else if (val.val.f->array_atom) + bin_atoms_weights(val.val.f->array_atom[j-1],val.val.f->size_peratom_cols, weights,stride); } else if (kind == LOCAL) { - if (j == 0) bin_vector_weights(fix->size_local_rows,fix->vector_local,1, + if (j == 0) bin_vector_weights(val.val.f->size_local_rows,val.val.f->vector_local,1, weights,stride); - else if (fix->array_local) - bin_vector_weights(fix->size_local_rows,&fix->array_local[0][j-1], - fix->size_local_cols,weights,stride); + else if (val.val.f->array_local) + bin_vector_weights(val.val.f->size_local_rows,&val.val.f->array_local[0][j-1], + val.val.f->size_local_cols,weights,stride); } // evaluate equal-style variable - } else if (which[i] == ArgInfo::VARIABLE && kind == GLOBAL) { - bin_one_weights(input->variable->compute_equal(m),weight); + } else if (val.which == ArgInfo::VARIABLE && kind == GLOBAL) { + bin_one_weights(input->variable->compute_equal(val.val.v),weight); - } else if (which[i] == ArgInfo::VARIABLE && kind == PERATOM) { + } else if (val.which == ArgInfo::VARIABLE && kind == PERATOM) { if (atom->nmax > maxatom) { memory->destroy(vector); maxatom = atom->nmax; memory->create(vector,maxatom,"ave/histo/weight:vector"); } - input->variable->compute_atom(m,igroup,vector,1,0); + input->variable->compute_atom(val.val.v,igroup,vector,1,0); bin_atoms_weights(vector,1,weights,stride); } @@ -409,7 +394,7 @@ void FixAveHistoWeight::end_of_step() stats[1] = stats_all[1]; stats[2] = stats_all[2]; stats[3] = stats_all[3]; - for (i = 0; i < nbins; i++) bin[i] = bin_all[i]; + for (int i = 0; i < nbins; i++) bin[i] = bin_all[i]; } // if ave = ONE, only single Nfreq timestep value is needed @@ -421,14 +406,14 @@ void FixAveHistoWeight::end_of_step() stats_total[1] = stats[1]; stats_total[2] = stats[2]; stats_total[3] = stats[3]; - for (i = 0; i < nbins; i++) bin_total[i] = bin[i]; + for (int i = 0; i < nbins; i++) bin_total[i] = bin[i]; } else if (ave == RUNNING) { stats_total[0] += stats[0]; stats_total[1] += stats[1]; stats_total[2] = MIN(stats_total[2],stats[2]); stats_total[3] = MAX(stats_total[3],stats[3]); - for (i = 0; i < nbins; i++) bin_total[i] += bin[i]; + for (int i = 0; i < nbins; i++) bin_total[i] += bin[i]; } else if (ave == WINDOW) { stats_total[0] += stats[0]; @@ -438,19 +423,20 @@ void FixAveHistoWeight::end_of_step() if (window_limit) stats_total[1] -= stats_list[iwindow][1]; stats_list[iwindow][1] = stats[1]; + int m; if (window_limit) m = nwindow; else m = iwindow+1; stats_list[iwindow][2] = stats[2]; stats_total[2] = stats_list[0][2]; - for (i = 1; i < m; i++) + for (int i = 1; i < m; i++) stats_total[2] = MIN(stats_total[2],stats_list[i][2]); stats_list[iwindow][3] = stats[3]; stats_total[3] = stats_list[0][3]; - for (i = 1; i < m; i++) + for (int i = 1; i < m; i++) stats_total[3] = MAX(stats_total[3],stats_list[i][3]); - for (i = 0; i < nbins; i++) { + for (int i = 0; i < nbins; i++) { bin_total[i] += bin[i]; if (window_limit) bin_total[i] -= bin_list[iwindow][i]; bin_list[iwindow][i] = bin[i]; @@ -465,17 +451,17 @@ void FixAveHistoWeight::end_of_step() // output result to file - if (fp && me == 0) { + if (fp && comm->me == 0) { clearerr(fp); if (overwrite) platform::fseek(fp,filepos); fmt::print(fp,"{} {} {} {} {} {}\n",ntimestep,nbins, stats_total[0],stats_total[1],stats_total[2],stats_total[3]); if (stats_total[0] != 0.0) - for (i = 0; i < nbins; i++) + for (int i = 0; i < nbins; i++) fprintf(fp,"%d %g %g %g\n", i+1,coord[i],bin_total[i],bin_total[i]/stats_total[0]); else - for (i = 0; i < nbins; i++) + for (int i = 0; i < nbins; i++) fprintf(fp,"%d %g %g %g\n",i+1,coord[i],0.0,0.0); if (ferror(fp)) From 8ebad9ecd84027d4c6c68061a964c5a688acd2b6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 15 Oct 2022 09:34:47 -0400 Subject: [PATCH 10/20] convert fix ave/atom and fix ave/chunk --- src/fix_ave_atom.cpp | 279 ++++++++++++++++------------------- src/fix_ave_atom.h | 15 +- src/fix_ave_chunk.cpp | 333 +++++++++++++++++++----------------------- src/fix_ave_chunk.h | 17 ++- src/fix_ave_time.cpp | 15 +- 5 files changed, 307 insertions(+), 352 deletions(-) diff --git a/src/fix_ave_atom.cpp b/src/fix_ave_atom.cpp index a5661b1f52..303c06d227 100644 --- a/src/fix_ave_atom.cpp +++ b/src/fix_ave_atom.cpp @@ -31,149 +31,135 @@ using namespace FixConst; /* ---------------------------------------------------------------------- */ -FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), - ids(nullptr), array(nullptr) +FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), array(nullptr) { - if (narg < 7) error->all(FLERR,"Illegal fix ave/atom command"); + if (narg < 7) utils::missing_cmd_args(FLERR, "fix ave/atom", error); - nevery = utils::inumeric(FLERR,arg[3],false,lmp); - nrepeat = utils::inumeric(FLERR,arg[4],false,lmp); - peratom_freq = utils::inumeric(FLERR,arg[5],false,lmp); + nevery = utils::inumeric(FLERR, arg[3], false, lmp); + nrepeat = utils::inumeric(FLERR, arg[4], false, lmp); + peratom_freq = utils::inumeric(FLERR, arg[5], false, lmp); time_depend = 1; - nvalues = narg - 6; - // expand args if any have wildcard character "*" // this can reset nvalues int expand = 0; char **earg; - nvalues = utils::expand_args(FLERR,nvalues,&arg[6],1,earg,lmp); + int nvalues = utils::expand_args(FLERR, narg - 6, &arg[6], 1, earg, lmp); if (earg != &arg[6]) expand = 1; arg = earg; // parse values - which = new int[nvalues]; - argindex = new int[nvalues]; - ids = new char*[nvalues]; - value2index = new int[nvalues]; - + values.clear(); for (int i = 0; i < nvalues; i++) { - ids[i] = nullptr; - if (strcmp(arg[i],"x") == 0) { - which[i] = ArgInfo::X; - argindex[i] = 0; - } else if (strcmp(arg[i],"y") == 0) { - which[i] = ArgInfo::X; - argindex[i] = 1; - } else if (strcmp(arg[i],"z") == 0) { - which[i] = ArgInfo::X; - argindex[i] = 2; + value_t val; + val.id = ""; + val.val.c = nullptr; - } else if (strcmp(arg[i],"vx") == 0) { - which[i] = ArgInfo::V; - argindex[i] = 0; - } else if (strcmp(arg[i],"vy") == 0) { - which[i] = ArgInfo::V; - argindex[i] = 1; - } else if (strcmp(arg[i],"vz") == 0) { - which[i] = ArgInfo::V; - argindex[i] = 2; + if (strcmp(arg[i], "x") == 0) { + val.which = ArgInfo::X; + val.argindex = 0; + } else if (strcmp(arg[i], "y") == 0) { + val.which = ArgInfo::X; + val.argindex = 1; + } else if (strcmp(arg[i], "z") == 0) { + val.which = ArgInfo::X; + val.argindex = 2; - } else if (strcmp(arg[i],"fx") == 0) { - which[i] = ArgInfo::F; - argindex[i] = 0; - } else if (strcmp(arg[i],"fy") == 0) { - which[i] = ArgInfo::F; - argindex[i] = 1; - } else if (strcmp(arg[i],"fz") == 0) { - which[i] = ArgInfo::F; - argindex[i] = 2; + } else if (strcmp(arg[i], "vx") == 0) { + val.which = ArgInfo::V; + val.argindex = 0; + } else if (strcmp(arg[i], "vy") == 0) { + val.which = ArgInfo::V; + val.argindex = 1; + } else if (strcmp(arg[i], "vz") == 0) { + val.which = ArgInfo::V; + val.argindex = 2; + + } else if (strcmp(arg[i], "fx") == 0) { + val.which = ArgInfo::F; + val.argindex = 0; + } else if (strcmp(arg[i], "fy") == 0) { + val.which = ArgInfo::F; + val.argindex = 1; + } else if (strcmp(arg[i], "fz") == 0) { + val.which = ArgInfo::F; + val.argindex = 2; } else { ArgInfo argi(arg[i]); - which[i] = argi.get_type(); - argindex[i] = argi.get_index1(); - ids[i] = argi.copy_name(); + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); - if ((which[i] == ArgInfo::UNKNOWN) || (which[i] == ArgInfo::NONE) - || (argi.get_dim() > 1)) - error->all(FLERR,"Illegal fix ave/atom command"); + if ((val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi.get_dim() > 1)) + error->all(FLERR, "Invalid fix ave/atom argument: {}", arg[i]); } + values.push_back(val); } // if wildcard expansion occurred, free earg memory from exapnd_args() if (expand) { - for (int i = 0; i < nvalues; i++) delete [] earg[i]; + for (int i = 0; i < nvalues; i++) delete[] earg[i]; memory->sfree(earg); } // setup and error check // for fix inputs, check that fix frequency is acceptable - if (nevery <= 0 || nrepeat <= 0 || peratom_freq <= 0) - error->all(FLERR,"Illegal fix ave/atom command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix ave/atom nevery value: {}", nevery); + if (nrepeat <= 0) error->all(FLERR,"Illegal fix ave/atom nrepeat value: {}", nrepeat); + if (peratom_freq <= 0) error->all(FLERR,"Illegal fix ave/atom nfreq value: {}", peratom_freq); if (peratom_freq % nevery || nrepeat*nevery > peratom_freq) - error->all(FLERR,"Illegal fix ave/atom command"); + error->all(FLERR,"Inconsistent fix ave/atom nevery/nrepeat/nfreq values"); - 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 ave/atom does not exist"); - if (modify->compute[icompute]->peratom_flag == 0) - error->all(FLERR, - "Fix ave/atom compute does not calculate per-atom values"); - if (argindex[i] == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Fix ave/atom compute does not " - "calculate a per-atom vector"); - if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR,"Fix ave/atom compute does not " - "calculate a per-atom array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR,"Fix ave/atom compute array is accessed out-of-range"); + for (auto &val : values) { - } else if (which[i] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/atom does not exist"); - if (modify->fix[ifix]->peratom_flag == 0) - error->all(FLERR,"Fix ave/atom fix does not calculate per-atom values"); - if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all(FLERR, - "Fix ave/atom fix does not calculate a per-atom vector"); - if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all(FLERR, - "Fix ave/atom fix does not calculate a per-atom array"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all(FLERR,"Fix ave/atom fix array is accessed out-of-range"); - if (nevery % modify->fix[ifix]->peratom_freq) - error->all(FLERR, - "Fix for fix ave/atom not computed at compatible time"); + 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 ave/atom does not exist", val.id); + if (val.val.c->peratom_flag == 0) + error->all(FLERR, "Fix ave/atom compute {} does not calculate per-atom values", val.id); + if (val.argindex == 0 && val.val.c->size_peratom_cols != 0) + error->all(FLERR,"Fix ave/atom compute {} does not calculate a per-atom vector", val.id); + if (val.argindex && val.val.c->size_peratom_cols == 0) + error->all(FLERR,"Fix ave/atom compute {} does not calculate a per-atom array", val.id); + if (val.argindex && val.argindex > val.val.c->size_peratom_cols) + error->all(FLERR,"Fix ave/atom compute {} 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 fix ave/atom does not exist"); - if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/atom variable is not atom-style variable"); + } 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 ave/atom does not exist", val.id); + if (val.val.f->peratom_flag == 0) + error->all(FLERR, "Fix ave/atom fix {} does not calculate per-atom values", val.id); + if (val.argindex == 0 && val.val.f->size_peratom_cols != 0) + error->all(FLERR, "Fix ave/atom fix {} does not calculate a per-atom vector", val.id); + if (val.argindex && val.val.f->size_peratom_cols == 0) + error->all(FLERR, "Fix ave/atom fix {} does not calculate a per-atom array", val.id); + if (val.argindex && val.argindex > val.val.f->size_peratom_cols) + error->all(FLERR,"Fix ave/atom fix {} array is accessed out-of-range", val.id); + if (nevery % val.val.f->peratom_freq) + error->all(FLERR, "Fix {} for fix ave/atom not computed at compatible time", val.id); + + } 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 fix ave/atom does not exist", val.id); + if (input->variable->atomstyle(val.val.v) == 0) + error->all(FLERR,"Fix ave/atom variable {} is not atom-style variable", val.id); } } // this fix produces either a per-atom vector or array peratom_flag = 1; - if (nvalues == 1) size_peratom_cols = 0; - else size_peratom_cols = nvalues; + if (values.size() == 1) size_peratom_cols = 0; + else size_peratom_cols = values.size(); // perform initial allocation of atom-based array // register with Atom class @@ -186,7 +172,7 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - for (int m = 0; m < nvalues; m++) + for (std::size_t m = 0; m < values.size(); m++) array[i][m] = 0.0; // nvalid = next step on which end_of_step does something @@ -207,13 +193,6 @@ FixAveAtom::~FixAveAtom() // unregister callback to this fix from Atom class atom->delete_callback(id,Atom::GROW); - - delete [] which; - delete [] argindex; - for (int m = 0; m < nvalues; m++) delete [] ids[m]; - delete [] ids; - delete [] value2index; - memory->destroy(array); } @@ -232,26 +211,20 @@ void FixAveAtom::init() { // set indices and check validity 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 fix ave/atom 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 fix ave/atom 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 fix ave/atom 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 fix ave/atom 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 fix ave/atom does not exist"); - value2index[m] = ivariable; - - } else value2index[m] = -1; + } 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 fix ave/atom does not exist", val.id); + } } // need to reset nvalid if nvalid < ntimestep b/c minimize was performed @@ -276,8 +249,6 @@ void FixAveAtom::setup(int /*vflag*/) void FixAveAtom::end_of_step() { - int i,j,m,n; - // skip if not step which requires doing something bigint ntimestep = update->ntimestep; @@ -289,8 +260,8 @@ void FixAveAtom::end_of_step() int nlocal = atom->nlocal; if (irepeat == 0) - for (i = 0; i < nlocal; i++) - for (m = 0; m < nvalues; m++) + for (int i = 0; i < nlocal; i++) + for (std::size_t m = 0; m < values.size(); m++) array[i][m] = 0.0; // accumulate results of attributes,computes,fixes,variables to local copy @@ -300,55 +271,54 @@ void FixAveAtom::end_of_step() int *mask = atom->mask; - for (m = 0; m < nvalues; m++) { - n = value2index[m]; - j = argindex[m]; + int i, j, m = 0; + for (auto &val : values) { + j = val.argindex; - if (which[m] == ArgInfo::X) { + if (val.which == ArgInfo::X) { double **x = atom->x; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += x[i][j]; - } else if (which[m] == ArgInfo::V) { + } else if (val.which == ArgInfo::V) { double **v = atom->v; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += v[i][j]; - } else if (which[m] == ArgInfo::F) { + } else if (val.which == ArgInfo::F) { double **f = atom->f; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += f[i][j]; // invoke compute if not previously invoked - } else if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[n]; - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + } else 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 (j == 0) { - double *compute_vector = compute->vector_atom; + double *compute_vector = val.val.c->vector_atom; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += compute_vector[i]; } else { int jm1 = j - 1; - double **compute_array = compute->array_atom; + double **compute_array = val.val.c->array_atom; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += compute_array[i][jm1]; } // access fix fields, guaranteed to be ready - } else if (which[m] == ArgInfo::FIX) { + } else if (val.which == ArgInfo::FIX) { if (j == 0) { - double *fix_vector = modify->fix[n]->vector_atom; + double *fix_vector = val.val.f->vector_atom; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += fix_vector[i]; } else { int jm1 = j - 1; - double **fix_array = modify->fix[n]->array_atom; + double **fix_array = val.val.f->array_atom; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) array[i][m] += fix_array[i][jm1]; } @@ -356,10 +326,11 @@ void FixAveAtom::end_of_step() // evaluate atom-style variable // final argument = 1 sums result to array - } else if (which[m] == ArgInfo::VARIABLE) { - if (array) input->variable->compute_atom(n,igroup,&array[0][m],nvalues,1); - else input->variable->compute_atom(n,igroup,nullptr,nvalues,1); + } else if (val.which == ArgInfo::VARIABLE) { + if (array) input->variable->compute_atom(val.val.v,igroup,&array[0][m],values.size(),1); + else input->variable->compute_atom(val.val.v,igroup,nullptr,values.size(),1); } + ++m; } // done if irepeat < nrepeat @@ -382,7 +353,7 @@ void FixAveAtom::end_of_step() double repeat = nrepeat; for (i = 0; i < nlocal; i++) - for (m = 0; m < nvalues; m++) + for (m = 0; m < (int)values.size(); m++) array[i][m] /= repeat; } @@ -393,7 +364,7 @@ void FixAveAtom::end_of_step() double FixAveAtom::memory_usage() { double bytes; - bytes = (double)atom->nmax*nvalues * sizeof(double); + bytes = (double)atom->nmax*values.size() * sizeof(double); return bytes; } @@ -403,7 +374,7 @@ double FixAveAtom::memory_usage() void FixAveAtom::grow_arrays(int nmax) { - memory->grow(array,nmax,nvalues,"fix_ave/atom:array"); + memory->grow(array,nmax,values.size(),"fix_ave/atom:array"); array_atom = array; if (array) vector_atom = array[0]; else vector_atom = nullptr; @@ -415,7 +386,7 @@ void FixAveAtom::grow_arrays(int nmax) void FixAveAtom::copy_arrays(int i, int j, int /*delflag*/) { - for (int m = 0; m < nvalues; m++) + for (int m = 0; m < values.size(); m++) array[j][m] = array[i][m]; } @@ -425,8 +396,8 @@ void FixAveAtom::copy_arrays(int i, int j, int /*delflag*/) int FixAveAtom::pack_exchange(int i, double *buf) { - for (int m = 0; m < nvalues; m++) buf[m] = array[i][m]; - return nvalues; + for (int m = 0; m < values.size(); m++) buf[m] = array[i][m]; + return values.size(); } /* ---------------------------------------------------------------------- @@ -435,8 +406,8 @@ int FixAveAtom::pack_exchange(int i, double *buf) int FixAveAtom::unpack_exchange(int nlocal, double *buf) { - for (int m = 0; m < nvalues; m++) array[nlocal][m] = buf[m]; - return nvalues; + for (int m = 0; m < values.size(); m++) array[nlocal][m] = buf[m]; + return values.size(); } /* ---------------------------------------------------------------------- diff --git a/src/fix_ave_atom.h b/src/fix_ave_atom.h index f285004305..110eb1373a 100644 --- a/src/fix_ave_atom.h +++ b/src/fix_ave_atom.h @@ -40,11 +40,20 @@ class FixAveAtom : public Fix { int unpack_exchange(int, double *) override; private: - int nvalues; + struct value_t { + int which; // type of data: COMPUTE, FIX, VARIABLE + int argindex; // 1-based index if data is vector, else 0 + std::string id; // compute/fix/variable ID + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; + int nrepeat, irepeat; bigint nvalid, nvalid_last; - int *which, *argindex, *value2index; - char **ids; double **array; bigint nextvalid(); diff --git a/src/fix_ave_chunk.cpp b/src/fix_ave_chunk.cpp index 688c4676e1..6f399ed0d5 100644 --- a/src/fix_ave_chunk.cpp +++ b/src/fix_ave_chunk.cpp @@ -33,29 +33,24 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{SCALAR,VECTOR}; -enum{SAMPLE,ALL}; -enum{NOSCALE,ATOM}; -enum{ONE,RUNNING,WINDOW}; - +enum { SCALAR, VECTOR }; +enum { SAMPLE, ALL }; +enum { NOSCALE, ATOM }; +enum { ONE, RUNNING, WINDOW }; /* ---------------------------------------------------------------------- */ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - nvalues(0), nrepeat(0), - which(nullptr), argindex(nullptr), value2index(nullptr), ids(nullptr), - fp(nullptr), idchunk(nullptr), varatom(nullptr), - count_one(nullptr), count_many(nullptr), count_sum(nullptr), - values_one(nullptr), values_many(nullptr), values_sum(nullptr), - count_total(nullptr), count_list(nullptr), - values_total(nullptr), values_list(nullptr) + Fix(lmp, narg, arg), nvalues(0), nrepeat(0), fp(nullptr), idchunk(nullptr), varatom(nullptr), + count_one(nullptr), count_many(nullptr), count_sum(nullptr), values_one(nullptr), + values_many(nullptr), values_sum(nullptr), count_total(nullptr), count_list(nullptr), + values_total(nullptr), values_list(nullptr) { - if (narg < 7) error->all(FLERR,"Illegal fix ave/chunk command"); + if (narg < 7) utils::missing_cmd_args(FLERR, "fix ave/chunk", error); - nevery = utils::inumeric(FLERR,arg[3],false,lmp); - nrepeat = utils::inumeric(FLERR,arg[4],false,lmp); - nfreq = utils::inumeric(FLERR,arg[5],false,lmp); + nevery = utils::inumeric(FLERR, arg[3], false, lmp); + nrepeat = utils::inumeric(FLERR, arg[4], false, lmp); + nfreq = utils::inumeric(FLERR, arg[5], false, lmp); idchunk = utils::strdup(arg[6]); @@ -63,82 +58,81 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : no_change_box = 1; time_depend = 1; - char * group = arg[1]; + char *group = arg[1]; // expand args if any have wildcard character "*" int expand = 0; char **earg; - int nargnew = utils::expand_args(FLERR,narg-7,&arg[7],1,earg,lmp); + int nargnew = utils::expand_args(FLERR, narg - 7, &arg[7], 1, earg, lmp); if (earg != &arg[7]) 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]; densityflag = 0; int iarg = 0; + values.clear(); while (iarg < nargnew) { - ids[nvalues] = nullptr; + value_t val; + val.id = ""; + val.val.c = nullptr; if (strcmp(arg[iarg],"vx") == 0) { - which[nvalues] = ArgInfo::V; - argindex[nvalues++] = 0; + val.which = ArgInfo::V; + val.which = 0; } else if (strcmp(arg[iarg],"vy") == 0) { - which[nvalues] = ArgInfo::V; - argindex[nvalues++] = 1; + val.which = ArgInfo::V; + val.which = 1; } else if (strcmp(arg[iarg],"vz") == 0) { - which[nvalues] = ArgInfo::V; - argindex[nvalues++] = 2; + val.which = ArgInfo::V; + val.which = 2; } else if (strcmp(arg[iarg],"fx") == 0) { - which[nvalues] = ArgInfo::F; - argindex[nvalues++] = 0; + val.which = ArgInfo::F; + val.which = 0; } else if (strcmp(arg[iarg],"fy") == 0) { - which[nvalues] = ArgInfo::F; - argindex[nvalues++] = 1; + val.which = ArgInfo::F; + val.which = 1; } else if (strcmp(arg[iarg],"fz") == 0) { - which[nvalues] = ArgInfo::F; - argindex[nvalues++] = 2; + val.which = ArgInfo::F; + val.which = 2; } else if (strcmp(arg[iarg],"mass") == 0) { - which[nvalues] = ArgInfo::MASS; - argindex[nvalues++] = 0; + val.which = ArgInfo::MASS; + val.which = 0; } else if (strcmp(arg[iarg],"density/number") == 0) { densityflag = 1; - which[nvalues] = ArgInfo::DENSITY_NUMBER; - argindex[nvalues++] = 0; + val.which = ArgInfo::DENSITY_NUMBER; + val.which = 0; } else if (strcmp(arg[iarg],"density/mass") == 0) { densityflag = 1; - which[nvalues] = ArgInfo::DENSITY_MASS; - argindex[nvalues++] = 0; + val.which = ArgInfo::DENSITY_MASS; + val.which = 0; } else if (strcmp(arg[iarg],"temp") == 0) { - which[nvalues] = ArgInfo::TEMPERATURE; - argindex[nvalues++] = 0; + val.which = ArgInfo::TEMPERATURE; + val.which = 0; } else { ArgInfo argi(arg[iarg]); if (argi.get_type() == ArgInfo::NONE) break; if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) - error->all(FLERR,"Invalid fix ave/chunk command"); + error->all(FLERR,"Unknown fix ave/chunk data value: {}", arg[iarg]); - which[nvalues] = argi.get_type(); - argindex[nvalues] = argi.get_index1(); - ids[nvalues] = argi.copy_name(); - - nvalues++; + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); } + values.push_back(val); iarg++; } - if (nvalues == 0) error->all(FLERR,"No values in fix ave/chunk command"); + nvalues = values.size(); + if (nvalues == 0) error->all(FLERR, "No values in fix ave/chunk command"); // optional args @@ -159,7 +153,7 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : while (iarg < nargnew) { if (strcmp(arg[iarg],"norm") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk norm", error); if (strcmp(arg[iarg+1],"all") == 0) { normflag = ALL; scaleflag = ATOM; @@ -169,127 +163,124 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg+1],"none") == 0) { normflag = SAMPLE; scaleflag = NOSCALE; - } else error->all(FLERR,"Illegal fix ave/chunk command"); + } else error->all(FLERR,"Unknown fix ave/chunk norm mode: {}", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk ave", error); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW; - else error->all(FLERR,"Illegal fix ave/chunk command"); + else error->all(FLERR,"Unknown fix ave/chunk ave mode: {}", arg[iarg+1]); if (ave == WINDOW) { - if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk ave window", error); nwindow = utils::inumeric(FLERR,arg[iarg+2],false,lmp); - if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/chunk command"); + if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/chunk number of windows: {}", nwindow); } iarg += 2; if (ave == WINDOW) iarg++; } else if (strcmp(arg[iarg],"bias") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk bias", error); biasflag = 1; id_bias = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"adof") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk adof", error); adof = utils::numeric(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"cdof") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk cdof", error); cdof = utils::numeric(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk file", error); if (comm->me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == nullptr) - error->one(FLERR,"Cannot open fix ave/chunk file {}: {}", - arg[iarg+1], utils::getsyserror()); + error->one(FLERR, "Cannot open fix ave/chunk file {}: {}", + arg[iarg+1], utils::getsyserror()); } iarg += 2; } else if (strcmp(arg[iarg],"overwrite") == 0) { overwrite = 1; iarg += 1; } else if (strcmp(arg[iarg],"format") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk format", error); delete[] format_user; format_user = utils::strdup(arg[iarg+1]); format = format_user; iarg += 2; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk title1", error); delete[] title1; title1 = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk title2", error); delete[] title2; title2 = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/chunk command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/chunk title3", error); delete[] title3; title3 = utils::strdup(arg[iarg+1]); iarg += 2; - } else error->all(FLERR,"Illegal fix ave/chunk command"); + } else error->all(FLERR,"Unknown fix ave/chunk keyword: {}", arg[iarg]); } // setup and error check - if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all(FLERR,"Illegal fix ave/chunk command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix ave/chunk nevery value: {}", nevery); + if (nrepeat <= 0) error->all(FLERR,"Illegal fix ave/chunk nrepeat value: {}", nrepeat); + if (nfreq <= 0) error->all(FLERR,"Illegal fix ave/chunk nfreq value: {}", nfreq); if (nfreq % nevery || nrepeat*nevery > nfreq) - error->all(FLERR,"Illegal fix ave/chunk command"); + error->all(FLERR,"Inconsistent fix ave/chunk nevery/nrepeat/nfreq values"); if (ave != RUNNING && overwrite) - error->all(FLERR,"Illegal fix ave/chunk command"); + error->all(FLERR,"Fix ave/chunk overwrite keyword requires ave running setting"); if (biasflag) { - int i = modify->find_compute(id_bias); - if (i < 0) - error->all(FLERR,"Could not find compute ID for temperature bias"); - tbias = modify->compute[i]; + tbias = modify->get_compute_by_id(id_bias); + if (!tbias) error->all(FLERR,"Could not find compute ID {} for temperature bias", id_bias); if (tbias->tempflag == 0) - error->all(FLERR,"Bias compute does not calculate temperature"); + error->all(FLERR,"Bias compute {} does not calculate temperature", id_bias); if (tbias->tempbias == 0) - error->all(FLERR,"Bias compute does not calculate a velocity bias"); + error->all(FLERR,"Bias compute {} does not calculate a velocity bias", id_bias); } - 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 ave/chunk does not exist",ids[i]); - if (icompute->peratom_flag == 0) - error->all(FLERR,"Fix ave/chunk compute {} does not calculate per-atom values",ids[i]); - if (argindex[i] == 0 && (icompute->size_peratom_cols != 0)) - error->all(FLERR,"Fix ave/chunk compute {} does not calculate a per-atom vector",ids[i]); - if (argindex[i] && (icompute->size_peratom_cols == 0)) - error->all(FLERR,"Fix ave/chunk compute {} does not calculate a per-atom array",ids[i]); - if (argindex[i] && (argindex[i] > icompute->size_peratom_cols)) - error->all(FLERR,"Fix ave/chunk compute {} vector is accessed out-of-range",ids[i]); + for (auto &val : values) { - } else if (which[i] == ArgInfo::FIX) { - auto ifix = modify->get_fix_by_id(ids[i]); - if (!ifix) - error->all(FLERR, "Fix ID {} for fix ave/chunk does not exist",ids[i]); - if (ifix->peratom_flag == 0) - error->all(FLERR, "Fix ave/chunk fix {} does not calculate per-atom values",ids[i]); - if (argindex[i] == 0 && (ifix->size_peratom_cols != 0)) - error->all(FLERR, "Fix ave/chunk fix {} does not calculate a per-atom vector",ids[i]); - if (argindex[i] && (ifix->size_peratom_cols == 0)) - error->all(FLERR, "Fix ave/chunk fix {} does not calculate a per-atom array",ids[i]); - if (argindex[i] && argindex[i] > ifix->size_peratom_cols) - error->all(FLERR,"Fix ave/chunk fix {} vector is accessed out-of-range",ids[i]); - } else if (which[i] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) - error->all(FLERR,"Variable name {} for fix ave/chunk does not exist",ids[i]); - if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/chunk variable {} is not atom-style variable",ids[i]); + 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 ave/chunk does not exist",val.id); + if (val.val.c->peratom_flag == 0) + error->all(FLERR,"Fix ave/chunk compute {} does not calculate per-atom values",val.id); + if (val.argindex == 0 && (val.val.c->size_peratom_cols != 0)) + error->all(FLERR,"Fix ave/chunk compute {} does not calculate a per-atom vector",val.id); + if (val.argindex && (val.val.c->size_peratom_cols == 0)) + error->all(FLERR,"Fix ave/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,"Fix ave/chunk compute {} vector is accessed out-of-range",val.id); + + } 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 ave/chunk does not exist",val.id); + if (val.val.f->peratom_flag == 0) + error->all(FLERR, "Fix ave/chunk fix {} does not calculate per-atom values",val.id); + if (val.argindex == 0 && (val.val.f->size_peratom_cols != 0)) + error->all(FLERR, "Fix ave/chunk fix {} does not calculate a per-atom vector",val.id); + if (val.argindex && (val.val.f->size_peratom_cols == 0)) + error->all(FLERR, "Fix ave/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,"Fix ave/chunk fix {} vector is accessed out-of-range",val.id); + } 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 fix ave/chunk does not exist",val.id); + if (input->variable->atomstyle(val.val.v) == 0) + error->all(FLERR,"Fix ave/chunk variable {} is not atom-style variable",val.id); } } @@ -396,12 +387,6 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : FixAveChunk::~FixAveChunk() { - delete[] which; - delete[] argindex; - for (int i = 0; i < nvalues; i++) delete[] ids[i]; - delete[] ids; - delete[] value2index; - if (fp && comm->me == 0) fclose(fp); memory->destroy(varatom); @@ -427,10 +412,6 @@ FixAveChunk::~FixAveChunk() } delete[] idchunk; - which = nullptr; - argindex = nullptr; - ids = nullptr; - value2index = nullptr; fp = nullptr; varatom = nullptr; count_one = nullptr; @@ -463,42 +444,34 @@ void FixAveChunk::init() // set indices and check validity of all computes,fixes,variables // check that fix frequency is acceptable - int icompute = modify->find_compute(idchunk); - if (icompute < 0) - error->all(FLERR,"Chunk/atom compute does not exist for fix ave/chunk"); - cchunk = dynamic_cast(modify->compute[icompute]); + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (!cchunk) + error->all(FLERR,"Chunk/atom compute {} does not exist or is " + "incorrect style for fix ave/chunk",idchunk); if (biasflag) { - int i = modify->find_compute(id_bias); - if (i < 0) - error->all(FLERR,"Could not find compute ID for temperature bias"); - tbias = modify->compute[i]; + tbias = modify->get_compute_by_id(id_bias); + if (!tbias) + error->all(FLERR,"Could not find compute ID {} for temperature bias", id_bias); } - for (int m = 0; m < nvalues; m++) { - if (which[m] == ArgInfo::COMPUTE) { - icompute = modify->find_compute(ids[m]); - if (icompute < 0) - error->all(FLERR,"Compute ID for fix ave/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 fix ave/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 fix ave/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 fix ave/chunk does not exist", val.id); - if (nevery % modify->fix[ifix]->peratom_freq) - error->all(FLERR, - "Fix for fix ave/chunk not computed at compatible time"); + if (nevery % val.val.f->peratom_freq) + error->all(FLERR, "Fix {} for fix ave/chunk not computed at compatible time", val.id); - } else if (which[m] == ArgInfo::VARIABLE) { - int ivariable = input->variable->find(ids[m]); - if (ivariable < 0) - error->all(FLERR,"Variable name for fix ave/chunk does not exist"); - value2index[m] = ivariable; - - } else value2index[m] = -1; + } 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 fix ave/chunk does not exist", val.id); + } } // need to reset nvalid if nvalid < ntimestep b/c minimize was performed @@ -527,7 +500,7 @@ void FixAveChunk::setup(int /*vflag*/) void FixAveChunk::end_of_step() { - int i,j,m,n,index; + int i,j,m,index; // skip if not step which requires doing something @@ -609,15 +582,15 @@ void FixAveChunk::end_of_step() modify->clearstep_compute(); - for (m = 0; m < nvalues; m++) { - n = value2index[m]; - j = argindex[m]; + m = 0; + for (auto &val : values) { + j = val.argindex; // V,F adds velocities,forces to values - if (which[m] == ArgInfo::V || which[m] == ArgInfo::F) { + if (val.which == ArgInfo::V || val.which == ArgInfo::F) { double **attribute; - if (which[m] == ArgInfo::V) attribute = atom->v; + if (val.which == ArgInfo::V) attribute = atom->v; else attribute = atom->f; for (i = 0; i < nlocal; i++) @@ -628,7 +601,7 @@ void FixAveChunk::end_of_step() // DENSITY_NUMBER adds 1 to values - } else if (which[m] == ArgInfo::DENSITY_NUMBER) { + } else if (val.which == ArgInfo::DENSITY_NUMBER) { for (i = 0; i < nlocal; i++) if (mask[i] & groupbit && ichunk[i] > 0) { @@ -638,8 +611,7 @@ void FixAveChunk::end_of_step() // DENSITY_MASS or MASS adds mass to values - } else if ((which[m] == ArgInfo::DENSITY_MASS) - || (which[m] == ArgInfo::MASS)) { + } else if ((val.which == ArgInfo::DENSITY_MASS) || (val.which == ArgInfo::MASS)) { int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; @@ -661,7 +633,7 @@ void FixAveChunk::end_of_step() // TEMPERATURE adds KE to values // subtract and restore velocity bias if requested - } else if (which[m] == ArgInfo::TEMPERATURE) { + } else if (val.which == ArgInfo::TEMPERATURE) { if (biasflag) { if (tbias->invoked_scalar != ntimestep) tbias->compute_scalar(); @@ -695,14 +667,13 @@ void FixAveChunk::end_of_step() // COMPUTE adds its scalar or vector component to values // invoke compute if not previously invoked - } else if (which[m] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[n]; - if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { - compute->compute_peratom(); - compute->invoked_flag |= Compute::INVOKED_PERATOM; + } else 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; } - double *vector = compute->vector_atom; - double **array = compute->array_atom; + double *vector = val.val.c->vector_atom; + double **array = val.val.c->array_atom; int jm1 = j - 1; for (i = 0; i < nlocal; i++) @@ -715,9 +686,9 @@ void FixAveChunk::end_of_step() // FIX adds its scalar or vector component to values // access fix fields, guaranteed to be ready - } else if (which[m] == ArgInfo::FIX) { - double *vector = modify->fix[n]->vector_atom; - double **array = modify->fix[n]->array_atom; + } else if (val.which == ArgInfo::FIX) { + double *vector = val.val.f->vector_atom; + double **array = val.val.f->array_atom; int jm1 = j - 1; for (i = 0; i < nlocal; i++) @@ -730,14 +701,14 @@ void FixAveChunk::end_of_step() // VARIABLE adds its per-atom quantities to values // evaluate atom-style variable - } else if (which[m] == ArgInfo::VARIABLE) { + } else if (val.which == ArgInfo::VARIABLE) { if (atom->nmax > maxvar) { maxvar = atom->nmax; memory->destroy(varatom); memory->create(varatom,maxvar,"ave/chunk:varatom"); } - input->variable->compute_atom(n,igroup,varatom,1,0); + input->variable->compute_atom(val.val.v,igroup,varatom,1,0); for (i = 0; i < nlocal; i++) if (mask[i] & groupbit && ichunk[i] > 0) { @@ -745,6 +716,7 @@ void FixAveChunk::end_of_step() values_one[index][m] += varatom[i]; } } + ++m; } // process the current sample @@ -784,14 +756,14 @@ void FixAveChunk::end_of_step() for (m = 0; m < nchunk; m++) { if (count_many[m] > 0.0) for (j = 0; j < nvalues; j++) { - if (which[j] == ArgInfo::TEMPERATURE) { + if (values[j].which == ArgInfo::TEMPERATURE) { values_many[m][j] += mvv2e*values_one[m][j] / ((cdof + adof*count_many[m]) * boltz); - } else if (which[j] == ArgInfo::DENSITY_NUMBER) { + } else if (values[j].which == ArgInfo::DENSITY_NUMBER) { if (volflag == SCALAR) values_one[m][j] /= chunk_volume_scalar; else values_one[m][j] /= chunk_volume_vec[m]; values_many[m][j] += values_one[m][j]; - } else if (which[j] == ArgInfo::DENSITY_MASS) { + } else if (values[j].which == ArgInfo::DENSITY_MASS) { if (volflag == SCALAR) values_one[m][j] /= chunk_volume_scalar; else values_one[m][j] /= chunk_volume_vec[m]; values_many[m][j] += mv2d*values_one[m][j]; @@ -854,13 +826,13 @@ void FixAveChunk::end_of_step() for (m = 0; m < nchunk; m++) { if (count_sum[m] > 0.0) for (j = 0; j < nvalues; j++) { - if (which[j] == ArgInfo::TEMPERATURE) { + if (values[j].which == ArgInfo::TEMPERATURE) { values_sum[m][j] *= mvv2e/((repeat*cdof + adof*count_sum[m])*boltz); - } else if (which[j] == ArgInfo::DENSITY_NUMBER) { + } else if (values[j].which == ArgInfo::DENSITY_NUMBER) { if (volflag == SCALAR) values_sum[m][j] /= chunk_volume_scalar; else values_sum[m][j] /= chunk_volume_vec[m]; values_sum[m][j] /= repeat; - } else if (which[j] == ArgInfo::DENSITY_MASS) { + } else if (values[j].which == ArgInfo::DENSITY_MASS) { if (volflag == SCALAR) values_sum[m][j] /= chunk_volume_scalar; else values_sum[m][j] /= chunk_volume_vec[m]; values_sum[m][j] *= mv2d/repeat; @@ -1045,8 +1017,7 @@ void FixAveChunk::allocate() if (ave == WINDOW) { memory->create(count_list,nwindow,nchunk,"ave/chunk:count_list"); - memory->create(values_list,nwindow,nchunk,nvalues, - "ave/chunk:values_list"); + memory->create(values_list,nwindow,nchunk,nvalues,"ave/chunk:values_list"); } // reinitialize regrown count/values total since they accumulate diff --git a/src/fix_ave_chunk.h b/src/fix_ave_chunk.h index 1183b089e8..19d799ad02 100644 --- a/src/fix_ave_chunk.h +++ b/src/fix_ave_chunk.h @@ -36,15 +36,24 @@ class FixAveChunk : public Fix { double memory_usage() override; private: - int nvalues; - int nrepeat, nfreq, irepeat; + struct value_t { + int which; // type of data: COMPUTE, FIX, VARIABLE + int argindex; // 1-based index if data is vector, else 0 + std::string id; // compute/fix/variable ID + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; + + int nvalues, nrepeat, nfreq, irepeat; int normflag, scaleflag, overwrite, biasflag, colextra; bigint nvalid, nvalid_last; double adof, cdof; char *format, *format_user; char *tstring, *sstring, *id_bias; - int *which, *argindex, *value2index; - char **ids; class Compute *tbias; // ptr to additional bias compute FILE *fp; diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp index bd8ed1468d..1fe49d5409 100644 --- a/src/fix_ave_time.cpp +++ b/src/fix_ave_time.cpp @@ -92,14 +92,12 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : value_t val; val.keyword = arg[i]; + val.which = argi.get_type(); key2col[arg[i]] = i; - if ((argi.get_type() == ArgInfo::NONE) - || (argi.get_type() == ArgInfo::UNKNOWN) - || (argi.get_dim() > 1)) + if ((val.which == ArgInfo::NONE) || (val.which == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) error->all(FLERR,"Invalid fix ave/time argument: {}", arg[i]); - val.which = argi.get_type(); val.argindex = argi.get_index1(); val.varlen = 0; val.offcol = 0; @@ -123,12 +121,9 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : // for fix inputs, check that fix frequency is acceptable // set variable_length if any compute is variable length - if (nevery <= 0) - error->all(FLERR,"Illegal fix ave/time nevery value: {}", nevery); - if (nrepeat <= 0) - error->all(FLERR,"Illegal fix ave/time nrepeat value: {}", nrepeat); - if (nfreq <= 0) - error->all(FLERR,"Illegal fix ave/time nfreq value: {}", nfreq); + if (nevery <= 0) error->all(FLERR,"Illegal fix ave/time nevery value: {}", nevery); + if (nrepeat <= 0) error->all(FLERR,"Illegal fix ave/time nrepeat value: {}", nrepeat); + if (nfreq <= 0) error->all(FLERR,"Illegal fix ave/time nfreq value: {}", nfreq); if (nfreq % nevery || nrepeat*nevery > nfreq) error->all(FLERR,"Inconsistent fix ave/time nevery/nrepeat/nfreq values"); if (ave != RUNNING && overwrite) From 26468eccca71ed81a32abc29d9d8ecfabf4f86f4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 16 Oct 2022 11:46:38 -0400 Subject: [PATCH 11/20] silence compiler warnings --- src/compute_slice.cpp | 2 +- src/fix_ave_atom.cpp | 6 +++--- src/fix_store_state.cpp | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/compute_slice.cpp b/src/compute_slice.cpp index 53f79a3275..0e34d0a1e7 100644 --- a/src/compute_slice.cpp +++ b/src/compute_slice.cpp @@ -222,7 +222,7 @@ void ComputeSlice::compute_array() { invoked_array = update->ntimestep; - for (int m = 0; m < values.size(); m++) extract_one(0, &array[m][0], values.size()); + for (std::size_t m = 0; m < values.size(); m++) extract_one(0, &array[m][0], values.size()); } /* ---------------------------------------------------------------------- diff --git a/src/fix_ave_atom.cpp b/src/fix_ave_atom.cpp index 303c06d227..bf57d85063 100644 --- a/src/fix_ave_atom.cpp +++ b/src/fix_ave_atom.cpp @@ -386,7 +386,7 @@ void FixAveAtom::grow_arrays(int nmax) void FixAveAtom::copy_arrays(int i, int j, int /*delflag*/) { - for (int m = 0; m < values.size(); m++) + for (std::size_t m = 0; m < values.size(); m++) array[j][m] = array[i][m]; } @@ -396,7 +396,7 @@ void FixAveAtom::copy_arrays(int i, int j, int /*delflag*/) int FixAveAtom::pack_exchange(int i, double *buf) { - for (int m = 0; m < values.size(); m++) buf[m] = array[i][m]; + for (std::size_t m = 0; m < values.size(); m++) buf[m] = array[i][m]; return values.size(); } @@ -406,7 +406,7 @@ int FixAveAtom::pack_exchange(int i, double *buf) int FixAveAtom::unpack_exchange(int nlocal, double *buf) { - for (int m = 0; m < values.size(); m++) array[nlocal][m] = buf[m]; + for (std::size_t m = 0; m < values.size(); m++) array[nlocal][m] = buf[m]; return values.size(); } diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp index 664aac841a..b9b301158d 100644 --- a/src/fix_store_state.cpp +++ b/src/fix_store_state.cpp @@ -338,7 +338,7 @@ FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) : int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - for (int m = 0; m < values.size(); m++) + for (std::size_t m = 0; m < values.size(); m++) avalues[i][m] = 0.0; // store current values for keywords but not for compute, fix, variable @@ -560,7 +560,7 @@ void FixStoreState::grow_arrays(int nmax) void FixStoreState::copy_arrays(int i, int j, int /*delflag*/) { - for (int m = 0; m < values.size(); m++) avalues[j][m] = avalues[i][m]; + for (std::size_t m = 0; m < values.size(); m++) avalues[j][m] = avalues[i][m]; } /* ---------------------------------------------------------------------- @@ -569,7 +569,7 @@ void FixStoreState::copy_arrays(int i, int j, int /*delflag*/) int FixStoreState::pack_exchange(int i, double *buf) { - for (int m = 0; m < values.size(); m++) buf[m] = avalues[i][m]; + for (std::size_t m = 0; m < values.size(); m++) buf[m] = avalues[i][m]; return values.size(); } @@ -579,7 +579,7 @@ int FixStoreState::pack_exchange(int i, double *buf) int FixStoreState::unpack_exchange(int nlocal, double *buf) { - for (int m = 0; m < values.size(); m++) avalues[nlocal][m] = buf[m]; + for (std::size_t m = 0; m < values.size(); m++) avalues[nlocal][m] = buf[m]; return values.size(); } @@ -591,7 +591,7 @@ int FixStoreState::pack_restart(int i, double *buf) { // pack buf[0] this way because other fixes unpack it buf[0] = values.size()+1; - for (int m = 0; m < values.size(); m++) buf[m+1] = avalues[i][m]; + for (std::size_t m = 0; m < values.size(); m++) buf[m+1] = avalues[i][m]; return values.size()+1; } @@ -607,10 +607,10 @@ void FixStoreState::unpack_restart(int nlocal, int nth) // unpack the Nth first values this way because other fixes pack them int m = 0; - for (int i = 0; i < nth; i++) m += static_cast (extra[nlocal][m]); + for (int i = 0; i < nth; i++) m += static_cast(extra[nlocal][m]); m++; - for (int i = 0; i < values.size(); i++) avalues[nlocal][i] = extra[nlocal][m++]; + for (std::size_t i = 0; i < values.size(); i++) avalues[nlocal][i] = extra[nlocal][m++]; } /* ---------------------------------------------------------------------- From ec121ab812253e358cc1561ce574cdbefe7df783 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 16 Oct 2022 11:47:11 -0400 Subject: [PATCH 12/20] convert fix ave/correlate and fix ave/correlate/long --- src/EXTRA-FIX/fix_ave_correlate_long.cpp | 539 ++++++++++++----------- src/EXTRA-FIX/fix_ave_correlate_long.h | 19 +- src/fix_ave_correlate.cpp | 261 +++++------ src/fix_ave_correlate.h | 19 +- 4 files changed, 431 insertions(+), 407 deletions(-) diff --git a/src/EXTRA-FIX/fix_ave_correlate_long.cpp b/src/EXTRA-FIX/fix_ave_correlate_long.cpp index 9ed8a1e466..d81fce1673 100644 --- a/src/EXTRA-FIX/fix_ave_correlate_long.cpp +++ b/src/EXTRA-FIX/fix_ave_correlate_long.cpp @@ -26,9 +26,11 @@ #include "arg_info.h" #include "citeme.h" +#include "comm.h" #include "compute.h" #include "error.h" #include "input.h" +#include "math_special.h" #include "memory.h" #include "modify.h" #include "update.h" @@ -39,63 +41,72 @@ using namespace LAMMPS_NS; using namespace FixConst; +using MathSpecial::powint; -enum{AUTO,UPPER,LOWER,AUTOUPPER,AUTOLOWER,FULL}; +enum { AUTO, UPPER, LOWER, AUTOUPPER, AUTOLOWER, FULL }; static const char cite_fix_ave_correlate_long[] = -"fix ave/correlate/long command: doi:10.1063/1.3491098\n\n" -"@Article{Ramirez10,\n" -" author = {Jorge Rami{\'}rez and Sathish K. Sukumaran and Bart Vorselaars and Alexei E. Likhtman},\n" -" title = {Efficient on the Fly Calculation of Time Correlation Functions in Computer Simulations}," -" journal = {J.~Chem.\\ Phys.},\n" -" year = 2010,\n" -" volume = 133,\n" -" number = 15,\n" -" pages = {154103}\n" -"}\n\n"; + "fix ave/correlate/long command: doi:10.1063/1.3491098\n\n" + "@Article{Ramirez10,\n" + " author = {Jorge Rami{\'}rez and Sathish K. Sukumaran and Bart Vorselaars and Alexei E. " + "Likhtman},\n" + " title = {Efficient on the Fly Calculation of Time Correlation Functions in Computer " + "Simulations}," + " journal = {J.~Chem.\\ Phys.},\n" + " year = 2010,\n" + " volume = 133,\n" + " number = 15,\n" + " pages = {154103}\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ -FixAveCorrelateLong::FixAveCorrelateLong(LAMMPS * lmp, int narg, char **arg): - Fix (lmp, narg, arg) +FixAveCorrelateLong::FixAveCorrelateLong(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), shift(nullptr), shift2(nullptr), correlation(nullptr), + accumulator(nullptr), accumulator2(nullptr), ncorrelation(nullptr), naccumulator(nullptr), + insertindex(nullptr), fp(nullptr), cvalues(nullptr) { if (lmp->citeme) lmp->citeme->add(cite_fix_ave_correlate_long); - // At least nevery nfrez and one value are needed - if (narg < 6) error->all(FLERR,"Illegal fix ave/correlate/long command"); + // At least nevery nfreq and one value are needed + if (narg < 6) utils::missing_cmd_args(FLERR, "fix ave/correlate/long", error); - MPI_Comm_rank(world,&me); - - nevery = utils::inumeric(FLERR,arg[3],false,lmp); - nfreq = utils::inumeric(FLERR,arg[4],false,lmp); + nevery = utils::inumeric(FLERR, arg[3], false, lmp); + nfreq = utils::inumeric(FLERR, arg[4], false, lmp); restart_global = 1; global_freq = nfreq; time_depend = 1; - // parse values until one isn't recognized + // expand args if any have wildcard character "*" - which = new int[narg-5]; - argindex = new int[narg-5]; - ids = new char*[narg-5]; - value2index = new int[narg-5]; - nvalues = 0; + int expand = 0; + char **earg; + int nargnew = utils::expand_args(FLERR, narg - 5, &arg[5], 0, earg, lmp); - int iarg = 5; - while (iarg < narg) { + if (earg != &arg[5]) expand = 1; + arg = earg; + // parse values + + int iarg = 0; + while (iarg < nargnew) { ArgInfo argi(arg[iarg]); + value_t val; + if (argi.get_type() == ArgInfo::NONE) break; if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) - error->all(FLERR,"Illegal fix ave/correlate/long command"); + error->all(FLERR, "Unknown fix ave/correlate/long data type: {}", arg[iarg]); - which[nvalues] = argi.get_type(); - argindex[nvalues] = argi.get_index1(); - ids[nvalues] = argi.copy_name(); + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); + val.val.c = nullptr; - nvalues++; + values.push_back(val); iarg++; } + nvalues = values.size(); // optional args @@ -103,128 +114,136 @@ FixAveCorrelateLong::FixAveCorrelateLong(LAMMPS * lmp, int narg, char **arg): startstep = 0; fp = nullptr; overwrite = 0; - numcorrelators=20; + numcorrelators = 20; p = 16; m = 2; char *title1 = nullptr; char *title2 = nullptr; - while (iarg < narg) { - if (strcmp(arg[iarg],"type") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - if (strcmp(arg[iarg+1],"auto") == 0) type = AUTO; - else if (strcmp(arg[iarg+1],"upper") == 0) type = UPPER; - else if (strcmp(arg[iarg+1],"lower") == 0) type = LOWER; - else if (strcmp(arg[iarg+1],"auto/upper") == 0) type = AUTOUPPER; - else if (strcmp(arg[iarg+1],"auto/lower") == 0) type = AUTOLOWER; - else if (strcmp(arg[iarg+1],"full") == 0) type = FULL; - else error->all(FLERR,"Illegal fix ave/correlate/long command"); + while (iarg < nargnew) { + if (strcmp(arg[iarg], "type") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long type", error); + if (strcmp(arg[iarg + 1], "auto") == 0) + type = AUTO; + else if (strcmp(arg[iarg + 1], "upper") == 0) + type = UPPER; + else if (strcmp(arg[iarg + 1], "lower") == 0) + type = LOWER; + else if (strcmp(arg[iarg + 1], "auto/upper") == 0) + type = AUTOUPPER; + else if (strcmp(arg[iarg + 1], "auto/lower") == 0) + type = AUTOLOWER; + else if (strcmp(arg[iarg + 1], "full") == 0) + type = FULL; + else + error->all(FLERR, "Unknown fix ave/correlate/long type: {}"); iarg += 2; - } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - startstep = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + } else if (strcmp(arg[iarg], "start") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long start", error); + startstep = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"ncorr") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - numcorrelators = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + } else if (strcmp(arg[iarg], "ncorr") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long ncorr", error); + numcorrelators = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"nlen") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - p = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + } else if (strcmp(arg[iarg], "nlen") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long nlen", error); + p = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"ncount") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - m = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + } else if (strcmp(arg[iarg], "ncount") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long ncount", error); + m = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); iarg += 2; - } else if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - if (me == 0) { - fp = fopen(arg[iarg+1],"w"); + } else if (strcmp(arg[iarg], "file") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long file", error); + if (comm->me == 0) { + fp = fopen(arg[iarg + 1], "w"); if (fp == nullptr) - error->one(FLERR,"Cannot open fix ave/correlate/long file {}: {}", - arg[iarg+1],utils::getsyserror()); + error->one(FLERR, "Cannot open fix ave/correlate/long file {}: {}", arg[iarg + 1], + utils::getsyserror()); } iarg += 2; - } else if (strcmp(arg[iarg],"overwrite") == 0) { + } else if (strcmp(arg[iarg], "overwrite") == 0) { overwrite = 1; iarg += 1; - } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); + } else if (strcmp(arg[iarg], "title1") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long title1", error); delete[] title1; - title1 = utils::strdup(arg[iarg+1]); + title1 = utils::strdup(arg[iarg + 1]); iarg += 2; - } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) - error->all(FLERR,"Illegal fix ave/correlate/long command"); + } else if (strcmp(arg[iarg], "title2") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate/long title2", error); delete[] title2; - title2 = utils::strdup(arg[iarg+1]); + title2 = utils::strdup(arg[iarg + 1]); iarg += 2; - } else error->all(FLERR,"Illegal fix ave/correlate/long command"); + } else + error->all(FLERR, "Unknown fix ave/correlate/long keyword: {}", arg[iarg]); } - if (p % m != 0) error->all(FLERR,"fix_correlator: p mod m must be 0"); - dmin = p/m; - length = numcorrelators*p; + if (p % m != 0) error->all(FLERR, "Fix ave/correlate/long: nlen must be divisible by ncount"); + dmin = p / m; + length = numcorrelators * p; npcorr = 0; kmax = 0; // setup and error check // for fix inputs, check that fix frequency is acceptable - if (nevery <= 0 || nfreq <= 0) - error->all(FLERR,"Illegal fix ave/correlate/long command"); - if (nfreq % nevery) - error->all(FLERR,"Illegal fix ave/correlate/long command"); + if (nevery <= 0) error->all(FLERR, "Illegal fix ave/correlate/long nevery value: {}", nevery); + if (nfreq <= 0) error->all(FLERR, "Illegal fix ave/correlate/long nfreq value: {}", nfreq); + if (nfreq % nevery) error->all(FLERR, "Inconsistent fix ave/correlate/long nevery/nfreq values"); - 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 ave/correlate/long does not exist"); - if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) - error->all(FLERR,"Fix ave/correlate/long compute does not calculate a scalar"); - if (argindex[i] && modify->compute[icompute]->vector_flag == 0) - error->all(FLERR,"Fix ave/correlate/long compute does not calculate a vector"); - if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) - error->all(FLERR,"Fix ave/correlate/long compute vector is accessed out-of-range"); + for (auto &val : values) { - } else if (which[i] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/correlate/long does not exist"); - if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) - error->all(FLERR,"Fix ave/correlate/long fix does not calculate a scalar"); - if (argindex[i] && modify->fix[ifix]->vector_flag == 0) - error->all(FLERR,"Fix ave/correlate/long fix does not calculate a vector"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) - error->all(FLERR,"Fix ave/correlate/long fix vector is accessed out-of-range"); - if (nevery % modify->fix[ifix]->global_freq) - error->all(FLERR,"Fix for fix ave/correlate/long not computed at compatible time"); + 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 ave/correlate/long does not exist", val.id); + if (val.argindex == 0 && val.val.c->scalar_flag == 0) + error->all(FLERR, "Fix ave/correlate/long compute {} does not calculate a scalar", val.id); + if (val.argindex && val.val.c->vector_flag == 0) + error->all(FLERR, "Fix ave/correlate/long compute {} does not calculate a vector", val.id); + if (val.argindex && val.argindex > val.val.c->size_vector) + error->all(FLERR, "Fix ave/correlate/long compute {} vector 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 fix ave/correlate/long does not exist"); - if (input->variable->equalstyle(ivariable) == 0) - error->all(FLERR,"Fix ave/correlate/long variable is not equal-style variable"); + } 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 ave/correlate/long does not exist", val.id); + if (val.argindex == 0 && val.val.f->scalar_flag == 0) + error->all(FLERR, "Fix ave/correlate/long fix {} does not calculate a scalar", val.id); + if (val.argindex && val.val.f->vector_flag == 0) + error->all(FLERR, "Fix ave/correlate/long fix {} does not calculate a vector", val.id); + if (val.argindex && val.argindex > val.val.f->size_vector) + error->all(FLERR, "Fix ave/correlate/long fix {} vector is accessed out-of-range", val.id); + if (nevery % val.val.f->global_freq) + error->all(FLERR, "Fix {} for fix ave/correlate/long not computed at compatible time", + val.id); + + } 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 fix ave/correlate/long does not exist", val.id); + if (val.argindex == 0 && input->variable->equalstyle(val.val.v) == 0) + error->all(FLERR, "Fix ave/correlate/long variable {} is not equal-style variable", val.id); + if (val.argindex && input->variable->vectorstyle(val.val.v) == 0) + error->all(FLERR, "Fix ave/correlate/long variable {} is not vector-style variable", + val.id); } } // npair = # of correlation pairs to calculate + if (type == AUTO) npair = nvalues; - if (type == UPPER || type == LOWER) npair = nvalues*(nvalues-1)/2; - if (type == AUTOUPPER || type == AUTOLOWER) npair = nvalues*(nvalues+1)/2; - if (type == FULL) npair = nvalues*nvalues; + if (type == UPPER || type == LOWER) npair = nvalues * (nvalues - 1) / 2; + if (type == AUTOUPPER || type == AUTOLOWER) npair = nvalues * (nvalues + 1) / 2; + if (type == FULL) npair = nvalues * nvalues; // print file comment lines - if (fp && me == 0) { + + if (fp && comm->me == 0) { + clearerr(fp); if (title1) fprintf(fp,"%s\n",title1); else fprintf(fp,"# Time-correlated data for fix %s\n",id); if (title2) fprintf(fp,"%s\n",title2); @@ -232,38 +251,49 @@ FixAveCorrelateLong::FixAveCorrelateLong(LAMMPS * lmp, int narg, char **arg): fprintf(fp,"# Time"); if (type == AUTO) for (int i = 0; i < nvalues; i++) - fprintf(fp," %s*%s",arg[5+i],arg[5+i]); + fprintf(fp," %s*%s",earg[i],earg[i]); else if (type == UPPER) for (int i = 0; i < nvalues; i++) for (int j = i+1; j < nvalues; j++) - fprintf(fp," %s*%s",arg[5+i],arg[5+j]); + fprintf(fp," %s*%s",earg[i],earg[j]); else if (type == LOWER) for (int i = 0; i < nvalues; i++) for (int j = 0; j < i-1; j++) - fprintf(fp," %s*%s",arg[5+i],arg[5+j]); + fprintf(fp," %s*%s",earg[i],earg[j]); else if (type == AUTOUPPER) for (int i = 0; i < nvalues; i++) for (int j = i; j < nvalues; j++) - fprintf(fp," %s*%s",arg[5+i],arg[5+j]); + fprintf(fp," %s*%s",earg[i],earg[j]); else if (type == AUTOLOWER) for (int i = 0; i < nvalues; i++) for (int j = 0; j < i; j++) - fprintf(fp," %s*%s",arg[5+i],arg[5+j]); + fprintf(fp," %s*%s",earg[i],earg[j]); else if (type == FULL) for (int i = 0; i < nvalues; i++) for (int j = 0; j < nvalues; j++) - fprintf(fp," %s*%s",arg[5+i],arg[5+j]); + fprintf(fp," %s*%s",earg[i],earg[j]); fprintf(fp,"\n"); } + if (ferror(fp)) + error->one(FLERR,"Error writing ave/correlate/long header: {}", utils::getsyserror()); + filepos = platform::ftell(fp); } delete[] title1; delete[] title2; + // if wildcard expansion occurred, free earg memory from expand_args() + // wait to do this until after file comment lines are printed + + if (expand) { + for (int i = 0; i < nargnew; i++) delete[] earg[i]; + memory->sfree(earg); + } + // allocate and initialize memory for calculated values and correlators - memory->create(values,nvalues,"correlator:values"); + memory->create(cvalues,nvalues,"correlator:values"); memory->create(shift,npair,numcorrelators,p,"correlator:shift"); memory->create(shift2,npair,numcorrelators,p,"correlator:shift2"); //NOT OPTMAL memory->create(correlation,npair,numcorrelators,p,"correlator:correlation"); @@ -276,10 +306,10 @@ FixAveCorrelateLong::FixAveCorrelateLong(LAMMPS * lmp, int narg, char **arg): memory->create(t,length,"correlator:t"); memory->create(f,npair,length,"correlator:f"); - for (int i=0;idestroy(values); + memory->destroy(cvalues); memory->destroy(shift); memory->destroy(shift2); memory->destroy(correlation); @@ -332,7 +355,7 @@ FixAveCorrelateLong::~FixAveCorrelateLong() memory->destroy(t); memory->destroy(f); - if (fp && me == 0) fclose(fp); + if (fp && comm->me == 0) fclose(fp); } /* ---------------------------------------------------------------------- */ @@ -350,24 +373,22 @@ void FixAveCorrelateLong::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 ave/correlate/long does not exist"); - 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 ave/correlate/long 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 ave/correlate/long does not exist"); - 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 ave/correlate/long 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 ave/correlate/long does not exist"); - value2index[i] = 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 fix ave/correlate/long does not exist", val.id); } } @@ -392,9 +413,6 @@ void FixAveCorrelateLong::setup(int /*vflag*/) void FixAveCorrelateLong::end_of_step() { - int i,m; - double scalar; - // skip if not step which requires doing something bigint ntimestep = update->ntimestep; @@ -405,44 +423,52 @@ void FixAveCorrelateLong::end_of_step() // compute/fix/variable may invoke computes so wrap with clear/add modify->clearstep_compute(); - - for (i = 0; i < nvalues; i++) { - m = value2index[i]; - scalar = 0.0; + + int i = 0; + for (auto &val : values) { + double scalar = 0.0; // invoke compute if not previously invoked - if (which[i] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[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; } - scalar = compute->scalar; + scalar = 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; } - scalar = compute->vector[argindex[i]-1]; + scalar = 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) - scalar = modify->fix[m]->compute_scalar(); + } else if (val.which == ArgInfo::FIX) { + if (val.argindex == 0) + scalar = val.val.f->compute_scalar(); else - scalar = modify->fix[m]->compute_vector(argindex[i]-1); + scalar = val.val.f->compute_vector(val.argindex-1); - // evaluate equal-style variable + // evaluate equal-style or vector-style variable - } else if (which[i] == ArgInfo::VARIABLE) - scalar = input->variable->compute_equal(m); + } else if (val.which == ArgInfo::VARIABLE) { + if (val.argindex == 0) + scalar = input->variable->compute_equal(val.val.v); + else { + double *varvec; + int nvec = input->variable->compute_vector(val.val.v,&varvec); + int index = val.argindex; + if (nvec < index) scalar = 0.0; + else scalar = varvec[index-1]; + } + } - values[i] = scalar; + cvalues[i++] = scalar; } // fistindex = index in values ring of earliest time sample @@ -456,19 +482,25 @@ void FixAveCorrelateLong::end_of_step() if (ntimestep % nfreq) return; // output result to file + evaluate(); - if (fp && me == 0) { + if (fp && comm->me == 0) { + clearerr(fp); if (overwrite) platform::fseek(fp,filepos); fmt::print(fp,"# Timestep: {}\n", ntimestep); - for (unsigned int i=0;idt*nevery); - for (int j=0;jone(FLERR,"Error writing out fix ave/correlate/long data: {}", utils::getsyserror()); + fflush(fp); + if (overwrite) { bigint fileend = platform::ftell(fp); if ((fileend > 0) && (platform::ftruncate(fp,fileend))) @@ -481,20 +513,20 @@ void FixAveCorrelateLong::evaluate() { unsigned int jm=0; // First correlator - for (unsigned int j=0;j 0) { t[jm] = j; - for (int i=0;i0) { - t[jm] = j * pow((double)m, k); + t[jm] = j * powint((double)m, k); for (int i=0;intimestep <= last_accumulated_step) return; if (type == AUTO) { - for (i=0; intimestep; @@ -565,38 +597,38 @@ void FixAveCorrelateLong::add(const int i, const double w, const int k) { // Add to accumulator and, if needed, add to next correlator accumulator[i][k] += w; - if (i==0) ++naccumulator[k]; + if (i == 0) ++naccumulator[k]; if (naccumulator[k]==m) { add(i,accumulator[i][k]/m, k+1); accumulator[i][k]=0; - if (i==npair-1) naccumulator[k]=0; + if (i == npair-1) naccumulator[k]=0; } // Calculate correlation function unsigned int ind1=insertindex[k]; - if (k==0) { // First correlator is different + if (k == 0) { // First correlator is different int ind2=ind1; - for (unsigned int j=0;j -1e10) { correlation[i][k][j]+= shift[i][k][ind1]*shift[i][k][ind2]; if (i==0) ++ncorrelation[k][j]; } --ind2; - if (ind2<0) ind2+=p; + if (ind2 < 0) ind2+=p; } } else { int ind2=ind1-dmin; for (unsigned int j=dmin;j -1e10) { correlation[i][k][j]+= shift[i][k][ind1]*shift[i][k][ind2]; - if (i==0) ++ncorrelation[k][j]; + if (i == 0) ++ncorrelation[k][j]; } --ind2; } } - if (i==npair-1) { + if (i == npair-1) { ++insertindex[k]; if (insertindex[k]==p) insertindex[k]=0; } @@ -606,8 +638,7 @@ void FixAveCorrelateLong::add(const int i, const double w, const int k) { /* ---------------------------------------------------------------------- Add 2 scalar values to the cross-correlator k of pair i ------------------------------------------------------------------------- */ -void FixAveCorrelateLong::add(const int i, const double wA, const double wB, - const int k) { +void FixAveCorrelateLong::add(const int i, const double wA, const double wB, const int k) { if (k == numcorrelators) return; if (k > kmax) kmax=k; @@ -616,21 +647,21 @@ void FixAveCorrelateLong::add(const int i, const double wA, const double wB, accumulator[i][k] += wA; accumulator2[i][k] += wB; - if (i==0) ++naccumulator[k]; - if (naccumulator[k]==m) { + if (i == 0) ++naccumulator[k]; + if (naccumulator[k] == m) { add(i,accumulator[i][k]/m, accumulator2[i][k]/m,k+1); accumulator[i][k]=0; accumulator2[i][k]=0; - if (i==npair-1) naccumulator[k]=0; + if (i == npair-1) naccumulator[k]=0; } unsigned int ind1=insertindex[k]; - if (k==0) { + if (k == 0) { int ind2=ind1; - for (unsigned int j=0;j -1e10) { correlation[i][k][j]+= shift[i][k][ind1]*shift2[i][k][ind2]; - if (i==0) ++ncorrelation[k][j]; + if (i == 0) ++ncorrelation[k][j]; } --ind2; if (ind2<0) ind2+=p; @@ -638,19 +669,19 @@ void FixAveCorrelateLong::add(const int i, const double wA, const double wB, } else { int ind2=ind1-dmin; - for (unsigned int j=dmin;j -1e10) { correlation[i][k][j]+= shift[i][k][ind1]*shift2[i][k][ind2]; - if (i==0) ++ncorrelation[k][j]; + if (i == 0) ++ncorrelation[k][j]; } --ind2; } } - if (i==npair-1) { + if (i == npair-1) { ++insertindex[k]; - if (insertindex[k]==p) insertindex[k]=0; + if (insertindex[k] == p) insertindex[k]=0; } } @@ -696,20 +727,20 @@ double FixAveCorrelateLong::memory_usage() { ------------------------------------------------------------------------- */ // Save everything except t and f void FixAveCorrelateLong::write_restart(FILE *fp) { - if (me == 0) { + if (comm->me == 0) { int nsize = 3*npair*numcorrelators*p + 2*npair*numcorrelators + numcorrelators*p + 2*numcorrelators + 6; int n=0; double *list; memory->create(list,nsize,"correlator:list"); - list[n++]=npair; - list[n++]=numcorrelators; - list[n++]=p; - list[n++]=m; + list[n++] = npair; + list[n++] = numcorrelators; + list[n++] = p; + list[n++] = m; list[n++] = last_accumulated_step; - for (int i=0;i (list[n++]); + int npairin = static_cast(list[n++]); int numcorrelatorsin = static_cast (list[n++]); - int pin = static_cast (list[n++]); - int min = static_cast (list[n++]); - last_accumulated_step = static_cast (list[n++]); + int pin = static_cast(list[n++]); + int min = static_cast(list[n++]); + last_accumulated_step = static_cast(list[n++]); - if ((npairin!=npair) || (numcorrelatorsin!=numcorrelators) - || (pin!=(int)p) || (min!=(int)m)) - error->all(FLERR,"Fix ave/correlate/long: restart and input data are different"); + if ((npairin!=npair) || (numcorrelatorsin!=numcorrelators) || (pin!=(int)p) || (min!=(int)m)) + error->all(FLERR, "Fix ave/correlate/long: restart and input data are different"); - for (int i=0;i(list[n++]); - naccumulator[i] = static_cast (list[n++]); - insertindex[i] = static_cast (list[n++]); + naccumulator[i] = static_cast(list[n++]); + insertindex[i] = static_cast(list[n++]); } } diff --git a/src/EXTRA-FIX/fix_ave_correlate_long.h b/src/EXTRA-FIX/fix_ave_correlate_long.h index 0c540aa727..0495664934 100644 --- a/src/EXTRA-FIX/fix_ave_correlate_long.h +++ b/src/EXTRA-FIX/fix_ave_correlate_long.h @@ -58,18 +58,27 @@ class FixAveCorrelateLong : public Fix { int length; // Length of result arrays int kmax; // Maximum correlator attained during simulation - int me, nvalues; - int nfreq; + struct value_t { + int which; // type of data: COMPUTE, FIX, VARIABLE + int argindex; // 1-based index if data is vector, else 0 + std::string id; // compute/fix/variable ID + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; + + int nvalues, nfreq; bigint nvalid, nvalid_last, last_accumulated_step; - int *which, *argindex, *value2index; - char **ids; FILE *fp; int type, startstep, overwrite; bigint filepos; int npair; // number of correlation pairs to calculate - double *values; + double *cvalues; void accumulate(); void evaluate(); diff --git a/src/fix_ave_correlate.cpp b/src/fix_ave_correlate.cpp index 17182c8667..30d3e10e67 100644 --- a/src/fix_ave_correlate.cpp +++ b/src/fix_ave_correlate.cpp @@ -21,6 +21,7 @@ #include "fix_ave_correlate.h" #include "arg_info.h" +#include "comm.h" #include "compute.h" #include "error.h" #include "input.h" @@ -34,23 +35,20 @@ using namespace LAMMPS_NS; using namespace FixConst; -enum{ONE,RUNNING}; -enum{AUTO,UPPER,LOWER,AUTOUPPER,AUTOLOWER,FULL}; +enum { ONE, RUNNING }; +enum { AUTO, UPPER, LOWER, AUTOUPPER, AUTOLOWER, FULL }; /* ---------------------------------------------------------------------- */ -FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): - Fix (lmp, narg, arg), - nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), ids(nullptr), fp(nullptr), - count(nullptr), values(nullptr), corr(nullptr), save_count(nullptr), save_corr(nullptr) +FixAveCorrelate::FixAveCorrelate(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), fp(nullptr), count(nullptr), cvalues(nullptr), corr(nullptr), + save_count(nullptr), save_corr(nullptr) { - if (narg < 7) error->all(FLERR,"Illegal fix ave/correlate command"); + if (narg < 7) utils::missing_cmd_args(FLERR, "fix ave/correlate", error); - MPI_Comm_rank(world,&me); - - nevery = utils::inumeric(FLERR,arg[3],false,lmp); - nrepeat = utils::inumeric(FLERR,arg[4],false,lmp); - nfreq = utils::inumeric(FLERR,arg[5],false,lmp); + nevery = utils::inumeric(FLERR, arg[3], false, lmp); + nrepeat = utils::inumeric(FLERR, arg[4], false, lmp); + nfreq = utils::inumeric(FLERR, arg[5], false, lmp); time_depend = 1; global_freq = nfreq; @@ -59,34 +57,31 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): int expand = 0; char **earg; - int nargnew = utils::expand_args(FLERR,narg-6,&arg[6],0,earg,lmp); + int nargnew = utils::expand_args(FLERR, narg - 6, &arg[6], 0, earg, lmp); if (earg != &arg[6]) 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]; - nvalues = 0; + // parse values int iarg = 0; while (iarg < nargnew) { ArgInfo argi(arg[iarg]); + value_t val; if (argi.get_type() == ArgInfo::NONE) break; if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_dim() > 1)) - error->all(FLERR,"Invalid fix ave/correlate command"); + error->all(FLERR, "Unknown fix ave/correlate data type: {}", arg[iarg]); - which[nvalues] = argi.get_type(); - argindex[nvalues] = argi.get_index1(); - ids[nvalues] = argi.copy_name(); + val.which = argi.get_type(); + val.argindex = argi.get_index1(); + val.id = argi.get_name(); + val.val.c = nullptr; - nvalues++; + values.push_back(val); iarg++; } + nvalues = values.size(); // optional args @@ -102,32 +97,32 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): while (iarg < nargnew) { if (strcmp(arg[iarg],"type") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate type", error); if (strcmp(arg[iarg+1],"auto") == 0) type = AUTO; else if (strcmp(arg[iarg+1],"upper") == 0) type = UPPER; else if (strcmp(arg[iarg+1],"lower") == 0) type = LOWER; else if (strcmp(arg[iarg+1],"auto/upper") == 0) type = AUTOUPPER; else if (strcmp(arg[iarg+1],"auto/lower") == 0) type = AUTOLOWER; else if (strcmp(arg[iarg+1],"full") == 0) type = FULL; - else error->all(FLERR,"Illegal fix ave/correlate command"); + else error->all(FLERR,"Unknown fix ave/correlate type: {}"); iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate ave", error); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING; - else error->all(FLERR,"Illegal fix ave/correlate command"); + else error->all(FLERR,"Unknown fix ave/correlate ave mode: {}", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate start", error); startstep = utils::inumeric(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"prefactor") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate prefactor", error); prefactor = utils::numeric(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); - if (me == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate file", error); + if (comm->me == 0) { fp = fopen(arg[iarg+1],"w"); if (fp == nullptr) error->one(FLERR,"Cannot open fix ave/correlate file {}:"" {}", @@ -138,75 +133,67 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): overwrite = 1; iarg += 1; } else if (strcmp(arg[iarg],"title1") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate title1", error); delete[] title1; title1 = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title2") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate title2", error); delete[] title2; title2 = utils::strdup(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"title3") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/correlate command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/correlate title3", error); delete[] title3; title3 = utils::strdup(arg[iarg+1]); iarg += 2; - } else error->all(FLERR,"Illegal fix ave/correlate command"); + } else error->all(FLERR,"Unkown fix ave/correlate keyword: {}", arg[iarg]); } // setup and error check // for fix inputs, check that fix frequency is acceptable - if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) - error->all(FLERR,"Illegal fix ave/correlate command"); - if (nfreq % nevery) - error->all(FLERR,"Illegal fix ave/correlate command"); - if (ave == ONE && nfreq < (nrepeat-1)*nevery) - error->all(FLERR,"Illegal fix ave/correlate command"); + if (nevery <= 0) error->all(FLERR,"Illegal fix ave/correlate nevery value: {}", nevery); + if (nrepeat <= 0) error->all(FLERR,"Illegal fix ave/correlate nrepeat value: {}", nrepeat); + if (nfreq <= 0) error->all(FLERR,"Illegal fix ave/correlate nfreq value: {}", nfreq); + if (nfreq % nevery || nrepeat*nevery > nfreq) + error->all(FLERR,"Inconsistent fix ave/correlate nevery/nrepeat/nfreq values"); if (ave != RUNNING && overwrite) - error->all(FLERR,"Illegal fix ave/correlate command"); + error->all(FLERR,"Fix ave/correlate overwrite keyword requires ave running setting"); - 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 ave/correlate does not exist"); - if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) - error->all(FLERR, - "Fix ave/correlate compute does not calculate a scalar"); - if (argindex[i] && modify->compute[icompute]->vector_flag == 0) - error->all(FLERR, - "Fix ave/correlate compute does not calculate a vector"); - if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) - error->all(FLERR,"Fix ave/correlate compute vector " - "is accessed out-of-range"); + for (auto &val : values) { - } else if (which[i] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/correlate does not exist"); - if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) - error->all(FLERR,"Fix ave/correlate fix does not calculate a scalar"); - if (argindex[i] && modify->fix[ifix]->vector_flag == 0) - error->all(FLERR,"Fix ave/correlate fix does not calculate a vector"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) - error->all(FLERR, - "Fix ave/correlate fix vector is accessed out-of-range"); - if (nevery % modify->fix[ifix]->global_freq) - error->all(FLERR,"Fix for fix ave/correlate " - "not computed at compatible time"); + 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 ave/correlate does not exist", val.id); + if (val.argindex == 0 && val.val.c->scalar_flag == 0) + error->all(FLERR, "Fix ave/correlate compute {} does not calculate a scalar", val.id); + if (val.argindex && val.val.c->vector_flag == 0) + error->all(FLERR, "Fix ave/correlate compute {} does not calculate a vector", val.id); + if (val.argindex && val.argindex > val.val.c->size_vector) + error->all(FLERR, "Fix ave/correlate compute {} vector 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 fix ave/correlate does not exist"); - if (argindex[i] == 0 && input->variable->equalstyle(ivariable) == 0) - error->all(FLERR, - "Fix ave/correlate variable is not equal-style variable"); - if (argindex[i] && input->variable->vectorstyle(ivariable) == 0) - error->all(FLERR, - "Fix ave/correlate variable is not vector-style variable"); + } 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 ave/correlate does not exist", val.id); + if (val.argindex == 0 && val.val.f->scalar_flag == 0) + error->all(FLERR, "Fix ave/correlate fix {} does not calculate a scalar", val.id); + if (val.argindex && val.val.f->vector_flag == 0) + error->all(FLERR, "Fix ave/correlate fix {} does not calculate a vector", val.id); + if (val.argindex && val.argindex > val.val.f->size_vector) + error->all(FLERR, "Fix ave/correlate fix {} vector is accessed out-of-range", val.id); + if (nevery % val.val.f->global_freq) + error->all(FLERR, "Fix {} for fix ave/correlate not computed at compatible time", val.id); + + } 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 fix ave/correlate does not exist", val.id); + if (val.argindex == 0 && input->variable->equalstyle(val.val.v) == 0) + error->all(FLERR, "Fix ave/correlate variable {} is not equal-style variable", val.id); + if (val.argindex && input->variable->vectorstyle(val.val.v) == 0) + error->all(FLERR, "Fix ave/correlate variable {} is not vector-style variable", val.id); } } @@ -219,7 +206,7 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): // print file comment lines - if (fp && me == 0) { + if (fp && comm->me == 0) { clearerr(fp); if (title1) fprintf(fp,"%s\n",title1); else fprintf(fp,"# Time-correlated data for fix %s\n",id); @@ -254,7 +241,7 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): fprintf(fp,"\n"); } if (ferror(fp)) - error->one(FLERR,"Error writing file header"); + error->one(FLERR,"Error writing ave/correlate header: {}", utils::getsyserror()); filepos = platform::ftell(fp); } @@ -275,7 +262,7 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): // set count and corr to zero since they accumulate // also set save versions to zero in case accessed via compute_array() - memory->create(values,nrepeat,nvalues,"ave/correlate:values"); + memory->create(cvalues,nrepeat,nvalues,"ave/correlate:cvalues"); memory->create(count,nrepeat,"ave/correlate:count"); memory->create(save_count,nrepeat,"ave/correlate:save_count"); memory->create(corr,nrepeat,npair,"ave/correlate:corr"); @@ -312,19 +299,13 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): FixAveCorrelate::~FixAveCorrelate() { - delete[] which; - delete[] argindex; - delete[] value2index; - for (int i = 0; i < nvalues; i++) delete[] ids[i]; - delete[] ids; - - memory->destroy(values); + memory->destroy(cvalues); memory->destroy(count); memory->destroy(save_count); memory->destroy(corr); memory->destroy(save_corr); - if (fp && me == 0) fclose(fp); + if (fp && comm->me == 0) fclose(fp); } /* ---------------------------------------------------------------------- */ @@ -342,24 +323,21 @@ void FixAveCorrelate::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 ave/correlate does not exist"); - 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 ave/correlate 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 ave/correlate does not exist"); - 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 ave/correlate 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 ave/correlate does not exist"); - value2index[i] = 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 fix ave/correlate does not exist", val.id); } } @@ -387,8 +365,7 @@ void FixAveCorrelate::setup(int /*vflag*/) void FixAveCorrelate::end_of_step() { - int i,j,m; - double scalar; + int i,j; // skip if not step which requires doing something @@ -406,51 +383,51 @@ void FixAveCorrelate::end_of_step() lastindex++; if (lastindex == nrepeat) lastindex = 0; - for (i = 0; i < nvalues; i++) { - m = value2index[i]; + i = 0; + for (auto &val : values) { + double scalar = 0.0; // invoke compute if not previously invoked - if (which[i] == ArgInfo::COMPUTE) { - Compute *compute = modify->compute[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; } - scalar = compute->scalar; + scalar = 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; } - scalar = compute->vector[argindex[i]-1]; + scalar = val.val.c->vector[val.argindex-1]; } // access fix fields, guaranteed to be ready - } else if (which[i] == ArgInfo::FIX) { - if (argindex[i] == 0) - scalar = modify->fix[m]->compute_scalar(); + } else if (val.which == ArgInfo::FIX) { + if (val.argindex == 0) + scalar = val.val.f->compute_scalar(); else - scalar = modify->fix[m]->compute_vector(argindex[i]-1); + scalar = val.val.f->compute_vector(val.argindex-1); // evaluate equal-style or vector-style variable - } else if (which[i] == ArgInfo::VARIABLE) { - if (argindex[i] == 0) - scalar = input->variable->compute_equal(m); + } else if (val.which == ArgInfo::VARIABLE) { + if (val.argindex == 0) + scalar = input->variable->compute_equal(val.val.v); else { double *varvec; - int nvec = input->variable->compute_vector(m,&varvec); - int index = argindex[i]; + int nvec = input->variable->compute_vector(val.val.v,&varvec); + int index = val.argindex; if (nvec < index) scalar = 0.0; else scalar = varvec[index-1]; } } - values[lastindex][i] = scalar; + cvalues[lastindex][i++] = scalar; } // fistindex = index in values ring of earliest time sample @@ -484,7 +461,7 @@ void FixAveCorrelate::end_of_step() // output result to file - if (fp && me == 0) { + if (fp && comm->me == 0) { clearerr(fp); if (overwrite) platform::fseek(fp,filepos); fmt::print(fp,"{} {}\n",ntimestep,nrepeat); @@ -499,7 +476,7 @@ void FixAveCorrelate::end_of_step() fprintf(fp,"\n"); } if (ferror(fp)) - error->one(FLERR,"Error writing out correlation data"); + error->one(FLERR,"Error writing out fix ave/correlate data: {}", utils::getsyserror()); fflush(fp); @@ -539,7 +516,7 @@ void FixAveCorrelate::accumulate() for (k = 0; k < nsample; k++) { ipair = 0; for (i = 0; i < nvalues; i++) { - corr[k][ipair++] += values[m][i]*values[n][i]; + corr[k][ipair++] += cvalues[m][i]*cvalues[n][i]; } m--; if (m < 0) m = nrepeat-1; @@ -550,7 +527,7 @@ void FixAveCorrelate::accumulate() ipair = 0; for (i = 0; i < nvalues; i++) for (j = i+1; j < nvalues; j++) - corr[k][ipair++] += values[m][i]*values[n][j]; + corr[k][ipair++] += cvalues[m][i]*cvalues[n][j]; m--; if (m < 0) m = nrepeat-1; } @@ -560,7 +537,7 @@ void FixAveCorrelate::accumulate() ipair = 0; for (i = 0; i < nvalues; i++) for (j = 0; j < i; j++) - corr[k][ipair++] += values[m][i]*values[n][j]; + corr[k][ipair++] += cvalues[m][i]*cvalues[n][j]; m--; if (m < 0) m = nrepeat-1; } @@ -570,7 +547,7 @@ void FixAveCorrelate::accumulate() ipair = 0; for (i = 0; i < nvalues; i++) for (j = i; j < nvalues; j++) - corr[k][ipair++] += values[m][i]*values[n][j]; + corr[k][ipair++] += cvalues[m][i]*cvalues[n][j]; m--; if (m < 0) m = nrepeat-1; } @@ -580,7 +557,7 @@ void FixAveCorrelate::accumulate() ipair = 0; for (i = 0; i < nvalues; i++) for (j = 0; j <= i; j++) - corr[k][ipair++] += values[m][i]*values[n][j]; + corr[k][ipair++] += cvalues[m][i]*cvalues[n][j]; m--; if (m < 0) m = nrepeat-1; } @@ -590,7 +567,7 @@ void FixAveCorrelate::accumulate() ipair = 0; for (i = 0; i < nvalues; i++) for (j = 0; j < nvalues; j++) - corr[k][ipair++] += values[m][i]*values[n][j]; + corr[k][ipair++] += cvalues[m][i]*cvalues[n][j]; m--; if (m < 0) m = nrepeat-1; } diff --git a/src/fix_ave_correlate.h b/src/fix_ave_correlate.h index 517740a121..5dc49ed343 100644 --- a/src/fix_ave_correlate.h +++ b/src/fix_ave_correlate.h @@ -35,11 +35,20 @@ class FixAveCorrelate : public Fix { double compute_array(int, int) override; private: - int me, nvalues; - int nrepeat, nfreq; + struct value_t { + int which; // type of data: COMPUTE, FIX, VARIABLE + int argindex; // 1-based index if data is vector, else 0 + std::string id; // compute/fix/variable ID + union { + class Compute *c; + class Fix *f; + int v; + } val; + }; + std::vector values; + + int nvalues, nrepeat, nfreq; bigint nvalid, nvalid_last; - int *which, *argindex, *value2index; - char **ids; FILE *fp; int type, ave, startstep, overwrite; @@ -52,7 +61,7 @@ class FixAveCorrelate : public Fix { int npair; // number of correlation pairs to calculate int *count; - double **values, **corr; + double **cvalues, **corr; int *save_count; // saved values at Nfreq for output via compute_array() double **save_corr; From 299281b0e2e3ce91c6269012008c90fb44d89323 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 16 Oct 2022 11:53:55 -0400 Subject: [PATCH 13/20] whitespace --- src/EXTRA-FIX/fix_ave_correlate_long.cpp | 4 ++-- src/fix_ave_correlate.cpp | 2 +- src/fix_ave_histo.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EXTRA-FIX/fix_ave_correlate_long.cpp b/src/EXTRA-FIX/fix_ave_correlate_long.cpp index d81fce1673..4734003031 100644 --- a/src/EXTRA-FIX/fix_ave_correlate_long.cpp +++ b/src/EXTRA-FIX/fix_ave_correlate_long.cpp @@ -374,7 +374,7 @@ void FixAveCorrelateLong::init() // set current indices for all computes,fixes,variables for (auto &val : values) { - + if (val.which == ArgInfo::COMPUTE) { val.val.c = modify->get_compute_by_id(val.id); if (!val.val.c) @@ -423,7 +423,7 @@ void FixAveCorrelateLong::end_of_step() // compute/fix/variable may invoke computes so wrap with clear/add modify->clearstep_compute(); - + int i = 0; for (auto &val : values) { double scalar = 0.0; diff --git a/src/fix_ave_correlate.cpp b/src/fix_ave_correlate.cpp index 30d3e10e67..3a524e68ed 100644 --- a/src/fix_ave_correlate.cpp +++ b/src/fix_ave_correlate.cpp @@ -324,7 +324,7 @@ void FixAveCorrelate::init() // set current indices for all computes,fixes,variables for (auto &val : values) { - + if (val.which == ArgInfo::COMPUTE) { val.val.c = modify->get_compute_by_id(val.id); if (!val.val.c) diff --git a/src/fix_ave_histo.cpp b/src/fix_ave_histo.cpp index 46c26acad7..cd8e461bdb 100644 --- a/src/fix_ave_histo.cpp +++ b/src/fix_ave_histo.cpp @@ -837,7 +837,7 @@ void FixAveHisto::options(int iarg, int narg, char **arg) // optional args auto mycmd = fmt::format("fix {}", style); - + while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { if (iarg+2 > narg) utils::missing_cmd_args(FLERR, mycmd + " file", error); From e6b67683aaaf6bb16443ecf7fc334a24a2e62916 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Oct 2022 07:02:16 -0400 Subject: [PATCH 14/20] update TIP4P howto --- doc/src/Howto_tip4p.rst | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/doc/src/Howto_tip4p.rst b/doc/src/Howto_tip4p.rst index 4e0a63adc6..19b811a282 100644 --- a/doc/src/Howto_tip4p.rst +++ b/doc/src/Howto_tip4p.rst @@ -8,18 +8,28 @@ This site M is located at a fixed distance away from the oxygen along the bisector of the HOH bond angle. A bond style of *harmonic* and an angle style of *harmonic* or *charmm* should also be used. -A TIP4P model is run with LAMMPS using either this command +A TIP4P model is run with LAMMPS using either these commands for a cutoff model: +* :doc:`pair_style tip4p/cut ` * :doc:`pair_style lj/cut/tip4p/cut ` -or these two commands for a long-range model: +or these commands for a long-range model: +* :doc:`pair_style tip4p/long ` * :doc:`pair_style lj/cut/tip4p/long ` +* :doc:`pair_style lj/long/tip4p/long ` +* :doc:`pair_style tip4p/long/soft ` +* :doc:`pair_style lj/cut/tip4p/long/soft ` * :doc:`kspace_style pppm/tip4p ` +* :doc:`kspace_style pppm/disp/tip4p ` -For both models, the bond lengths and bond angles should be held fixed -using the :doc:`fix shake ` command. +The bond lengths and bond angles should be held fixed using the +:doc:`fix shake ` or :doc:`fix rattle ` command, +unless a parameterization for a flexible TIP4P model is used. The +parameter sets listed below are all for rigid TIP4P model variants and +thus the bond and angle force constants are not used and can be set to +any legal value; only equilibrium length and angle are used. These are the additional parameters (in real units) to set for O and H atoms and the water molecule to run a rigid TIP4P model with a cutoff @@ -87,15 +97,16 @@ solver (e.g. Ewald or PPPM in LAMMPS): | LJ :math:`\epsilon`, :math:`\sigma` of OH, HH = 0.0 | -Note that the when using the TIP4P pair style, the neighbor list -cutoff for Coulomb interactions is effectively extended by a distance -2 \* (OM distance), to account for the offset distance of the -fictitious charges on O atoms in water molecules. Thus it is -typically best in an efficiency sense to use a LJ cutoff >= Coulomb -cutoff + 2\*(OM distance), to shrink the size of the neighbor list. -This leads to slightly larger cost for the long-range calculation, so -you can test the trade-off for your model. The OM distance and the LJ -and Coulombic cutoffs are set in the :doc:`pair_style lj/cut/tip4p/long ` command. +Note that the when using the TIP4P pair style, the neighbor list cutoff +for Coulomb interactions is effectively extended by a distance 2 \* (OM +distance), to account for the offset distance of the fictitious charges +on O atoms in water molecules. Thus it is typically best in an +efficiency sense to use a LJ cutoff >= Coulomb cutoff + 2\*(OM +distance), to shrink the size of the neighbor list. This leads to +slightly larger cost for the long-range calculation, so you can test the +trade-off for your model. The OM distance and the LJ and Coulombic +cutoffs are set in the :doc:`pair_style lj/cut/tip4p/long +` command. Wikipedia also has a nice article on `water models `_. From 5824534ac64b54f5408d4acddaa27f203651cb1f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Oct 2022 07:03:25 -0400 Subject: [PATCH 15/20] use symbolic constants Comm::BRICK / Comm::TILED for Comm::style --- src/KOKKOS/comm_tiled_kokkos.cpp | 4 ++-- src/KSPACE/msm.cpp | 5 ++--- src/KSPACE/pppm_dipole.cpp | 12 +++++------- src/KSPACE/pppm_dipole_spin.cpp | 12 +++++------- src/KSPACE/pppm_disp.cpp | 11 ++++------- src/LATBOLTZ/fix_lb_fluid.cpp | 4 ++-- src/MDI/mdi_engine.cpp | 2 +- src/REACTION/fix_bond_react.cpp | 2 +- src/REPLICA/verlet_split.cpp | 12 +++++------- src/SRD/fix_srd.cpp | 2 +- src/balance.cpp | 2 +- src/comm.h | 11 ++++++++--- src/comm_brick.cpp | 4 ++-- src/comm_tiled.cpp | 4 ++-- src/fix_balance.cpp | 2 +- src/input.cpp | 8 ++++---- 16 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/KOKKOS/comm_tiled_kokkos.cpp b/src/KOKKOS/comm_tiled_kokkos.cpp index c320abeab2..990b613630 100644 --- a/src/KOKKOS/comm_tiled_kokkos.cpp +++ b/src/KOKKOS/comm_tiled_kokkos.cpp @@ -30,7 +30,7 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -CommTiledKokkos::CommTiledKokkos(LAMMPS *lmp) : CommTiled(lmp) {} +CommTiledKokkos::CommTiledKokkos(LAMMPS *_lmp) : CommTiled(_lmp) {} /* ---------------------------------------------------------------------- */ //IMPORTANT: we *MUST* pass "*oldcomm" to the Comm initializer here, as @@ -39,7 +39,7 @@ CommTiledKokkos::CommTiledKokkos(LAMMPS *lmp) : CommTiled(lmp) {} // The call to Comm::copy_arrays() then converts the shallow copy // into a deep copy of the class with the new layout. -CommTiledKokkos::CommTiledKokkos(LAMMPS *lmp, Comm *oldcomm) : CommTiled(lmp,oldcomm) {} +CommTiledKokkos::CommTiledKokkos(LAMMPS *_lmp, Comm *oldcomm) : CommTiled(_lmp,oldcomm) {} /* ---------------------------------------------------------------------- */ diff --git a/src/KSPACE/msm.cpp b/src/KSPACE/msm.cpp index af02d34e27..c16323629b 100644 --- a/src/KSPACE/msm.cpp +++ b/src/KSPACE/msm.cpp @@ -124,9 +124,8 @@ void MSM::init() triclinic_check(); if (domain->dimension == 2) error->all(FLERR,"Cannot (yet) use MSM with 2d simulation"); - if (comm->style != 0) - error->universe_all(FLERR,"MSM can only currently be used with " - "comm_style brick"); + if (comm->style != Comm::BRICK) + error->universe_all(FLERR,"MSM can only currently be used with comm_style brick"); if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); diff --git a/src/KSPACE/pppm_dipole.cpp b/src/KSPACE/pppm_dipole.cpp index b1016e9b42..e13ade879b 100644 --- a/src/KSPACE/pppm_dipole.cpp +++ b/src/KSPACE/pppm_dipole.cpp @@ -116,14 +116,13 @@ void PPPMDipole::init() if (domain->dimension == 2) error->all(FLERR,"Cannot use PPPMDipole with 2d simulation"); - if (comm->style != 0) - error->universe_all(FLERR,"PPPMDipole can only currently be used with " - "comm_style brick"); + if (comm->style != Comm::BRICK) + error->universe_all(FLERR,"PPPMDipole can only currently be used with comm_style brick"); if (!atom->mu) error->all(FLERR,"Kspace style requires atom attribute mu"); - if (atom->mu && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" - " ad with dipoles"); + if (atom->mu && differentiation_flag == 1) + error->all(FLERR,"Cannot (yet) use kspace_modify diff ad with dipoles"); if (dipoleflag && strcmp(update->unit_style,"electron") == 0) error->all(FLERR,"Cannot (yet) use 'electron' units with dipoles"); @@ -137,8 +136,7 @@ void PPPMDipole::init() } if (order < 2 || order > MAXORDER) - error->all(FLERR,"PPPMDipole order cannot be < 2 or > {}", - MAXORDER); + error->all(FLERR,"PPPMDipole order cannot be < 2 or > {}", MAXORDER); // compute two charge force diff --git a/src/KSPACE/pppm_dipole_spin.cpp b/src/KSPACE/pppm_dipole_spin.cpp index a74b73edac..4551347482 100644 --- a/src/KSPACE/pppm_dipole_spin.cpp +++ b/src/KSPACE/pppm_dipole_spin.cpp @@ -101,14 +101,13 @@ void PPPMDipoleSpin::init() if (domain->dimension == 2) error->all(FLERR, "Cannot use PPPMDipoleSpin with 2d simulation"); - if (comm->style != 0) - error->universe_all(FLERR,"PPPMDipoleSpin can only currently be used with " - "comm_style brick"); + if (comm->style != Comm::BRICK) + error->universe_all(FLERR,"PPPMDipoleSpin can only currently be used with comm_style brick"); if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); - if (atom->sp && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use" - " kspace_modify diff ad with spins"); + if (atom->sp && differentiation_flag == 1) + error->all(FLERR,"Cannot (yet) use kspace_modify diff ad with spins"); if (spinflag && strcmp(update->unit_style,"metal") != 0) error->all(FLERR,"'metal' units have to be used with spins"); @@ -122,8 +121,7 @@ void PPPMDipoleSpin::init() } if (order < 2 || order > MAXORDER) - error->all(FLERR,"PPPMDipoleSpin order cannot be < 2 or > {}", - MAXORDER); + error->all(FLERR,"PPPMDipoleSpin order cannot be < 2 or > {}",MAXORDER); // compute two charge force diff --git a/src/KSPACE/pppm_disp.cpp b/src/KSPACE/pppm_disp.cpp index 52114dea84..d27986ffb8 100644 --- a/src/KSPACE/pppm_disp.cpp +++ b/src/KSPACE/pppm_disp.cpp @@ -266,9 +266,8 @@ void PPPMDisp::init() if (domain->dimension == 2) error->all(FLERR,"Cannot use PPPMDisp with 2d simulation"); - if (comm->style != 0) - error->universe_all(FLERR,"PPPMDisp can only currently be used with " - "comm_style brick"); + if (comm->style != Comm::BRICK) + error->universe_all(FLERR,"PPPMDisp can only currently be used with comm_style brick"); if (slabflag == 0 && domain->nonperiodic > 0) error->all(FLERR,"Cannot use non-periodic boundaries with PPPMDisp"); @@ -279,8 +278,7 @@ void PPPMDisp::init() } if (order > MAXORDER || order_6 > MAXORDER) - error->all(FLERR,"PPPMDisp coulomb or dispersion order cannot" - " be greater than {}",MAXORDER); + error->all(FLERR,"PPPMDisp coulomb or dispersion order cannot be greater than {}",MAXORDER); // compute two charge force @@ -328,8 +326,7 @@ void PPPMDisp::init() else error->all(FLERR,"Unsupported mixing rule in kspace_style pppm/disp"); break; default: - error->all(FLERR,std::string("Unsupported order in kspace_style " - "pppm/disp, pair_style ") + error->all(FLERR,std::string("Unsupported order in kspace_style pppm/disp, pair_style ") + force->pair_style); } function[k] = 1; diff --git a/src/LATBOLTZ/fix_lb_fluid.cpp b/src/LATBOLTZ/fix_lb_fluid.cpp index a9e12e3f52..18fc680026 100644 --- a/src/LATBOLTZ/fix_lb_fluid.cpp +++ b/src/LATBOLTZ/fix_lb_fluid.cpp @@ -181,9 +181,9 @@ FixLbFluid::FixLbFluid(LAMMPS *lmp, int narg, char **arg) : // we require continuous time stepping time_depend = 1; - if (narg < 6) error->all(FLERR, "Illegal fix lb/fluid command"); + if (narg < 6) utils::missing_cmd_args(FLERR, "fix lb/fluid",error); - if (comm->style != 0) + if (comm->style != Comm::BRICK) error->universe_all(FLERR, "Fix lb/fluid can only currently be used with comm_style brick"); MPI_Comm_rank(world, &me); diff --git a/src/MDI/mdi_engine.cpp b/src/MDI/mdi_engine.cpp index 14cc24c3a2..d866c0fea9 100644 --- a/src/MDI/mdi_engine.cpp +++ b/src/MDI/mdi_engine.cpp @@ -941,7 +941,7 @@ void MDIEngine::evaluate() output->thermo->compute(1); } else { - if (!comm->style) { + if (comm->style == Comm::BRICK) { if (domain->triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); domain->reset_box(); diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index ad42e77200..5dc5967c29 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -2774,7 +2774,7 @@ void FixBondReact::glove_ghostcheck() int ghostly = 0; #if !defined(MPI_STUBS) - if (comm->style == 0) { + if (comm->style == Comm::BRICK) { if (create_atoms_flag[rxnID] == 1) { ghostly = 1; } else { diff --git a/src/REPLICA/verlet_split.cpp b/src/REPLICA/verlet_split.cpp index 0109cc51f0..dbb91a95be 100644 --- a/src/REPLICA/verlet_split.cpp +++ b/src/REPLICA/verlet_split.cpp @@ -52,9 +52,8 @@ VerletSplit::VerletSplit(LAMMPS *lmp, int narg, char **arg) : if (universe->procs_per_world[0] % universe->procs_per_world[1]) error->universe_all(FLERR,"Verlet/split requires Rspace partition " "size be multiple of Kspace partition size"); - if (comm->style != 0) - error->universe_all(FLERR,"Verlet/split can only currently be used with " - "comm_style brick"); + if (comm->style != Comm::BRICK) + error->universe_all(FLERR,"Verlet/split can only currently be used with comm_style brick"); // master = 1 for Rspace procs, 0 for Kspace procs @@ -217,11 +216,10 @@ VerletSplit::~VerletSplit() void VerletSplit::init() { - if (comm->style != 0) - error->universe_all(FLERR,"Verlet/split can only currently be used with " - "comm_style brick"); + if (comm->style != Comm::BRICK) + error->universe_all(FLERR,"Verlet/split can only currently be used with comm_style brick"); if (!force->kspace && comm->me == 0) - error->warning(FLERR,"No Kspace calculation with verlet/split"); + error->warning(FLERR,"A KSpace style must be defined with verlet/split"); if (force->kspace_match("/tip4p",0)) tip4p_flag = 1; else tip4p_flag = 0; diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp index 6ae27500af..0822b4a9f9 100644 --- a/src/SRD/fix_srd.cpp +++ b/src/SRD/fix_srd.cpp @@ -355,7 +355,7 @@ void FixSRD::init() error->all(FLERR, "Fix srd no-slip requires atom attribute torque"); if (initflag && update->dt != dt_big) error->all(FLERR, "Cannot change timestep once fix srd is setup"); - if (comm->style != 0) + if (comm->style != Comm::BRICK) error->universe_all(FLERR, "Fix srd can only currently be used with comm_style brick"); // orthogonal vs triclinic simulation box diff --git a/src/balance.cpp b/src/balance.cpp index 4ae91c8d94..c8eb74b5a0 100644 --- a/src/balance.cpp +++ b/src/balance.cpp @@ -245,7 +245,7 @@ void Balance::command(int narg, char **arg) } } - if (style == BISECTION && comm->style == 0) + if (style == BISECTION && comm->style == Comm::BRICK) error->all(FLERR,"Balance rcb cannot be used with comm_style brick"); // process remaining optional args diff --git a/src/comm.h b/src/comm.h index aa353241c1..39786ee3ba 100644 --- a/src/comm.h +++ b/src/comm.h @@ -20,13 +20,18 @@ namespace LAMMPS_NS { class Comm : protected Pointers { public: - int style; // comm pattern: 0 = 6-way stencil, 1 = irregular tiling + enum { BRICK, TILED }; + int style; // BRICK = 6-way stencil communication + // TILED = irregular tiling communication + + enum { LAYOUT_UNIFORM, LAYOUT_NONUNIFORM, LAYOUT_TILED }; int layout; // LAYOUT_UNIFORM = equal-sized bricks // LAYOUT_NONUNIFORM = logical bricks, but diff sizes via LB // LAYOUT_TILED = general tiling, due to RCB LB - enum { LAYOUT_UNIFORM, LAYOUT_NONUNIFORM, LAYOUT_TILED }; - int mode; // 0 = single cutoff, 1 = multi-collection cutoff, 2 = multiold-type cutoff enum { SINGLE, MULTI, MULTIOLD }; + int mode; // SINGLE = single cutoff + // MULTI = multi-collection cutoff + // MULTIOLD = multiold-type cutoff int me, nprocs; // proc info int ghost_velocity; // 1 if ghost atoms have velocity, 0 if not diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index a93d1604f6..5e4e83cda7 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -50,7 +50,7 @@ CommBrick::CommBrick(LAMMPS *lmp) : pbc_flag(nullptr), pbc(nullptr), firstrecv(nullptr), sendlist(nullptr), localsendlist(nullptr), maxsendlist(nullptr), buf_send(nullptr), buf_recv(nullptr) { - style = 0; + style = Comm::BRICK; layout = Comm::LAYOUT_UNIFORM; pbc_flag = nullptr; init_buffers(); @@ -92,7 +92,7 @@ CommBrick::CommBrick(LAMMPS * /*lmp*/, Comm *oldcomm) : Comm(*oldcomm) if (oldcomm->layout == Comm::LAYOUT_TILED) error->all(FLERR,"Cannot change to comm_style brick from tiled layout"); - style = 0; + style = Comm::BRICK; layout = oldcomm->layout; Comm::copy_arrays(oldcomm); init_buffers(); diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index 1797db75f1..517b48c9a1 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -47,7 +47,7 @@ using namespace LAMMPS_NS; CommTiled::CommTiled(LAMMPS *lmp) : Comm(lmp) { - style = 1; + style = Comm::TILED; layout = Comm::LAYOUT_UNIFORM; pbc_flag = nullptr; buf_send = nullptr; @@ -68,7 +68,7 @@ CommTiled::CommTiled(LAMMPS *lmp) : Comm(lmp) CommTiled::CommTiled(LAMMPS * /*lmp*/, Comm *oldcomm) : Comm(*oldcomm) { - style = 1; + style = Comm::TILED; layout = oldcomm->layout; Comm::copy_arrays(oldcomm); init_buffers(); diff --git a/src/fix_balance.cpp b/src/fix_balance.cpp index 8ad3aaa8d0..aec507e7b9 100644 --- a/src/fix_balance.cpp +++ b/src/fix_balance.cpp @@ -94,7 +94,7 @@ FixBalance::FixBalance(LAMMPS *lmp, int narg, char **arg) : } } - if (lbstyle == BISECTION && comm->style == 0) + if (lbstyle == BISECTION && comm->style == Comm::BRICK) error->all(FLERR,"Fix balance rcb cannot be used with comm_style brick"); // create instance of Balance class diff --git a/src/input.cpp b/src/input.cpp index a2ea6c63b1..47b8f8eeee 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1429,21 +1429,21 @@ void Input::comm_modify() void Input::comm_style() { - if (narg < 1) error->all(FLERR,"Illegal comm_style command"); + if (narg < 1) utils::missing_cmd_args(FLERR, "comm_style", error); if (strcmp(arg[0],"brick") == 0) { - if (comm->style == 0) return; + if (comm->style == Comm::BRICK) return; Comm *oldcomm = comm; comm = new CommBrick(lmp,oldcomm); delete oldcomm; } else if (strcmp(arg[0],"tiled") == 0) { - if (comm->style == 1) return; + if (comm->style == Comm::TILED) return; Comm *oldcomm = comm; if (lmp->kokkos) comm = new CommTiledKokkos(lmp,oldcomm); else comm = new CommTiled(lmp,oldcomm); delete oldcomm; - } else error->all(FLERR,"Illegal comm_style command"); + } else error->all(FLERR,"Unknown comm_style argument: {}", arg[0]); } /* ---------------------------------------------------------------------- */ From a66f411edcf1ec630f81e6c5692cc9b2bb04fab2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Oct 2022 12:43:14 -0400 Subject: [PATCH 16/20] add support to detect the BuildID of Windows 10 22H2 --- src/platform.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform.cpp b/src/platform.cpp index d2370e0ce7..2d9c3aa6a8 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -229,6 +229,8 @@ std::string platform::os_info() buf = "Windows 10 21H1"; } else if (build == "19044") { buf = "Windows 10 21H2"; + } else if (build == "19045") { + buf = "Windows 10 22H2"; } else if (build == "20348") { buf = "Windows Server 2022"; } else if (build == "22000") { From ca091b2e757487a3caa60605cd8383d619434a6d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Oct 2022 16:23:55 -0400 Subject: [PATCH 17/20] update ELECTRODE package instructions for traditional make. fix plural/singular. --- doc/src/Build_extras.rst | 59 +++++++++++++++++++++-------------- lib/electrode/Makefile.serial | 2 +- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/doc/src/Build_extras.rst b/doc/src/Build_extras.rst index c15af87dc6..8a5eeaa485 100644 --- a/doc/src/Build_extras.rst +++ b/doc/src/Build_extras.rst @@ -234,7 +234,7 @@ LAMMPS code. This also applies to the ``-DLAMMPS_BIGBIG``\ , Makefile you use. You can also build the library in one step from the ``lammps/src`` dir, -using a command like these, which simply invoke the ``lib/gpu/Install.py`` +using a command like these, which simply invokes the ``lib/gpu/Install.py`` script with the specified args: .. code-block:: bash @@ -350,7 +350,7 @@ minutes to hours) to build. Of course you only need to do that once.) You can download and build the KIM library manually if you prefer; follow the instructions in ``lib/kim/README``. You can also do this in one step from the lammps/src directory, using a command like - these, which simply invoke the ``lib/kim/Install.py`` script with + these, which simply invokes the ``lib/kim/Install.py`` script with the specified args. .. code-block:: bash @@ -954,7 +954,7 @@ more details. You can download and build the MS-CG library manually if you prefer; follow the instructions in ``lib/mscg/README``\ . You can also do it in one step from the ``lammps/src`` dir, using a - command like these, which simply invoke the + command like these, which simply invokes the ``lib/mscg/Install.py`` script with the specified args: .. code-block:: bash @@ -1011,7 +1011,7 @@ POEMS package ``lib/poems``\ . You can do this manually if you prefer; follow the instructions in ``lib/poems/README``\ . You can also do it in one step from the ``lammps/src`` dir, using a command like these, - which simply invoke the ``lib/poems/Install.py`` script with the + which simply invokes the ``lib/poems/Install.py`` script with the specified args: .. code-block:: bash @@ -1100,7 +1100,7 @@ binary package provided by your operating system. You can download and build the Voro++ library manually if you prefer; follow the instructions in ``lib/voronoi/README``. You can also do it in one step from the ``lammps/src`` dir, using a - command like these, which simply invoke the + command like these, which simply invokes the ``lib/voronoi/Install.py`` script with the specified args: .. code-block:: bash @@ -1179,7 +1179,7 @@ The ATC package requires the MANYBODY package also be installed. ``lib/atc``. You can do this manually if you prefer; follow the instructions in ``lib/atc/README``. You can also do it in one step from the ``lammps/src`` dir, using a command like these, - which simply invoke the ``lib/atc/Install.py`` script with the + which simply invokes the ``lib/atc/Install.py`` script with the specified args: .. code-block:: bash @@ -1230,7 +1230,7 @@ AWPMD package ``lib/awpmd``. You can do this manually if you prefer; follow the instructions in ``lib/awpmd/README``. You can also do it in one step from the ``lammps/src`` dir, using a command like these, - which simply invoke the ``lib/awpmd/Install.py`` script with the + which simply invokes the ``lib/awpmd/Install.py`` script with the specified args: .. code-block:: bash @@ -1293,7 +1293,7 @@ be built for the most part with all major versions of the C++ language. In general, it is safer to use build setting consistent with the rest of LAMMPS. This is best carried out from the LAMMPS src - directory using a command like these, which simply invoke the + directory using a command like these, which simply invokes the ``lib/colvars/Install.py`` script with the specified args: .. code-block:: bash @@ -1334,20 +1334,30 @@ This package depends on the KSPACE package. .. tab:: CMake build - No additional settings are needed besides ``-D PKG_KSPACE=yes`` and ``-D - PKG_ELECTRODE=yes``. + No additional settings are needed besides ``-D PKG_KSPACE=yes`` and + ``-D PKG_ELECTRODE=yes``. .. tab:: Traditional make - The package is activated with ``make yes-KSPACE`` and ``make - yes-ELECTRODE`` + Before building LAMMPS, you must configure the ELECTRODE support + libraries and settings in ``lib/electrode``. You can do this + manually, if you prefer, or do it in one step from the + ``lammps/src`` dir, using a command like these, which simply + invokes the ``lib/electrode/Install.py`` script with the specified + args: + + .. code-block:: bash + + $ make lib-electrode # print help message + $ make lib-electrode args="-m serial" # build with GNU g++ compiler and MPI STUBS (settings as with "make serial") + $ make lib-electrode args="-m mpi" # build with default MPI compiler (settings as with "make mpi") - Note that the ``Makefile.lammps`` file has settings for the BLAS and - LAPACK linear algebra libraries. As explained in ``lib/awpmd/README`` - these can either exist on your system, or you can use the files provided - in ``lib/linalg``. In the latter case you also need to build the library - in ``lib/linalg`` with a command like these: + Note that the ``Makefile.lammps`` file has settings for the BLAS + and LAPACK linear algebra libraries. These can either exist on + your system, or you can use the files provided in ``lib/linalg``. + In the latter case you also need to build the library in + ``lib/linalg`` with a command like these: .. code-block:: bash @@ -1356,6 +1366,9 @@ This package depends on the KSPACE package. $ make lib-linalg args="-m mpi" # build with default MPI Fortran compiler (settings as with "make mpi") $ make lib-linalg args="-m gfortran" # build with GNU Fortran compiler + The package itself is activated with ``make yes-KSPACE`` and + ``make yes-ELECTRODE`` + ---------- .. _ml-pace: @@ -1555,7 +1568,7 @@ the HDF5 library. ``lib/h5md``. You can do this manually if you prefer; follow the instructions in ``lib/h5md/README``. You can also do it in one step from the ``lammps/src`` dir, using a command like these, - which simply invoke the ``lib/h5md/Install.py`` script with the + which simply invokes the ``lib/h5md/Install.py`` script with the specified args: .. code-block:: bash @@ -1611,7 +1624,7 @@ details please see ``lib/hdnnp/README`` and the `n2p2 build documentation You can download and build the *n2p2* library manually if you prefer; follow the instructions in ``lib/hdnnp/README``\ . You can also do it in one step from the ``lammps/src`` dir, using a command like these, which - simply invoke the ``lib/hdnnp/Install.py`` script with the specified args: + simply invokes the ``lib/hdnnp/Install.py`` script with the specified args: .. code-block:: bash @@ -1748,7 +1761,7 @@ they will be downloaded the first time this package is installed. Before building LAMMPS, you must build the *mesont* library in ``lib/mesont``\ . You can also do it in one step from the ``lammps/src`` dir, using a command like these, which simply - invoke the ``lib/mesont/Install.py`` script with the specified + invokes the ``lib/mesont/Install.py`` script with the specified args: .. code-block:: bash @@ -1917,7 +1930,7 @@ verified to work in February 2020 with Quantum Espresso versions 6.3 to ``lib/qmmm``. You can do this manually if you prefer; follow the first two steps explained in ``lib/qmmm/README``. You can also do it in one step from the ``lammps/src`` dir, using a command like - these, which simply invoke the ``lib/qmmm/Install.py`` script with + these, which simply invokes the ``lib/qmmm/Install.py`` script with the specified args: .. code-block:: bash @@ -2025,7 +2038,7 @@ To build with this package, you must download and build the You can download and build the ScaFaCoS library manually if you prefer; follow the instructions in ``lib/scafacos/README``. You can also do it in one step from the ``lammps/src`` dir, using a - command like these, which simply invoke the + command like these, which simply invokes the ``lib/scafacos/Install.py`` script with the specified args: .. code-block:: bash @@ -2069,7 +2082,7 @@ Eigen3 is a template library, so you do not need to build it. You can download the Eigen3 library manually if you prefer; follow the instructions in ``lib/smd/README``. You can also do it in one step from the ``lammps/src`` dir, using a command like these, - which simply invoke the ``lib/smd/Install.py`` script with the + which simply invokes the ``lib/smd/Install.py`` script with the specified args: .. code-block:: bash diff --git a/lib/electrode/Makefile.serial b/lib/electrode/Makefile.serial index 8bdd02bae3..0bcc22a58a 100644 --- a/lib/electrode/Makefile.serial +++ b/lib/electrode/Makefile.serial @@ -11,7 +11,7 @@ OBJ = $(SRC:.cpp=.o) # ------ SETTINGS ------ -# include any MPI settings needed for the ATC library to build with +# include any MPI settings needed for the electrode library to build with # the same MPI library that LAMMPS is built with CC = g++ From e2f263b8270778edf43fa256f29ed16be333d846 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Oct 2022 17:04:10 -0400 Subject: [PATCH 18/20] protect against division by zero --- src/KOKKOS/kokkos.cpp | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index dcdc26c13b..6506c86462 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -144,28 +144,36 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) set_flag = 1; } if ((str = getenv("MPT_LRANK"))) { - int local_rank = atoi(str); - device = local_rank % ngpus; - if (device >= skip_gpu) device++; - set_flag = 1; + if (ngpus > 0) { + int local_rank = atoi(str); + device = local_rank % ngpus; + if (device >= skip_gpu) device++; + set_flag = 1; + } } if ((str = getenv("MV2_COMM_WORLD_LOCAL_RANK"))) { - int local_rank = atoi(str); - device = local_rank % ngpus; - if (device >= skip_gpu) device++; - set_flag = 1; + if (ngpus > 0) { + int local_rank = atoi(str); + device = local_rank % ngpus; + if (device >= skip_gpu) device++; + set_flag = 1; + } } if ((str = getenv("OMPI_COMM_WORLD_LOCAL_RANK"))) { - int local_rank = atoi(str); - device = local_rank % ngpus; - if (device >= skip_gpu) device++; - set_flag = 1; + if (ngpus > 0) { + int local_rank = atoi(str); + device = local_rank % ngpus; + if (device >= skip_gpu) device++; + set_flag = 1; + } } if ((str = getenv("PMI_LOCAL_RANK"))) { - int local_rank = atoi(str); - device = local_rank % ngpus; - if (device >= skip_gpu) device++; - set_flag = 1; + if (ngpus > 0) { + int local_rank = atoi(str); + device = local_rank % ngpus; + if (device >= skip_gpu) device++; + set_flag = 1; + } } if (ngpus > 1 && !set_flag) From 3bfdc0aae972962614fe6d0fb6a8d243c1e7d63b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Oct 2022 17:05:55 -0400 Subject: [PATCH 19/20] initialize pointer to null --- src/ASPHERE/pair_ylz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASPHERE/pair_ylz.cpp b/src/ASPHERE/pair_ylz.cpp index 7504bb9d8e..2d035b6f5d 100644 --- a/src/ASPHERE/pair_ylz.cpp +++ b/src/ASPHERE/pair_ylz.cpp @@ -52,7 +52,7 @@ static const char cite_pair_ylz[] = PairYLZ::PairYLZ(LAMMPS *lmp) : Pair(lmp), epsilon(nullptr), sigma(nullptr), cut(nullptr), zeta(nullptr), mu(nullptr), - beta(nullptr) + beta(nullptr), avec(nullptr) { if (lmp->citeme) lmp->citeme->add(cite_pair_ylz); From e70ccf454dc31f830cf38664686e3881720fcb92 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 28 Oct 2022 10:11:50 -0400 Subject: [PATCH 20/20] fix cut-n-paste bug --- src/fix_ave_chunk.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fix_ave_chunk.cpp b/src/fix_ave_chunk.cpp index 0302074b71..7c37bbaaff 100644 --- a/src/fix_ave_chunk.cpp +++ b/src/fix_ave_chunk.cpp @@ -83,38 +83,38 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[iarg],"vx") == 0) { val.which = ArgInfo::V; - val.which = 0; + val.argindex = 0; } else if (strcmp(arg[iarg],"vy") == 0) { val.which = ArgInfo::V; - val.which = 1; + val.argindex = 1; } else if (strcmp(arg[iarg],"vz") == 0) { val.which = ArgInfo::V; - val.which = 2; + val.argindex = 2; } else if (strcmp(arg[iarg],"fx") == 0) { val.which = ArgInfo::F; - val.which = 0; + val.argindex = 0; } else if (strcmp(arg[iarg],"fy") == 0) { val.which = ArgInfo::F; - val.which = 1; + val.argindex = 1; } else if (strcmp(arg[iarg],"fz") == 0) { val.which = ArgInfo::F; - val.which = 2; + val.argindex = 2; } else if (strcmp(arg[iarg],"mass") == 0) { val.which = ArgInfo::MASS; - val.which = 0; + val.argindex = 0; } else if (strcmp(arg[iarg],"density/number") == 0) { densityflag = 1; val.which = ArgInfo::DENSITY_NUMBER; - val.which = 0; + val.argindex = 0; } else if (strcmp(arg[iarg],"density/mass") == 0) { densityflag = 1; val.which = ArgInfo::DENSITY_MASS; - val.which = 0; + val.argindex = 0; } else if (strcmp(arg[iarg],"temp") == 0) { val.which = ArgInfo::TEMPERATURE; - val.which = 0; + val.argindex = 0; } else { ArgInfo argi(arg[iarg]);