diff --git a/doc/Makefile b/doc/Makefile index 49ad98775d..d96b523915 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -54,7 +54,7 @@ DOXYFILES = $(shell sed -n -e 's/\#.*$$//' -e '/^ *INPUT \+=/,/^[A-Z_]\+ \+ help: @echo "Please use \`make ' where is one of" @echo " html create HTML doc pages in html dir" - @echo " pdf create Developer.pdf and Manual.pdf in this dir" + @echo " pdf create Manual.pdf in this dir" @echo " fetch fetch HTML and PDF files from LAMMPS web site" @echo " epub create ePUB format manual for e-book readers" @echo " mobi convert ePUB to MOBI format manual for e-book readers (e.g. Kindle)" @@ -69,7 +69,7 @@ help: # ------------------------------------------ clean-all: clean - rm -rf $(BUILDDIR)/docenv $(MATHJAX) $(BUILDDIR)/LAMMPS.mobi $(BUILDDIR)/LAMMPS.epub $(BUILDDIR)/Manual.pdf $(BUILDDIR)/Developer.pdf + rm -rf $(BUILDDIR)/docenv $(MATHJAX) $(BUILDDIR)/LAMMPS.mobi $(BUILDDIR)/LAMMPS.epub $(BUILDDIR)/Manual.pdf clean: clean-spelling rm -rf $(BUILDDIR)/html $(BUILDDIR)/epub $(BUILDDIR)/latex $(BUILDDIR)/doctrees $(BUILDDIR)/doxygen/xml $(BUILDDIR)/doxygen-warn.log $(BUILDDIR)/doxygen/Doxyfile $(SPHINXCONFIG)/conf.py @@ -139,13 +139,6 @@ mobi: epub pdf: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) @$(MAKE) $(MFLAGS) -C graphviz all @if [ "$(HAS_PDFLATEX)" == "NO" ] ; then echo "PDFLaTeX was not found! Please check README.md for further instructions" 1>&2; exit 1; fi - @(\ - cd src/Developer; \ - pdflatex developer; \ - pdflatex developer; \ - mv developer.pdf ../../Developer.pdf; \ - cd ../../; \ - ) @(\ . $(VENV)/bin/activate ; env PYTHONWARNINGS= \ sphinx-build $(SPHINXEXTRA) -b latex -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) latex ;\ @@ -175,12 +168,11 @@ pdf: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) @rm -rf latex/USER @cp -r src/PDF latex/PDF @rm -rf latex/PDF/.[sg]* - @echo "Build finished. Manual.pdf and Developer.pdf are in this directory." + @echo "Build finished. Manual.pdf is in this directory." fetch: - @rm -rf html_www Manual_www.pdf Developer_www.pdf + @rm -rf html_www Manual_www.pdf @curl -s -o Manual_www.pdf http://lammps.sandia.gov/doc/Manual.pdf - @curl -s -o Developer_www.pdf http://lammps.sandia.gov/doc/Developer.pdf @curl -s -o lammps-doc.tar.gz http://lammps.sandia.gov/tars/lammps-doc.tar.gz @tar xzf lammps-doc.tar.gz @rm -f lammps-doc.tar.gz diff --git a/doc/src/Build_basics.rst b/doc/src/Build_basics.rst index 0ddf65ab46..baace2e063 100644 --- a/doc/src/Build_basics.rst +++ b/doc/src/Build_basics.rst @@ -471,7 +471,7 @@ LAMMPS source distribution. .. code-block:: bash make html # create HTML doc pages in html directory - make pdf # create Developer.pdf and Manual.pdf in this directory + make pdf # create Manual.pdf in this directory make fetch # fetch HTML and PDF files from LAMMPS web site make clean # remove all intermediate files make clean-all # reset the entire doc build environment diff --git a/doc/src/Developer/.gitignore b/doc/src/Developer/.gitignore deleted file mode 100644 index 38f7323f7b..0000000000 --- a/doc/src/Developer/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/developer.aux -/developer.log -/developer.toc diff --git a/doc/src/Developer/classes.fig b/doc/src/Developer/classes.fig deleted file mode 100644 index a2d9b6d6f1..0000000000 --- a/doc/src/Developer/classes.fig +++ /dev/null @@ -1,198 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5a -Portrait -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2232 1170 3540 1170 3540 1505 2232 1505 2232 1170 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2220 1830 3015 1830 3015 2219 2220 2219 2220 1830 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2226 3285 3300 3285 3300 3665 2226 3665 2226 3285 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2223 5190 3225 5190 3225 5525 2223 5525 2223 5190 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2232 7125 3090 7125 3090 7478 2232 7478 2232 7125 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2226 10230 3300 10230 3300 10565 2226 10565 2226 10230 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4026 10305 4980 10305 4980 10592 4026 10592 4026 10305 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4029 9900 5205 9900 5205 10250 4029 10250 4029 9900 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4038 9315 5370 9315 5370 9659 4038 9659 4038 9315 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4023 8955 4530 8955 4530 9278 4023 9278 4023 8955 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4029 8475 5190 8475 5190 8762 4029 8762 4029 8475 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4008 8115 5430 8115 5430 8408 4008 8408 4008 8115 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4026 7425 4995 7425 4995 7712 4026 7712 4026 7425 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4035 6720 4650 6720 4650 7025 4035 7025 4035 6720 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4044 7080 4830 7080 4830 7358 4044 7358 4044 7080 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4032 6105 5205 6105 5205 6419 4032 6419 4032 6105 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4026 5715 5115 5715 5115 6062 4026 6062 4026 5715 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4023 3585 4605 3585 4605 3872 4023 3872 4023 3585 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3954 1680 5175 1680 5175 1997 3954 1997 3954 1680 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 1620 5235 2100 615 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 1605 5445 2070 10695 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3120 1935 3855 1800 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3150 2115 3765 2250 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3135 7230 3945 6840 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3150 7335 3945 8610 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 5265 8610 6195 8400 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 5280 8655 6180 8820 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3345 10290 3930 10020 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3360 10395 3930 10425 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3360 10455 3930 10755 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2193 360 3435 360 3435 647 2193 647 2193 360 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3398 3472 3923 3307 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3413 3601 3923 3721 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3285 2806 3870 2802 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3315 5372 3900 5368 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6354 2280 7470 2280 7470 2585 6354 2585 6354 2280 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6348 1875 7320 1875 7320 2222 6348 2222 6348 1875 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3954 2070 5505 2070 5505 2372 3954 2372 3954 2070 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 5634 2137 6230 2045 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 5670 2310 6265 2418 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 3900 2640 5400 2640 5400 2975 3900 2975 3900 2640 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4038 3165 5385 3165 5385 3497 4038 3497 4038 3165 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4245 4110 5730 4110 5730 4499 4245 4499 4245 4110 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4233 4545 6390 4545 6390 4862 4233 4862 4233 4545 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4026 5190 5385 5190 5385 5525 4026 5525 4026 5190 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4038 7755 5310 7755 5310 8075 4038 8075 4038 7755 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6270 8250 7365 8250 7365 8610 6270 8610 6270 8250 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 6273 8655 7380 8655 7380 8978 6273 8978 6273 8655 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4041 10620 5985 10620 5985 10943 4041 10943 4041 10620 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2217 10830 3135 10830 3135 11156 2217 11156 2217 10830 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2229 9780 3240 9780 3240 10118 2229 10118 2229 9780 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2214 9015 3285 9015 3285 9362 2214 9362 2214 9015 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2208 5850 3420 5850 3420 6209 2208 6209 2208 5850 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2217 4275 3615 4275 3615 4634 2217 4634 2217 4275 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2235 2655 3150 2655 3150 3000 2235 3000 2235 2655 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 60 5115 1500 5115 1500 5610 60 5610 60 5115 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3486 6018 4011 5853 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3486 6129 3996 6249 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3361 9291 3991 9531 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3345 9129 4005 9099 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3691 4412 4216 4277 -2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 1 1 2.00 120.00 240.00 - 3695 4561 4175 4711 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 2220 735 3129 735 3129 1043 2220 1043 2220 735 -4 0 1 50 -1 18 18 0.0000 4 225 1275 2265 1455 Universe\001 -4 0 1 50 -1 18 18 0.0000 4 285 735 2265 2175 Input\001 -4 0 1 50 -1 18 18 0.0000 4 225 780 2265 2925 Atom\001 -4 0 1 50 -1 18 18 0.0000 4 285 1020 2265 3600 Update\001 -4 0 1 50 -1 18 18 0.0000 4 285 1320 2265 4575 Neighbor\001 -4 0 1 50 -1 18 18 0.0000 4 225 945 2265 5475 Comm\001 -4 0 1 50 -1 18 18 0.0000 4 225 1110 2265 6150 Domain\001 -4 0 1 50 -1 18 18 0.0000 4 225 810 2265 7425 Force\001 -4 0 1 50 -1 18 18 0.0000 4 285 975 2265 9300 Modify\001 -4 0 1 50 -1 18 18 0.0000 4 285 900 2265 10050 Group\001 -4 0 1 50 -1 18 18 0.0000 4 285 990 2265 10500 Output\001 -4 0 1 50 -1 18 18 0.0000 4 225 825 2265 11100 Timer\001 -4 0 0 50 -1 18 18 0.0000 4 225 1170 3990 1950 Variable\001 -4 0 4 50 -1 18 18 0.0000 4 225 1470 3990 2325 Command\001 -4 0 4 50 -1 18 18 0.0000 4 285 1275 4065 3450 Integrate\001 -4 0 4 50 -1 18 18 0.0000 4 225 525 4065 3825 Min\001 -4 0 0 50 -1 18 18 0.0000 4 285 1230 4065 5475 Irregular\001 -4 0 4 50 -1 18 18 0.0000 4 285 1020 4065 6000 Region\001 -4 0 0 50 -1 18 18 0.0000 4 225 975 4065 6375 Lattice\001 -4 0 4 50 -1 18 18 0.0000 4 225 435 4065 9225 Fix\001 -4 0 4 50 -1 18 18 0.0000 4 285 1305 4065 9600 Compute\001 -4 0 4 50 -1 18 18 0.0000 4 225 570 4065 6975 Pair\001 -4 0 4 50 -1 18 18 0.0000 4 285 840 4065 7665 Angle\001 -4 0 4 50 -1 18 18 0.0000 4 225 1215 4065 8010 Dihedral\001 -4 0 4 50 -1 18 18 0.0000 4 285 1305 4065 8355 Improper\001 -4 0 4 50 -1 18 18 0.0000 4 285 1095 4065 8700 KSpace\001 -4 0 4 50 -1 18 18 0.0000 4 285 855 4065 10545 Dump\001 -4 0 0 50 -1 18 18 0.0000 4 225 1815 4065 10890 WriteRestart\001 -4 0 0 50 -1 18 18 0.0000 4 225 930 6315 8550 FFT3D\001 -4 0 0 50 -1 18 18 0.0000 4 285 1005 6315 8925 Remap\001 -4 0 0 50 -1 18 18 0.0000 4 225 885 6390 2175 Finish\001 -4 0 0 50 -1 18 18 0.0000 4 285 1050 6390 2550 Special\001 -4 0 4 50 -1 18 18 0.0000 4 225 1305 3990 2925 AtomVec\001 -4 0 4 50 -1 18 18 0.0000 4 225 765 4065 7320 Bond\001 -4 0 0 50 -1 18 18 0.0000 4 225 1095 4065 10200 Thermo\001 -4 0 0 50 -1 18 18 0.0000 4 285 1380 4305 4425 NeighList\001 -4 0 0 50 -1 18 18 0.0000 4 285 2025 4305 4800 NeighRequest\001 -4 0 1 50 -1 18 18 0.0000 4 285 1155 2250 600 Memory\001 -4 0 0 50 -1 18 18 0.0000 4 225 1305 120 5475 LAMMPS\001 -4 0 1 50 -1 18 18 0.0000 4 225 735 2265 1005 Error\001 diff --git a/doc/src/Developer/classes.pdf b/doc/src/Developer/classes.pdf deleted file mode 100644 index 566089ac9e..0000000000 Binary files a/doc/src/Developer/classes.pdf and /dev/null differ diff --git a/doc/src/Developer/developer.tex b/doc/src/Developer/developer.tex deleted file mode 100644 index c7f619c84f..0000000000 --- a/doc/src/Developer/developer.tex +++ /dev/null @@ -1,699 +0,0 @@ -\documentclass{article} -\usepackage{graphicx} - -\begin{document} - -\centerline{\Large \bf LAMMPS Developer Guide} -\centerline{\bf 23 Aug 2011} - -\vspace{0.5in} - -This document is a developer guide to the LAMMPS molecular dynamics -package, whose WWW site is at lammps.sandia.gov. It describes the -internal structure and algorithms of the code. Sections will be added -as we have time, and in response to requests from developers and -users. - -\tableofcontents - -\pagebreak -\section{LAMMPS source files} - -LAMMPS source files are in two directories of the distribution -tarball. The src directory has the majority of them, all of which are -C++ files (*.cpp and *.h). Many of these files are in the src -directory itself. There are also dozens of ``packages'', which can be -included or excluded when LAMMPS is built. See the -doc/Section\_build.html section of the manual for more information -about packages, or type ``make'' from within the src directory, which -lists package-related commands, such as ``make package-status''. The -source files for each package are in an all-uppercase sub-directory of -src, like src/MOLECULE or src/USER-CUDA. If the package is currently -installed, copies of the package source files will also exist in the -src directory itself. The src/STUBS sub-directory is not a package -but contains a dummy version of the MPI library, used when building a -serial version of the code. - -The lib directory also contains source code for external libraries, -used by a few of the packages. Each sub-directory, like meam or gpu, -contains the source files, some of which are in different languages -such as Fortran. The files are compiled into libraries from within -each sub-directory, e.g. performing a ``make'' in the lib/meam directory -creates a libmeam.a file. These libraries are linked to during a -LAMMPS build, if the corresponding package is installed. - -LAMMPS C++ source files almost always come in pairs, such as run.cpp -and run.h. The pair of files defines a C++ class, the Run class in -this case, which contains the code invoked by the ``run'' command in a -LAMMPS input script. As this example illustrates, source file and -class names often have a one-to-one correspondence with a command used -in a LAMMPS input script. Some source files and classes do not have a -corresponding input script command, e.g. ``force.cpp'' and the Force -class. They are discussed in the next section. - -\pagebreak -\section{Class hierarchy of LAMMPS} - -Though LAMMPS has a lot of source files and classes, its class -hierarchy is quite simple, as outlined in Fig \ref{fig:classes}. Each -boxed name refers to a class and has a pair of associated source files -in lammps/src, e.g. ``memory.cpp'' and ``memory.h''. More details on the -class and its methods and data structures can be found by examining -its *.h file. - -LAMMPS (lammps.cpp/h) is the top-level class for the entire code. It -holds an ``instance'' of LAMMPS and can be instantiated one or more -times by a calling code. For example, the file src/main.cpp simply -instantiates one instance of LAMMPS and passes it the input script. - -The file src/library.cpp contains a C-style library interface to the -LAMMPS class. See the lammps/couple and lammps/python directories for -examples of simple programs that use LAMMPS through its library -interface. A driver program can instantiate the LAMMPS class multiple -times, e.g. to embed several atomistic simulation regions within a -mesoscale or continuum simulation domain. - -There are a dozen or so top-level classes within the LAMMPS class that -are visible everywhere in the code. They are shaded blue in Fig -\ref{fig:classes}. Thus any class can refer to the y-coordinate of -local atom $I$ as atom$\rightarrow$x[i][1]. This visibility is -enabled by a bit of cleverness in the Pointers class (see -src/pointers.h) which every class inherits from. - -There are a handful of virtual parent classes in LAMMPS that define -what LAMMPS calls ``styles''. They are shaded red in Fig -\ref{fig:classes}. Each of these are parents of a number of child -classes that implement the interface defined by the parent class. For -example, the fix style has around 100 child classes. They are the -possible fixes that can be specified by the fix command in an input -script, e.g. fix nve, fix shake, fix ave/time, etc. The corresponding -classes are Fix (for the parent class), FixNVE, FixShake, FixAveTime, -etc. The source files for these classes are easy to identify in the -src directory, since they begin with the word ``fix'', e,g, -fix\_nve.cpp, fix\_shake,cpp, fix\_ave\_time.cpp, etc. - -The one exception is child class files for the ``command'' style. These -implement specific commands in the input script that can be invoked -before/after/between runs or which launch a simulation. Examples are -the create\_box, minimize, run, and velocity commands which encode the -CreateBox, Minimize, Run, and Velocity classes. The corresponding -files are create\_box,cpp, minimize.cpp, run.cpp, and velocity.cpp. -The list of command style files can be found by typing ``grep -COMMAND\_CLASS *.h'' from within the src directory, since that word in -the header file identifies the class as an input script command. -Similar words can be grepped to list files for the other LAMMPS -styles. E.g. ATOM\_CLASS, PAIR\_CLASS, BOND\_CLASS, REGION\_CLASS, -FIX\_CLASS, COMPUTE\_CLASS, DUMP\_CLASS, etc. - -\begin{figure}[htb] - \begin{center} - \includegraphics[height=4in]{classes.pdf} - \end{center} - \caption{Class hierarchy within LAMMPS source code.} -\label{fig:classes} -\end{figure} - -More details on individual classes in Fig \ref{fig:classes} are as -follows: - -\begin{itemize} - -\item The Memory class handles allocation of all large vectors and - arrays. - -\item The Error class prints all error and warning messages. - -\item The Universe class sets up partitions of processors so that - multiple simulations can be run, each on a subset of the processors - allocated for a run, e.g. by the mpirun command. - -\item The Input class reads an input script, stores variables, and - invokes stand-alone commands that are child classes of the Command - class. - -\item As discussed above, the Command class is a parent class for - certain input script commands that perform a one-time operation - before/after/between simulations or which invoke a simulation. They - are instantiated from within the Input class, invoked, then - immediately destructed. - -\item The Finish class is instantiated to print statistics to the - screen after a simulation is performed, by commands like run and - minimize. - -\item The Special class walks the bond topology of a molecular system - to find first, second, third neighbors of each atom. It is invoked by - several commands, like read\_data, read\_restart, and replicate. - -\item The Atom class stores all per-atom arrays. More precisely, they - are allocated and stored by the AtomVec class, and the Atom class - simply stores a pointer to them. The AtomVec class is a parent - class for atom styles, defined by the atom\_style command. - -\item The Update class holds an integrator and a minimizer. The - Integrate class is a parent style for the Verlet and rRESPA time - integrators, as defined by the run\_style input command. The Min - class is a parent style for various energy minimizers. - -\item The Neighbor class builds and stores neighbor lists. The - NeighList class stores a single list (for all atoms). The - NeighRequest class is called by pair, fix, or compute styles when - they need a particular kind of neighbor list. - -\item The Comm class performs interprocessor communication, typically - of ghost atom information. This usually involves MPI message - exchanges with 6 neighboring processors in the 3d logical grid of - processors mapped to the simulation box. Sometimes the Irregular - class is used, when atoms may migrate to arbitrary processors. - -\item The Domain class stores the simulation box geometry, as well as - geometric Regions and any user definition of a Lattice. The latter - are defined by region and lattice commands in an input script. - -\item The Force class computes various forces between atoms. The Pair - parent class is for non-bonded or pair-wise forces, which in LAMMPS - lingo includes many-body forces such as the Tersoff 3-body - potential. The Bond, Angle, Dihedral, Improper parent classes are - styles for bonded interactions within a static molecular topology. - The KSpace parent class is for computing long-range Coulombic - interactions. One of its child classes, PPPM, uses the FFT3D and - Remap classes to communicate grid-based information with neighboring - processors. - -\item The Modify class stores lists of Fix and Compute classes, both - of which are parent styles. - -\item The Group class manipulates groups that atoms are assigned to - via the group command. It also computes various attributes of - groups of atoms. - -\item The Output class is used to generate 3 kinds of output from a - LAMMPS simulation: thermodynamic information printed to the screen - and log file, dump file snapshots, and restart files. These - correspond to the Thermo, Dump, and WriteRestart classes - respectively. The Dump class is a parent style. - -\item The Timer class logs MPI timing information, output at the end - of a run. - -\end{itemize} - -%%\pagebreak -%%\section{Spatial decomposition and parallel operations} -%%distributed memory -%%Ref to JCP paper -%%diagram of 3d grid of procs and spatial decomp -%%6-way comm -%%ghost atoms, PBC added when comm (in atom class) - -%%\pagebreak -%%\section{Fixes, computes, variables} -%%fixes intercolate in timestep, store per-atom info -%%computes based on current snapshot -%%equal- and atom-style variables -%%output they produce - see write-up in HowTo - -\pagebreak -\section{How a timestep works} - -The first and most fundamental operation within LAMMPS to understand -is how a timestep is structured. Timestepping is performed by the -Integrate class within the Update class. Since Integrate is a parent -class, corresponding to the run\_style input script command, it has -child classes. In this section, the timestep implemented by the -Verlet child class is described. A similar timestep is implemented by -the Respa child class, for the rRESPA hierarchical timestepping -method. The Min parent class performs energy minimization, so does -not perform a literal timestep. But it has logic similar to what is -described here, to compute forces and invoke fixes at each iteration -of a minimization. Differences between time integration and -minimization are highlighted at the end of this section. - -The Verlet class is encoded in the src/verlet.cpp and verlet.h files. -It implements the velocity-Verlet timestepping algorithm. The -workhorse method is Verlet::run(), but first we highlight several -other methods in the class. - -\begin{itemize} - -\item The init() method is called at the beginning of each dynamics - run. It simply sets some internal flags, based on user settings in - other parts of the code. - -\item The setup() or setup\_minimal() methods are also called before - each run. The velocity-Verlet method requires current forces be - calculated before the first timestep, so these routines compute - forces due to all atomic interactions, using the same logic that - appears in the timestepping described next. A few fixes are also - invoked, using the mechanism described in the next section. Various - counters are also initialized before the run begins. The - setup\_minimal() method is a variant that has a flag for performing - less setup. This is used when runs are continued and information - from the previous run is still valid. For example, if repeated - short LAMMPS runs are being invoked, interleaved by other commands, - via the ``pre no'' and ``every'' options of the run command, the - setup\_minimal() method is used. - -\item The force\_clear() method initializes force and other arrays to - zero before each timestep, so that forces (torques, etc) can be - accumulated. - -\end{itemize} - -Now for the Verlet::run() method. Its structure in hi-level pseudo -code is shown in Fig \ref{fig:verlet}. In the actual code in -src/verlet.cpp some of these operations are conditionally invoked. - -\begin{figure}[htb] - \begin{center} - \begin{verbatim} -loop over N timesteps: - ev_set() - - fix->initial_integrate() - fix->post_integrate() - - nflag = neighbor->decide() - if nflag: - fix->pre_exchange() - domain->pbc() - domain->reset_box() - comm->setup() - neighbor->setup_bins() - comm->exchange() - comm->borders() - fix->pre_neighbor() - neighbor->build() - else - comm->forward_comm() - - force_clear() - fix->pre_force() - - pair->compute() - bond->compute() - angle->compute() - dihedral->compute() - improper->compute() - kspace->compute() - - comm->reverse_comm() - - fix->post_force() - fix->final_integrate() - fix->end_of_step() - - if any output on this step: output->write() - \end{verbatim} - \end{center} - \caption{Pseudo-code for the Verlet::run() method.} -\label{fig:verlet} -\end{figure} - -The ev\_set() method (in the parent Integrate class), sets two flags -({\em eflag} and {\em vflag}) for energy and virial computation. Each -flag encodes whether global and/or per-atom energy and virial should -be calculated on this timestep, because some fix or variable or output -will need it. These flags are passed to the various methods that -compute particle interactions, so that they can skip the extra -calculations if the energy and virial are not needed. See the -comments with the Integrate::ev\_set() method which document the flag -values. - -At various points of the timestep, fixes are invoked, -e.g. fix$\rightarrow$initial\_integrate(). In the code, this is -actually done via the Modify class which stores all the Fix objects -and lists of which should be invoked at what point in the timestep. -Fixes are the LAMMPS mechanism for tailoring the operations of a -timestep for a particular simulation. As described elsewhere -(unwritten section), each fix has one or more methods, each of which -is invoked at a specific stage of the timestep, as in Fig -\ref{fig:verlet}. All the fixes defined in an input script with an -initial\_integrate() method are invoked at the beginning of each -timestep. Fix nve, nvt, npt are examples, since they perform the -start-of-timestep velocity-Verlet integration to update velocities by -a half-step, and coordinates by a full step. The post\_integrate() -method is next. Only a few fixes use this, e.g. to reflect particles -off box boundaries in the FixWallReflect class. - -The decide() method in the Neighbor class determines whether neighbor -lists need to be rebuilt on the current timestep. If not, coordinates -of ghost atoms are acquired by each processor via the forward\_comm() -method of the Comm class. If neighbor lists need to be built, several -operations within the inner if clause of Fig \ref{fig:verlet} are -first invoked. The pre\_exchange() method of any defined fixes is -invoked first. Typically this inserts or deletes particles from the -system. - -Periodic boundary conditions are then applied by the Domain class via -its pbc() method to remap particles that have moved outside the -simulation box back into the box. Note that this is not done every -timestep. but only when neighbor lists are rebuilt. This is so that -each processor's sub-domain will have consistent (nearby) atom -coordinates for its owned and ghost atoms. It is also why dumped atom -coordinates can be slightly outside the simulation box. - -The box boundaries are then reset (if needed) via the reset\_box() -method of the Domain class, e.g. if box boundaries are shrink-wrapped -to current particle coordinates. A change in the box size or shape -requires internal information for communicating ghost atoms (Comm -class) and neighbor list bins (Neighbor class) be updated. The -setup() method of the Comm class and setup\_bins() method of the -Neighbor class perform the update. - -The code is now ready to migrate atoms that have left a processor's -geometric sub-domain to new processors. The exchange() method of the -Comm class performs this operation. The borders() method of the Comm -class then identifies ghost atoms surrounding each processor's -sub-domain and communicates ghost atom information to neighboring -processors. It does this by looping over all the atoms owned by a -processor to make lists of those to send to each neighbor processor. -On subsequent timesteps, the lists are used by the -Comm::forward\_comm() method. - -Fixes with a pre\_neighbor() method are then called. These typically -re-build some data structure stored by the fix that depends on the -current atoms owned by each processor. - -Now that each processor has a current list of its owned and ghost -atoms, LAMMPS is ready to rebuild neighbor lists via the build() -method of the Neighbor class. This is typically done by binning all -owned and ghost atoms, and scanning a stencil of bins around each -owned atom's bin to make a Verlet list of neighboring atoms within the -force cutoff plus neighbor skin distance. - -In the next portion of the timestep, all interaction forces between -particles are computed, after zeroing the per-atom force vector via -the force\_clear() method. If the newton flag is set to ``on'' by the -newton command, forces on both owned and ghost atoms are calculated. - -Pairwise forces are calculated first, which enables the global virial -(if requested) to be calculated cheaply (at the end of the -Pair::compute() method), by a dot product of atom coordinates and -forces. By including owned and ghost atoms in the dot product, the -effect of periodic boundary conditions is correctly accounted for. -Molecular topology interactions (bonds, angles, dihedrals, impropers) -are calculated next. The final contribution is from long-range -Coulombic interactions, invoked by the KSpace class. - -If the newton flag is on, forces on ghost atoms are communicated and -summed back to their corresponding owned atoms. The reverse\_comm() -method of the Comm class performs this operation, which is essentially -the inverse operation of sending copies of owned atom coordinates to -other processor's ghost atoms. - -At this point in the timestep, the total force on each atom is known. -Additional force constraints (external forces, SHAKE, etc) are applied -by Fixes that have a post\_force() method. The second half of the -velocity-Verlet integration is then performed (another half-step -update of the velocities) via fixes like nve, nvt, npt. - -At the end of the timestep, fixes that define an end\_of\_step() -method are invoked. These typically perform a diagnostic calculation, -e.g. the ave/time and ave/spatial fixes. The final operation of the -timestep is to perform any requested output, via the write() method of -the Output class. There are 3 kinds of LAMMPS output: thermodynamic -output to the screen and log file, snapshots of atom data to a dump -file, and restart files. See the thermo\_style, dump, and restart -commands for more details. - -The iteration performed by an energy minimization is similar to the -dynamics timestep of Fig \ref{fig:verlet}. Forces are computed, -neighbor lists are built as needed, atoms migrate to new processors, -and atom coordinates and forces are communicated to neighboring -processors. The only difference is what Fix class operations are -invoked when. Only a subset of LAMMPS fixes are useful during energy -minimization, as explained in their individual doc pages. The -relevant Fix class methods are min\_pre\_exchange(), -min\_pre\_force(), and min\_post\_force(). Each is invoked at the -appropriate place within the minimization iteration. For example, the -min\_post\_force() method is analogous to the post\_force() method for -dynamics; it is used to alter or constrain forces on each atom, which -affects the minimization procedure. - -\pagebreak -\section{Extending LAMMPS} - -The Section\_modify.html file in the doc directory of -the LAMMPS distribution gives an overview of how LAMMPS can -be extended by writing new classes that derive from existing -parent classes in LAMMPS. Here, some specific coding -details are provided for writing a new fix. - -\subsection{New fixes} - -(this section provided by Kirill Lykov) -\vspace{0.25cm} - -Writing fixes is a flexible way of extending LAMMPS. Users can -implement many things using fixes: - -\begin{itemize} -\item changing particles attributes (positions, velocities, forces, etc.). -Example: FixFreeze. -\item reading/writing data. Example: FixRestart. -\item implementing boundary conditions. Example: FixWall. -\item saving information about particles for future use (previous positions, -for instance). Example: FixStoreState. -\end{itemize} - -All fixes are derived from class Fix and must have constructor with the -signature: FixMine(class LAMMPS *, int, char **). - -Every fix must be registered in LAMMPS by writing the following lines -of code in the header before include guards: - - \begin{center} - \begin{verbatim} -#ifdef FIX_CLASS -FixStyle(your/fix/name,FixMine) -#else - \end{verbatim} - \end{center} - -Where ``your/fix/name'' is a name of your fix in the script and FixMine -is the name of the class. This code allows LAMMPS to find your fix -when it parses input script. In addition, your fix header must be -included in the file ``style\_fix.h''. In case if you use LAMMPS make, -this file is generated automatically - all files starting with prefix -fix\_ are included, so call your header the same way. Otherwise, don't -forget to add your include into ``style\_fix.h''. - -Let's write a simple fix which will print average velocity at the end -of each timestep. First of all, implement a constructor: - - \begin{center} - \begin{verbatim} -FixPrintVel::FixPrintVel(LAMMPS *lmp, int narg, char **arg) -: Fix(lmp, narg, arg) -{ - if (narg < 4) - error->all(FLERR,"Illegal fix print command"); - - nevery = atoi(arg[3]); - if (nevery <= 0) - error->all(FLERR,"Illegal fix print command"); -} - \end{verbatim} - \end{center} - -In the constructor you should parse your fix arguments which are -specified in the script. All fixes have pretty the same syntax: fix -[fix\_identifier] [group\_name] [fix\_name] [fix\_arguments]. The -first 3 parameters are parsed by Fix class constructor, while -[fix\_arguments] should be parsed by you. In our case, we need to -specify how often we want to print an average velocity. For instance, -once in 50 timesteps: fix 1 print/vel 50. There is a special variable -in Fix class called nevery which specifies how often method -end\_of\_step() is called. Thus all we need to do is just set it up. - -The next method we need to implement is setmask(): -\begin{center} -\begin{verbatim} -int FixPrintVel::setmask() -{ - int mask = 0; - mask |= FixConst::END_OF_STEP; - return mask; -} -\end{verbatim} -\end{center} - -Here user specifies which methods of your fix should be called during -the execution. For instance, END\_OF\_STEP corresponds to the -end\_of\_step() method. Overall, there are 8 most important methods, -methods are called in predefined order during the execution of the -verlet algorithm as was mentioned in the Section 3: - -\begin{itemize} -\item initial\_integrate() -\item post\_integrate() -\item pre\_exchange() -\item pre\_neighbor() -\item pre\_force() -\item post\_force() -\item final\_integrate() -\item end\_of\_step() -\end{itemize} - -Fix developer must understand when he wants to execute his code. In -case if we want to write FixPrintVel, we need only end\_of\_step(): - -\begin{center} -\begin{verbatim} -void FixPrintVel::end_of_step() -{ - // for add3, scale3 - using namespace MathExtra; - - double** v = atom->v; - int nlocal = atom->nlocal; - double localAvgVel[4]; // 4th element for particles count - memset(localAvgVel, 0, 4 * sizeof(double)); - for (int particleInd = 0; particleInd < nlocal; ++particleInd) { - add3(localAvgVel, v[particleInd], localAvgVel); - } - localAvgVel[3] = nlocal; - double globalAvgVel[4]; - memset(globalAvgVel, 0, 4 * sizeof(double)); - MPI_Allreduce(localAvgVel, globalAvgVel, 4, MPI_DOUBLE, MPI_SUM, world); - scale3(1.0 / globalAvgVel[3], globalAvgVel); - if (comm->me == 0) { - printf("\%e, \%e, \%e\n", - globalAvgVel[0], globalAvgVel[1], globalAvgVel[2]); - } -} -\end{verbatim} -\end{center} - -In the code above, we use MathExtra routines defined in -``math\_extra.h''. There are bunch of math functions to work with -arrays of doubles as with math vectors. - -In this code we use an instance of Atom class. This object is stored -in the Pointers class (see ``pointers.h''). This object contains all -global information about the simulation system. Data from Pointers -class available to all classes inherited from it using protected -inheritance. Hence when you write you own class, which is going to use -LAMMPS data, don't forget to inherit from Pointers. When writing -fixes we inherit from class Fix which is inherited from Pointers so -there is no need to inherit from it directly. - -The code above computes average velocity for all particles in the -simulation. Yet you have one unused parameter in fix call from the -script - [group\_name]. This parameter specifies the group of atoms -used in the fix. So we should compute average for all particles in the -simulation if group\_name == all, but it can be any group. The group -information is specified by groupbit which is defined in class Fix: - -\begin{center} -\begin{verbatim} -for (int particleInd = 0; particleInd < nlocal; ++particleInd) { - if (atom->mask[particleInd] & groupbit) { - //Do all job here - } -} -\end{verbatim} -\end{center} - -Class Atom encapsulates atoms positions, velocities, forces, etc. User -can access them using particle index. Note, that particle indexes are -usually changed every timestep because of sorting. - -Lets consider another Fix example. We want to have a fix which stores -atoms position from previous time step in your fix. The local atoms -indexes will not be valid on the next iteration. In order to handle -this situation there are several methods which should be implemented: - -\begin{itemize} -\item \verb|double memory_usage| - return how much memory fix uses -\item \verb|void grow_arrays(int)| - do reallocation of the per particle arrays - in your fix -\item \verb|void copy_arrays(int i, int j, int delflag)| - copy i-th per-particle - information to j-th. Used when atoms sorting is performed. if delflag is set - and atom j owns a body, move the body information to atom i. -\item \verb|void set_arrays(int i)| - sets i-th particle related information to zero -\end{itemize} - -Note, that if your class implements these methods, it must call add calls of -add\_callback and delete\_callback to constructor and destructor: - -\begin{center} -\begin{verbatim} -FixSavePos::FixSavePos(LAMMPS *lmp, int narg, char **arg) { - //... - atom->add_callback(0); -} - -FixSavePos::~FixSavePos() { - atom->delete_callback(id, 0); -} -\end{verbatim} -\end{center} - -Since we want to store positions of atoms from previous timestep, we -need to add double** x to the header file. Than add allocation code to -constructor: - -\verb|memory->create(this->x, atom->nmax, 3, "FixSavePos:x");|. Free memory -at destructor: \verb|memory->destroy(x);| - -Finally, implement mentioned methods: - -\begin{center} -\begin{verbatim} -double FixSavePos::memory_usage() -{ - int nmax = atom->nmax; - double bytes = 0.0; - bytes += nmax * 3 * sizeof(double); - return bytes; -} - -void FixSavePos::grow_arrays(int nmax) -{ - memory->grow(this->x, nmax, 3, "FixSavePos:x"); -} - -void FixSavePos::copy_arrays(int i, int j, int delflag) -{ - memcpy(this->x[j], this->x[i], sizeof(double) * 3); -} - -void FixSavePos::set_arrays(int i) -{ - memset(this->x[i], 0, sizeof(double) * 3); -} - -int FixSavePos::pack_exchange(int i, double *buf) -{ - int m = 0; - buf[m++] = x[i][0]; - buf[m++] = x[i][1]; - buf[m++] = x[i][2]; - - return m; -} - -int FixSavePos::unpack_exchange(int nlocal, double *buf) -{ - int m = 0; - x[nlocal][0] = buf[m++]; - x[nlocal][1] = buf[m++]; - x[nlocal][2] = buf[m++]; - - return m; -} -\end{verbatim} -\end{center} - -Now, a little bit about memory allocation. We used Memory class which -is just a bunch of template functions for allocating 1D and 2D -arrays. So you need to add include ``memory.h'' to have access to them. - -Finally, if you need to write/read some global information used in -your fix to the restart file, you might do it by setting flag -restart\_global = 1 in the constructor and implementing methods void -write\_restart(FILE *fp) and void restart(char *buf). - -\end{document} diff --git a/doc/src/Intro_website.rst b/doc/src/Intro_website.rst index 0999e90907..125d2e0f4c 100644 --- a/doc/src/Intro_website.rst +++ b/doc/src/Intro_website.rst @@ -23,7 +23,6 @@ this Intr are included in this list. * `Mail list `_ * `Workshops `_ * `Tutorials `_ -* `Developer guide `_ * `Pre- and post-processing tools for LAMMPS `_ * `Other software usable with LAMMPS `_ diff --git a/doc/src/Manual.rst b/doc/src/Manual.rst index 29852093d0..b43e60208c 100644 --- a/doc/src/Manual.rst +++ b/doc/src/Manual.rst @@ -27,8 +27,7 @@ all LAMMPS development is coordinated. The content for this manual is part of the LAMMPS distribution. You can build a local copy of the Manual as HTML pages or a PDF file, by following the steps on the :doc:`Manual build ` doc page. -There is also a `Developer.pdf `_ document which gives -a brief description of the basic code structure of LAMMPS. +The manual is split into two parts: 1) User documentation and 2) Programmer documentation. ---------- diff --git a/doc/src/Manual_build.rst b/doc/src/Manual_build.rst index 972f38bf2e..affa9e5057 100644 --- a/doc/src/Manual_build.rst +++ b/doc/src/Manual_build.rst @@ -14,7 +14,6 @@ files. Here is a list with descriptions: lammps.1 # man page for the lammps command msi2lmp.1 # man page for the msi2lmp command Manual.pdf # large PDF version of entire manual - Developer.pdf # small PDF with info about how LAMMPS is structured LAMMPS.epub # Manual in ePUB e-book format LAMMPS.mobi # Manual in MOBI e-book format docenv # virtualenv folder for processing the manual sources @@ -35,7 +34,7 @@ of two ways: a. You can "fetch" the current HTML and PDF files from the LAMMPS web site. Just type ``make fetch``. This should download a html_www - directory and Manual_www.pdf/Developer_www.pdf files. Note that if + directory and a Manual_www.pdf file. Note that if new LAMMPS features have been added more recently than the date of your LAMMPS version, the fetched documentation will include those changes (but your source code will not, unless you update your local @@ -49,6 +48,11 @@ b. You can build the HTML or PDF files yourself, by typing ``make html`` only once, unless you type ``make clean-all``. After that, viewing and processing of the documentation can be done without internet access. +A current version of the manual (latest patch release, aka unstable branch) +is is available online at: `https://lammps.sandia.gov/doc/Manual.html `_ +A version of the manual corresponding to the ongoing development +(aka master branch) is available online at: `https://doc.lammps.org/ `_ + ---------- The generation of all documentation is managed by the Makefile in the @@ -58,10 +62,9 @@ available: .. code-block:: bash make html # generate HTML in html dir using Sphinx - make pdf # generate 2 PDF files (Manual.pdf,Developer.pdf) - # in doc dir via htmldoc and pdflatex - make fetch # fetch HTML doc pages and 2 PDF files from web site - # as a tarball and unpack into html dir and 2 PDFs + make pdf # generate PDF as Manual.pdf using Sphinx and pdflatex + make fetch # fetch HTML doc pages and PDF file from web site + # as a tarball and unpack into html dir and PDF make epub # generate LAMMPS.epub in ePUB format using Sphinx make mobi # generate LAMMPS.mobi in MOBI format using ebook-convert diff --git a/doc/src/pg_developer.rst b/doc/src/pg_developer.rst index 1ca9bcc4cc..848abc46bd 100644 --- a/doc/src/pg_developer.rst +++ b/doc/src/pg_developer.rst @@ -530,3 +530,213 @@ Where ``mine`` is the style name of your fix in the input script and automatically integrate it into the executable when compiling and find your fix class when it parses input script. +Let's write a simple fix which will print average velocity at the end +of each timestep. First of all, implement a constructor: + +.. code-block:: C++ + + FixPrintVel::FixPrintVel(LAMMPS *lmp, int narg, char **arg) + : Fix(lmp, narg, arg) + { + if (narg < 4) + error->all(FLERR,"Illegal fix print command"); + + nevery = atoi(arg[3]); + if (nevery <= 0) + error->all(FLERR,"Illegal fix print command"); + } + +In the constructor you should parse your fix arguments which are +specified in the script. All fixes have pretty the same syntax: +``fix [fix_identifier] [group_name] [fix_name] [fix_arguments]``. The +first 3 parameters are parsed by Fix base class constructor, while +``[fix_arguments]`` should be parsed by you. In our case, we need to +specify how often we want to print an average velocity. For instance, +once in 50 timesteps: ``fix 1 print/vel 50``. There is a special variable +in Fix class called nevery which specifies how often method +``end_of_step()`` is called. Thus all we need to do is just set it up. + +The next method we need to implement is ``setmask()``: + +.. code-block:: C++ + + int FixPrintVel::setmask() + { + int mask = 0; + mask |= FixConst::END_OF_STEP; + return mask; + } + +Here user specifies which methods of your fix should be called during +the execution. For instance, ``END_OF_STEP`` corresponds to the +``end_of_step()`` method. Overall, there are 8 most important methods, +methods are called in predefined order during the execution of the +verlet algorithm as was mentioned in the previous section: + +- ``initial_integrate()`` +- ``post_integrate()`` +- ``pre_exchange()`` +- ``pre_neighbor()`` +- ``pre_force()`` +- ``post_force()`` +- ``final_integrate()`` +- ``end_of_step()`` + +Fix developer must understand when he wants to execute his code. In +case if we want to write FixPrintVel, we need only end\_of\_step(): + +.. code-block:: C++ + + void FixPrintVel::end_of_step() + { + // for add3, scale3 + using namespace MathExtra; + + double** v = atom->v; + int nlocal = atom->nlocal; + double localAvgVel[4]; // 4th element for particles count + memset(localAvgVel, 0, 4 * sizeof(double)); + for (int particleInd = 0; particleInd < nlocal; ++particleInd) { + add3(localAvgVel, v[particleInd], localAvgVel); + } + localAvgVel[3] = nlocal; + double globalAvgVel[4]; + memset(globalAvgVel, 0, 4 * sizeof(double)); + MPI_Allreduce(localAvgVel, globalAvgVel, 4, MPI_DOUBLE, MPI_SUM, world); + scale3(1.0 / globalAvgVel[3], globalAvgVel); + if (comm->me == 0) { + printf("\%e, \%e, \%e\n", + globalAvgVel[0], globalAvgVel[1], globalAvgVel[2]); + } + } + +In the code above, we use MathExtra routines defined in +``math_extra.h``. There are bunch of math functions to work with +arrays of doubles as with math vectors. + +In this code we use an instance of Atom class. This object is stored +in the Pointers class (see ``pointers.h``). This object contains all +global information about the simulation system. Data from Pointers +class available to all classes inherited from it using protected +inheritance. Hence when you write you own class, which is going to use +LAMMPS data, don't forget to inherit from Pointers. When writing +fixes we inherit from class Fix which is inherited from Pointers so +there is no need to inherit from it directly. + +The code above computes average velocity for all particles in the +simulation. Yet you have one unused parameter in fix call from the +script: ``group_name``. This parameter specifies the group of atoms +used in the fix. So we should compute average for all particles in the +simulation only if ``group_name == "all"``, but it can be any group. +The group membership information of an atom is contained in the *mask* +property of and atom and the bit corresponding to a given group is +stored in the groupbit variable which is defined in Fix base class: + +.. code-block:: C++ + + for (int i = 0; i < nlocal; ++i) { + if (atom->mask[i] & groupbit) { + // Do all job here + } + } + +Class Atom encapsulates atoms positions, velocities, forces, etc. User +can access them using particle index. Note, that particle indexes are +usually changed every timestep because of sorting. + +Let us consider another Fix example: We want to have a fix which stores +atoms position from previous time step in your fix. The local atoms +indexes may not be valid on the next iteration. In order to handle +this situation there are several methods which should be implemented: + +- ``double memory_usage()``: return how much memory the fix uses (optional) +- ``void grow_arrays(int)``: do reallocation of the per particle arrays in your fix +- ``void copy_arrays(int i, int j, int delflag)``: copy i-th per-particle + information to j-th. Used when atom sorting is performed. if delflag is set + and atom j owns a body, move the body information to atom i. +- ``void set_arrays(int i)``: sets i-th particle related information to zero + +Note, that if your class implements these methods, it must call add calls of +add_callback and delete_callback to constructor and destructor. Since we want +to store positions of atoms from previous timestep, we need to add +``double** xold`` to the header file. Than add allocation code +to the constructor: + +.. code-block:: C++ + + FixSavePos::FixSavePos(LAMMPS *lmp, int narg, char **arg), xold(nullptr) + { + //... + memory->create(xold, atom->nmax, 3, "FixSavePos:x"); + atom->add_callback(0); + } + + FixSavePos::~FixSavePos() { + atom->delete_callback(id, 0); + memory->destroy(xold); + } + +Implement the aforementioned methods: + +.. code-block:: C++ + + double FixSavePos::memory_usage() + { + int nmax = atom->nmax; + double bytes = 0.0; + bytes += nmax * 3 * sizeof(double); + return bytes; + } + + void FixSavePos::grow_arrays(int nmax) + { + memory->grow(xold, nmax, 3, "FixSavePos:xold"); + } + + void FixSavePos::copy_arrays(int i, int j, int delflag) + { + memcpy(xold[j], xold[i], sizeof(double) * 3); + } + + void FixSavePos::set_arrays(int i) + { + memset(xold[i], 0, sizeof(double) * 3); + } + + int FixSavePos::pack_exchange(int i, double *buf) + { + int m = 0; + buf[m++] = xold[i][0]; + buf[m++] = xold[i][1]; + buf[m++] = xold[i][2]; + + return m; + } + + int FixSavePos::unpack_exchange(int nlocal, double *buf) + { + int m = 0; + xold[nlocal][0] = buf[m++]; + xold[nlocal][1] = buf[m++]; + xold[nlocal][2] = buf[m++]; + + return m; + } + +Now, a little bit about memory allocation. We use the Memory class which +is just a bunch of template functions for allocating 1D and 2D +arrays. So you need to add include ``memory.h`` to have access to them. + +Finally, if you need to write/read some global information used in +your fix to the restart file, you might do it by setting flag +``restart_global = 1`` in the constructor and implementing methods void +``write_restart(FILE *fp)`` and ``void restart(char *buf)``. +If, in addition, you want to write the per-atom property to restart +files additional settings and functions are needed: + +- a fix flag indicating this needs to be set ``restart_peratom = 1;`` +- ``atom->add_callback()`` and ``atom->delete_callback()`` must be called + a second time with the final argument set to 1 instead of 0 (indicating + restart processing instead of per-atom data memory management). +- the functions ``void pack_restart(int i, double *buf)`` and + ``void unpack_restart(int nlocal, int nth)`` need to be implemented