From 824b1b0b66ee55e3b0033824be2ae535c5daad45 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 23 Mar 2025 16:36:16 -0400 Subject: [PATCH 01/29] relax epsilon to pass tests on macos-arm64 --- unittest/force-styles/tests/mol-pair-lj_cut_tip4p_table.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/force-styles/tests/mol-pair-lj_cut_tip4p_table.yaml b/unittest/force-styles/tests/mol-pair-lj_cut_tip4p_table.yaml index 5e6d460b65..ce0aa04004 100644 --- a/unittest/force-styles/tests/mol-pair-lj_cut_tip4p_table.yaml +++ b/unittest/force-styles/tests/mol-pair-lj_cut_tip4p_table.yaml @@ -2,7 +2,7 @@ lammps_version: 17 Feb 2022 tags: unstable date_generated: Fri Mar 18 22:17:32 2022 -epsilon: 5e-13 +epsilon: 5e-12 skip_tests: gpu prerequisites: ! | atom full From a64863caa6b5cf61d5178e189c4f92c6a1dde7b5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 23 Mar 2025 16:37:20 -0400 Subject: [PATCH 02/29] fix sphinx directive error in embedded docs --- src/library.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index 0127a0e198..17ec0612b4 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -7132,7 +7132,7 @@ has thrown a :ref:`C++ exception `. .. note:: - .. versionchanged: 2Aug2023 + .. versionchanged:: 2Aug2023 The *handle* pointer may be ``NULL`` for this function, as would be the case when a call to create a LAMMPS instance has failed. Then @@ -7175,7 +7175,7 @@ the failing MPI ranks to send messages. .. note:: - .. versionchanged: 2Aug2023 + .. versionchanged:: 2Aug2023 The *handle* pointer may be ``NULL`` for this function, as would be the case when a call to create a LAMMPS instance has failed. Then @@ -7183,7 +7183,7 @@ the failing MPI ranks to send messages. instance, but instead would check the global error buffer of the library interface. - .. versionchanged: 21Nov2023 + .. versionchanged:: 21Nov2023 The *buffer* pointer may be ``NULL``. This will clear any error status without copying the error message. From e79fcfb4ef62eacf1b45a0b60b0f420a0140380f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 24 Mar 2025 00:14:50 -0400 Subject: [PATCH 03/29] implement improved version of go-to-top button with javascript requiring only one click --- .../_themes/lammps_theme/layout.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/utils/sphinx-config/_themes/lammps_theme/layout.html b/doc/utils/sphinx-config/_themes/lammps_theme/layout.html index 7e938d2d70..e78b54f8f0 100644 --- a/doc/utils/sphinx-config/_themes/lammps_theme/layout.html +++ b/doc/utils/sphinx-config/_themes/lammps_theme/layout.html @@ -129,7 +129,7 @@
{#- SIDE NAV, TOGGLES ON MOBILE #}
From 15026cfa569d205b48b3ce218392bc302600421e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 24 Mar 2025 22:59:05 -0400 Subject: [PATCH 04/29] cosmetic --- src/ML-IAP/compute_mliap.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ML-IAP/compute_mliap.cpp b/src/ML-IAP/compute_mliap.cpp index b6c6d4e637..6a878e3f4e 100644 --- a/src/ML-IAP/compute_mliap.cpp +++ b/src/ML-IAP/compute_mliap.cpp @@ -188,10 +188,8 @@ void ComputeMLIAP::init() // allocate memory for global array - memory->create(mliaparray,size_array_rows,size_array_cols, - "compute_mliap:mliaparray"); - memory->create(mliaparrayall,size_array_rows,size_array_cols, - "compute_mliap:mliaparrayall"); + memory->create(mliaparray,size_array_rows,size_array_cols, "compute_mliap:mliaparray"); + memory->create(mliaparrayall,size_array_rows,size_array_cols, "compute_mliap:mliaparrayall"); array = mliaparrayall; // find compute for reference energy From 3ed03c40443d0fbfccf4810034639c84bee57b30 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 24 Mar 2025 22:59:36 -0400 Subject: [PATCH 05/29] add post_constructor() method to computes for symmetry with fixes --- src/compute.h | 1 + src/modify.cpp | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/compute.h b/src/compute.h index 870d9ae088..aee4a676ec 100644 --- a/src/compute.h +++ b/src/compute.h @@ -115,6 +115,7 @@ class Compute : protected Pointers { void modify_params(int, char **); virtual int modify_param(int, char **) { return 0; } virtual void reset_extra_dof(); + virtual void post_constructor() {} void init_flags(); virtual void init() = 0; diff --git a/src/modify.cpp b/src/modify.cpp index 9908b96d79..74f0d950a2 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -1293,7 +1293,18 @@ Compute *Modify::add_compute(int narg, char **arg, int trysuffix) error->all(FLERR, utils::check_packages_for_style("compute", arg[2], lmp)); compute_list = std::vector(compute, compute + ncompute + 1); - return compute[ncompute++]; + + // post_constructor() can call virtual methods in parent or child + // which would otherwise not yet be visible in child class + // post_constructor() allows new compute to create other computes + // ncompute increment must come first so recursive call to add_compute within + // post_constructor() will see updated ncompute + + auto *newcompute = compute[ncompute]; + ++ncompute; + newcompute->post_constructor(); + + return newcompute; } /* ---------------------------------------------------------------------- From 3872fa16d4bb945ccdc151d7ace798a81ff104fa Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 25 Mar 2025 04:37:15 -0400 Subject: [PATCH 06/29] small update to internal command documentation --- doc/src/Developer_internal.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/src/Developer_internal.rst b/doc/src/Developer_internal.rst index 739422d8b7..89dac47be5 100644 --- a/doc/src/Developer_internal.rst +++ b/doc/src/Developer_internal.rst @@ -1,4 +1,3 @@ - Internal Styles --------------- @@ -44,6 +43,14 @@ and packages ` with additional explanations. Internal fix styles ^^^^^^^^^^^^^^^^^^^ +These provide an implementation of features that would otherwise have +been replicated across multiple styles. The used fix ID is generally +derived from the compute or fix ID creating the fix with some string +appended. When needed, the fix can be looked up with +``Modify::get_fix_by_id()``, which returns a pointer to the fix +instance. The data managed by the fix can be accessed just as for other +fixes that can be used in input files. + fix DUMMY """"""""" @@ -52,7 +59,7 @@ been created since they access data that is only available then. However, in some cases it is required that a fix must be at or close to the top of the list of all fixes. In those cases an instance of the DUMMY fix style may be created by calling ``Modify::add_fix()`` and then -later replaced by calling ``Modify::replace_fix()``. +later replaced by the intended fix through calling ``Modify::replace_fix()``. fix STORE/ATOM """""""""""""" From 678e90f669bd4259d41530463e43f71961875872 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 25 Mar 2025 14:55:30 -0400 Subject: [PATCH 07/29] make spellchecker happy --- doc/src/Howto_moltemplate.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/Howto_moltemplate.rst b/doc/src/Howto_moltemplate.rst index c4f89a4e26..cd5a1fb100 100644 --- a/doc/src/Howto_moltemplate.rst +++ b/doc/src/Howto_moltemplate.rst @@ -277,7 +277,7 @@ This ``Butane`` object is a molecule which can be used anywhere other molecules can be used. (You can arrange ``Butane`` molecules on a lattice, as we did previously. You can also modify individual butane molecules by adding or deleting atoms or bonds. You can add bonds between specific butane molecules or use ``Butane`` as a -subunit to define even larger molecules. See the moltemplate manual for details.) +sub-unit to define even larger molecules. See the moltemplate manual for details.) From 24389a55dcf2a2ddd18277f1c319f0a209945ea9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 04:11:51 -0400 Subject: [PATCH 08/29] remove argument expansion since it would take only the first expanded argument only. this is better made explicit. --- doc/src/compute_slcsa_atom.rst | 4 ++-- src/EXTRA-COMPUTE/compute_slcsa_atom.cpp | 15 +-------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/doc/src/compute_slcsa_atom.rst b/doc/src/compute_slcsa_atom.rst index 7338b92d59..f7852cd4c7 100644 --- a/doc/src/compute_slcsa_atom.rst +++ b/doc/src/compute_slcsa_atom.rst @@ -19,7 +19,7 @@ Syntax * lr_decision_file = file name of file containing the scaling matrix for logistic regression classification * lr_bias_file = file name of file containing the bias vector for logistic regression classification * maha_file = file name of file containing for each crystal structure: the Mahalanobis distance threshold for sanity check purposes, the average reduced descriptor and the inverse of the corresponding covariance matrix -* c_ID[*] = compute ID of previously required *compute sna/atom* command +* c_ID[1] = compute ID and output data column of previously defined *compute sna/atom* command Examples """""""" @@ -27,7 +27,7 @@ Examples .. code-block:: LAMMPS compute b1 all sna/atom 9.0 0.99363 8 0.5 1.0 rmin0 0.0 nnn 24 wmode 1 delta 0.3 - compute b2 all slcsa/atom 8 4 mean_descriptors.dat lda_scalings.dat lr_decision.dat lr_bias.dat maha_thresholds.dat c_b1[*] + compute b2 all slcsa/atom 8 4 mean_descriptors.dat lda_scalings.dat lr_decision.dat lr_bias.dat maha_thresholds.dat c_b1[1] Description """"""""""" diff --git a/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp b/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp index 7ca13cc77a..f5cc1a7492 100644 --- a/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp +++ b/src/EXTRA-COMPUTE/compute_slcsa_atom.cpp @@ -103,13 +103,7 @@ ComputeSLCSAAtom::ComputeSLCSAAtom(LAMMPS *lmp, int narg, char **arg) : utils::logmesg(lmp, mesg); } - int expand = 0; - char **earg; - int nvalues = utils::expand_args(FLERR, narg - 10, &arg[10], 1, earg, lmp); - if (earg != &arg[10]) expand = 1; - arg = earg; - - ArgInfo argi(arg[0]); + ArgInfo argi(arg[10]); value_t val; val.id = ""; val.val.c = nullptr; @@ -121,13 +115,6 @@ ComputeSLCSAAtom::ComputeSLCSAAtom(LAMMPS *lmp, int narg, char **arg) : (val.which == ArgInfo::UNKNOWN) || (val.which == ArgInfo::NONE) || (argi.get_dim() > 1)) error->all(FLERR, 10, "Invalid compute slcsa/atom argument: {}", arg[0]); - // if wildcard expansion occurred, free earg memory from expand_args() - - if (expand) { - for (int i = 0; i < nvalues; i++) delete[] earg[i]; - memory->sfree(earg); - } - val.val.c = modify->get_compute_by_id(val.id); if (!val.val.c) error->all(FLERR, 10, "Compute ID {} for fix slcsa/atom does not exist", val.id); if (val.val.c->peratom_flag == 0) From c95d43f647ac71cf853b2d3106f3779ae0a76789 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 04:16:54 -0400 Subject: [PATCH 09/29] plug memory leaks --- src/EXTRA-FIX/fix_ave_correlate_long.cpp | 1 + src/compute_chunk_spread_atom.cpp | 1 + src/compute_global_atom.cpp | 1 + src/compute_reduce.cpp | 1 + src/compute_reduce_chunk.cpp | 1 + src/fix_ave_chunk.cpp | 1 + src/fix_ave_correlate.cpp | 1 + 7 files changed, 7 insertions(+) diff --git a/src/EXTRA-FIX/fix_ave_correlate_long.cpp b/src/EXTRA-FIX/fix_ave_correlate_long.cpp index e3ee7b2c34..7b47d58e51 100644 --- a/src/EXTRA-FIX/fix_ave_correlate_long.cpp +++ b/src/EXTRA-FIX/fix_ave_correlate_long.cpp @@ -321,6 +321,7 @@ FixAveCorrelateLong::FixAveCorrelateLong(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete[] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // allocate and initialize memory for calculated values and correlators diff --git a/src/compute_chunk_spread_atom.cpp b/src/compute_chunk_spread_atom.cpp index 5c47b7770e..993a16a42d 100644 --- a/src/compute_chunk_spread_atom.cpp +++ b/src/compute_chunk_spread_atom.cpp @@ -78,6 +78,7 @@ ComputeChunkSpreadAtom(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete[] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // setup and error check diff --git a/src/compute_global_atom.cpp b/src/compute_global_atom.cpp index b7bfc4a15e..6301e21770 100644 --- a/src/compute_global_atom.cpp +++ b/src/compute_global_atom.cpp @@ -89,6 +89,7 @@ ComputeGlobalAtom::ComputeGlobalAtom(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete [] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // setup and error check for both, index arg and values diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp index 385e6f300b..b695a4919a 100644 --- a/src/compute_reduce.cpp +++ b/src/compute_reduce.cpp @@ -257,6 +257,7 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete[] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // setup and error check diff --git a/src/compute_reduce_chunk.cpp b/src/compute_reduce_chunk.cpp index 133932bb63..974cbba23f 100644 --- a/src/compute_reduce_chunk.cpp +++ b/src/compute_reduce_chunk.cpp @@ -92,6 +92,7 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete[] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // error check diff --git a/src/fix_ave_chunk.cpp b/src/fix_ave_chunk.cpp index f2d324a073..c93d79337a 100644 --- a/src/fix_ave_chunk.cpp +++ b/src/fix_ave_chunk.cpp @@ -355,6 +355,7 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete[] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // this fix produces a global array diff --git a/src/fix_ave_correlate.cpp b/src/fix_ave_correlate.cpp index b3632e559a..2007acd160 100644 --- a/src/fix_ave_correlate.cpp +++ b/src/fix_ave_correlate.cpp @@ -277,6 +277,7 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS *lmp, int narg, char **arg) : if (expand) { for (int i = 0; i < nargnew; i++) delete[] earg[i]; memory->sfree(earg); + memory->sfree(amap); } // allocate and initialize memory for averaging From a9f2bdf3266284b0df819db2dc15282a19432d48 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 04:17:36 -0400 Subject: [PATCH 10/29] remove misplaced excess error call --- src/set.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/set.cpp b/src/set.cpp index 37aeb212be..7ae41e9246 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -532,7 +532,6 @@ void Set::command(int narg, char **arg) atom->get_style()); if (ivalue <= 0 || ivalue > atom->ndihedraltypes) error->all(FLERR, iarg + 1, "Invalid value {} in set dihedral command", ivalue); - error->all(FLERR,"Invalid value in set command"); topology(DIHEDRAL); iarg += 2; From c22716f5c01834c12ce4e6f08aea405835441653 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 04:45:13 -0400 Subject: [PATCH 11/29] error out on non-existing groups and improve error messages --- src/displace_atoms.cpp | 39 +++++++++++++++++++++++++-------------- src/fix_spring.cpp | 23 +++++++++++++++-------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp index 88b888200c..bc4ea8d90b 100644 --- a/src/displace_atoms.cpp +++ b/src/displace_atoms.cpp @@ -66,14 +66,16 @@ void DisplaceAtoms::command(int narg, char **arg) error->all(FLERR,"Displace_atoms command before simulation box is defined" + utils::errorurl(33)); if (narg < 2) error->all(FLERR,"Illegal displace_atoms command"); if (modify->nfix_restart_peratom) - error->all(FLERR,"Cannot displace_atoms after " - "reading restart file with per-atom info"); + error->all(FLERR,"Cannot displace_atoms after reading restart file with per-atom info"); if (comm->me == 0) utils::logmesg(lmp,"Displacing atoms ...\n"); // group and style igroup = group->find(arg[0]); + if (igroup < 0) + error->all(FLERR, Error::ARGZERO, "Could not find display_atoms group {}", arg[0]); + groupbit = group->get_bitmask_by_id(FLERR, arg[0], "displace_atoms"); if (modify->check_rigid_group_overlap(groupbit)) @@ -84,7 +86,7 @@ void DisplaceAtoms::command(int narg, char **arg) else if (strcmp(arg[1],"ramp") == 0) style = RAMP; else if (strcmp(arg[1],"random") == 0) style = RANDOM; else if (strcmp(arg[1],"rotate") == 0) style = ROTATE; - else error->all(FLERR,"Illegal displace_atoms command"); + else error->all(FLERR, 1, "Unknown displace_atoms keyword {}", arg[1]); // set option defaults @@ -123,7 +125,7 @@ void DisplaceAtoms::command(int narg, char **arg) if (strcmp(arg[2],"x") == 0) d_dim = 0; else if (strcmp(arg[2],"y") == 0) d_dim = 1; else if (strcmp(arg[2],"z") == 0) d_dim = 2; - else error->all(FLERR,"Illegal displace_atoms ramp command"); + else error->all(FLERR, 2, "Unknown displace_atoms ramp keyword {}", arg[2]); double d_lo,d_hi; if (d_dim == 0) { @@ -141,7 +143,7 @@ void DisplaceAtoms::command(int narg, char **arg) if (strcmp(arg[5],"x") == 0) coord_dim = 0; else if (strcmp(arg[5],"y") == 0) coord_dim = 1; else if (strcmp(arg[5],"z") == 0) coord_dim = 2; - else error->all(FLERR,"Illegal displace_atoms ramp command"); + else error->all(FLERR, 5, "Unknown displace_atoms ramp keyword {}", arg[5]); double coord_lo,coord_hi; if (coord_dim == 0) { @@ -182,7 +184,7 @@ void DisplaceAtoms::command(int narg, char **arg) double dy = yscale*utils::numeric(FLERR,arg[3],false,lmp); double dz = zscale*utils::numeric(FLERR,arg[4],false,lmp); int seed = utils::inumeric(FLERR,arg[5],false,lmp); - if (seed <= 0) error->all(FLERR,"Illegal displace_atoms random command"); + if (seed <= 0) error->all(FLERR, 5, "Illegal displace_atoms random seed {}", arg[5]); double **x = atom->x; int *mask = atom->mask; @@ -226,11 +228,11 @@ void DisplaceAtoms::command(int narg, char **arg) axis[2] = utils::numeric(FLERR,arg[7],false,lmp); double theta = utils::numeric(FLERR,arg[8],false,lmp); if (dim == 2 && (axis[0] != 0.0 || axis[1] != 0.0)) - error->all(FLERR,"Invalid displace_atoms rotate axis for 2d"); + error->all(FLERR, Error::NOLASTLINE, "Invalid displace_atoms rotate axis for 2d"); double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); if (len == 0.0) - error->all(FLERR,"Zero length rotation vector with displace_atoms"); + error->all(FLERR, Error::NOLASTLINE, "Zero length rotation vector with displace_atoms"); runit[0] = axis[0]/len; runit[1] = axis[1]/len; runit[2] = axis[2]/len; @@ -384,7 +386,8 @@ void DisplaceAtoms::move(int idim, char *arg, double scale) } else { int ivar = input->variable->find(arg+2); if (ivar < 0) - error->all(FLERR,"Variable name for displace_atoms does not exist"); + error->all(FLERR, Error::NOLASTLINE, + "Variable {} for displace_atoms move does not exist", arg+2); if (input->variable->equalstyle(ivar)) { double delta = scale * input->variable->compute_equal(ivar); @@ -395,7 +398,8 @@ void DisplaceAtoms::move(int idim, char *arg, double scale) input->variable->compute_atom(ivar,igroup,mvec,1,0); for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) x[i][idim] += scale*mvec[i]; - } else error->all(FLERR,"Variable for displace_atoms is invalid style"); + } else error->all(FLERR, Error::NOLASTLINE, + "Variable {} for displace_atoms is invalid style", arg+2); } } @@ -405,16 +409,23 @@ void DisplaceAtoms::move(int idim, char *arg, double scale) void DisplaceAtoms::options(int narg, char **arg) { - if (narg < 0) error->all(FLERR,"Illegal displace_atoms command"); + if (narg < 0) utils::missing_cmd_args(FLERR, "displace_atoms", error); + + // determine argument offset, if possible + int ioffset = 0; + if (lmp->input->arg) { + for (int i = 0; i < lmp->input->narg; ++i) + if (lmp->input->arg[i] == arg[0]) ioffset = i; + } int iarg = 0; while (iarg < narg) { if (strcmp(arg[iarg],"units") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal displace_atoms command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "displace_atoms units", error); if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0; else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1; - else error->all(FLERR,"Illegal displace_atoms command"); + else error->all(FLERR, ioffset + iarg + 1, "Unknown displace_atoms units argument {}", arg[iarg+1]); iarg += 2; - } else error->all(FLERR,"Illegal displace_atoms command"); + } else error->all(FLERR, ioffset + iarg, "Unknown displace_atoms keyword {}", arg[iarg]); } } diff --git a/src/fix_spring.cpp b/src/fix_spring.cpp index 829073179d..dd010654f6 100644 --- a/src/fix_spring.cpp +++ b/src/fix_spring.cpp @@ -40,7 +40,7 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), group2(nullptr) { - if (narg < 9) error->all(FLERR,"Illegal fix spring command"); + if (narg < 9) utils::missing_cmd_args(FLERR, "fix spring", error); scalar_flag = 1; vector_flag = 1; @@ -53,8 +53,9 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : respa_level_support = 1; ilevel_respa = 0; - if (strcmp(arg[3],"tether") == 0) { - if (narg != 9) error->all(FLERR,"Illegal fix spring command"); + if (strcmp(arg[3], "tether") == 0) { + if (narg != 9) + error->all(FLERR, Error::NOPOINTER, "Icorrect number of arguments for tether mode"); styleflag = TETHER; k_spring = utils::numeric(FLERR,arg[4],false,lmp); xflag = yflag = zflag = 1; @@ -65,17 +66,20 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[7],"NULL") == 0) zflag = 0; else zc = utils::numeric(FLERR,arg[7],false,lmp); r0 = utils::numeric(FLERR,arg[8],false,lmp); - if (r0 < 0) error->all(FLERR,"R0 < 0 for fix spring command"); + if (r0 < 0) error->all(FLERR, 8, "R0 < 0 for fix spring command"); } else if (strcmp(arg[3],"couple") == 0) { - if (narg != 10) error->all(FLERR,"Illegal fix spring command"); + if (narg != 10) + error->all(FLERR, Error::NOPOINTER, "Icorrect number of arguments for couple mode"); styleflag = COUPLE; group2 = utils::strdup(arg[4]); - igroup2 = group->find(arg[4]); + igroup2 = group->find(group2); + if (igroup2 < 0) + error->all(FLERR, 4, "Could not find fix spring couple second group ID {}", group2); if (igroup2 == igroup) error->all(FLERR,"The two groups cannot be the same in fix spring couple"); - group2bit = group->get_bitmask_by_id(FLERR, arg[4], "fix spring"); + group2bit = group->get_bitmask_by_id(FLERR, group2, "fix spring"); k_spring = utils::numeric(FLERR,arg[5],false,lmp); xflag = yflag = zflag = 1; @@ -88,7 +92,7 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : r0 = utils::numeric(FLERR,arg[9],false,lmp); if (r0 < 0) error->all(FLERR,"R0 < 0 for fix spring command"); - } else error->all(FLERR,"Illegal fix spring command"); + } else error->all(FLERR, 3, "Unknown fix spring keyword {}", arg[3]); ftotal[0] = ftotal[1] = ftotal[2] = ftotal[3] = 0.0; } @@ -119,6 +123,9 @@ void FixSpring::init() if (group2) { igroup2 = group->find(group2); + if (igroup2 < 0) + error->all(FLERR, Error::NOLASTLINE, "Could not find fix spring couple second group ID {}", + group2); group2bit = group->get_bitmask_by_id(FLERR, group2, "fix spring"); } From 811f79abc6ce4a0c2ed94276c742ff8cea3770d7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 04:57:01 -0400 Subject: [PATCH 12/29] error out or ignore on displacements in z-direction with 2d system --- src/displace_atoms.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp index bc4ea8d90b..b9eb121b3d 100644 --- a/src/displace_atoms.cpp +++ b/src/displace_atoms.cpp @@ -79,13 +79,13 @@ void DisplaceAtoms::command(int narg, char **arg) groupbit = group->get_bitmask_by_id(FLERR, arg[0], "displace_atoms"); if (modify->check_rigid_group_overlap(groupbit)) - error->warning(FLERR,"Attempting to displace atoms in rigid bodies"); + error->warning(FLERR, "Attempting to displace atoms in rigid bodies"); int style = -1; - if (strcmp(arg[1],"move") == 0) style = MOVE; - else if (strcmp(arg[1],"ramp") == 0) style = RAMP; - else if (strcmp(arg[1],"random") == 0) style = RANDOM; - else if (strcmp(arg[1],"rotate") == 0) style = ROTATE; + if (strcmp(arg[1], "move") == 0) style = MOVE; + else if (strcmp(arg[1], "ramp") == 0) style = RAMP; + else if (strcmp(arg[1], "random") == 0) style = RANDOM; + else if (strcmp(arg[1], "rotate") == 0) style = ROTATE; else error->all(FLERR, 1, "Unknown displace_atoms keyword {}", arg[1]); // set option defaults @@ -94,10 +94,10 @@ void DisplaceAtoms::command(int narg, char **arg) // read options from end of input line - if (style == MOVE) options(narg-5,&arg[5]); - else if (style == RAMP) options(narg-8,&arg[8]); - else if (style == RANDOM) options(narg-6,&arg[6]); - else if (style == ROTATE) options(narg-9,&arg[9]); + if (style == MOVE) options(narg-5, &arg[5]); + else if (style == RAMP) options(narg-8, &arg[8]); + else if (style == RANDOM) options(narg-6, &arg[6]); + else if (style == ROTATE) options(narg-9, &arg[9]); // setup scaling @@ -106,15 +106,14 @@ void DisplaceAtoms::command(int narg, char **arg) xscale = domain->lattice->xlattice; yscale = domain->lattice->ylattice; zscale = domain->lattice->zlattice; - } - else xscale = yscale = zscale = 1.0; + } else xscale = yscale = zscale = 1.0; // move atoms by 3-vector or specified variable(s) if (style == MOVE) { move(0,arg[2],xscale); move(1,arg[3],yscale); - move(2,arg[4],zscale); + if (domain->dimension == 3) move(2,arg[4],zscale); } // move atoms in ramped fashion @@ -125,7 +124,9 @@ void DisplaceAtoms::command(int narg, char **arg) if (strcmp(arg[2],"x") == 0) d_dim = 0; else if (strcmp(arg[2],"y") == 0) d_dim = 1; else if (strcmp(arg[2],"z") == 0) d_dim = 2; - else error->all(FLERR, 2, "Unknown displace_atoms ramp keyword {}", arg[2]); + else error->all(FLERR, 2, "Unknown displace_atoms ramp dimension {}", arg[2]); + if ((domain->dimension == 2) && (d_dim = 2)) + error->all(FLERR, 2, "Must not displace atoms in z-direction with 2d system"); double d_lo,d_hi; if (d_dim == 0) { @@ -143,7 +144,7 @@ void DisplaceAtoms::command(int narg, char **arg) if (strcmp(arg[5],"x") == 0) coord_dim = 0; else if (strcmp(arg[5],"y") == 0) coord_dim = 1; else if (strcmp(arg[5],"z") == 0) coord_dim = 2; - else error->all(FLERR, 5, "Unknown displace_atoms ramp keyword {}", arg[5]); + else error->all(FLERR, 5, "Unknown displace_atoms ramp dimension {}", arg[5]); double coord_lo,coord_hi; if (coord_dim == 0) { @@ -185,17 +186,20 @@ void DisplaceAtoms::command(int narg, char **arg) double dz = zscale*utils::numeric(FLERR,arg[4],false,lmp); int seed = utils::inumeric(FLERR,arg[5],false,lmp); if (seed <= 0) error->all(FLERR, 5, "Illegal displace_atoms random seed {}", arg[5]); + if ((domain->dimension == 2) && (dz != 0.0)) + error->all(FLERR, 4, "Must not displace atoms in z-direction with 2d system"); double **x = atom->x; int *mask = atom->mask; int nlocal = atom->nlocal; + int dim = domain->dimension; for (i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { random->reset(seed,x[i]); x[i][0] += dx * 2.0*(random->uniform()-0.5); x[i][1] += dy * 2.0*(random->uniform()-0.5); - x[i][2] += dz * 2.0*(random->uniform()-0.5); + if (dim == 3) x[i][2] += dz * 2.0*(random->uniform()-0.5); } } @@ -228,7 +232,7 @@ void DisplaceAtoms::command(int narg, char **arg) axis[2] = utils::numeric(FLERR,arg[7],false,lmp); double theta = utils::numeric(FLERR,arg[8],false,lmp); if (dim == 2 && (axis[0] != 0.0 || axis[1] != 0.0)) - error->all(FLERR, Error::NOLASTLINE, "Invalid displace_atoms rotate axis for 2d"); + error->all(FLERR, Error::NOLASTLINE, "Invalid displace_atoms rotate axis for 2d system"); double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); if (len == 0.0) From cf5d74b315c4e7dca0d1122b673afd6f3dac0f21 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 05:54:21 -0400 Subject: [PATCH 13/29] add pair style pedone to list of pair styles compatible with fix adapt --- doc/src/fix_adapt.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/fix_adapt.rst b/doc/src/fix_adapt.rst index 34e3e450f6..83a82baaa9 100644 --- a/doc/src/fix_adapt.rst +++ b/doc/src/fix_adapt.rst @@ -216,6 +216,8 @@ formulas for the meaning of these parameters: +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`pace, pace/extrapolation ` | scale | type pairs | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ +| :doc:`pedone ` | c0,d0,r0,alpha | type pairs | ++------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`quip ` | scale | type global | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`snap ` | scale | type pairs | From 8a373ab5d8aa94d2e4a1052732f2851368ad3089 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 09:00:25 -0400 Subject: [PATCH 14/29] spelling --- doc/src/Errors_details.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/Errors_details.rst b/doc/src/Errors_details.rst index 9ca69c5068..c94d96b405 100644 --- a/doc/src/Errors_details.rst +++ b/doc/src/Errors_details.rst @@ -471,7 +471,7 @@ pair-wise additive pair styles like :doc:`Lennard-Jones `, :doc:`Morse `, :doc:`Born-Meyer-Huggins `, and similar. Such required callbacks have not been implemented for many-body potentials so one would have to implement them to add -compatiability with these computes (which may be difficult to do in a +compatibility with these computes (which may be difficult to do in a generic fashion). Whether this warning indicates that contributions to the computed properties are missing depends on the groups used. At any rate, careful testing of the results is advised when this warning @@ -931,7 +931,7 @@ the documentation carefully. XXX command before simulation box is defined -------------------------------------------- -This error occurs when trying to excute a LAMMPS command that requires +This error occurs when trying to execute a LAMMPS command that requires information about the system dimensions, or the number atom, bond, angle, dihedral, or improper types, or the number of atoms or similar data that is only available *after* the simulation box has been created. @@ -943,7 +943,7 @@ created ` for additional information. XXX command after simulation box is defined -------------------------------------------- -This error occurs when trying to excute a LAMMPS command that changes a +This error occurs when trying to execute a LAMMPS command that changes a global setting *after* it is locked in when the simulation box is created (for instance defining the :doc:`atom style `, :doc:`dimension `, :doc:`newton `, or :doc:`units From c45558b640dd76dc2683b602d887910f697ff94c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 20:09:54 -0400 Subject: [PATCH 15/29] some tweaks for local table of contents --- doc/src/Commands_removed.rst | 4 ++-- doc/src/Developer_notes.rst | 2 +- doc/src/Errors_details.rst | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/src/Commands_removed.rst b/doc/src/Commands_removed.rst index cb67a3d07d..cea964fe79 100644 --- a/doc/src/Commands_removed.rst +++ b/doc/src/Commands_removed.rst @@ -1,7 +1,7 @@ Removed commands and packages ============================= -.. contents:: +.. contents:: \ ------ @@ -171,7 +171,7 @@ and the :ref:`GPU package ` are maintained and allow running LAMMPS with GPU acceleration. Compute atom/molecule -_____________________ +--------------------- .. deprecated:: 11 Dec2015 diff --git a/doc/src/Developer_notes.rst b/doc/src/Developer_notes.rst index 3f78f33d25..4c789abb3a 100644 --- a/doc/src/Developer_notes.rst +++ b/doc/src/Developer_notes.rst @@ -7,7 +7,7 @@ typically document what a variable stores, what a small section of code does, or what a function does and its input/outputs. The topics on this page are intended to document code functionality at a higher level. -.. contents:: +.. contents:: Available notes ---- diff --git a/doc/src/Errors_details.rst b/doc/src/Errors_details.rst index c94d96b405..71e7ff08e3 100644 --- a/doc/src/Errors_details.rst +++ b/doc/src/Errors_details.rst @@ -10,7 +10,9 @@ then for specific errors. In the latter cases, LAMMPS will output a short message and then provide a URL that links to a specific section on this page. -.. contents:: +------- + +.. contents:: Individual paragraphs ------ From dd313465e1ec3444fb7340800f1a7960926b7956 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 22:44:35 -0400 Subject: [PATCH 16/29] add support for writing one file per timestep with '*' wildcard --- doc/src/fix_modify.rst | 15 ++++++- doc/src/fix_reaxff_bonds.rst | 32 ++++++++----- src/REAXFF/fix_reaxff_bonds.cpp | 80 ++++++++++++++++++++------------- src/REAXFF/fix_reaxff_bonds.h | 5 ++- 4 files changed, 88 insertions(+), 44 deletions(-) diff --git a/doc/src/fix_modify.rst b/doc/src/fix_modify.rst index 265803c213..a5a499e220 100644 --- a/doc/src/fix_modify.rst +++ b/doc/src/fix_modify.rst @@ -12,7 +12,7 @@ Syntax * fix-ID = ID of the fix to modify * one or more keyword/value pairs may be appended -* keyword = *bodyforces* or *colname* or *dynamic/dof* or *energy* or *press* or *respa* or *temp* or *virial* +* keyword = *bodyforces* or *colname* or *dynamic/dof* or *energy* or *pad* or *press* or *respa* or *temp* or *virial* .. parsed-literal:: @@ -25,6 +25,7 @@ Syntax *dynamic/dof* value = *yes* or *no* yes/no = do or do not re-compute the number of degrees of freedom (DOF) contributing to the temperature *energy* value = *yes* or *no* + *pad* arg = Nchar = # of characters to convert timestep to *press* value = compute ID that calculates a pressure *respa* value = *1* to *max respa level* or *0* (for outermost level) *temp* value = compute ID that calculates a temperature @@ -184,6 +185,18 @@ replaces the string for that specific keyword. The *colname* keyword can be used multiple times. If multiple *colname* settings refer to the same keyword, the last setting has precedence. +.. versionadded:: TBD + +The *pad* keyword only applies when a fix produces a file and the output +filename is specified with a wildcard "\*" character which becomes the +timestep. If *pad* is 0, which is the default, the timestep is +converted into a string of unpadded length (e.g., 100 or 12000 or +2000000). When *pad* is specified with *Nchar* :math:`>` 0, the string +is padded with leading zeroes so they are all the same length = *Nchar*\ +. For example, pad 7 would yield 0000100, 0012000, 2000000. This can +be useful so that post-processing programs can easily read the files in +ascending timestep order. Please see the documentation of the individual +fix styles if this keyword is supported. Restrictions """""""""""" diff --git a/doc/src/fix_reaxff_bonds.rst b/doc/src/fix_reaxff_bonds.rst index 15fd9abafa..f0f6e33443 100644 --- a/doc/src/fix_reaxff_bonds.rst +++ b/doc/src/fix_reaxff_bonds.rst @@ -56,16 +56,28 @@ If the filename ends with ".gz", the output file is written in gzipped format. A gzipped dump file will be about 3x smaller than the text version, but will also take longer to write. +.. versionadded:: TBD + +If the filename contains the wildcard character "\*", a new file is +created on every timestep there bond information is written. The "\*" +character is replaced with the timestep value. Note that the +:doc:`fix_modify pad ` command can be used so that all +timestep numbers have the same length by adding leading zeroes +(e.g. 00010 for a pad value of 5). The default pad value is 0, i.e. no +leading zeroes. + ---------- Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" -No information about this fix is written to :doc:`binary restart files `. None of the :doc:`fix_modify ` options -are relevant to this fix. No global or per-atom quantities are stored -by this fix for access by various :doc:`output commands `. -No parameter of this fix can be used with the *start/stop* keywords of -the :doc:`run ` command. This fix is not invoked during :doc:`energy minimization `. +No information about this fix is written to :doc:`binary restart files +`. This fix supports the :doc:`fix_modify pad ` +option. No global or per-atom quantities are stored by this fix for +access by various :doc:`output commands `. No parameter +of this fix can be used with the *start/stop* keywords of the :doc:`run +` command. This fix is not invoked during :doc:`energy +minimization `. ---------- @@ -76,10 +88,10 @@ the :doc:`run ` command. This fix is not invoked during :doc:`energy minim Restrictions """""""""""" -The fix reaxff/bonds command requires that the :doc:`pair_style reaxff ` is invoked. This fix is part of the -REAXFF package. It is only enabled if LAMMPS was built with that -package. See the :doc:`Build package ` page for more -info. +The fix reaxff/bonds command requires that the :doc:`pair_style reaxff +` is invoked. This fix is part of the REAXFF package. It +is only enabled if LAMMPS was built with that package. See the +:doc:`Build package ` page for more info. To write gzipped bond files, you must compile LAMMPS with the -DLAMMPS_GZIP option. @@ -92,4 +104,4 @@ Related commands Default """"""" -none +pad = 0 diff --git a/src/REAXFF/fix_reaxff_bonds.cpp b/src/REAXFF/fix_reaxff_bonds.cpp index 54ad593486..7686c5ea23 100644 --- a/src/REAXFF/fix_reaxff_bonds.cpp +++ b/src/REAXFF/fix_reaxff_bonds.cpp @@ -19,6 +19,7 @@ #include "fix_reaxff_bonds.h" #include "atom.h" +#include "comm.h" #include "error.h" #include "force.h" #include "memory.h" @@ -35,38 +36,27 @@ using namespace ReaxFF; /* ---------------------------------------------------------------------- */ FixReaxFFBonds::FixReaxFFBonds(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg) + Fix(lmp, narg, arg), neighid(nullptr), abo(nullptr), fp(nullptr), lists(nullptr), + reaxff(nullptr), list(nullptr) { - if (narg != 5) error->all(FLERR,"Illegal fix reaxff/bonds command"); + if (narg != 5) + error->all(FLERR, Error::NOPOINTER, "Fix reaxff/bonds expected 5 arguments but got {}", narg); - MPI_Comm_rank(world,&me); - MPI_Comm_size(world,&nprocs); - ntypes = atom->ntypes; nmax = atom->nmax; compressed = 0; + multifile = 0; + padflag = 0; first_flag = true; nevery = utils::inumeric(FLERR,arg[3],false,lmp); + if (nevery <= 0) error->all(FLERR, 3, "Illegal fix reaxff/bonds nevery value {}", nevery); - if (nevery <= 0) error->all(FLERR,"Illegal fix reaxff/bonds command"); - - if (me == 0) { - if (platform::has_compress_extension(arg[4])) { - compressed = 1; - fp = platform::compressed_write(arg[4]); - if (!fp) error->one(FLERR,"Cannot open compressed file"); - } else fp = fopen(arg[4],"w"); - - if (!fp) error->one(FLERR,"Cannot open fix reaxff/bonds file {}: {}", - arg[4],utils::getsyserror()); - } + filename = arg[4]; + if (filename.rfind('*') != std::string::npos) multifile = 1; + if (platform::has_compress_extension(filename)) compressed = 1; if (atom->tag_consecutive() == 0) - error->all(FLERR,"Atom IDs must be consecutive for fix reaxff bonds"); - - abo = nullptr; - neighid = nullptr; - numneigh = nullptr; + error->all(FLERR, Error::NOLASTLINE, "Fix reaxff/bonds requires consecutive atom-IDs"); allocate(); } @@ -75,11 +65,9 @@ FixReaxFFBonds::FixReaxFFBonds(LAMMPS *lmp, int narg, char **arg) : FixReaxFFBonds::~FixReaxFFBonds() { - MPI_Comm_rank(world,&me); - destroy(); - if (me == 0) fclose(fp); + if (fp) fclose(fp); } /* ---------------------------------------------------------------------- */ @@ -115,7 +103,6 @@ void FixReaxFFBonds::init() void FixReaxFFBonds::end_of_step() { Output_ReaxFF_Bonds(); - if (me == 0) fflush(fp); } /* ---------------------------------------------------------------------- */ @@ -252,7 +239,24 @@ void FixReaxFFBonds::RecvBuffer(double *buf, int nbuf, int nbuf_local, double cutof3 = reaxff->api->control->bg_cut; MPI_Request irequest, irequest2; - if (me == 0) { + if (comm->me == 0) { + std::string myfile = filename; + if (multifile) myfile = utils::star_subst(myfile, update->ntimestep, padflag); + if (multifile && fp) { + fclose(fp); + fp = nullptr; + } + if (!fp) { + if (compressed) { + fp = platform::compressed_write(myfile); + } else { + fp = fopen(myfile.c_str(), "w"); + } + if (!fp) + error->one(FLERR, Error::NOLASTLINE, + "Cannot open fix reaxff/bonds file {}: {}", myfile, utils::getsyserror()); + } + utils::print(fp,"# Timestep {}\n#\n",ntimestep); utils::print(fp,"# Number of particles {}\n#\n",natoms); utils::print(fp,"# Max number of bonds per atom {} with coarse bond order cutoff {:5.3f}\n", @@ -262,8 +266,8 @@ void FixReaxFFBonds::RecvBuffer(double *buf, int nbuf, int nbuf_local, } j = 2; - if (me == 0) { - for (inode = 0; inode < nprocs; inode ++) { + if (comm->me == 0) { + for (inode = 0; inode < comm->nprocs; inode ++) { if (inode == 0) { nlocal_tmp = nlocal; } else { @@ -299,8 +303,10 @@ void FixReaxFFBonds::RecvBuffer(double *buf, int nbuf, int nbuf_local, MPI_Isend(&buf[0],nbuf_local,MPI_DOUBLE,0,0,world,&irequest2); MPI_Wait(&irequest2,MPI_STATUS_IGNORE); } - if (me == 0) fputs("# \n",fp); - + if (fp) { + fputs("# \n",fp); + fflush(fp); + } } /* ---------------------------------------------------------------------- */ @@ -333,6 +339,18 @@ void FixReaxFFBonds::allocate() /* ---------------------------------------------------------------------- */ +int FixReaxFFBonds::modify_param(int narg, char **arg) +{ + if (strcmp(arg[0], "pad") == 0) { + if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify pad", error); + padflag = utils::inumeric(FLERR, arg[1], false, lmp); + return 2; + } + return 0; +} + +/* ---------------------------------------------------------------------- */ + double FixReaxFFBonds::memory_usage() { double bytes; diff --git a/src/REAXFF/fix_reaxff_bonds.h b/src/REAXFF/fix_reaxff_bonds.h index 91ce2531bf..5a00a49a60 100644 --- a/src/REAXFF/fix_reaxff_bonds.h +++ b/src/REAXFF/fix_reaxff_bonds.h @@ -1,4 +1,3 @@ -// clang-format off /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -35,11 +34,12 @@ class FixReaxFFBonds : public Fix { void end_of_step() override; protected: - int me, nprocs, nmax, ntypes, maxsize, compressed; + int nmax, compressed, multifile, padflag; int *numneigh; tagint **neighid; double **abo; FILE *fp; + std::string filename; bool first_flag; void allocate(); @@ -49,6 +49,7 @@ class FixReaxFFBonds : public Fix { void PassBuffer(double *, int &); void RecvBuffer(double *, int, int, int, int); int nint(const double &); + int modify_param(int, char **) override; double memory_usage() override; struct _reax_list *lists; From f0b3b20653f619a55bf0e7683574d340c5e1c696 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Mar 2025 23:09:39 -0400 Subject: [PATCH 17/29] add a write permission check before opening a pipe for compressed writes --- src/platform.cpp | 27 +++++++++++++++++++++++++++ src/platform.h | 7 +++++++ 2 files changed, 34 insertions(+) diff --git a/src/platform.cpp b/src/platform.cpp index 71b2035c81..8e6b6c72e6 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -1053,6 +1053,32 @@ bool platform::file_is_readable(const std::string &path) } return false; } + +/* ---------------------------------------------------------------------- + try to open file for writing to prove if it can be written to +------------------------------------------------------------------------- */ + +bool platform::file_is_writable(const std::string &path) +{ + // if the file exists, try to append and don't delete + + if (file_is_readable(path)) { + FILE *fp = fopen(path.c_str(), "a"); + if (fp) { + fclose(fp); + return true; + } + } else { + FILE *fp = fopen(path.c_str(), "w"); + if (fp) { + fclose(fp); + unlink(path); + return true; + } + } + return false; +} + /* ---------------------------------------------------------------------- determine available disk space, if supported. Return -1 if not. ------------------------------------------------------------------------- */ @@ -1123,6 +1149,7 @@ FILE *platform::compressed_write(const std::string &file) #if defined(LAMMPS_GZIP) const auto &compress = find_compress_type(file); if (compress.style == ::compress_info::NONE) return nullptr; + if (!file_is_writable(file)) return nullptr; if (find_exe_path(compress.command).size()) // put quotes around file name so that they may contain blanks diff --git a/src/platform.h b/src/platform.h index 6cb2380b50..e693e328de 100644 --- a/src/platform.h +++ b/src/platform.h @@ -377,6 +377,13 @@ namespace platform { bool file_is_readable(const std::string &path); + /*! Check if file can be opened for writing + * + * \param path file path + * \return true if file can be opened for writing */ + + bool file_is_writable(const std::string &path); + /*! Return free disk space in bytes of file system pointed to by path * * Returns -1.0 if the path is invalid or free space reporting not supported. From 8eceb2b944174ddbe14c8f52d5ae3414503f01e0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 12:52:48 -0400 Subject: [PATCH 18/29] small updates and clarifications --- doc/src/Intro_overview.rst | 14 ++++++++--- doc/src/Manual_version.rst | 51 ++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/doc/src/Intro_overview.rst b/doc/src/Intro_overview.rst index 57fa7fbfb6..0f777a9adc 100644 --- a/doc/src/Intro_overview.rst +++ b/doc/src/Intro_overview.rst @@ -20,13 +20,21 @@ acceleration. .. _lws: https://www.lammps.org .. _omp: https://www.openmp.org -LAMMPS is written in C++ and requires a compiler that is at least -compatible with the C++-11 standard. Earlier versions were written in -F77, F90, and C++-98. See the `History page +LAMMPS is written in C++ and currently requires a compiler that is at +least compatible with the C++-11 standard. Earlier versions were +written in F77, F90, and C++-98. See the `History page `_ of the website for details. All versions can be downloaded as source code from the `LAMMPS website `_. +Through a :ref:`C language API ` LAMMPS functionality can +be accessed and managed from other programming languages rather than +running the LAMMPS executable. Ready to use modules for :ref:`Python +` and :ref:`Fortran ` exist, and +an example :ref:`SWIG interface file ` as well as example C files +for dynamically loading LAMMPS as a shared library into other +executables are provided. + LAMMPS is designed to be easy to modify or extend with new capabilities, such as new force fields, atom types, boundary conditions, or diagnostics. See the :doc:`Modify` section of for more details. diff --git a/doc/src/Manual_version.rst b/doc/src/Manual_version.rst index 1bfaffaf6d..0c757fc0ea 100644 --- a/doc/src/Manual_version.rst +++ b/doc/src/Manual_version.rst @@ -2,9 +2,15 @@ What does a LAMMPS version mean ------------------------------- The LAMMPS "version" is the date when it was released, such as 1 May -2014. LAMMPS is updated continuously, and we aim to keep it working -correctly and reliably at all times. Also, several variants of static -code analysis are run regularly to maintain or improve the overall code +2014. LAMMPS is updated continuously, and with the help of extensive +automated testing (mostly applied *before* changes are included) we aim +to keep it working correctly and reliably at all times, but there also +are regular *feature releases* with new and expanded functionality, and +there are designated *stable releases* that receive updates with bug +fixes back-ported from the development branch. + +In addition to automated testing, several variants of static code +analysis are run regularly to maintain or improve the overall code quality, consistency, and compliance with programming standards, best practices and style conventions. You can follow its development in a public `git repository on GitHub `_. @@ -19,17 +25,18 @@ Identifying the Version The version date is printed to the screen and log file every time you run LAMMPS. There also is an indication, if a LAMMPS binary was -compiled from version with modifications **after** a release. -It is also visible in the file src/version.h and in the LAMMPS directory -name created when you unpack a downloaded tarball. And it is on the -first page of the :doc:`manual `. +compiled from version with modifications **after** a release, either +from the development version or the maintenance version of the last +stable release. It is also visible in the file src/version.h and in the +LAMMPS directory name created when you unpack a downloaded tarball. And +it is on the first page of the :doc:`manual `. * If you browse the HTML pages of the online version of the LAMMPS manual, they will by default describe the most current feature release version of LAMMPS. In the navigation bar on the bottom left, there is the option to view instead the documentation for the most recent *stable* version or the documentation corresponding to the state of - the development branch. + the development branch *develop*. * If you browse the HTML pages included in your downloaded tarball, they describe the version you have, which may be older than the online version. @@ -48,8 +55,9 @@ Development Modifications of the LAMMPS source code (like bug fixes, code refactoring, updates to existing features, or addition of new features) are organized into pull requests. Pull requests will be merged into the -*develop* branch of the git repository after they pass automated testing -and code review by the LAMMPS developers. +*develop* branch of the LAMMPS git repository on GitHub after they pass +automated testing and code review by :doc:`core LAMMPS developers +`. Feature Releases """""""""""""""" @@ -62,8 +70,7 @@ repository is updated with every such *feature release* and a tag in the format ``patch_1May2014`` is added. A summary of the most important changes of these releases for the current year are posted on `this website page `_. More detailed release -notes are `available on GitHub -`_. +notes are `available on GitHub `_. Stable Releases """"""""""""""" @@ -71,18 +78,18 @@ Stable Releases About once a year, we release a *stable release* version of LAMMPS. This is done after a "stabilization period" where we apply only bug fixes and small, non-intrusive changes to the *develop* branch but no -new features. At the same time, the code is subjected to more detailed -and thorough manual testing than the default automated testing. -After such a *stable release*, both the *release* and the *stable* -branches are updated and two tags are applied, a ``patch_1May2014`` format -and a ``stable_1May2014`` format tag. +new features to the core code. At the same time, the code is subjected +to more detailed and thorough manual testing than the default automated +testing. After such a *stable release*, both the *release* and the +*stable* branches are updated and two tags are applied, a +``patch_1May2014`` format and a ``stable_1May2014`` format tag. Stable Release Updates """""""""""""""""""""" -Between *stable releases*, we collect bug fixes and updates back-ported -from the *develop* branch in a branch called *maintenance*. From the -*maintenance* branch we make occasional *stable update releases* and -update the *stable* branch accordingly. The first update to the -``stable_1May2014`` release would be tagged as +Between *stable releases*, we collect bug fixes and updates that are +back-ported from the *develop* branch in a branch called *maintenance*. +From the *maintenance* branch we make occasional *stable update +releases* and update the *stable* branch accordingly. The first update +to the ``stable_1May2014`` release would be tagged as ``stable_1May2014_update1``. These updates contain no new features. From c9d557a9f2bfceccc507469473e5c0430fab2f02 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 13:20:08 -0400 Subject: [PATCH 19/29] add test for version related tags missing a colon --- tools/coding_standard/versiontags.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/coding_standard/versiontags.py b/tools/coding_standard/versiontags.py index ec512a3fad..3f71ba905e 100644 --- a/tools/coding_standard/versiontags.py +++ b/tools/coding_standard/versiontags.py @@ -49,22 +49,42 @@ def check_pending_tag(f): return errors, last_line +def check_bad_tag(f): + pattern = re.compile(r'^ *\.\. +(version(changed|added)|deprecated):\s+\w*') + last_line = "\n" + lineno = 1 + errors = set() + + for line in f: + if pattern.match(line): + errors.add(lineno) + last_line = line + lineno += 1 + + return errors, last_line + def check_file(path): encoding = 'UTF-8' pending_tags = set() + bad_tags = set() try: with open(path, 'r') as f: pending_tags, last_line = check_pending_tag(f) + f.seek(0) + bad_tags, last_line = check_bad_tag(f) except UnicodeDecodeError: encoding = 'ISO-8859-1' try: with open(path, 'r', encoding=encoding) as f: pending_tags, last_line = check_pending_tag(f) + f.seek(0) + bad_tags, last_line = check_bad_tag(f) except Exception: encoding = 'unknown' return { 'pending_tags': pending_tags, + 'bad_tags': bad_tags, 'encoding': encoding } @@ -90,6 +110,9 @@ def check_folder(directory, config, verbose=False): for lineno in result['pending_tags']: print("[Error] Pending version tag @ {}:{}".format(path, lineno)) success = False + for lineno in result['bad_tags']: + print("[Error] Bad version tag @ {}:{}".format(path, lineno)) + success = False if result['encoding'] == 'unknown': print("[Error] Unknown text encoding @ {}".format(path)) From fce3246439912af11a4b7d2aadb9d9c4f599798f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 13:37:13 -0400 Subject: [PATCH 20/29] detect misformatted Sphinx directives --- doc/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/Makefile b/doc/Makefile index 703a55cc3d..92132e7d8c 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -112,6 +112,8 @@ html: xmlgen globbed-tocs $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) $(MATHJ env LC_ALL=C grep -n ':\(ref\|doc\):[^`]' $(RSTDIR)/*.rst ;\ env LC_ALL=C grep -n '\(ref\|doc\)`[^`]' $(RSTDIR)/*.rst ;\ $(PYTHON) $(BUILDDIR)/utils/check-styles.py -s ../src -d src ;\ + env LC_ALL=C grep -n -E '^ *\.\. [a-z0-9]+:(\s+.*|)$$' \ + $(RSTDIR)/*.rst ../src/*.{cpp,h} ../src/*/*.{cpp,h} ;\ echo "############################################" ;\ deactivate ;\ ) @@ -193,6 +195,8 @@ pdf: xmlgen globbed-tocs $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) env LC_ALL=C grep -n ':\(ref\|doc\):[^`]' $(RSTDIR)/*.rst ;\ env LC_ALL=C grep -n '\(ref\|doc\)`[^`]' $(RSTDIR)/*.rst ;\ $(PYTHON) utils/check-styles.py -s ../src -d src ;\ + env LC_ALL=C grep -n -E '^ *\.\. [a-z0-9]+:(\s+.*|)$$' \ + $(RSTDIR)/*.rst ../src/*.{cpp,h} ../src/*/*.{cpp,h} ;\ echo "############################################" ;\ deactivate ;\ ) @@ -242,6 +246,8 @@ role_check : @( env LC_ALL=C grep -n ' `[^`]\+<[a-z][^`]\+`[^_]' $(RSTDIR)/*.rst && exit 1 || : ) @( env LC_ALL=C grep -n ':\(ref\|doc\):[^`]' $(RSTDIR)/*.rst && exit 1 || : ) @( env LC_ALL=C grep -n '\(ref\|doc\)`[^`]' $(RSTDIR)/*.rst && exit 1 || : ) + @( env LC_ALL=C grep -n -E '^ *\.\. [a-z0-9]+:(\s+.*|)$$' \ + $(RSTDIR)/*.rst ../src/*.{cpp,h} ../src/*/*.{cpp,h} && exit 1 || : ) link_check : $(VENV) html @(\ From c3309bc0b30231549f77ee0bbdd68dba0b03500e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 18:35:40 -0400 Subject: [PATCH 21/29] error message and programming style updates --- src/compute.cpp | 18 +++++++++++------- src/modify.cpp | 21 +++++++++++++-------- src/output.cpp | 18 +++++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/compute.cpp b/src/compute.cpp index 4832a26e25..92e633e9a9 100644 --- a/src/compute.cpp +++ b/src/compute.cpp @@ -48,11 +48,12 @@ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : id = utils::strdup(arg[0]); if (!utils::is_id(id)) - error->all(FLERR,"Compute ID {} must only have alphanumeric or underscore characters", id); + error->all(FLERR, Error::ARGZERO, + "Compute ID {} must only have alphanumeric or underscore characters", id); groupbit = group->get_bitmask_by_id(FLERR, arg[1], fmt::format("compute {}", arg[2])); igroup = group->find(arg[1]); - if (igroup == -1) error->all(FLERR,"Could not find compute group ID {}", arg[1]); + if (igroup == -1) error->all(FLERR, 1, "Could not find compute group ID {}", arg[1]); style = utils::strdup(arg[2]); @@ -119,13 +120,16 @@ void Compute::init_flags() invoked_peratom = invoked_local = -1; if (scalar_flag && (extscalar < 0)) - error->all(FLERR, "Must set 'extscalar' when setting 'scalar_flag' for compute {}. " + error->all(FLERR, Error::NOLASTLINE, + "Must set 'extscalar' when setting 'scalar_flag' for compute {}. " "Contact the developer.", style); if (vector_flag && (extvector < 0) && !extlist) - error->all(FLERR, "Must set 'extvector' or 'extlist' when setting 'vector_flag' for compute {}. " + error->all(FLERR, Error::NOLASTLINE, + "Must set 'extvector' or 'extlist' when setting 'vector_flag' for compute {}. " "Contact the developer.", style); if (array_flag && (extarray < 0)) - error->all(FLERR, "Must set 'extarray' when setting 'array_flag' for compute {}. " + error->all(FLERR, Error::NOLASTLINE, + "Must set 'extarray' when setting 'array_flag' for compute {}. " "Contact the developer.", style); } @@ -133,7 +137,7 @@ void Compute::init_flags() void Compute::modify_params(int narg, char **arg) { - if (narg == 0) error->all(FLERR,"Illegal compute_modify command"); + if (narg == 0) error->all(FLERR, Error::NOLASTLINE, "Illegal compute_modify command"); int iarg = 0; while (iarg < narg) { @@ -179,7 +183,7 @@ void Compute::reset_extra_dof() void Compute::reset_extra_compute_fix(const char *) { - error->all(FLERR, + error->all(FLERR, Error::NOLASTLINE, "Compute does not allow an extra compute or fix to be reset"); } diff --git a/src/modify.cpp b/src/modify.cpp index 1d27573db0..4fd20bc74b 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -1006,19 +1006,22 @@ Fix *Modify::add_fix(const std::string &fixcmd, int trysuffix) Fix *Modify::replace_fix(const char *replaceID, int narg, char **arg, int trysuffix) { auto oldfix = get_fix_by_id(replaceID); - if (!oldfix) error->all(FLERR, "Modify replace_fix ID {} could not be found", replaceID); + if (!oldfix) error->all(FLERR, Error::NOLASTLINE, + "Modify replace_fix ID {} could not be found", replaceID); // change ID, igroup, style of fix being replaced to match new fix // requires some error checking on arguments for new fix - if (narg < 3) error->all(FLERR, "Not enough arguments for replace_fix invocation"); + if (narg < 3) + error->all(FLERR, Error::NOLASTLINE, "Not enough arguments for replace_fix invocation"); if (get_fix_by_id(arg[0])) error->all(FLERR, "Replace_fix ID {} is already in use", arg[0]); delete[] oldfix->id; oldfix->id = utils::strdup(arg[0]); int jgroup = group->find(arg[1]); - if (jgroup == -1) error->all(FLERR, "Could not find replace_fix group ID {}", arg[1]); + if (jgroup == -1) error->all(FLERR, Error::NOLASTLINE, + "Could not find replace_fix group ID {}", arg[1]); oldfix->igroup = jgroup; delete[] oldfix->style; @@ -1052,7 +1055,7 @@ void Modify::modify_fix(int narg, char **arg) if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify", error); auto ifix = get_fix_by_id(arg[0]); - if (!ifix) error->all(FLERR, "Could not find fix_modify ID {}", arg[0]); + if (!ifix) error->all(FLERR, Error::NOLASTLINE, "Could not find fix_modify ID {}", arg[0]); ifix->modify_params(narg - 1, &arg[1]); } @@ -1064,7 +1067,7 @@ void Modify::modify_fix(int narg, char **arg) void Modify::delete_fix(const std::string &id) { int ifix = find_fix(id); - if (ifix < 0) error->all(FLERR, "Could not find fix ID {} to delete", id); + if (ifix < 0) error->all(FLERR, Error::NOLASTLINE, "Could not find fix ID {} to delete", id); delete_fix(ifix); } @@ -1291,7 +1294,7 @@ Compute *Modify::add_compute(int narg, char **arg, int trysuffix) } if (compute[ncompute] == nullptr) - error->all(FLERR, utils::check_packages_for_style("compute", arg[2], lmp)); + error->all(FLERR, Error::NOLASTLINE, utils::check_packages_for_style("compute", arg[2], lmp)); compute_list = std::vector(compute, compute + ncompute + 1); @@ -1332,7 +1335,8 @@ void Modify::modify_compute(int narg, char **arg) // lookup Compute ID auto icompute = get_compute_by_id(arg[0]); - if (!icompute) error->all(FLERR, "Could not find compute_modify ID {}", arg[0]); + if (!icompute) + error->all(FLERR, Error::NOLASTLINE, "Could not find compute_modify ID {}", arg[0]); icompute->modify_params(narg - 1, &arg[1]); } @@ -1343,7 +1347,8 @@ void Modify::modify_compute(int narg, char **arg) void Modify::delete_compute(const std::string &id) { int icompute = find_compute(id); - if (icompute < 0) error->all(FLERR, "Could not find compute ID {} to delete", id); + if (icompute < 0) + error->all(FLERR, Error::NOLASTLINE, "Could not find compute ID {} to delete", id); delete_compute(icompute); } diff --git a/src/output.cpp b/src/output.cpp index 0602c4f52d..2e92ccb4cb 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -154,8 +154,8 @@ void Output::init() any_time_dumps = 0; for (int i = 0; i < ndump; i++) { if (mode_dump[i]) any_time_dumps = 1; - if ((mode_dump[i] == 0 && every_dump[i] == 0) || - (mode_dump[i] == 1 && every_time_dump[i] == 0.0)) { + if (((mode_dump[i] == 0) && (every_dump[i] == 0)) || + ((mode_dump[i] == 1) && (every_time_dump[i] == 0.0))) { ivar_dump[i] = input->variable->find(var_dump[i]); if (ivar_dump[i] < 0) error->all(FLERR,"Variable name for dump every or delta does not exist"); @@ -228,7 +228,7 @@ void Output::setup(int memflag) // wrap step dumps that invoke computes or do variable eval with clear/add // see NOTE in write() about also wrapping time dumps - if (mode_dump[idump] == 0 && (dump[idump]->clearstep || var_dump[idump])) + if ((mode_dump[idump] == 0) && (dump[idump]->clearstep || var_dump[idump])) modify->clearstep_compute(); // write a snapshot at setup only if any of these 3 conditions hold @@ -274,7 +274,7 @@ void Output::setup(int memflag) // if dump not written now, use addstep_compute_all() // since don't know what computes the dump will invoke - if (mode_dump[idump] == 0 && (dump[idump]->clearstep || var_dump[idump])) { + if ((mode_dump[idump] == 0) && (dump[idump]->clearstep || var_dump[idump])) { if (writeflag) modify->addstep_compute(next_dump[idump]); else modify->addstep_compute_all(next_dump[idump]); } @@ -350,7 +350,8 @@ void Output::write(bigint ntimestep) next_thermo = static_cast (input->variable->compute_equal(ivar_thermo)); if (next_thermo <= ntimestep) - error->all(FLERR,"Thermo every variable returned a bad timestep"); + error->all(FLERR, Error::NOLASTLINE, "Thermo every variable returned a bad timestep: {} " + "vs {}", next_thermo, ntimestep); } else if (thermo_every) next_thermo += thermo_every; else next_thermo = update->laststep; next_thermo = MIN(next_thermo,update->laststep); @@ -381,8 +382,7 @@ void Output::write(bigint ntimestep) if (next_dump[idump] == ntimestep) { if (last_dump[idump] == ntimestep) continue; - if (mode_dump[idump] == 0 && - (dump[idump]->clearstep || var_dump[idump])) + if ((mode_dump[idump] == 0) && (dump[idump]->clearstep || var_dump[idump])) modify->clearstep_compute(); // perform dump @@ -392,8 +392,8 @@ void Output::write(bigint ntimestep) last_dump[idump] = ntimestep; calculate_next_dump(WRITE,idump,ntimestep); - if (mode_dump[idump] == 0 && - (dump[idump]->clearstep || var_dump[idump])) + + if ((mode_dump[idump] == 0) && (dump[idump]->clearstep || var_dump[idump])) modify->addstep_compute(next_dump[idump]); } From 8949a6262da928b6216dc7fe968bd85ef6fda098 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 19:04:32 -0400 Subject: [PATCH 22/29] Use "Contact the LAMMPS developers" consistently and add an errorurl() to such errors --- doc/src/Errors_details.rst | 29 +++++++++++++++++++++++++++++ src/comm.cpp | 6 ++++-- src/compute.cpp | 6 +++--- src/fix.cpp | 6 +++--- src/neighbor.cpp | 5 +++-- src/variable.cpp | 2 +- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/doc/src/Errors_details.rst b/doc/src/Errors_details.rst index 71e7ff08e3..f2728321e6 100644 --- a/doc/src/Errors_details.rst +++ b/doc/src/Errors_details.rst @@ -953,3 +953,32 @@ created (for instance defining the :doc:`atom style `, simulation box has been created. See the paragraph on :ref:`errors before or after the simulation box is created ` for additional information. + +.. _err0035: + +Error messages ending in 'Please contact the LAMMPS developers' +--------------------------------------------------------------- + +Such error messages indicate that something unexpected has happened and +that it will require a good understanding of the details of the design +of LAMMPS to resolve this. This can be due to some bug in contributed +code, and oversight when updating functionality, a feature that is +scheduled to be removed or reaching a combination of flags and settings +that should not be possible or similar. + +Even if you find a way to work around this error or warning, you should +contact the LAMMPS developers and prepare a minimal set of inputs that +can be used to reproduce this error or warning. By providing the input, +the LAMMPS developers can then assess whether additional action is +needed and who else to contact about this, if needed. + +There are multiple ways to get into contact and report your issue. In +order of preference there are: + +- Submit a bug report `issue in the LAMMPS GitHub + ` repository +- Post a message in the "LAMMPS Development" forum in the + `MatSci Community Discourse `_ +- Send an email to ``developers@lammps.org`` +- Send an email to an :doc:`individual LAMMPS developer ` + that you know and trust diff --git a/src/comm.cpp b/src/comm.cpp index 9b40d71021..8f59ed628a 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -308,7 +308,8 @@ void Comm::modify_params(int narg, char **arg) } else if (strcmp(arg[iarg+1],"multi/old") == 0) { if (me == 0) error->warning(FLERR, "Comm mode 'multi/old' is deprecated and will be removed soon.\n" - "Contact the LAMMPS developers if that creates problems for you."); + "Please contact the LAMMPS developers if you cannot use mode 'multi'." + + utils::errorurl(35)); if (neighbor->style == Neighbor::MULTI) error->all(FLERR, iarg+1, "Cannot use comm mode 'multi/old' with 'multi' style neighbor lists"); @@ -372,7 +373,8 @@ void Comm::modify_params(int narg, char **arg) double cut; if (me == 0) error->warning(FLERR, "Comm mode 'multi/old' is deprecated and will be removed soon.\n" - "Contact the LAMMPS developers if that creates problems for you."); + "Please contact the LAMMPS developers if you cannot use mode 'multi'." + + utils::errorurl(35)); if (mode == Comm::SINGLE) error->all(FLERR, iarg, "Use cutoff keyword to set cutoff in single mode"); if (mode == Comm::MULTI) diff --git a/src/compute.cpp b/src/compute.cpp index 92e633e9a9..e57ae8336a 100644 --- a/src/compute.cpp +++ b/src/compute.cpp @@ -122,15 +122,15 @@ void Compute::init_flags() if (scalar_flag && (extscalar < 0)) error->all(FLERR, Error::NOLASTLINE, "Must set 'extscalar' when setting 'scalar_flag' for compute {}. " - "Contact the developer.", style); + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); if (vector_flag && (extvector < 0) && !extlist) error->all(FLERR, Error::NOLASTLINE, "Must set 'extvector' or 'extlist' when setting 'vector_flag' for compute {}. " - "Contact the developer.", style); + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); if (array_flag && (extarray < 0)) error->all(FLERR, Error::NOLASTLINE, "Must set 'extarray' when setting 'array_flag' for compute {}. " - "Contact the developer.", style); + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix.cpp b/src/fix.cpp index 3f3b585e0a..25e0617332 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -133,13 +133,13 @@ void Fix::init_flags() { if (scalar_flag && (extscalar < 0)) error->all(FLERR, "Must set 'extscalar' when setting 'scalar_flag' for fix {}. " - "Contact the developer.", style); + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); if (vector_flag && (extvector < 0) && !extlist) error->all(FLERR, "Must set 'extvector' or 'extlist' when setting 'vector_flag' for fix {}. " - "Contact the developer.", style); + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); if (array_flag && (extarray < 0)) error->all(FLERR, "Must set 'extarray' when setting 'array_flag' for fix {}. " - "Contact the developer.", style); + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); } /* ---------------------------------------------------------------------- diff --git a/src/neighbor.cpp b/src/neighbor.cpp index c90eaa752c..a2aa3f411b 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1144,7 +1144,7 @@ int Neighbor::init_pair() } if (count == 100) error->all(FLERR, Error::NOLASTLINE, "Failed to reorder neighbor lists to satisfy " - "constraints - Contact the LAMMPS developers for assistance"); + "constraints - Please contact the LAMMPS developers." + utils::errorurl(35)); // debug output @@ -2646,7 +2646,8 @@ void Neighbor::set(int narg, char **arg) style = Neighbor::MULTI_OLD; if (me == 0) error->warning(FLERR, "Neighbor list style 'multi/old' is deprecated and will be removed " - "soon.\nContact the LAMMPS developers if that creates problems for you."); + "soon.\nPlease contact the LAMMPS developers if you cannot use style 'multi'." + + utils::errorurl(35)); } else error->all(FLERR, 1, "Unknown neighbor {} argument: {}", arg[0], arg[1]); if (style == Neighbor::MULTI_OLD && lmp->citeme) lmp->citeme->add(cite_neigh_multi_old); diff --git a/src/variable.cpp b/src/variable.cpp index 226e886a91..ee2114998c 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -855,7 +855,7 @@ int Variable::next(int narg, char **arg) if (nextindex < 0) error->one(FLERR,"Unexpected error while incrementing uloop style variable. " - "Please contact the LAMMPS developers."); + "Please contact the LAMMPS developers." + utils::errorurl(35)); fp = fopen("tmp.lammps.variable.lock","w"); fprintf(fp,"%d\n",nextindex+1); From 02637745955f3b5f8c1df98b804f424c7ef820e8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 23:50:37 -0400 Subject: [PATCH 23/29] must use addstep_compute() on next time based or variable step dump output --- src/output.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/output.cpp b/src/output.cpp index 2e92ccb4cb..cc83bcab4f 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -374,6 +374,7 @@ void Output::write(bigint ntimestep) // can't remove an uneeded addstep from a compute, b/c don't know // what other command may have added it + int mode_dump_any = 0; // any variable time or clearstep dump if (next_dump_any == ntimestep) { next_dump_any = next_time_dump_any = MAXBIGINT; @@ -397,11 +398,15 @@ void Output::write(bigint ntimestep) modify->addstep_compute(next_dump[idump]); } - if (mode_dump[idump] && (dump[idump]->clearstep || var_dump[idump])) + if (mode_dump[idump] && (dump[idump]->clearstep || var_dump[idump])) { + mode_dump_any = 1; next_time_dump_any = MIN(next_time_dump_any,next_dump[idump]); + } next_dump_any = MIN(next_dump_any,next_dump[idump]); } } + // trigger computes for any time based or variable step dumps + if (mode_dump_any) modify->addstep_compute(next_time_dump_any); // next_restart does not force output on last step of run // for toggle = 0, replace "*" with current timestep in restart filename From a17ec2a8d37d9ca62f90b49093fe10c7ba57076f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 27 Mar 2025 18:28:06 -0400 Subject: [PATCH 24/29] fix bug with addstep_compute skipping on first step --- src/modify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modify.cpp b/src/modify.cpp index 4fd20bc74b..aa2b0cccc6 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -1447,7 +1447,7 @@ void Modify::addstep_compute(bigint newstep) } for (int icompute = 0; icompute < n_timeflag; icompute++) - if (compute[list_timeflag[icompute]]->invoked_flag) + if (compute[list_timeflag[icompute]]->invoked_flag >=0) compute[list_timeflag[icompute]]->addstep(newstep); } From 9a5585675892fb8ce69ddeb7a1acdb072444c3aa Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 28 Mar 2025 00:31:01 -0400 Subject: [PATCH 25/29] forgot handling addstep_compute in setup() --- src/output.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/output.cpp b/src/output.cpp index cc83bcab4f..8bac766213 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -222,7 +222,7 @@ void Output::setup(int memflag) if (ndump && update->restrict_output == 0) { next_dump_any = next_time_dump_any = MAXBIGINT; - + int mode_dump_any = 0; for (int idump = 0; idump < ndump; idump++) { // wrap step dumps that invoke computes or do variable eval with clear/add @@ -279,10 +279,13 @@ void Output::setup(int memflag) else modify->addstep_compute_all(next_dump[idump]); } - if (mode_dump[idump] && (dump[idump]->clearstep || var_dump[idump])) + if (mode_dump[idump] && (dump[idump]->clearstep || var_dump[idump])) { next_time_dump_any = MIN(next_time_dump_any,next_dump[idump]); + mode_dump_any = 1; + } next_dump_any = MIN(next_dump_any,next_dump[idump]); } + if (mode_dump_any) modify->addstep_compute(next_time_dump_any); // if no dumps, set next_dump_any to last+1 so will not influence next @@ -379,7 +382,6 @@ void Output::write(bigint ntimestep) next_dump_any = next_time_dump_any = MAXBIGINT; for (int idump = 0; idump < ndump; idump++) { - if (next_dump[idump] == ntimestep) { if (last_dump[idump] == ntimestep) continue; From aeed7a425f7e75481fe656ee8acb2061f783ac31 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 28 Mar 2025 18:25:42 -0400 Subject: [PATCH 26/29] we only need to worry about Python3 now --- src/Makefile | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Makefile b/src/Makefile index f4eafbf299..866c778aeb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,13 +1,7 @@ # LAMMPS multiple-machine -*- Makefile -*- SHELL = /bin/bash -PYTHON = python -PYTHON_VERSION=$(word 2,$(shell $(PYTHON) -V 2>&1 | tr '.' ' ')) -ifeq ($(PYTHON_VERSION),2) -PYTHON_CHECK=@echo LAMMPS requires Python 3. Try: 'make PYTHON=python3 ...' ; exit 1 -else -PYTHON_CHECK=@echo -endif +PYTHON = $(word 3,$(shell type python3)) DYN_LIB = -ldl #.IGNORE: @@ -282,7 +276,6 @@ LIBDIR = $(@:lib-%=%) # List of all targets help: - $(PYTHON_CHECK) @echo 'make clean-all delete all object files' @echo 'make clean-machine delete object files for one machine' @echo 'make mpi-stubs build dummy MPI library in STUBS' @@ -384,7 +377,6 @@ gitversion: # shared = shared compile in Obj_shared_machine .DEFAULT: - $(PYTHON_CHECK) @if [ $@ = "serial" ]; \ then cd STUBS; $(MAKE); cd ..; fi @test -f MAKE/Makefile.$@ -o -f MAKE/OPTIONS/Makefile.$@ -o \ @@ -472,7 +464,6 @@ mpi-stubs: sinclude ../lib/python/Makefile.lammps install-python: - $(PYTHON_CHECK) @rm -rf ../python/build @$(PYTHON) ../python/install.py -p ../python/lammps -l ../src/liblammps.so -w $(PWD) -v $(PWD)/version.h @@ -491,51 +482,39 @@ tar: check: check-whitespace check-permissions check-homepage check-errordocs check-fmtlib check-docs check-version check-whitespace: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/whitespace.py .. fix-whitespace: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/whitespace.py .. -f check-permissions: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/permissions.py .. fix-permissions: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/permissions.py .. -f check-homepage: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/homepage.py .. fix-homepage: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/homepage.py .. -f check-errordocs: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/errordocs.py .. fix-errordocs: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/errordocs.py .. -f check-fmtlib: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/fmtlib.py .. fix-fmtlib: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/fmtlib.py .. -f check-docs: - $(PYTHON_CHECK) $(MAKE) $(MFLAGS) -C ../doc anchor_check style_check package_check role_check check-version: - $(PYTHON_CHECK) $(PYTHON) ../tools/coding_standard/versiontags.py .. || echo format-src: From e577528099ac1c2445a9431a2be5ac0414a489f9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 31 Mar 2025 23:24:21 -0400 Subject: [PATCH 27/29] switch CWD to home if default is "/" or contains "AppData" --- tools/lammps-gui/lammpsgui.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 602ae58900..79a7d0b908 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -83,8 +83,11 @@ LammpsGui::LammpsGui(QWidget *parent, const QString &filename) : capturer = new StdCapture; current_file.clear(); current_dir = QDir(".").absolutePath(); - // use $HOME if we get dropped to "/" like on macOS - if (current_dir == "/") current_dir = QDir::homePath(); + // use $HOME if we get dropped to "/" like on macOS or the installation folder like on Windows + if ((current_dir == "/") || (current_dir.path().contains("AppData"))) + current_dir = QDir::homePath(); + QDir::setCurrent(current_dir); + inspectList.clear(); setAutoFillBackground(true); From 6964156b6fe54f8f8b29fcfa93827dc7c5c56de8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 1 Apr 2025 00:00:22 -0400 Subject: [PATCH 28/29] fix syntax error --- tools/lammps-gui/lammpsgui.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 79a7d0b908..003345de57 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -84,8 +84,7 @@ LammpsGui::LammpsGui(QWidget *parent, const QString &filename) : current_file.clear(); current_dir = QDir(".").absolutePath(); // use $HOME if we get dropped to "/" like on macOS or the installation folder like on Windows - if ((current_dir == "/") || (current_dir.path().contains("AppData"))) - current_dir = QDir::homePath(); + if ((current_dir == "/") || (current_dir.contains("AppData"))) current_dir = QDir::homePath(); QDir::setCurrent(current_dir); inspectList.clear(); From 618c92aeee3f7eac372684d450eb5375b29b03ef Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 1 Apr 2025 19:25:48 -0400 Subject: [PATCH 29/29] fix typos --- src/fix_spring.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fix_spring.cpp b/src/fix_spring.cpp index dd010654f6..e35c2610e4 100644 --- a/src/fix_spring.cpp +++ b/src/fix_spring.cpp @@ -55,7 +55,7 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[3], "tether") == 0) { if (narg != 9) - error->all(FLERR, Error::NOPOINTER, "Icorrect number of arguments for tether mode"); + error->all(FLERR, Error::NOPOINTER, "Incorrect number of arguments for tether mode"); styleflag = TETHER; k_spring = utils::numeric(FLERR,arg[4],false,lmp); xflag = yflag = zflag = 1; @@ -70,7 +70,7 @@ FixSpring::FixSpring(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[3],"couple") == 0) { if (narg != 10) - error->all(FLERR, Error::NOPOINTER, "Icorrect number of arguments for couple mode"); + error->all(FLERR, Error::NOPOINTER, "Incorrect number of arguments for couple mode"); styleflag = COUPLE; group2 = utils::strdup(arg[4]);