Source files
------------

The source files of the LAMMPS code are found in two
directories of the distribution: ``src`` and ``lib``.
Most of the code is C++ but there are small numbers of files
in several other languages.

The core of the code is located in the
``src`` folder and its sub-directories.
A sizable number of these files are in the ``src`` directory
itself, but there are plenty of :doc:`packages <Packages>`, which can be
included or excluded when LAMMPS is built.  See the :doc:`Include
packages in build <Build_package>` section of the manual for more
information about that part of the build process.  LAMMPS currently
supports building with :doc:`conventional makefiles <Build_make>` and
through :doc:`CMake <Build_cmake>` which differ in how packages are
enabled or disabled for a LAMMPS binary.  The source files for each
package are in all-uppercase sub-directories of the ``src`` folder, for
example ``src/MOLECULE`` or ``src/USER-MISC``.  The ``src/STUBS``
sub-directory is not a package but contains a dummy MPI library, that is
used when building a serial version of the code. The ``src/MAKE``
directory contains makefiles with settings and flags for a variety of
configuration and machines for the build process with traditional
makefiles.

The ``lib`` directory contains the source code for several supporting
libraries or files with configuration settings to use globally installed
libraries, that are required by some of the optional packages.
Each sub-directory, like ``lib/poems`` or ``lib/gpu``, contains the
source files, some of which are in different languages such as Fortran
or CUDA. 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
``src/run.cpp`` (implementation file) and ``src/run.h`` (header file).
Each pair of files defines a C++
class, for example the :cpp:class:`LAMMPS_NS::Run` class which contains
the code invoked by the :doc:`run <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. ``src/force.cpp`` and the :cpp:class:`LAMMPS_NS::Force`
class.  They are discussed in the next section.

A small number of C++ classes and utility functions are implemented with
only a ``.h`` file. Examples are the Pointer class or the MathVec functions.

Class topology
--------------

Though LAMMPS has a lot of source files and classes, its class topology
is relative flat, as outlined in the :ref:`class-topology` figure.  Each
name refers to a class and has a pair of associated source files in the
``src`` folder, for example the class :cpp:class:`LAMMPS_NS::Memory`
corresponds to the files ``memory.cpp`` and ``memory.h``, or the class
:cpp:class:`LAMMPS_NS::AtomVec` corresponds to the files
``atom_vec.cpp`` and ``atom_vec.h``.  Full lines in the figure represent
compositing: that is the class to the left holds a pointer to an
instance of the class to the right.  Dashed lines instead represent
inheritance: the class to the right is derived from the class on the
left. Classes with a red boundary are not instantiated directly, but
they represent the base classes for "styles".  Those "styles" make up
the bulk of the LAMMPS code and only a few typical examples are included
in the figure for demonstration purposes.

.. _class-topology:
.. figure:: JPG/lammps-classes.png

   LAMMPS class topology

   This figure shows some of the relations of the base classes of the
   LAMMPS simulation package.  Full lines indicate that a class holds an
   instance of the class it is pointing to; dashed lines point to
   derived classes that are given as examples of what classes may be
   instantiated during a LAMMPS run based on the input commands and
   accessed through the API define by their respective base classes.  At
   the core is the :cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class, which
   holds pointers to class instances with specific purposes.  Those may
   hold instances of other classes, sometimes directly, or only
   temporarily, sometimes as derived classes or derived classes of
   derived classes, which may also hold instances of other classes.

The :cpp:class:`LAMMPS_NS::LAMMPS` class is the topmost class and
represents what is referred to an "instance" of LAMMPS.  It is a
composite holding references to instances of other core classes
providing the core functionality of the MD engine in LAMMPS and through
them abstractions of the required operations.  The constructor of the
LAMMPS class will instantiate those instances, process the command line
flags, initialize MPI (if not already done) and set up file pointers for
input and output. The destructor will shut everything down and free all
associated memory.  Thus code for the standalone LAMMPS executable in
``main.cpp`` simply initializes MPI, instantiates a single instance of
LAMMPS, and passes it the command line flags and input script. It
deletes the LAMMPS instance after the method reading the input returns
and shuts down the MPI environment before it exits the executable.

The :cpp:class:`LAMMPS_NS::Pointers` is not shown in the
:ref:`class-topology` figure, it holds references to members of the
`LAMMPS_NS::LAMMPS`, so that all classes derived from
:cpp:class:`LAMMPS_NS::Pointers` have direct access to those reference.
From the class topology all classes with blue boundary are referenced in
this class and all classes in the second and third columns, that are not
listed as derived classes are instead derived from
:cpp:class:`LAMMPS_NS::Pointers`.

Since all storage is encapsulated, the LAMMPS class can also be
instantiated multiple times by a calling code, and that can be either
simultaneously or consecutively.  When running in parallel with MPI,
care has to be taken, that suitable communicators are used to not
create conflicts between different instances.

The LAMMPS class currently holds instances of 19 classes representing
different core functionalities There are a handful of virtual parent
classes in LAMMPS that define what LAMMPS calls ``styles``.  They are
shaded red in the :ref:`class-topology` figure.  Each of these are
parents of a number of child classes that implement the interface
defined by the parent class.  There are two main categories of these
``styles``: some may only have one instance active at a time (e.g. atom,
pair, bond, angle, dihedral, improper, kspace, comm) and there is a
dedicated pointer variable in the composite class that manages them.
Setups that require a mix of different such styles have to use a
*hybrid* class that manages and forwards calls to the corresponding
sub-styles for the designated subset of atoms or data. or the composite
class may have lists of class instances, e.g. Modify handles lists of
compute and fix styles, while Output handles dumps class instances.

The exception to this scheme are the ``command`` style classes. These
implement specific commands that can be invoked before, after, or between
runs or are commands which launch a simulation.  For these an instance
of the class is created, its command() method called and then, after
completion, the class instance deleted.  Examples for this are the
create_box, create_atoms, minimize, run, or velocity command styles.

For all those ``styles`` certain naming conventions are employed: for
the fix nve command the class is called FixNVE and the files are
``fix_nve.h`` and ``fix_nve.cpp``. Similarly for fix ave/time we have
FixAveTime and ``fix_ave_time.h`` and ``fix_ave_time.cpp``. Style names
are lower case and without spaces or special characters. A suffix or
multiple appended with a forward slash '/' denotes a variant of the
corresponding class without the suffix. To connect the style name and
the class name, LAMMPS uses macros like the following ATOM\_CLASS,
PAIR\_CLASS, BOND\_CLASS, REGION\_CLASS, FIX\_CLASS, COMPUTE\_CLASS,
or DUMP\_CLASS in the corresponding header file.  During compilation
files with the pattern ``style_name.h`` are created that contain include
statements including all headers of all styles of a given type that
are currently active (or "installed).


More details on individual classes in the :ref:`class-topology` are as
follows:

- The Memory class handles allocation of all large vectors and arrays.

- The Error class prints all error and warning messages.

- 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.

- The Input class reads and processes input input strings and files,
  stores variables, and invokes :doc:`commands <Commands_all>`.

- As discussed above, command style classes are directly derived from
  the Pointers class. They provide input script commands that perform
  one-time operations before/after/between simulations or which invoke a
  simulation.  They are instantiated from within the Input class,
  invoked, then immediately destructed.

- The Finish class is instantiated to print statistics to the screen
  after a simulation is performed, by commands like run and minimize.

- 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 :doc:`read_data <read_data>`,
  :doc:`read_restart <read_restart>`, or :doc:`replicate <replicate>`.

- The Atom class stores per-atom properties associated with atom styles.
  More precisely, they are allocated and managed by a class derived from
  the AtomVec class, and the Atom class simply stores pointers to them.
  The classes derived from AtomVec represent the different atom styles
  and they are instantiated through the :doc:`atom_style <atom_style>`
  command.

- The Update class holds instances of an integrator and a minimizer
  class.  The Integrate class is a parent style for the Verlet and
  r-RESPA time integrators, as defined by the :doc:`run_style
  <run_style>` command.  The Min class is a parent style for various
  energy minimizers.

- The Neighbor class builds and stores neighbor lists.  The NeighList
  class stores a single list (for all atoms).  A NeighRequest class
  instance is created by pair, fix, or compute styles when they need a
  particular kind of neighbor list and use the NeighRequest properties
  to select the neighbor list settings for the given request. There can
  be multiple instances of the NeighRequest class and the Neighbor class
  will try to optimize how they are computed by creating copies or
  sub-lists where possible.

- The Comm class performs inter-processor 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. There are two :doc:`communication styles
  <comm_style>` enabling different ways to do the domain decomposition.
  Sometimes the Irregular class is used, when atoms may migrate to
  arbitrary processors.

- 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 the :doc:`region <region>` and :doc:`lattice <lattice>`
  commands in an input script.

- The Force class computes various forces between atoms.  The Pair
  parent class is for non-bonded or pair-wise forces, which in LAMMPS
  also includes many-body forces such as the Tersoff 3-body potential if
  those are computed by walking pairwise neighbor lists.  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 redistribute
  and communicate grid-based information across the parallel processors.

- The Modify class stores lists of class instances derived from the
  :doc:`Fix <fix>` and :doc:`Compute <compute>` base classes.

- The Group class manipulates groups that atoms are assigned to via the
  :doc:`group <group>` command.  It also has functions to compute
  various attributes of groups of atoms.

- 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
  :doc:`Thermo <thermo_style>`, :doc:`Dump <dump>`, and
  :doc:`WriteRestart <write_restart>` classes respectively.  The Dump
  class is a base class with several derived classes implementing
  various dump style variants.

- The Timer class logs timing information, output at the end
  of a run.

.. TODO section on "Spatial decomposition and parallel operations"
..       diagram of 3d processor grid, brick vs. tiled. local vs. ghost
..       atoms, 6-way communication with pack/unpack functions,
..       PBC as part of the communication

.. TODO section on "Fixes, Computes, and Variables"
..      how and when data is computed and provided and how it is
..      referenced. flags in Fix/Compute/Variable classes tell
..      style and amount of available data.

