diff --git a/doc/src/Developer_plugins.rst b/doc/src/Developer_plugins.rst index 7275c12605..68f1f1387c 100644 --- a/doc/src/Developer_plugins.rst +++ b/doc/src/Developer_plugins.rst @@ -2,36 +2,95 @@ Writing plugins --------------- Plugins provide a mechanism to add functionality to a LAMMPS executable -without recompiling LAMMPS. This uses the operating system's -capability to load dynamic shared object (DSO) files in a way similar -shared libraries and then references specific functions those DSOs. -Any DSO file with plugins has to include an initialization function -with a specific name that has to follow specific rules. When loading -the DSO, this function is called and will then register the contained -plugin(s) with LAMMPS. +without recompiling LAMMPS. The functionality for this and the +:doc:`plugin command ` are implemented in the +:ref:`PLUGIN package ` which must be installed to use plugins. + +Plugins use the operating system's capability to load dynamic shared +object (DSO) files in a way similar shared libraries and then reference +specific functions in those DSOs. Any DSO file with plugins has to include +an initialization function with a specific name, "lammpsplugin_init", that +has to follow specific rules described below. When loading the DSO with +the "plugin" command, this function is looked up and called and will then +register the contained plugin(s) with LAMMPS. From the programmer perspective this can work because of the object -oriented design where all pair style commands are derived from the class -Pair, all fix style commands from the class Fix and so on and only -functions from those base classes are called directly. When a -:doc:`pair_style` command or :doc:`fix` command is issued a new -instance of such a derived class is created. This is done by a -so-called factory function which is mapped to the style name. Thus -when, for example, the LAMMPS processes the command -``pair_style lj/cut 2.5``, LAMMPS will look up the factory function -for creating the ``PairLJCut`` class and then execute it. The return -value of that function is a ``Pair *`` pointer and the pointer will -be assigned to the location for the currently active pair style. +oriented design of LAMMPS where all pair style commands are derived from +the class Pair, all fix style commands from the class Fix and so on and +usually only functions present in those base classes are called +directly. When a :doc:`pair_style` command or :doc:`fix` command is +issued a new instance of such a derived class is created. This is done +by a so-called factory function which is mapped to the style name. Thus +when, for example, the LAMMPS processes the command ``pair_style lj/cut +2.5``, LAMMPS will look up the factory function for creating the +``PairLJCut`` class and then execute it. The return value of that +function is a ``Pair *`` pointer and the pointer will be assigned to the +location for the currently active pair style. -A plugin thus has to implement such a factory function and register it -with LAMMPS so that it gets added to the map of available styles of -the given category. To register a plugin with LAMMPS an initialization -function has to be called that follows specific rules explained below. +A DSO file with a plugin thus has to implement such a factory function +and register it with LAMMPS so that it gets added to the map of available +styles of the given category. To register a plugin with LAMMPS an +initialization function has to be present in the DSO file called +``lammpsplugin_init`` which is called with three ``void *`` arguments: +a pointer to the current LAMMPS instance, a pointer to the opened DSO +handle, and a pointer to the registration function. The registration +function takes two arguments: a pointer to a ``lammpsplugin_t`` struct +with information about the plugin and a pointer to the current LAMMPS +instance. Please see below for an example of how the registration is +done. +Members of ``lammpsplugin_t`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -As an example, for a hypothetical pair style "morse2" implemented in a -class ``PairMorse2`` in the files ``pair_morse2.h`` and -``pair_morse2.cpp`` the file with the factory function and initialization +.. list-table:: + :header-rows: 1 + :widths: auto + + * - Member + - Description + * - version + - LAMMPS Version string the plugin was compiled for + * - style + - Style of the plugin (pair, bond, fix, command, etc.) + * - name + - Name of the plugin style + * - info + - String with information about the plugin + * - author + - String with the name and email of the author + * - creator.v1 + - Pointer to factory function for pair, bond, angle, dihedral, or improper styles + * - creator.v2 + - Pointer to factory function for compute, fix, or region styles + * - creator.v3 + - Pointer to factory function for command styles + * - handle + - Pointer to the open DSO file handle + +Only one of the three alternate creator entries can be used at a time +and which of those is determined by the style of plugin. The "creator.v1" +element is for factory functions of supported styles computing forces (i.e. +pair, bond, angle, dihedral, or improper styles) and the function takes +as single argument the pointer to the LAMMPS instance. The factory function +is cast to the ``lammpsplugin_factory1`` type before assignment. The +"creator.v2" element is for factory functions creating an instance of +a fix, compute, or region style and takes three arguments: a pointer to +the LAMMPS instance, an integer with the length of the argument list and +a ``char **`` pointer to the list of arguments. The factory function pointer +needs to be cast to the ``lammpsplugin_factory2`` type before assignment. +The "creator.v3" element takes the same arguments as "creator.v3" but is +specific to creating command styles: the factory function has to instantiate +the command style locally passing the LAMMPS pointer as argument and then +call its "command" member function with the number and list of arguments. +The factory function pointer needs to be cast to the +``lammpsplugin_factory3`` type before assignment. + +Pair style example +^^^^^^^^^^^^^^^^^^ + +As an example, a hypothetical pair style plugin "morse2" implemented in +a class ``PairMorse2`` in the files ``pair_morse2.h`` and +``pair_morse2.cpp`` with the factory function and initialization function would look like this: .. code-block:: C++ @@ -70,6 +129,10 @@ pointer to the allocated class instance derived from the ``Pair`` class. This function may be declared static to avoid clashes with other plugins. The name of the derived class, ``PairMorse2``, must be unique inside the entire LAMMPS executable. + +Fix style example +^^^^^^^^^^^^^^^^^ + If the factory function would be for a fix or compute, which take three arguments (a pointer to the LAMMPS class, the number of arguments and the list of argument strings), then the pointer type is ``lammpsplugin_factory2`` @@ -104,6 +167,8 @@ Below is an example for that: (*register_plugin)(&plugin,lmp); } +Command style example +^^^^^^^^^^^^^^^^^^^^^ For command styles there is a third variant of factory function as demonstrated in the following example, which also shows that the implementation of the plugin class may also be within the same @@ -158,6 +223,9 @@ file as the plugin interface code: (*register_plugin)(&plugin,lmp); } +Additional Details +^^^^^^^^^^^^^^^^^^ + The initialization function **must** be called ``lammpsplugin_init``, it **must** have C bindings and it takes three void pointers as arguments. The first is a pointer to the LAMMPS class that calls it and it needs to @@ -167,7 +235,7 @@ to the plugin info struct, so that the DSO can be closed and unloaded when all its contained plugins are unloaded. The third argument is a function pointer to the registration function and needs to be stored in a variable of ``lammpsplugin_regfunc`` type and then called with a -pointer to the ``lammpsplugin_`` struct and the pointer to the LAMMPS +pointer to the ``lammpsplugin_t`` struct and the pointer to the LAMMPS instance as arguments to register a single plugin. There may be multiple calls to multiple plugins in the same initialization function. diff --git a/doc/src/plugin.rst b/doc/src/plugin.rst index 48638bf97a..02228636bc 100644 --- a/doc/src/plugin.rst +++ b/doc/src/plugin.rst @@ -17,7 +17,7 @@ Syntax *load* file = load plugin(s) from shared object in *file* *unload* style name = unload plugin *name* of style *style* - *style* = *pair* or *fix* or *command* + *style* = *pair* or *bond* or *angle* or *dihedral* or *improper* or *compute* or *fix* or *region* or *command* *list* = print a list of currently loaded plugins *clear* = unload all currently loaded plugins diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 1d66028621..38a6971f4c 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1588,6 +1588,7 @@ lammps Lammps LAMMPS lammpsplot +lammpsplugin Lampis Lamoureux Lanczos