From 37d4c4c7f197d6f5f9b5413b62cdc95c5126dae7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 29 Aug 2022 12:52:16 -0400 Subject: [PATCH 01/27] properly initialize result storage for per-chunk arrays --- src/compute_reduce_chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compute_reduce_chunk.cpp b/src/compute_reduce_chunk.cpp index 1749503254..5236917688 100644 --- a/src/compute_reduce_chunk.cpp +++ b/src/compute_reduce_chunk.cpp @@ -323,7 +323,7 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) { // initialize per-chunk values in accumulation vector - for (int i = 0; i < nchunk; i += nstride) vchunk[i] = initvalue; + for (int i = 0; i < nvalues*nchunk; i += nstride) vchunk[i] = initvalue; // loop over my atoms // use peratom input and chunk ID of each atom to update vector From 0cc174243cca1ecfc31dc613538c95233d5ad7f5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 29 Aug 2022 14:47:33 -0400 Subject: [PATCH 02/27] workaround for hipcc/dpcpp compilers that silently convert long double to double --- src/fmt/format.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/fmt/format.h b/src/fmt/format.h index 7c607dbd30..12670a0b87 100644 --- a/src/fmt/format.h +++ b/src/fmt/format.h @@ -1312,6 +1312,17 @@ template <> struct float_info { static const int shorter_interval_tie_upper_threshold = -77; }; +#if 1 +// LAMMPS workaround: Some LLVM based compilers (e.g. AMD's hipcc, Intel's dpcpp) +// fail to match the following mixed 80/128-bit template below for "long double". +// since they silently change long double to double. So we provide an explicit one. + +template <> struct float_info { + using carrier_uint = detail::uint128_t; + static const int exponent_bits = 15; +}; +#endif + // An 80- or 128-bit floating point number. template struct float_info::digits == 64 || From 118b464a5328a069e26edbc569d951040c7887d1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 29 Aug 2022 17:04:48 -0400 Subject: [PATCH 03/27] add example for a 1-d pressure profile --- doc/src/compute_stress_atom.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/src/compute_stress_atom.rst b/doc/src/compute_stress_atom.rst index 08f7e3032e..3b21fbf102 100644 --- a/doc/src/compute_stress_atom.rst +++ b/doc/src/compute_stress_atom.rst @@ -222,6 +222,26 @@ result. I.e. the last 2 columns of thermo output will be the same: ` command, since those are contributions to the global system pressure. +The compute stress/atom can be used in a number of ways. Here is an +example to compute a 1-d pressure profile in z-direction across the +complete simulation box. You will need to adjust the number of bins and the +selections for time averaging to your specific simulation. This assumes +that the dimensions of the simulation cell does not change. + +.. code-block:: LAMMPS + + # set number of bins + variable nbins index 20 + variable fraction equal 1.0/v_nbins + # define bins as chunks + compute cchunk all chunk/atom bin/1d x lower ${fraction} units reduced + compute stress all stress/atom NULL + # apply conversion to pressure early since we have no variable style for processing chunks + variable press atom -(c_stress[1]+c_stress[2]+c_stress[3])/(3.0*vol*${fraction}) + compute binpress all reduce/chunk cchunk sum v_press + fix avg all ave/time 10 40 400 c_binpress mode vector file ave_stress.txt + + Output info """"""""""" From 978165377d486e0b18192250a6d10a4b34fc2bed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 05:00:06 -0400 Subject: [PATCH 04/27] clarify and correct units of "k" --- doc/src/pair_harmonic_cut.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/src/pair_harmonic_cut.rst b/doc/src/pair_harmonic_cut.rst index ab719ee3d6..6b28db5fda 100644 --- a/doc/src/pair_harmonic_cut.rst +++ b/doc/src/pair_harmonic_cut.rst @@ -33,7 +33,8 @@ Style *harmonic/cut* computes pairwise repulsive-only harmonic interactions with E = k (r_c - r)^2 \qquad r < r_c -:math:`r_c` is the cutoff. +where :math:`r_c` is the cutoff. Note that the usual 1/2 factor is +included in :math:`k`. The following coefficients must be defined for each pair of atoms types via the :doc:`pair_coeff ` command as in the examples @@ -41,7 +42,7 @@ above, or in the data file or restart files read by the :doc:`read_data ` or :doc:`read_restart ` commands: -* :math:`k` (energy units) +* :math:`k` (energy/distance^2 units) * :math:`r_c` (distance units) ---------- From d369c4eb157464642fb86b80ae4dd9de67368bb7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 15:00:24 -0400 Subject: [PATCH 05/27] fix bug from incorrect use of constexpr --- unittest/commands/test_set_property.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index f482463060..f5e290c671 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -316,7 +316,7 @@ TEST_F(SetTest, SpinPackage) constexpr double vx = 0.1; constexpr double vy = 0.5; constexpr double vz = -0.1; - constexpr double norm = 1.0 / sqrt(vx * vx + vy * vy + vz * vz); + const double norm = 1.0 / sqrt(vx * vx + vy * vy + vz * vz); ASSERT_EQ(atom->sp[0][0], vx * norm); ASSERT_EQ(atom->sp[0][1], vy * norm); ASSERT_EQ(atom->sp[0][2], vz * norm); From fe47680491f999592dcb47da5392b8f448ee5f35 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 15:07:53 -0400 Subject: [PATCH 06/27] revise workflow triggers --- .github/workflows/compile-msvc.yml | 6 ++++-- .github/workflows/unittest-macos.yml | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/compile-msvc.yml b/.github/workflows/compile-msvc.yml index 216f465568..3ec5fc4cb0 100644 --- a/.github/workflows/compile-msvc.yml +++ b/.github/workflows/compile-msvc.yml @@ -3,9 +3,11 @@ name: "Native Windows Compilation and Unit Tests" on: push: - branches: [ develop ] + branches: + - develop pull_request: - branches: [ $default-branch ] + branches: + - develop workflow_dispatch: diff --git a/.github/workflows/unittest-macos.yml b/.github/workflows/unittest-macos.yml index aba0570f2b..2d29eac83e 100644 --- a/.github/workflows/unittest-macos.yml +++ b/.github/workflows/unittest-macos.yml @@ -3,9 +3,11 @@ name: "Unittest for MacOS" on: push: - branches: [ develop ] + branches: + - develop pull_request: - branches: [ $default-branch ] + branches: + - develop workflow_dispatch: From 673eeff58170e87765ff723e849b473773eaa6ad Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 Aug 2022 14:39:46 -0400 Subject: [PATCH 07/27] recover dump_modify every behavior --- src/dump.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dump.cpp b/src/dump.cpp index c4b4cc02e9..b04a9bf413 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -1074,6 +1074,7 @@ void Dump::modify_params(int narg, char **arg) } output->mode_dump[idump] = 0; output->every_dump[idump] = n; + output->next_dump[idump] = (update->ntimestep/n)*n+n; iarg += 2; } else if (strcmp(arg[iarg],"every/time") == 0) { From 6a745f40ea9767d02caf53df3b67c19f0720ce2d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 Aug 2022 17:16:26 -0400 Subject: [PATCH 08/27] make bugfix compatible with using a variable for dump_modify every --- src/dump.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dump.cpp b/src/dump.cpp index b04a9bf413..51dae8b131 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -1067,14 +1067,15 @@ void Dump::modify_params(int narg, char **arg) if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) { delete[] output->var_dump[idump]; output->var_dump[idump] = utils::strdup(&arg[iarg+1][2]); + output->last_dump[idump] = -1; n = 0; } else { n = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (n <= 0) error->all(FLERR, "Invalid dump_modify every argument: {}", n); + output->next_dump[idump] = (update->ntimestep/n)*n+n; } output->mode_dump[idump] = 0; output->every_dump[idump] = n; - output->next_dump[idump] = (update->ntimestep/n)*n+n; iarg += 2; } else if (strcmp(arg[iarg],"every/time") == 0) { From bb225c4be63dedc40210131ed05e16b891266381 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 Aug 2022 17:20:04 -0400 Subject: [PATCH 09/27] add unit test for checking dump_modify every --- unittest/formats/test_dump_atom.cpp | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 12dd8bee8a..015c8125b4 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -21,7 +21,9 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include +#include using ::testing::Eq; @@ -108,6 +110,21 @@ public: END_HIDE_OUTPUT(); return fmt::format("{}.txt", binary_file); } + + std::vector extract_items(const std::string &file, const std::string &item) + { + std::string match = fmt::format("^ITEM: {}", item); + std::vector values; + + std::ifstream dump(file); + for (std::string buffer; std::getline(dump, buffer);) { + if (utils::strmatch(buffer, match)) { + std::getline(dump, buffer); + values.push_back(utils::trim(buffer)); + } + } + return values; + } }; TEST_F(DumpAtomTest, run0) @@ -680,7 +697,49 @@ TEST_F(DumpAtomTest, binary_write_dump) delete_file(reference); delete_file(dump_file); } + +TEST_F(DumpAtomTest, every) +{ + auto dump_file = dump_filename("every"); + BEGIN_HIDE_OUTPUT(); + command("dump id all atom 10 " + dump_file); + command("run 20 post no"); + command("dump_modify id every 5"); + command("run 15 post no"); + command("dump_modify id every 10"); + command("run 25 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + auto timesteps = extract_items(dump_file, "TIMESTEP"); + std::vector expected = {"0", "10", "20", "25", "30", "35", "40", "50", "60"}; + ASSERT_EQ(timesteps.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(timesteps[i], Eq(expected[i])); + + delete_file(dump_file); + + BEGIN_HIDE_OUTPUT(); + command("reset_timestep 0"); + command("dump id all atom 1 " + dump_file); + command("variable next equal (step+1)*(step+1)"); + command("dump_modify id every v_next"); + command("run 50 post no"); + command("variable next equal logfreq(10,7,10)"); + command("dump_modify id every v_next"); + command("run 100 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + timesteps = extract_items(dump_file, "TIMESTEP"); + expected = {"1", "4", "25", "60", "70", "100"}; + ASSERT_EQ(timesteps.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(timesteps[i], Eq(expected[i])); + + delete_file(dump_file); } +} // namespace LAMMPS_NS int main(int argc, char **argv) { From be53dda249bec164889a414c3154d282c959fa25 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 Aug 2022 21:23:23 -0400 Subject: [PATCH 10/27] more dump_modify testing --- unittest/formats/test_dump_atom.cpp | 108 +++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 11 deletions(-) diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 015c8125b4..9fce211b7a 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -113,14 +113,15 @@ public: std::vector extract_items(const std::string &file, const std::string &item) { - std::string match = fmt::format("^ITEM: {}", item); + std::string match = fmt::format("^ITEM: {}$", item); std::vector values; std::ifstream dump(file); - for (std::string buffer; std::getline(dump, buffer);) { + for (std::string buffer; std::getline(dump, buffer); /* */) { + buffer = utils::trim(buffer); if (utils::strmatch(buffer, match)) { std::getline(dump, buffer); - values.push_back(utils::trim(buffer)); + values.push_back(buffer); } } return values; @@ -698,6 +699,38 @@ TEST_F(DumpAtomTest, binary_write_dump) delete_file(dump_file); } +//------------------------------------------------------------------------------------------------- +// dump_modify +//------------------------------------------------------------------------------------------------- + +TEST_F(DumpAtomTest, units_time) +{ + auto dump_file = dump_filename("units_time"); + BEGIN_HIDE_OUTPUT(); + command("dump id all atom 10 " + dump_file); + command("dump_modify id units yes time yes"); + command("run 30 post no"); + command("timestep 0.01"); + command("run 30 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + std::vector expected, values; + values = extract_items(dump_file, "TIME"); + expected = {"0", "0.05", "0.1", "0.15", "0.25", "0.35", "0.45"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + EXPECT_THAT(values[i], Eq(expected[i])); + + values = extract_items(dump_file, "UNITS"); + expected = {"lj"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + EXPECT_THAT(values[i], Eq(expected[i])); + + delete_file(dump_file); +} + TEST_F(DumpAtomTest, every) { auto dump_file = dump_filename("every"); @@ -711,11 +744,12 @@ TEST_F(DumpAtomTest, every) command("undump id"); END_HIDE_OUTPUT(); - auto timesteps = extract_items(dump_file, "TIMESTEP"); - std::vector expected = {"0", "10", "20", "25", "30", "35", "40", "50", "60"}; - ASSERT_EQ(timesteps.size(), expected.size()); + std::vector expected, values; + values = extract_items(dump_file, "TIMESTEP"); + expected = {"0", "10", "20", "25", "30", "35", "40", "50", "60"}; + ASSERT_EQ(values.size(), expected.size()); for (int i = 0; i < expected.size(); ++i) - ASSERT_THAT(timesteps[i], Eq(expected[i])); + ASSERT_THAT(values[i], Eq(expected[i])); delete_file(dump_file); @@ -731,14 +765,66 @@ TEST_F(DumpAtomTest, every) command("undump id"); END_HIDE_OUTPUT(); - timesteps = extract_items(dump_file, "TIMESTEP"); - expected = {"1", "4", "25", "60", "70", "100"}; - ASSERT_EQ(timesteps.size(), expected.size()); + values = extract_items(dump_file, "TIMESTEP"); + expected = {"1", "4", "25", "60", "70", "100"}; + ASSERT_EQ(values.size(), expected.size()); for (int i = 0; i < expected.size(); ++i) - ASSERT_THAT(timesteps[i], Eq(expected[i])); + ASSERT_THAT(values[i], Eq(expected[i])); delete_file(dump_file); } + +TEST_F(DumpAtomTest, every_time) +{ + auto dump_file = dump_filename("every_time"); + BEGIN_HIDE_OUTPUT(); + command("dump id all atom 10 " + dump_file); + command("dump_modify id every/time 0.1"); + command("run 40 post no"); + command("timestep 0.01"); + command("run 20 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + std::vector expected, values; + values = extract_items(dump_file, "TIMESTEP"); + expected = {"0", "20", "40", "50", "60"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(values[i], Eq(expected[i])); + + delete_file(dump_file); +} + +TEST_F(DumpAtomTest, header) +{ + auto dump_file = dump_filename("header"); + BEGIN_HIDE_OUTPUT(); + command("reset_timestep 5"); + command("dump id all atom 10 " + dump_file); + command("dump_modify id first no header yes"); + command("run 40 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + std::vector expected, values; + values = extract_items(dump_file, "TIMESTEP"); + expected = {"10", "20", "30", "40"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(values[i], Eq(expected[i])); + + BEGIN_HIDE_OUTPUT(); + command("dump id all atom 10 " + dump_file); + command("dump_modify id header no"); + command("run 40 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + values = extract_items(dump_file, "TIMESTEP"); + ASSERT_EQ(values.size(), 0); + delete_file(dump_file); +} } // namespace LAMMPS_NS int main(int argc, char **argv) From ced73080b81637728f875037164d057d7ae87155 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 03:59:34 -0400 Subject: [PATCH 11/27] more dump_modify tests --- unittest/formats/test_dump_atom.cpp | 52 +++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 9fce211b7a..c38d8438ca 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -703,6 +703,54 @@ TEST_F(DumpAtomTest, binary_write_dump) // dump_modify //------------------------------------------------------------------------------------------------- +TEST_F(DumpAtomTest, delay) +{ + auto dump_file = dump_filename("delay"); + BEGIN_HIDE_OUTPUT(); + command("dump id all atom 10 " + dump_file); + command("dump_modify id delay 20"); + command("run 50 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + std::vector expected, values; + values = extract_items(dump_file, "TIMESTEP"); + expected = {"20", "30", "40", "50"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(values[i], Eq(expected[i])); + + delete_file(dump_file); +} + +TEST_F(DumpAtomTest, colname) +{ + auto dump_file = dump_filename("colname"); + BEGIN_HIDE_OUTPUT(); + command("group one id 1"); + command("dump id one atom 10 " + dump_file); + command("run 5 post no"); + command("dump_modify id colname id AtomID colname 3 x-scaled colname -1 z-scaled"); + command("run 10 post no"); + command("undump id"); + END_HIDE_OUTPUT(); + + std::vector expected, values; + values = extract_items(dump_file, "ATOMS id type xs ys zs"); + expected = {"1 1 0 0 0"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(values[i], Eq(expected[i])); + + values = extract_items(dump_file, "ATOMS AtomID type x-scaled ys z-scaled"); + expected = {"1 1 0 0 0"}; + ASSERT_EQ(values.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) + ASSERT_THAT(values[i], Eq(expected[i])); + + delete_file(dump_file); +} + TEST_F(DumpAtomTest, units_time) { auto dump_file = dump_filename("units_time"); @@ -720,13 +768,13 @@ TEST_F(DumpAtomTest, units_time) expected = {"0", "0.05", "0.1", "0.15", "0.25", "0.35", "0.45"}; ASSERT_EQ(values.size(), expected.size()); for (int i = 0; i < expected.size(); ++i) - EXPECT_THAT(values[i], Eq(expected[i])); + ASSERT_THAT(values[i], Eq(expected[i])); values = extract_items(dump_file, "UNITS"); expected = {"lj"}; ASSERT_EQ(values.size(), expected.size()); for (int i = 0; i < expected.size(); ++i) - EXPECT_THAT(values[i], Eq(expected[i])); + ASSERT_THAT(values[i], Eq(expected[i])); delete_file(dump_file); } From 4cff211a5e91532fc68d3fce77e3ef0721f74d66 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 1 Sep 2022 09:53:57 -0600 Subject: [PATCH 12/27] clarify dump doc page meaning Nevery = N --- doc/src/dump.rst | 51 ++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/doc/src/dump.rst b/doc/src/dump.rst index bd57ef0353..13332e2bc3 100644 --- a/doc/src/dump.rst +++ b/doc/src/dump.rst @@ -62,7 +62,7 @@ Syntax * ID = user-assigned name for the dump * group-ID = ID of the group of atoms to be dumped * style = *atom* or *atom/gz* or *atom/zstd* or *atom/mpiio* or *cfg* or *cfg/gz* or *cfg/zstd* or *cfg/mpiio* or *cfg/uef* or *custom* or *custom/gz* or *custom/zstd* or *custom/mpiio* or *dcd* or *h5md* or *image* or *local* or *local/gz* or *local/zstd* or *molfile* or *movie* or *netcdf* or *netcdf/mpiio* or *vtk* or *xtc* or *xyz* or *xyz/gz* or *xyz/zstd* or *xyz/mpiio* or *yaml* -* N = dump every this many timesteps +* N = dump on timesteps which are a multiple of N * file = name of file to write dump info to * args = list of arguments for a particular style @@ -176,14 +176,15 @@ Examples Description """"""""""" -Dump a snapshot of atom quantities to one or more files every :math:`N` -timesteps in one of several styles. The *image* and *movie* styles are -the exception: the *image* style renders a JPG, PNG, or PPM image file -of the atom configuration every :math:`N` timesteps while the *movie* style -combines and compresses them into a movie file; both are discussed in -detail on the :doc:`dump image ` page. The timesteps on -which dump output is written can also be controlled by a variable. -See the :doc:`dump_modify every ` command. +Dump a snapshot of atom quantities to one or more files once every +:math:`N` timesteps in one of several styles. The *image* and *movie* +styles are the exception: the *image* style renders a JPG, PNG, or PPM +image file of the atom configuration every :math:`N` timesteps while +the *movie* style combines and compresses them into a movie file; both +are discussed in detail on the :doc:`dump image ` page. +The timesteps on which dump output is written can also be controlled +by a variable. See the :doc:`dump_modify every ` +command. Only information for atoms in the specified group is dumped. The :doc:`dump_modify thresh and region and refresh ` commands @@ -485,21 +486,29 @@ popular molecular viewing program. ---------- -Dumps are performed on timesteps that are a multiple of :math:`N` (including -timestep 0) and on the last timestep of a minimization if the -minimization converges. Note that this means a dump will not be +Dumps are performed on timesteps that are a multiple of :math:`N` +(including timestep 0) and on the last timestep of a minimization if +the minimization converges. Note that this means a dump will not be performed on the initial timestep after the dump command is invoked, -if the current timestep is not a multiple of :math:`N`. This behavior can be -changed via the :doc:`dump_modify first ` command, which -can also be useful if the dump command is invoked after a minimization -ended on an arbitrary timestep. :math:`N` can be changed between runs by -using the :doc:`dump_modify every ` command (not allowed -for *dcd* style). The :doc:`dump_modify every ` command -also allows a variable to be used to determine the sequence of -timesteps on which dump files are written. In this mode a dump on the -first timestep of a run will also not be written unless the +if the current timestep is not a multiple of :math:`N`. This behavior +can be changed via the :doc:`dump_modify first ` command, +which can also be useful if the dump command is invoked after a +minimization ended on an arbitrary timestep. + +The value of :math:`N` can be changed between runs by using the +:doc:`dump_modify every ` command (not allowed for *dcd* +style). The :doc:`dump_modify every ` command also +allows a variable to be used to determine the sequence of timesteps on +which dump files are written. In this mode a dump on the first +timestep of a run will also not be written unless the :doc:`dump_modify first ` command is used. +If you instead want to dump snapshots based on simulation time (in +time units of the :doc:`units` command), the :doc:`dump_modify +every/time ` command can be used. This can be useful +when the timestep size varies during a simulation run, e.g. by use of +the :doc:`fix dt/reset ` command. + The specified filename determines how the dump file(s) is written. The default is to write one large text file, which is opened when the dump command is invoked and closed when an :doc:`undump ` From 566ea864b898e2f8e717d930476adf72156b7016 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 1 Sep 2022 10:01:08 -0600 Subject: [PATCH 13/27] clarify dump_modify doc page meaning for every and every/time --- doc/src/dump_modify.rst | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/src/dump_modify.rst b/doc/src/dump_modify.rst index d3611e0ba9..b791395259 100644 --- a/doc/src/dump_modify.rst +++ b/doc/src/dump_modify.rst @@ -35,10 +35,10 @@ Syntax *element* args = E1 E2 ... EN, where N = # of atom types E1,...,EN = element name (e.g., C or Fe or Ga) *every* arg = N - N = dump every this many timesteps + N = dump on timesteps which are a multiple of N N can be a variable (see below) *every/time* arg = Delta - Delta = dump every this interval in simulation time (time units) + Delta = dump once every Delta interval of simulation time (time units) Delta can be a variable (see below) *fileper* arg = Np Np = write one file for every this many processors @@ -207,13 +207,10 @@ will be accepted. ---------- The *every* keyword can be used with any dump style except the *dcd* -and *xtc* styles. It does two things. It specifies that the interval -between dump snapshots will be set in timesteps, which is the default -if the *every* or *every/time* keywords are not used. See the -*every/time* keyword for how to specify the interval in simulation -time, i.e. in time units of the :doc:`units ` command. The -*every* keyword also sets the interval value, which overrides the dump -frequency originally specified by the :doc:`dump ` command. +and *xtc* styles. It specifies that the output of dump snapshots will +now be performed on timesteps which are a multiple of a new :math:`N` +value, This overrides the dump frequency originally specified by the +:doc:`dump ` command. The *every* keyword can be specified in one of two ways. It can be a numeric value in which case it must be > 0. Or it can be an @@ -273,6 +270,17 @@ in file tmp.times: ---------- +The *every/time* keyword can be used with any dump style except the +*dcd* and *xtc* styles. It changes the frequency of dump snapshots +from being based on the current timestep to being determined by +elapsed simulation time, i.e. in time units of the :doc:`units +` command, and specifies *Delta* for the interval between +snapshots. This can be useful when the timestep size varies during a +simulation run, e.g. by use of the :doc:`fix dt/reset ` +command. The default is to perform output on timesteps which a +multiples of specified timestep value :math:`N`; see the *every* +keyword. + The *every/time* keyword can be used with any dump style except the *dcd* and *xtc* styles. It does two things. It specifies that the interval between dump snapshots will be set in simulation time From e0e4be187233b3d70e11d495cb6e58ae76e0bba4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 14:18:05 -0400 Subject: [PATCH 14/27] alternate workaround for hipcc/dpcpp fmtlib issue from upstream --- src/fmt/format.h | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/fmt/format.h b/src/fmt/format.h index 12670a0b87..49b7fb6d3f 100644 --- a/src/fmt/format.h +++ b/src/fmt/format.h @@ -1312,17 +1312,6 @@ template <> struct float_info { static const int shorter_interval_tie_upper_threshold = -77; }; -#if 1 -// LAMMPS workaround: Some LLVM based compilers (e.g. AMD's hipcc, Intel's dpcpp) -// fail to match the following mixed 80/128-bit template below for "long double". -// since they silently change long double to double. So we provide an explicit one. - -template <> struct float_info { - using carrier_uint = detail::uint128_t; - static const int exponent_bits = 15; -}; -#endif - // An 80- or 128-bit floating point number. template struct float_info::digits == 64 || @@ -1636,7 +1625,9 @@ auto snprintf_float(T value, int precision, float_specs specs, template using convert_float_result = - conditional_t::value || sizeof(T) == sizeof(double), + conditional_t::value || + std::numeric_limits::digits == + std::numeric_limits::digits, double, T>; template From 7bba3c516f6c5b0d32fa6e4b515bc1b2885eb2d1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 16:02:32 -0400 Subject: [PATCH 15/27] avoid excess string copy in auto loops --- src/ADIOS/dump_custom_adios.cpp | 2 +- src/MPIIO/dump_atom_mpiio.cpp | 2 +- src/MPIIO/dump_custom_mpiio.cpp | 2 +- src/PLUGIN/plugin.cpp | 2 +- src/dump.cpp | 2 +- src/dump_atom.cpp | 2 +- src/dump_custom.cpp | 2 +- src/dump_local.cpp | 2 +- src/fix_ave_time.cpp | 4 ++-- src/thermo.cpp | 6 +++--- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ADIOS/dump_custom_adios.cpp b/src/ADIOS/dump_custom_adios.cpp index 211a550f5e..305f3d3032 100644 --- a/src/ADIOS/dump_custom_adios.cpp +++ b/src/ADIOS/dump_custom_adios.cpp @@ -219,7 +219,7 @@ void DumpCustomADIOS::init_style() delete[] columns; std::string combined; int icol = 0; - for (auto item : utils::split_words(columns_default)) { + for (const auto &item : utils::split_words(columns_default)) { if (combined.size()) combined += " "; if (keyword_user[icol].size()) combined += keyword_user[icol]; diff --git a/src/MPIIO/dump_atom_mpiio.cpp b/src/MPIIO/dump_atom_mpiio.cpp index c275b387db..87ef2b0342 100644 --- a/src/MPIIO/dump_atom_mpiio.cpp +++ b/src/MPIIO/dump_atom_mpiio.cpp @@ -236,7 +236,7 @@ void DumpAtomMPIIO::init_style() int icol = 0; columns.clear(); - for (auto item : utils::split_words(default_columns)) { + for (const auto &item : utils::split_words(default_columns)) { if (columns.size()) columns += " "; if (keyword_user[icol].size()) columns += keyword_user[icol]; diff --git a/src/MPIIO/dump_custom_mpiio.cpp b/src/MPIIO/dump_custom_mpiio.cpp index 678ee3dadd..a5b2a681d3 100644 --- a/src/MPIIO/dump_custom_mpiio.cpp +++ b/src/MPIIO/dump_custom_mpiio.cpp @@ -207,7 +207,7 @@ void DumpCustomMPIIO::init_style() delete[] columns; std::string combined; int icol = 0; - for (auto item : utils::split_words(columns_default)) { + for (const auto &item : utils::split_words(columns_default)) { if (combined.size()) combined += " "; if (keyword_user[icol].size()) combined += keyword_user[icol]; diff --git a/src/PLUGIN/plugin.cpp b/src/PLUGIN/plugin.cpp index 6b11ac269f..5451cd31e2 100644 --- a/src/PLUGIN/plugin.cpp +++ b/src/PLUGIN/plugin.cpp @@ -448,7 +448,7 @@ int plugin_get_num_plugins() int plugin_find(const char *style, const char *name) { int i = 0; - for (auto entry : pluginlist) { + for (const auto &entry : pluginlist) { if ((strcmp(style, entry.style) == 0) && (strcmp(name, entry.name) == 0)) return i; ++i; } diff --git a/src/dump.cpp b/src/dump.cpp index 51dae8b131..247da8595a 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -1136,7 +1136,7 @@ void Dump::modify_params(int narg, char **arg) } else if (strcmp(arg[iarg],"colname") == 0) { if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "dump_modify colname", error); if (strcmp(arg[iarg+1],"default") == 0) { - for (auto item : keyword_user) item.clear(); + for (auto &item : keyword_user) item.clear(); iarg += 2; } else { if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "dump_modify colname", error); diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp index f52ba94f33..ef567abdb2 100644 --- a/src/dump_atom.cpp +++ b/src/dump_atom.cpp @@ -80,7 +80,7 @@ void DumpAtom::init_style() int icol = 0; columns.clear(); - for (auto item : utils::split_words(default_columns)) { + for (const auto &item : utils::split_words(default_columns)) { if (columns.size()) columns += " "; if (keyword_user[icol].size()) columns += keyword_user[icol]; else columns += item; diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 1e7ad367ec..2417a05c2c 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -241,7 +241,7 @@ void DumpCustom::init_style() delete[] columns; std::string combined; int icol = 0; - for (auto item : utils::split_words(columns_default)) { + for (const auto &item : utils::split_words(columns_default)) { if (combined.size()) combined += " "; if (keyword_user[icol].size()) combined += keyword_user[icol]; else combined += item; diff --git a/src/dump_local.cpp b/src/dump_local.cpp index bf26890b05..b7a390a749 100644 --- a/src/dump_local.cpp +++ b/src/dump_local.cpp @@ -161,7 +161,7 @@ void DumpLocal::init_style() delete[] columns; std::string combined; int icol = 0; - for (auto item : utils::split_words(columns_default)) { + for (const auto &item : utils::split_words(columns_default)) { if (combined.size()) combined += " "; if (keyword_user[icol].size()) combined += keyword_user[icol]; else combined += item; diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp index 010170e149..1a437783e7 100644 --- a/src/fix_ave_time.cpp +++ b/src/fix_ave_time.cpp @@ -678,7 +678,7 @@ void FixAveTime::invoke_scalar(bigint ntimestep) if (!yaml_header || overwrite) { yaml_header = true; fputs("keywords: ['Step', ", fp); - for (auto k : keyword) fmt::print(fp, "'{}', ", k); + for (const auto &k : keyword) fmt::print(fp, "'{}', ", k); fputs("]\ndata:\n", fp); } fmt::print(fp, " - [{}, ", ntimestep); @@ -900,7 +900,7 @@ void FixAveTime::invoke_vector(bigint ntimestep) if (!yaml_header || overwrite) { yaml_header = true; fputs("keywords: [", fp); - for (auto k : keyword) fmt::print(fp, "'{}', ", k); + for (const auto &k : keyword) fmt::print(fp, "'{}', ", k); fputs("]\ndata:\n", fp); } fmt::print(fp, " {}:\n", ntimestep); diff --git a/src/thermo.cpp b/src/thermo.cpp index c4a914e3a3..518deab618 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -629,7 +629,7 @@ void Thermo::modify_params(int narg, char **arg) } else if (strcmp(arg[iarg], "colname") == 0) { if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "thermo_modify colname", error); if (strcmp(arg[iarg + 1], "default") == 0) { - for (auto item : keyword_user) item.clear(); + for (auto &item : keyword_user) item.clear(); iarg += 2; } else { if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "thermo_modify colname", error); @@ -658,7 +658,7 @@ void Thermo::modify_params(int narg, char **arg) format_int_user.clear(); format_bigint_user.clear(); format_float_user.clear(); - for (auto item : format_column_user) item.clear(); + for (auto &item : format_column_user) item.clear(); iarg += 2; continue; } @@ -747,7 +747,7 @@ void Thermo::allocate() int i = 0; key2col.clear(); - for (auto item : utils::split_words(line)) { key2col[item] = i++; } + for (const auto &item : utils::split_words(line)) { key2col[item] = i++; } } /* ---------------------------------------------------------------------- From d503e441ff84b38716ef003d4f00b3749fd84916 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 16:03:02 -0400 Subject: [PATCH 16/27] modernize accessor handling --- src/fix_ave_chunk.cpp | 74 ++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/src/fix_ave_chunk.cpp b/src/fix_ave_chunk.cpp index f3242cac54..9d378f2e0c 100644 --- a/src/fix_ave_chunk.cpp +++ b/src/fix_ave_chunk.cpp @@ -260,45 +260,36 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : 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/chunk does not exist"); - if (modify->compute[icompute]->peratom_flag == 0) - error->all(FLERR,"Fix ave/chunk compute does not " - "calculate per-atom values"); - if (argindex[i] == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Fix ave/chunk compute does not " - "calculate a per-atom vector"); - if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR,"Fix ave/chunk compute does not " - "calculate a per-atom array"); - if (argindex[i] && - argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, - "Fix ave/chunk compute vector is accessed out-of-range"); + 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]); } else if (which[i] == ArgInfo::FIX) { - int ifix = modify->find_fix(ids[i]); - if (ifix < 0) - error->all(FLERR,"Fix ID for fix ave/chunk does not exist"); - if (modify->fix[ifix]->peratom_flag == 0) - error->all(FLERR, - "Fix ave/chunk fix does not calculate per-atom values"); - if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0) - error->all(FLERR, - "Fix ave/chunk fix does not calculate a per-atom vector"); - if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all(FLERR, - "Fix ave/chunk fix does not calculate a per-atom array"); - if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all(FLERR,"Fix ave/chunk fix vector is accessed out-of-range"); + 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"); + 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"); + error->all(FLERR,"Fix ave/chunk variable {} is not atom-style variable",ids[i]); } } @@ -306,14 +297,12 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : // only if nrepeat > 1 or ave = RUNNING/WINDOW, // so that locking spans multiple timesteps - 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]); - if (strcmp(cchunk->style,"chunk/atom") != 0) - error->all(FLERR,"Fix ave/chunk does not use chunk/atom compute"); + 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 (nrepeat > 1 || ave == RUNNING || ave == WINDOW) cchunk->lockcount++; + if ((nrepeat > 1) || (ave == RUNNING) || (ave == WINDOW)) cchunk->lockcount++; lockforever = 0; // print file comment lines @@ -430,9 +419,8 @@ FixAveChunk::~FixAveChunk() // decrement lock counter in compute chunk/atom, it if still exists if (nrepeat > 1 || ave == RUNNING || ave == WINDOW) { - int icompute = modify->find_compute(idchunk); - if (icompute >= 0) { - cchunk = dynamic_cast( modify->compute[icompute]); + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (cchunk) { if (ave == RUNNING || ave == WINDOW) cchunk->unlock(this); cchunk->lockcount--; } From ea254d9105a2b7e20492fcb23ea39d9889b6f94f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 16:03:23 -0400 Subject: [PATCH 17/27] remove bogus else branch --- src/SPIN/fix_nve_spin.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/SPIN/fix_nve_spin.cpp b/src/SPIN/fix_nve_spin.cpp index b075c2f88b..e578462526 100644 --- a/src/SPIN/fix_nve_spin.cpp +++ b/src/SPIN/fix_nve_spin.cpp @@ -431,22 +431,21 @@ void FixNVESpin::initial_integrate(int /*vflag*/) } } } - } else if (sector_flag == 0) { // serial seq. update + } else { // serial seq. update comm->forward_comm(); // comm. positions of ghost atoms - for (int i = 0; i < nlocal; i++) { // advance quarter s for nlocal-1 + for (int i = 0; i < nlocal; i++) { // advance quarter s for nlocal-1 if (mask[i] & groupbit) { ComputeInteractionsSpin(i); AdvanceSingleSpin(i); } } - for (int i = nlocal-1; i >= 0; i--) { // advance quarter s for nlocal-1 + for (int i = nlocal-1; i >= 0; i--) { // advance quarter s for nlocal-1 if (mask[i] & groupbit) { ComputeInteractionsSpin(i); AdvanceSingleSpin(i); } } - } else error->all(FLERR,"Illegal fix nve/spin command"); - + } } /* ---------------------------------------------------------------------- From b0f58bd7c4b07d668398e0949bd6f283b3c9cd8d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 16:03:56 -0400 Subject: [PATCH 18/27] select array dimension so they cannot be overflown --- src/AMOEBA/pair_amoeba.cpp | 8 ++++++++ src/AMOEBA/pair_amoeba.h | 14 +++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/AMOEBA/pair_amoeba.cpp b/src/AMOEBA/pair_amoeba.cpp index bf52524567..1f1baa0280 100644 --- a/src/AMOEBA/pair_amoeba.cpp +++ b/src/AMOEBA/pair_amoeba.cpp @@ -134,6 +134,14 @@ PairAmoeba::PairAmoeba(LAMMPS *lmp) : Pair(lmp) id_pole = id_udalt = id_upalt = nullptr; + memset(special_hal, 0 , sizeof(special_hal)); + memset(special_repel, 0 , sizeof(special_repel)); + memset(special_disp, 0 , sizeof(special_disp)); + memset(special_mpole, 0 , sizeof(special_mpole)); + memset(special_polar_pscale, 0 , sizeof(special_polar_pscale)); + memset(special_polar_piscale, 0 , sizeof(special_polar_piscale)); + memset(special_polar_wscale, 0 , sizeof(special_polar_wscale)); + nualt = 0; first_flag = 1; first_flag_compute = 1; diff --git a/src/AMOEBA/pair_amoeba.h b/src/AMOEBA/pair_amoeba.h index 84bc480062..ad80a74879 100644 --- a/src/AMOEBA/pair_amoeba.h +++ b/src/AMOEBA/pair_amoeba.h @@ -99,13 +99,13 @@ class PairAmoeba : public Pair { int poltyp; - double special_hal[5]; - double special_repel[5]; - double special_disp[5]; - double special_mpole[5]; - double special_polar_pscale[5]; - double special_polar_piscale[5]; - double special_polar_wscale[5]; + double special_hal[8]; + double special_repel[8]; + double special_disp[8]; + double special_mpole[8]; + double special_polar_pscale[8]; + double special_polar_piscale[8]; + double special_polar_wscale[8]; double polar_dscale, polar_uscale; From 8d26cc96c81614eb6004456a8817a26289f507b9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 21:00:17 -0400 Subject: [PATCH 19/27] also test colname default keyword/value pair --- unittest/formats/test_dump_atom.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index c38d8438ca..0140b1a9e4 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -732,12 +732,14 @@ TEST_F(DumpAtomTest, colname) command("run 5 post no"); command("dump_modify id colname id AtomID colname 3 x-scaled colname -1 z-scaled"); command("run 10 post no"); + command("dump_modify id colname default"); + command("run 10 post no"); command("undump id"); END_HIDE_OUTPUT(); std::vector expected, values; values = extract_items(dump_file, "ATOMS id type xs ys zs"); - expected = {"1 1 0 0 0"}; + expected = {"1 1 0 0 0", "1 1 0 0 0"}; ASSERT_EQ(values.size(), expected.size()); for (int i = 0; i < expected.size(); ++i) ASSERT_THAT(values[i], Eq(expected[i])); From 874588c74f20ae08dee8a3315d3088fa7c85733e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 1 Sep 2022 21:00:55 -0400 Subject: [PATCH 20/27] load/test pizza.py dump class only if NumPy is found --- unittest/python/python-pizza.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/unittest/python/python-pizza.py b/unittest/python/python-pizza.py index 745816d8e1..fd28ff9129 100644 --- a/unittest/python/python-pizza.py +++ b/unittest/python/python-pizza.py @@ -9,7 +9,15 @@ DEFAULT_STYLE_EXAMPLE_LOG=os.path.join('melt', 'log.*.melt.g++.1') MULTI_STYLE_EXAMPLE_LOG=os.path.join('peptide', 'log.27Nov18.peptide.g++.1') sys.path.insert(1,PIZZA_DIR) -import dump +# dump class uses NumPy, so only load and test dump if NumPy is available +has_numpy = False +try: + import numpy + has_numpy = True + import dump +except: + pass + import log class Logfiles(unittest.TestCase): @@ -112,6 +120,7 @@ class PythonDump(unittest.TestCase): def tearDown(self): del self.lmp + @unittest.skipIf(not has_numpy,"Missing the NumPy python module") def testDumpCustom(self): dumpfile = os.path.join(os.path.abspath('.'), 'dump.custom') self.lmp.command('shell cd ' + os.environ['TEST_INPUT_DIR']) From ff10b2bc26d8cd5f0d3acd7159c3e208ed76a93f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 2 Sep 2022 05:42:35 -0400 Subject: [PATCH 21/27] modernize accessors and error handling in fixes box/relax and spring/chunk --- src/fix_box_relax.cpp | 172 ++++++++++++++++++--------------------- src/fix_spring_chunk.cpp | 47 +++++------ 2 files changed, 100 insertions(+), 119 deletions(-) diff --git a/src/fix_box_relax.cpp b/src/fix_box_relax.cpp index 7988657339..756a62bb51 100644 --- a/src/fix_box_relax.cpp +++ b/src/fix_box_relax.cpp @@ -46,7 +46,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), id_temp(nullptr), id_press(nullptr), tflag(0), pflag(0) { - if (narg < 5) error->all(FLERR,"Illegal fix box/relax command"); + if (narg < 5) utils::missing_cmd_args(FLERR, "fix box/relax", error); scalar_flag = 1; extscalar = 1; @@ -89,7 +89,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : while (iarg < narg) { if (strcmp(arg[iarg],"iso") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax iso", error); pcouple = XYZ; p_target[0] = p_target[1] = p_target[2] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[0] = p_flag[1] = p_flag[2] = 1; @@ -99,7 +99,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : } iarg += 2; } else if (strcmp(arg[iarg],"aniso") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax aniso", error); pcouple = NONE; p_target[0] = p_target[1] = p_target[2] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[0] = p_flag[1] = p_flag[2] = 1; @@ -109,7 +109,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : } iarg += 2; } else if (strcmp(arg[iarg],"tri") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax tri", error); pcouple = NONE; scalexy = scalexz = scaleyz = 0; p_target[0] = p_target[1] = p_target[2] = utils::numeric(FLERR,arg[iarg+1],false,lmp); @@ -123,46 +123,43 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : iarg += 2; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax x", error); p_target[0] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[0] = 1; deviatoric_flag = 1; iarg += 2; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax y", error); p_target[1] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[1] = 1; deviatoric_flag = 1; iarg += 2; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax z", error); p_target[2] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[2] = 1; deviatoric_flag = 1; iarg += 2; - if (dimension == 2) - error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); + if (dimension == 2) error->all(FLERR,"Fix box/relax z not allowed for a 2d simulation"); } else if (strcmp(arg[iarg],"yz") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax yz", error); p_target[3] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[3] = 1; deviatoric_flag = 1; scaleyz = 0; iarg += 2; - if (dimension == 2) - error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); + if (dimension == 2) error->all(FLERR,"Fix box/relax yz not allowed for a 2d simulation"); } else if (strcmp(arg[iarg],"xz") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax xz", error); p_target[4] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[4] = 1; deviatoric_flag = 1; scalexz = 0; iarg += 2; - if (dimension == 2) - error->all(FLERR,"Invalid fix box/relax command for a 2d simulation"); + if (dimension == 2) error->all(FLERR,"Fix box/relax xz not allowed for a 2d simulation"); } else if (strcmp(arg[iarg],"xy") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax xy", error); p_target[5] = utils::numeric(FLERR,arg[iarg+1],false,lmp); p_flag[5] = 1; deviatoric_flag = 1; @@ -170,49 +167,50 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : iarg += 2; } else if (strcmp(arg[iarg],"couple") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax couple", error); if (strcmp(arg[iarg+1],"xyz") == 0) pcouple = XYZ; else if (strcmp(arg[iarg+1],"xy") == 0) pcouple = XY; else if (strcmp(arg[iarg+1],"yz") == 0) pcouple = YZ; else if (strcmp(arg[iarg+1],"xz") == 0) pcouple = XZ; else if (strcmp(arg[iarg+1],"none") == 0) pcouple = NONE; - else error->all(FLERR,"Illegal fix box/relax command"); + else error->all(FLERR,"Illegal fix box/relax couple command: {} unknown", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"dilate") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax dilate", error); if (strcmp(arg[iarg+1],"all") == 0) allremap = 1; else if (strcmp(arg[iarg+1],"partial") == 0) allremap = 0; - else error->all(FLERR,"Illegal fix box/relax command"); + else error->all(FLERR,"Illegal fix box/relax dilate command: {} unkown", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"vmax") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax vmax", error); vmax = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (vmax <= 0.0) error->all(FLERR,"Fix box/relax vmax value {} must be > 0", vmax); iarg += 2; } else if (strcmp(arg[iarg],"nreset") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax nreset", error); nreset_h0 = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (nreset_h0 < 0) error->all(FLERR,"Illegal fix box/relax command"); + if (nreset_h0 < 0) error->all(FLERR,"Fix box/relax nreset value {} must be >= 0", nreset_h0); iarg += 2; } else if (strcmp(arg[iarg],"scalexy") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax scalexy", error); scalexy = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"scalexz") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax scalexz", error); scalexz = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"scaleyz") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix box/relax scaleyz", error); scaleyz = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; } else if (strcmp(arg[iarg],"fixedpoint") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal fix box/relax command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "fix box/relax fixedpoint", error); fixedpoint[0] = utils::numeric(FLERR,arg[iarg+1],false,lmp); fixedpoint[1] = utils::numeric(FLERR,arg[iarg+2],false,lmp); fixedpoint[2] = utils::numeric(FLERR,arg[iarg+3],false,lmp); iarg += 4; - } else error->all(FLERR,"Illegal fix box/relax command"); + } else error->all(FLERR,"Unknown fix box/relax keyword {}", arg[iarg]); } if (p_flag[0]) box_change |= BOX_CHANGE_X; @@ -245,61 +243,55 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : // require periodicity in tensile dimension if (p_flag[0] && domain->xperiodic == 0) - error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax with non-periodic x dimension"); if (p_flag[1] && domain->yperiodic == 0) - error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax with non-periodic y dimension"); if (p_flag[2] && domain->zperiodic == 0) - error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax with non-periodic z dimension"); // require periodicity in 2nd dim of off-diagonal tilt component if (p_flag[3] && domain->zperiodic == 0) - error->all(FLERR, - "Cannot use fix box/relax on a 2nd non-periodic dimension"); + error->all(FLERR, "Cannot use fix box/relax yz with non-periodic z dimension"); if (p_flag[4] && domain->zperiodic == 0) - error->all(FLERR, - "Cannot use fix box/relax on a 2nd non-periodic dimension"); + error->all(FLERR, "Cannot use fix box/relax xz with non-periodic z dimension"); if (p_flag[5] && domain->yperiodic == 0) - error->all(FLERR, - "Cannot use fix box/relax on a 2nd non-periodic dimension"); + error->all(FLERR, "Cannot use fix box/relax xz with non-periodic y dimension"); if (scaleyz == 1 && domain->zperiodic == 0) - error->all(FLERR,"Cannot use fix box/relax " - "with tilt factor scaling on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax with yz tilt factor scaling " + "with non-periodic z dimension"); if (scalexz == 1 && domain->zperiodic == 0) - error->all(FLERR,"Cannot use fix box/relax " - "with tilt factor scaling on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax with xz tilt factor scaling " + "with non-periodic z dimension"); if (scalexy == 1 && domain->yperiodic == 0) - error->all(FLERR,"Cannot use fix box/relax " - "with tilt factor scaling on a 2nd non-periodic dimension"); + error->all(FLERR,"Cannot use fix box/relax with xy tilt factor scaling " + "with non-periodic y dimension"); if (p_flag[3] && scaleyz == 1) - error->all(FLERR,"Cannot use fix box/relax with " - "both relaxation and scaling on a tilt factor"); + error->all(FLERR,"Cannot use fix box/relax with both yz relaxation " + "and scaling on yz tilt factor"); if (p_flag[4] && scalexz == 1) - error->all(FLERR,"Cannot use fix box/relax with " - "both relaxation and scaling on a tilt factor"); + error->all(FLERR,"Cannot use fix box/relax with both xy relaxation " + "and scaling on xz tilt factor"); if (p_flag[5] && scalexy == 1) - error->all(FLERR,"Cannot use fix box/relax with " - "both relaxation and scaling on a tilt factor"); + error->all(FLERR,"Cannot use fix box/relax with both xy relaxation " + "and scaling on xy tilt factor"); if (!domain->triclinic && (p_flag[3] || p_flag[4] || p_flag[5])) - error->all(FLERR,"Can not specify Pxy/Pxz/Pyz in " - "fix box/relax with non-triclinic box"); + error->all(FLERR,"Cannot specify Pxy/Pxz/Pyz in fix box/relax with non-triclinic box"); if (pcouple == XYZ && dimension == 3 && (p_target[0] != p_target[1] || p_target[0] != p_target[2])) - error->all(FLERR,"Invalid fix box/relax pressure settings"); + error->all(FLERR,"Fix box/relax pressure for x, y, and z must be the same with couple xyz"); if (pcouple == XYZ && dimension == 2 && p_target[0] != p_target[1]) - error->all(FLERR,"Invalid fix box/relax pressure settings"); + error->all(FLERR,"Fix box/relax pressure for x and y must be the same with couple xyz"); if (pcouple == XY && p_target[0] != p_target[1]) - error->all(FLERR,"Invalid fix box/relax pressure settings"); + error->all(FLERR,"Fix box/relax pressure for x and y must be the same with couple xy"); if (pcouple == YZ && p_target[1] != p_target[2]) - error->all(FLERR,"Invalid fix box/relax pressure settings"); + error->all(FLERR,"Fix box/relax pressure for y and z must be the same with couple yz"); if (pcouple == XZ && p_target[0] != p_target[2]) - error->all(FLERR,"Invalid fix box/relax pressure settings"); - - if (vmax <= 0.0) error->all(FLERR,"Illegal fix box/relax command"); + error->all(FLERR,"Fix box/relax pressure for x and z must be the same with couple xz"); // pstyle = TRICLINIC if any off-diagonal term is controlled -> 6 dof // else pstyle = ISO if XYZ coupling or XY coupling in 2d -> 1 dof @@ -315,7 +307,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : // and thus its KE/temperature contribution should use group all id_temp = utils::strdup(std::string(id) + "_temp"); - modify->add_compute(fmt::format("{} all temp",id_temp)); + temperature = modify->add_compute(fmt::format("{} all temp",id_temp)); tflag = 1; // create a new compute pressure style (virial only) @@ -323,7 +315,7 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : // pass id_temp as 4th arg to pressure constructor id_press = utils::strdup(std::string(id) + "_press"); - modify->add_compute(fmt::format("{} all pressure {} virial",id_press, id_temp)); + pressure = modify->add_compute(fmt::format("{} all pressure {} virial", id_press, id_temp)); pflag = 1; dimension = domain->dimension; @@ -337,14 +329,14 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) : FixBoxRelax::~FixBoxRelax() { - delete [] rfix; + delete[] rfix; // delete temperature and pressure if fix created them if (tflag) modify->delete_compute(id_temp); if (pflag) modify->delete_compute(id_press); - delete [] id_temp; - delete [] id_press; + delete[] id_temp; + delete[] id_press; } /* ---------------------------------------------------------------------- */ @@ -362,15 +354,13 @@ void FixBoxRelax::init() { // set temperature and pressure ptrs - int icompute = modify->find_compute(id_temp); - if (icompute < 0) - error->all(FLERR,"Temperature ID for fix box/relax does not exist"); - temperature = modify->compute[icompute]; + temperature = modify->get_compute_by_id(id_temp); + if (!temperature) + error->all(FLERR,"Temperature compute ID {} for fix box/relax does not exist", id_temp); - icompute = modify->find_compute(id_press); - if (icompute < 0) - error->all(FLERR,"Pressure ID for fix box/relax does not exist"); - pressure = modify->compute[icompute]; + pressure = modify->get_compute_by_id(id_press); + if (!pressure) + error->all(FLERR,"Pressure compute ID {} for fix box/relax does not exist", id_press); pv2e = 1.0 / force->nktv2p; @@ -380,7 +370,7 @@ void FixBoxRelax::init() // detect if any rigid fixes exist so rigid bodies move when box is remapped // rfix[] = indices to each fix rigid - delete [] rfix; + delete[] rfix; nrigid = 0; rfix = nullptr; @@ -742,49 +732,49 @@ void FixBoxRelax::couple() int FixBoxRelax::modify_param(int narg, char **arg) { if (strcmp(arg[0],"temp") == 0) { - if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify", error); if (tflag) { modify->delete_compute(id_temp); tflag = 0; } - delete [] id_temp; + delete[] id_temp; id_temp = utils::strdup(arg[1]); - int icompute = modify->find_compute(arg[1]); - if (icompute < 0) - error->all(FLERR,"Could not find fix_modify temperature ID"); - temperature = modify->compute[icompute]; + temperature = modify->get_compute_by_id(id_temp); + if (!temperature) + error->all(FLERR,"Could not find fix_modify {} temperature compute ID {}", id, id_temp); if (temperature->tempflag == 0) - error->all(FLERR, - "Fix_modify temperature ID does not compute temperature"); + error->all(FLERR, "Fix_modify {} temperature compute {} does not compute temperature", + id, id_temp); if (temperature->igroup != 0 && comm->me == 0) - error->warning(FLERR,"Temperature for fix modify is not for group all"); + error->warning(FLERR,"Temperature compute {} for fix modify {} is not for group all", + id, id_temp); // reset id_temp of pressure to new temperature ID - icompute = modify->find_compute(id_press); - if (icompute < 0) - error->all(FLERR,"Pressure ID for fix modify does not exist"); - modify->compute[icompute]->reset_extra_compute_fix(id_temp); + pressure = modify->get_compute_by_id(id_press); + if (!pressure) + error->all(FLERR,"Pressure compute ID {} for fix modify {} does not exist", id_press, id); + pressure->reset_extra_compute_fix(id_temp); return 2; } else if (strcmp(arg[0],"press") == 0) { - if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify", error); if (pflag) { modify->delete_compute(id_press); pflag = 0; } - delete [] id_press; + delete[] id_press; id_press = utils::strdup(arg[1]); - int icompute = modify->find_compute(arg[1]); - if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID"); - pressure = modify->compute[icompute]; + pressure = modify->get_compute_by_id(id_press); + if (!pressure) + error->all(FLERR,"Could not find fix_modify {} compute pressure ID {}", id, id_press); if (pressure->pressflag == 0) - error->all(FLERR,"Fix_modify pressure ID does not compute pressure"); + error->all(FLERR,"Fix_modify {} pressure compute {} does not compute pressure", id, id_press); return 2; } return 0; diff --git a/src/fix_spring_chunk.cpp b/src/fix_spring_chunk.cpp index 411f056645..7d316af50d 100644 --- a/src/fix_spring_chunk.cpp +++ b/src/fix_spring_chunk.cpp @@ -38,7 +38,7 @@ FixSpringChunk::FixSpringChunk(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), idchunk(nullptr), idcom(nullptr), com0(nullptr), fcom(nullptr) { - if (narg != 6) error->all(FLERR,"Illegal fix spring/chunk command"); + if (narg != 6) utils::missing_cmd_args(FLERR, "fix spring/chunk", error); restart_global = 1; scalar_flag = 1; @@ -66,15 +66,14 @@ FixSpringChunk::~FixSpringChunk() // decrement lock counter in compute chunk/atom, it if still exists - int icompute = modify->find_compute(idchunk); - if (icompute >= 0) { - cchunk = dynamic_cast( modify->compute[icompute]); + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (cchunk) { cchunk->unlock(this); cchunk->lockcount--; } - delete [] idchunk; - delete [] idcom; + delete[] idchunk; + delete[] idcom; } /* ---------------------------------------------------------------------- */ @@ -94,24 +93,19 @@ void FixSpringChunk::init() { // current indices for idchunk and idcom - int icompute = modify->find_compute(idchunk); - if (icompute < 0) - error->all(FLERR,"Chunk/atom compute does not exist for fix spring/chunk"); - cchunk = dynamic_cast( modify->compute[icompute]); - if (strcmp(cchunk->style,"chunk/atom") != 0) - error->all(FLERR,"Fix spring/chunk does not use chunk/atom compute"); + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (!cchunk) + error->all(FLERR,"Chunk/atom compute {} does not exist or is not chunk/atom style", idchunk); - icompute = modify->find_compute(idcom); - if (icompute < 0) - error->all(FLERR,"Com/chunk compute does not exist for fix spring/chunk"); - ccom = dynamic_cast( modify->compute[icompute]); - if (strcmp(ccom->style,"com/chunk") != 0) - error->all(FLERR,"Fix spring/chunk does not use com/chunk compute"); + ccom = dynamic_cast(modify->get_compute_by_id(idcom)); + if (!ccom) + error->all(FLERR,"Com/chunk compute {} does not exist or is not com/chunk style", idcom); // check that idchunk is consistent with ccom->idchunk - if (strcmp(idchunk,ccom->idchunk) != 0) - error->all(FLERR,"Fix spring chunk chunkID not same as comID chunkID"); + if (ccom && (strcmp(idchunk,ccom->idchunk) != 0)) + error->all(FLERR,"Fix spring/chunk chunk ID {} not the same as compute com/chunk chunk ID {}", + idchunk, ccom->idchunk); if (utils::strmatch(update->integrate_style,"^respa")) { ilevel_respa = (dynamic_cast( update->integrate))->nlevels-1; @@ -268,21 +262,18 @@ void FixSpringChunk::restart(char *buf) memory->destroy(com0); memory->destroy(fcom); - int icompute = modify->find_compute(idchunk); - if (icompute < 0) - error->all(FLERR,"Chunk/atom compute does not exist for fix spring/chunk"); - cchunk = dynamic_cast( modify->compute[icompute]); - if (strcmp(cchunk->style,"chunk/atom") != 0) - error->all(FLERR,"Fix spring/chunk does not use chunk/atom compute"); + cchunk = dynamic_cast(modify->get_compute_by_id(idchunk)); + if (!cchunk) + error->all(FLERR,"Chunk/atom compute {} does not exist or is not chunk/atom style", idchunk); + nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); memory->create(com0,nchunk,3,"spring/chunk:com0"); memory->create(fcom,nchunk,3,"spring/chunk:fcom"); - printf("restart chunks:%d computed chunks: %d\n",n,nchunk); if (n != nchunk) { if (comm->me == 0) - error->warning(FLERR,"Number of chunks has changed. Cannot use restart"); + error->warning(FLERR,"Number of chunks changed from {} to {}. Cannot use restart", n, nchunk); memory->destroy(com0); memory->destroy(fcom); nchunk = 1; From b170ab056b303a08e0495d237d7746cc65dbfce0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 2 Sep 2022 06:22:35 -0400 Subject: [PATCH 22/27] properly link SPH and MACHDYN user guide PDFs from manual --- doc/src/Packages_details.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index 1da162a3c1..94211bb01b 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -1404,7 +1404,7 @@ This package has :ref:`specific installation instructions ` on the :doc * src/MACHDYN: filenames -> commands * src/MACHDYN/README -* doc/PDF/MACHDYN_LAMMPS_userguide.pdf +* `doc/PDF/MACHDYN_LAMMPS_userguide.pdf `_ * examples/PACKAGES/machdyn * https://www.lammps.org/movies.html#smd @@ -2692,7 +2692,7 @@ Dynamics, Ernst Mach Institute, Germany). * src/SPH: filenames -> commands * src/SPH/README -* doc/PDF/SPH_LAMMPS_userguide.pdf +* `doc/PDF/SPH_LAMMPS_userguide.pdf `_ * examples/PACKAGES/sph * https://www.lammps.org/movies.html#sph From 48b086b717b61a2ec23bf8385dbc5c99d1a589df Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 2 Sep 2022 08:04:11 -0400 Subject: [PATCH 23/27] protect potential file download against paths with blanks --- cmake/Modules/LAMMPSUtils.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/Modules/LAMMPSUtils.cmake b/cmake/Modules/LAMMPSUtils.cmake index 9f624fc007..41e35a63a5 100644 --- a/cmake/Modules/LAMMPSUtils.cmake +++ b/cmake/Modules/LAMMPSUtils.cmake @@ -110,14 +110,15 @@ function(FetchPotentials pkgfolder potfolder) math(EXPR plusone "${blank}+1") string(SUBSTRING ${line} 0 ${blank} pot) string(SUBSTRING ${line} ${plusone} -1 sum) - if(EXISTS ${LAMMPS_POTENTIALS_DIR}/${pot}) + if(EXISTS "${LAMMPS_POTENTIALS_DIR}/${pot}") file(MD5 "${LAMMPS_POTENTIALS_DIR}/${pot}" oldsum) endif() if(NOT sum STREQUAL oldsum) - message(STATUS "Checking external potential ${pot} from ${LAMMPS_POTENTIALS_URL}") + message(STATUS "Downloading external potential ${pot} from ${LAMMPS_POTENTIALS_URL}") file(DOWNLOAD "${LAMMPS_POTENTIALS_URL}/${pot}.${sum}" "${CMAKE_BINARY_DIR}/${pot}" EXPECTED_HASH MD5=${sum} SHOW_PROGRESS) - file(COPY "${CMAKE_BINARY_DIR}/${pot}" DESTINATION ${LAMMPS_POTENTIALS_DIR}) + file(REMOVE "${LAMMPS_POTENTIALS_DIR}/${pot}") + file(COPY "${CMAKE_BINARY_DIR}/${pot}" DESTINATION "${LAMMPS_POTENTIALS_DIR}") endif() endforeach() endif() From 51a4819bfc4e70823c0fd0cc1cf835ecb4c7f5a6 Mon Sep 17 00:00:00 2001 From: David Eberius Date: Fri, 2 Sep 2022 11:25:56 -0400 Subject: [PATCH 24/27] Fixed an illegal preprocessor issue. --- lib/gpu/lal_pre_cuda_hip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gpu/lal_pre_cuda_hip.h b/lib/gpu/lal_pre_cuda_hip.h index ec666a2863..92af47a4b7 100644 --- a/lib/gpu/lal_pre_cuda_hip.h +++ b/lib/gpu/lal_pre_cuda_hip.h @@ -134,7 +134,7 @@ int2 qt = tex1Dfetch(q_tex,i); \ ans=__hiloint2double(qt.y, qt.x); \ } - #elseif defined(__HIP_PLATFORM_SPIRV__) + #elif defined(__HIP_PLATFORM_SPIRV__) #define fetch4(ans,i,pos_tex) tex1Dfetch(&ans, pos_tex, i); #define fetch(ans,i,q_tex) tex1Dfetch(&ans, q_tex,i); #else From d65a6b9404c24961d9b76548053c9f91e7d9bf72 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 2 Sep 2022 13:00:29 -0400 Subject: [PATCH 25/27] make procedure to replace downloaded potential file atomic --- cmake/Modules/LAMMPSUtils.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/Modules/LAMMPSUtils.cmake b/cmake/Modules/LAMMPSUtils.cmake index 41e35a63a5..9b75209e16 100644 --- a/cmake/Modules/LAMMPSUtils.cmake +++ b/cmake/Modules/LAMMPSUtils.cmake @@ -115,10 +115,11 @@ function(FetchPotentials pkgfolder potfolder) endif() if(NOT sum STREQUAL oldsum) message(STATUS "Downloading external potential ${pot} from ${LAMMPS_POTENTIALS_URL}") - file(DOWNLOAD "${LAMMPS_POTENTIALS_URL}/${pot}.${sum}" "${CMAKE_BINARY_DIR}/${pot}" + string(MD5 TMP_EXT "${CMAKE_BINARY_DIR}") + file(DOWNLOAD "${LAMMPS_POTENTIALS_URL}/${pot}.${sum}" "${CMAKE_BINARY_DIR}/${pot}.${TMP_EXT}" EXPECTED_HASH MD5=${sum} SHOW_PROGRESS) - file(REMOVE "${LAMMPS_POTENTIALS_DIR}/${pot}") - file(COPY "${CMAKE_BINARY_DIR}/${pot}" DESTINATION "${LAMMPS_POTENTIALS_DIR}") + file(COPY "${CMAKE_BINARY_DIR}/${pot}.${TMP_EXT}" DESTINATION "${LAMMPS_POTENTIALS_DIR}") + file(RENAME "${LAMMPS_POTENTIALS_DIR}/${pot}.${TMP_EXT}" "${LAMMPS_POTENTIALS_DIR}/${pot}") endif() endforeach() endif() From 724a7cb5549c334d483281dca4d58774b62ba426 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 2 Sep 2022 16:42:14 -0400 Subject: [PATCH 26/27] fix typo --- doc/src/pair_mesocnt.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/pair_mesocnt.rst b/doc/src/pair_mesocnt.rst index e150c66721..4833ea6eb8 100644 --- a/doc/src/pair_mesocnt.rst +++ b/doc/src/pair_mesocnt.rst @@ -92,7 +92,7 @@ segments. Friction forces are a function of the relative velocity between a segment and its neighboring approximate chain (even in *segment* mode) and only act along the axes of the interacting segment and chain. In this potential, friction forces acting per unit length -of a nanotube segent are modelled as a shifted logistic function: +of a nanotube segment are modelled as a shifted logistic function: .. math:: From cad3cd7d8ee0e6796698865a537b1ff95ac8ad45 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 4 Sep 2022 17:27:32 -0400 Subject: [PATCH 27/27] fix a few typos with :doc: references --- doc/src/Packages_details.rst | 2 +- doc/src/compute_property_atom.rst | 4 ++-- doc/src/fix_orient_eco.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index dc6bb94b76..f2291b231e 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -652,7 +652,7 @@ short-range or long-range interactions. * :doc:`pair_style lj/cut/dipole/cut ` * :doc:`pair_style lj/cut/dipole/long ` * :doc:`pair_style lj/long/dipole/long ` -* :doc: `angle_style dipole ` +* :doc:`angle_style dipole ` * examples/dipole ---------- diff --git a/doc/src/compute_property_atom.rst b/doc/src/compute_property_atom.rst index 2e9619062e..dad83ee79c 100644 --- a/doc/src/compute_property_atom.rst +++ b/doc/src/compute_property_atom.rst @@ -198,8 +198,8 @@ Related commands """""""""""""""" :doc:`dump custom `, :doc:`compute reduce `, -:doc::doc:`fix ave/atom `, :doc:`fix ave/chunk -:doc:`, `fix property/atom ` +:doc:`fix ave/atom `, :doc:`fix ave/chunk` +:doc:``, `fix property/atom ` Default """"""" diff --git a/doc/src/fix_orient_eco.rst b/doc/src/fix_orient_eco.rst index b2fc71f1f7..2a2580f3cc 100644 --- a/doc/src/fix_orient_eco.rst +++ b/doc/src/fix_orient_eco.rst @@ -98,7 +98,7 @@ to track the grain boundary motion throughout the simulation. Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" -No information about this fix is written to :doc: `binary restart +No information about this fix is written to :doc:`binary restart files `. The :doc:`fix_modify ` *energy* option is supported by