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 @(\ 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_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 """""""""""""" 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..f2728321e6 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 ------ @@ -951,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/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.) 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. 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/doc/src/fix_adapt.rst b/doc/src/fix_adapt.rst index cd3953b758..2b39917d86 100644 --- a/doc/src/fix_adapt.rst +++ b/doc/src/fix_adapt.rst @@ -222,6 +222,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 | 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/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 #}
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) 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/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 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: 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; 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 4832a26e25..e57ae8336a 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,21 +120,24 @@ 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 {}. " - "Contact the developer.", style); + error->all(FLERR, Error::NOLASTLINE, + "Must set 'extscalar' when setting 'scalar_flag' for compute {}. " + "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 compute {}. " - "Contact the developer.", style); + error->all(FLERR, Error::NOLASTLINE, + "Must set 'extvector' or 'extlist' when setting 'vector_flag' for compute {}. " + "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 compute {}. " - "Contact the developer.", style); + error->all(FLERR, Error::NOLASTLINE, + "Must set 'extarray' when setting 'array_flag' for compute {}. " + "Please contact the LAMMPS developers.{}", style, utils::errorurl(35)); } /* ---------------------------------------------------------------------- */ 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/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/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/displace_atoms.cpp b/src/displace_atoms.cpp index 88b888200c..b9eb121b3d 100644 --- a/src/displace_atoms.cpp +++ b/src/displace_atoms.cpp @@ -66,25 +66,27 @@ 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)) - 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; - else error->all(FLERR,"Illegal displace_atoms command"); + 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 @@ -92,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 @@ -104,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 @@ -123,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,"Illegal displace_atoms ramp command"); + 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) { @@ -141,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,"Illegal displace_atoms ramp command"); + else error->all(FLERR, 5, "Unknown displace_atoms ramp dimension {}", arg[5]); double coord_lo,coord_hi; if (coord_dim == 0) { @@ -182,18 +185,21 @@ 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]); + 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); } } @@ -226,11 +232,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 system"); 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 +390,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 +402,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 +413,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.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/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 diff --git a/src/fix_spring.cpp b/src/fix_spring.cpp index 829073179d..e35c2610e4 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, "Incorrect 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, "Incorrect 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"); } diff --git a/src/library.cpp b/src/library.cpp index d8cc91ce5b..27148e9697 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -7472,7 +7472,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 @@ -7545,7 +7545,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 @@ -7553,7 +7553,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. diff --git a/src/modify.cpp b/src/modify.cpp index e571440ddd..aa2b0cccc6 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,10 +1294,21 @@ 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); - 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; } /* ---------------------------------------------------------------------- @@ -1321,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]); } @@ -1332,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); } @@ -1431,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); } 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/output.cpp b/src/output.cpp index 0602c4f52d..8bac766213 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"); @@ -222,13 +222,13 @@ 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 // 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,15 +274,18 @@ 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]); } - 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 @@ -350,7 +353,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); @@ -373,16 +377,15 @@ 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; for (int idump = 0; idump < ndump; idump++) { - 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,16 +395,20 @@ 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]); } - 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 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. 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; 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); 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)) diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 602ae58900..003345de57 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -83,8 +83,10 @@ 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.contains("AppData"))) current_dir = QDir::homePath(); + QDir::setCurrent(current_dir); + inspectList.clear(); setAutoFillBackground(true); 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