updates to the fortran module docs to make it more consistent, fix links, add example similar to C library docs

This commit is contained in:
Axel Kohlmeyer
2022-09-23 12:41:31 -04:00
parent 2a14397318
commit d9e2be4b75
3 changed files with 142 additions and 74 deletions

View File

@ -3,7 +3,9 @@ The ``LIBLAMMPS`` Fortran Module
The ``LIBLAMMPS`` module provides an interface to call LAMMPS from a The ``LIBLAMMPS`` module provides an interface to call LAMMPS from a
Fortran code. It is based on the LAMMPS C-library interface and Fortran code. It is based on the LAMMPS C-library interface and
requires a Fortran 2003 compatible compiler to be compiled. requires a Fortran 2003 compatible compiler to be compiled. It is
designed to be self-contained and not require any support functions
written in C, C++, or Fortran.
While C libraries have a defined binary interface (ABI) and can thus be While C libraries have a defined binary interface (ABI) and can thus be
used from multiple compiler versions from different vendors for as long used from multiple compiler versions from different vendors for as long
@ -19,12 +21,20 @@ for a simple program using the Fortran interface would be:
mpifort -o testlib.x lammps.f90 testlib.f90 -L. -llammps mpifort -o testlib.x lammps.f90 testlib.f90 -L. -llammps
Please note, that the MPI compiler wrapper is only required when the Please note, that the MPI compiler wrapper is only required when the
calling the library from an MPI parallel code. Please also note the calling the library from an MPI parallel code. Otherwise, using the
order of the source files: the ``lammps.f90`` file needs to be compiled fortran compiler (gfortran, ifort, flang, etc.) will suffice. It may be
first, since it provides the ``LIBLAMMPS`` module that is imported by necessary to link to additional libraries depending on how LAMMPS was
the Fortran code using the interface. A working example code can be configured and whether the LAMMPS library :doc:`was compiled as a static
found together with equivalent examples in C and C++ in the or shared library <Build_link>`.
``examples/COUPLE/simple`` folder of the LAMMPS distribution.
If the LAMMPS library itself has been compiled with MPI support, the
resulting executable will still be able to run LAMMPS in parallel with
``mpirun`` or equivalent. Please also note that the order of the source
files matters: the ``lammps.f90`` file needs to be compiled first, since
it provides the ``LIBLAMMPS`` module that is imported by the Fortran
code using the interface. A working example code can be found together
with equivalent examples in C and C++ in the ``examples/COUPLE/simple``
folder of the LAMMPS distribution.
.. versionadded:: 9Oct2020 .. versionadded:: 9Oct2020
@ -57,9 +67,10 @@ LIBLAMMPS`` statement. Internally it will call either
:cpp:func:`lammps_open_fortran` or :cpp:func:`lammps_open_no_mpi` from :cpp:func:`lammps_open_fortran` or :cpp:func:`lammps_open_no_mpi` from
the C library API to create the class instance. All arguments are the C library API to create the class instance. All arguments are
optional and :cpp:func:`lammps_mpi_init` will be called automatically, optional and :cpp:func:`lammps_mpi_init` will be called automatically,
if it is needed. Similarly, a possible call to :cpp:func:`lammps_finalize` if it is needed. Similarly, a possible call to
is integrated into the :f:func:`close` function and triggered with :cpp:func:`lammps_mpi_finalize` is integrated into the :f:func:`close`
the optional logical argument set to ``.true.``. Here is a simple example: function and triggered with the optional logical argument set to
``.true.``. Here is a simple example:
.. code-block:: fortran .. code-block:: fortran
@ -81,10 +92,10 @@ the optional logical argument set to ``.true.``. Here is a simple example:
It is also possible to pass command line flags from Fortran to C/C++ and It is also possible to pass command line flags from Fortran to C/C++ and
thus make the resulting executable behave similarly to the standalone thus make the resulting executable behave similarly to the standalone
executable (it will ignore the `-in/-i` flag, though). This allows one to executable (it will ignore the `-in/-i` flag, though). This allows
use the command line to configure accelerator and suffix settings, using the command line to configure accelerator and suffix settings,
configure screen and logfile output, or to set index style variables configure screen and logfile output, or to set index style variables
from the command line and more. Here is a correspondingly adapted from the command line and more. Here is a correspondingly adapted
version of the previous example: version of the previous example:
.. code-block:: fortran .. code-block:: fortran
@ -165,6 +176,57 @@ Below is a small demonstration of the uses of the different functions:
--------------- ---------------
Accessing system properties
===========================
The C-library interface allows the :doc:`extraction of different kinds
of information <Library_properties>` about the active simulation
instance and also - in some cases - to apply modifications to it. In
some cases, the C-library interface makes pointers to internal data
structures accessible, thus when accessing them from Fortran, special
care is needed to avoid data corruption and crashes. Thus please see
the documentation of the individual type bound procedures for details.
Below is an example demonstrating some of the possible uses.
.. code-block:: fortran
PROGRAM testprop
USE LIBLAMMPS
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t
TYPE(lammps) :: lmp
INTEGER(kind=8) :: natoms
REAL(c_double), POINTER :: dt
INTEGER(c_int64_t), POINTER :: ntimestep
REAL(kind=8) :: pe, ke
lmp = lammps()
CALL lmp%file('in.sysinit')
natoms = INT(lmp%get_natoms(),8)
WRITE(6,'(A,I8,A)') 'Running a simulation with', natoms, ' atoms'
WRITE(6,'(I8,A,I8,A,I3,A)') lmp%extract_setting('nlocal'), ' local and', &
lmp%extract_setting('nghost'), ' ghost atom. ', &
lmp%extract_setting('ntypes'), ' atom types'
CALL lmp%command('run 2 post no')
dt = lmp%extract_global('dt')
ntimestep = lmp%extract_global('ntimestep')
WRITE(6,'(A,I4,A,F4.1,A)') 'At step:', ntimestep, ' Changing timestep from', dt, ' to 0.5'
dt = 0.5
CALL lmp%command('run 2 post no')
WRITE(6,'(A,I4)') 'At step:', ntimestep
pe = lmp%get_thermo('pe')
ke = lmp%get_thermo('ke')
PRINT*, 'PE = ', pe
PRINT*, 'KE = ', ke
CALL lmp%close(.TRUE.)
END PROGRAM testprop
---------------
The ``LIBLAMMPS`` module API The ``LIBLAMMPS`` module API
**************************** ****************************
@ -292,7 +354,7 @@ Procedures Bound to the lammps Derived Type
This function will call :cpp:func:`lammps_get_natoms` and return the number This function will call :cpp:func:`lammps_get_natoms` and return the number
of atoms in the system. of atoms in the system.
:r real(C_double): number of atoms :r real(c_double): number of atoms
-------- --------
@ -302,16 +364,17 @@ Procedures Bound to the lammps Derived Type
of the corresponding thermodynamic keyword. of the corresponding thermodynamic keyword.
:p character(len=\*) name: string with the name of the thermo keyword :p character(len=\*) name: string with the name of the thermo keyword
:r real(C_double): value of the requested thermo property or 0.0_C_double :r real(c_double): value of the requested thermo property or `0.0_c_double`
-------- --------
.. f:subroutine:: extract_box([boxlo][, boxhi][, xy][, yz][, xz][, pflags][, boxflag]) .. f:subroutine:: extract_box([boxlo][, boxhi][, xy][, yz][, xz][, pflags][, boxflag])
This subroutine will call :cpp:func:`lammps_extract_box`. All parameters This subroutine will call :cpp:func:`lammps_extract_box`. All
are optional, though obviously at least one should be present. The parameters are optional, though obviously at least one should be
parameters *pflags* and *boxflag* are stored in LAMMPS as integers, but present. The parameters *pflags* and *boxflag* are stored in LAMMPS
should be declared as ``LOGICAL`` variables when calling from Fortran. as integers, but should be declared as ``LOGICAL`` variables when
calling from Fortran.
:o real(c_double) boxlo [dimension(3),optional]: vector in which to store :o real(c_double) boxlo [dimension(3),optional]: vector in which to store
lower-bounds of simulation box lower-bounds of simulation box
@ -377,17 +440,18 @@ Procedures Bound to the lammps Derived Type
.. note:: .. note::
The C library interface currently returns type "int" instead of type The C library interface currently returns type ``int`` instead of
"MPI_Fint", which is the C type corresponding to Fortran "INTEGER" type ``MPI_Fint``, which is the C type corresponding to Fortran
types of the default kind. On most compilers, these are the same anyway, ``INTEGER`` types of the default kind. On most compilers, these
but this interface exchanges values this way to avoid warning messages. are the same anyway, but this interface exchanges values this way
to avoid warning messages.
.. note:: .. note::
The MPI_F08 module, which defines Fortran 2008 bindings for MPI, is not The `MPI_F08` module, which defines Fortran 2008 bindings for MPI,
directly supported by this function. However, you should be able to is not directly supported by this function. However, you should be
convert between the two using the MPI_VAL member of the communicator. able to convert between the two using the `MPI_VAL` member of the
For example, communicator. For example,
.. code-block:: fortran .. code-block:: fortran
@ -398,14 +462,14 @@ Procedures Bound to the lammps Derived Type
! ... [commands to set up LAMMPS/etc.] ! ... [commands to set up LAMMPS/etc.]
comm%MPI_VAL = lmp%get_mpi_comm() comm%MPI_VAL = lmp%get_mpi_comm()
should assign an MPI_F08 communicator properly. should assign an `MPI_F08` communicator properly.
-------- --------
.. f:function:: extract_setting(keyword) .. f:function:: extract_setting(keyword)
Query LAMMPS about global settings. See the documentation for the Query LAMMPS about global settings. See the documentation for the
:c:func:`lammps_extract_setting` function from the C library. :cpp:func:`lammps_extract_setting` function from the C library.
:p character(len=\*) keyword: string containing the name of the thermo keyword :p character(len=\*) keyword: string containing the name of the thermo keyword
:r integer(c_int): value of the queried setting or :math:`-1` if unknown :r integer(c_int): value of the queried setting or :math:`-1` if unknown
@ -414,35 +478,36 @@ Procedures Bound to the lammps Derived Type
.. f:function:: extract_global(name) .. f:function:: extract_global(name)
This function calls :c:func:`lammps_extract_global` and returns either a This function calls :cpp:func:`lammps_extract_global` and returns
string or a pointer to internal global LAMMPS data, depending on the data either a string or a pointer to internal global LAMMPS data,
requested through *name*. depending on the data requested through *name*.
Note that this function actually does not return a value, but rather Note that this function actually does not return a value, but rather
associates the pointer on the left side of the assignment to point associates the pointer on the left side of the assignment to point to
to internal LAMMPS data (with the exception of string data, which are internal LAMMPS data (with the exception of string data, which are
copied and returned as ordinary Fortran strings). Pointers must be of the copied and returned as ordinary Fortran strings). Pointers must be of
correct data type to point to said data (typically INTEGER(c_int), the correct data type to point to said data (typically
INTEGER(c_int64_t), or REAL(c_double)) and have compatible kind and rank. ``INTEGER(c_int)``, ``INTEGER(c_int64_t)``, or ``REAL(c_double)``)
The pointer being associated with LAMMPS data is type-, kind-, and and have compatible kind and rank. The pointer being associated with
rank-checked at run-time via an overloaded assignment operator. LAMMPS data is type-, kind-, and rank-checked at run-time via an
The pointers returned by this function are generally persistent; therefore overloaded assignment operator. The pointers returned by this
it is not necessary to call the function again, unless a :doc:`clear` function are generally persistent; therefore it is not necessary to
command has been issued, which wipes out and recreates the contents of call the function again, unless a :doc:`clear` command has been
the :cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class. issued, which wipes out and recreates the contents of the
:cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class.
For example, For example,
.. code-block:: fortran .. code-block:: fortran
PROGRAM demo PROGRAM demo
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int64_t
USE LIBLAMMPS USE LIBLAMMPS
TYPE(lammps) :: lmp TYPE(lammps) :: lmp
INTEGER(C_int), POINTER :: nlocal INTEGER(c_int), POINTER :: nlocal
INTEGER(C_int64_t), POINTER :: ntimestep INTEGER(c_int64_t), POINTER :: ntimestep
CHARACTER(LEN=10) :: units CHARACTER(LEN=10) :: units
REAL(C_double), POINTER :: dt REAL(c_double), POINTER :: dt
lmp = lammps() lmp = lammps()
! other commands ! other commands
nlocal = lmp%extract_global('nlocal') nlocal = lmp%extract_global('nlocal')
@ -457,11 +522,13 @@ Procedures Bound to the lammps Derived Type
the size of the current time step, and the units being used into the the size of the current time step, and the units being used into the
variables *nlocal*, *ntimestep*, *dt*, and *units*, respectively. variables *nlocal*, *ntimestep*, *dt*, and *units*, respectively.
*Note*: if this function returns a string, the string must have .. note::
length greater than or equal to the length of the string (not including the
terminal NULL character) that LAMMPS returns. If the variable's length is if this function returns a string, the string must have
too short, the string will be truncated. As usual in Fortran, strings length greater than or equal to the length of the string (not including the
are padded with spaces at the end. terminal NULL character) that LAMMPS returns. If the variable's length is
too short, the string will be truncated. As usual in Fortran, strings
are padded with spaces at the end.
:p character(len=\*) name: string with the name of the extracted property :p character(len=\*) name: string with the name of the extracted property
:r polymorphic: pointer to LAMMPS data. The left-hand side of the assignment :r polymorphic: pointer to LAMMPS data. The left-hand side of the assignment
@ -469,11 +536,11 @@ Procedures Bound to the lammps Derived Type
pointer (e.g., ``INTEGER (c_int), POINTER :: nlocal``) to the extracted pointer (e.g., ``INTEGER (c_int), POINTER :: nlocal``) to the extracted
property. If expecting vector data, the pointer should have dimension ":". property. If expecting vector data, the pointer should have dimension ":".
.. warning:: .. warning::
Modifying the data in the location pointed to by the returned pointer Modifying the data in the location pointed to by the returned pointer
may lead to inconsistent internal data and thus may cause failures or may lead to inconsistent internal data and thus may cause failures or
crashes or bogus simulations. In general it is thus usually better crashes or bogus simulations. In general it is thus usually better
to use a LAMMPS input command that sets or changes these parameters. to use a LAMMPS input command that sets or changes these parameters.
Those will take care of all side effects and necessary updates of Those will take care of all side effects and necessary updates of
settings derived from such settings. settings derived from such settings.

View File

@ -15,21 +15,21 @@ This section documents the following functions:
-------------------- --------------------
The library interface allows extraction of different kinds of The library interface allows the extraction of different kinds of
information about the active simulation instance and also information about the active simulation instance and also - in some
modifications to it. This enables combining of a LAMMPS simulation cases - to apply modifications to it. This enables combining of a
with other processing and simulation methods computed by the calling LAMMPS simulation with other processing and simulation methods computed
code, or by another code that is coupled to LAMMPS via the library by the calling code, or by another code that is coupled to LAMMPS via
interface. In some cases the data returned is direct reference to the the library interface. In some cases the data returned is direct
original data inside LAMMPS, cast to a void pointer. In that case the reference to the original data inside LAMMPS, cast to a void pointer.
data needs to be cast to a suitable pointer for the calling program to In that case the data needs to be cast to a suitable pointer for the
access it, and you may need to know the correct dimensions and calling program to access it, and you may need to know the correct
lengths. This also means you can directly change those value(s) from dimensions and lengths. This also means you can directly change those
the calling program, e.g. to modify atom positions. Of course, this value(s) from the calling program, e.g. to modify atom positions. Of
should be done with care. When accessing per-atom data, please note course, this should be done with care. When accessing per-atom data,
that this data is the per-processor **local** data and is indexed please note that this data is the per-processor **local** data and is
accordingly. Per-atom data can change sizes and ordering at every indexed accordingly. Per-atom data can change sizes and ordering at
neighbor list rebuild or atom sort event as atoms migrate between every neighbor list rebuild or atom sort event as atoms migrate between
sub-domains and processors. sub-domains and processors.
.. code-block:: C .. code-block:: C

View File

@ -1094,6 +1094,7 @@ flagHI
flaglog flaglog
flagN flagN
flagVF flagVF
flang
fld fld
floralwhite floralwhite
Florez Florez