mirror of https://github.com/lammps/lammps.git
Merge pull request #3396 from hammondkd/fortran-tinkering
Expanding the Fortran interface
This commit is contained in:
commit
a4796dd872
|
@ -3,7 +3,9 @@ The ``LIBLAMMPS`` Fortran Module
|
|||
|
||||
The ``LIBLAMMPS`` module provides an interface to call LAMMPS from a
|
||||
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
|
||||
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
|
||||
|
||||
Please note, that the MPI compiler wrapper is only required when the
|
||||
calling the library from an MPI parallel code. Please also note the
|
||||
order of the source files: 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.
|
||||
calling the library from an MPI parallel code. Otherwise, using the
|
||||
fortran compiler (gfortran, ifort, flang, etc.) will suffice. It may be
|
||||
necessary to link to additional libraries depending on how LAMMPS was
|
||||
configured and whether the LAMMPS library :doc:`was compiled as a static
|
||||
or shared library <Build_link>`.
|
||||
|
||||
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
|
||||
|
||||
|
@ -49,17 +59,18 @@ found together with equivalent examples in C and C++ in the
|
|||
Creating or deleting a LAMMPS object
|
||||
************************************
|
||||
|
||||
With the Fortran interface the creation of a :cpp:class:`LAMMPS
|
||||
With the Fortran interface, the creation of a :cpp:class:`LAMMPS
|
||||
<LAMMPS_NS::LAMMPS>` instance is included in the constructor for
|
||||
creating the :f:func:`lammps` derived type. To import the definition of
|
||||
that type and its type bound procedures you need to add a ``USE
|
||||
that type and its type bound procedures, you need to add a ``USE
|
||||
LIBLAMMPS`` statement. Internally it will call either
|
||||
: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
|
||||
optional and :cpp:func:`lammps_mpi_init` will be called automatically,
|
||||
if it is needed. Similarly, a possible call to :cpp:func:`lammps_finalize`
|
||||
is integrated into the :f:func:`close` function and triggered with
|
||||
the optional logical argument set to ``.true.``. Here is a simple example:
|
||||
if it is needed. Similarly, a possible call to
|
||||
:cpp:func:`lammps_mpi_finalize` is integrated into the :f:func:`close`
|
||||
function and triggered with the optional logical argument set to
|
||||
``.true.``. Here is a simple example:
|
||||
|
||||
.. code-block:: fortran
|
||||
|
||||
|
@ -80,11 +91,11 @@ the optional logical argument set to ``.true.``. Here is a simple example:
|
|||
END PROGRAM testlib
|
||||
|
||||
It is also possible to pass command line flags from Fortran to C/C++ and
|
||||
thus make the resulting executable behave similar to the standalone
|
||||
executable (it will ignore the `-in/-i` flag, though). This allows to
|
||||
use the command line to configure accelerator and suffix settings,
|
||||
thus make the resulting executable behave similarly to the standalone
|
||||
executable (it will ignore the `-in/-i` flag, though). This allows
|
||||
using the command line to configure accelerator and suffix settings,
|
||||
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:
|
||||
|
||||
.. code-block:: fortran
|
||||
|
@ -117,13 +128,13 @@ version of the previous example:
|
|||
--------------------
|
||||
|
||||
Executing LAMMPS commands
|
||||
=========================
|
||||
*************************
|
||||
|
||||
Once a LAMMPS instance is created, it is possible to "drive" the LAMMPS
|
||||
simulation by telling LAMMPS to read commands from a file, or pass
|
||||
simulation by telling LAMMPS to read commands from a file or to pass
|
||||
individual or multiple commands from strings or lists of strings. This
|
||||
is done similar to how it is implemented in the `C-library
|
||||
<pg_lib_execute>` interface. Before handing off the calls to the
|
||||
is done similarly to how it is implemented in the :doc:`C-library
|
||||
interface <Library_execute>`. Before handing off the calls to the
|
||||
C-library interface, the corresponding Fortran versions of the calls
|
||||
(:f:func:`file`, :f:func:`command`, :f:func:`commands_list`, and
|
||||
:f:func:`commands_string`) have to make a copy of the strings passed as
|
||||
|
@ -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
|
||||
****************************
|
||||
|
||||
|
@ -178,14 +240,24 @@ of the contents of the ``LIBLAMMPS`` Fortran interface to LAMMPS.
|
|||
class instance that any of the included calls are forwarded to.
|
||||
|
||||
:f c_ptr handle: reference to the LAMMPS class
|
||||
:f close: :f:func:`close`
|
||||
:f version: :f:func:`version`
|
||||
:f file: :f:func:`file`
|
||||
:f command: :f:func:`command`
|
||||
:f commands_list: :f:func:`commands_list`
|
||||
:f commands_string: :f:func:`commands_string`
|
||||
:f subroutine close: :f:func:`close`
|
||||
:f subroutine error: :f:func:`error`
|
||||
:f function version: :f:func:`version`
|
||||
:f subroutine file: :f:func:`file`
|
||||
:f subroutine command: :f:func:`command`
|
||||
:f subroutine commands_list: :f:func:`commands_list`
|
||||
:f subroutine commands_string: :f:func:`commands_string`
|
||||
:f function get_natoms: :f:func:`get_natoms`
|
||||
:f function get_thermo: :f:func:`get_thermo`
|
||||
:f subroutine extract_box: :f:func:`extract_box`
|
||||
:f subroutine reset_box: :f:func:`reset_box`
|
||||
:f subroutine memory_usage: :f:func:`memory_usage`
|
||||
:f function extract_setting: :f:func:`extract_setting`
|
||||
:f function extract_global: :f:func:`extract_global`
|
||||
|
||||
.. f:function:: lammps(args[,comm])
|
||||
--------
|
||||
|
||||
.. f:function:: lammps([args][,comm])
|
||||
|
||||
This is the constructor for the Fortran class and will forward
|
||||
the arguments to a call to either :cpp:func:`lammps_open_fortran`
|
||||
|
@ -198,10 +270,31 @@ of the contents of the ``LIBLAMMPS`` Fortran interface to LAMMPS.
|
|||
If *comm* is not provided, ``MPI_COMM_WORLD`` is assumed. For
|
||||
more details please see the documentation of :cpp:func:`lammps_open`.
|
||||
|
||||
:p character(len=*) args(*) [optional]: arguments as list of strings
|
||||
:o character(len=\*) args(\*) [optional]: arguments as list of strings
|
||||
:o integer comm [optional]: MPI communicator
|
||||
:r lammps: an instance of the :f:type:`lammps` derived type
|
||||
|
||||
.. note::
|
||||
|
||||
The ``MPI_F08`` module, which defines Fortran 2008 bindings for MPI,
|
||||
is not directly supported by this interface due to the complexities of
|
||||
supporting both the ``MPI_F08`` and ``MPI`` modules at the same time.
|
||||
However, you should be able to use the ``MPI_VAL`` member of the
|
||||
``MPI_comm`` derived type to access the integer value of the
|
||||
communicator, such as in
|
||||
|
||||
.. code-block:: Fortran
|
||||
|
||||
PROGRAM testmpi
|
||||
USE LIBLAMMPS
|
||||
USE MPI_F08
|
||||
TYPE(lammps) :: lmp
|
||||
lmp = lammps(MPI_COMM_SELF%MPI_VAL)
|
||||
END PROGRAM testmpi
|
||||
|
||||
Procedures Bound to the lammps Derived Type
|
||||
===========================================
|
||||
|
||||
.. f:subroutine:: close([finalize])
|
||||
|
||||
This method will close down the LAMMPS instance through calling
|
||||
|
@ -211,6 +304,20 @@ of the contents of the ``LIBLAMMPS`` Fortran interface to LAMMPS.
|
|||
|
||||
:o logical finalize [optional]: shut down the MPI environment of the LAMMPS library if true.
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: error(error_type, error_text)
|
||||
|
||||
This method is a wrapper around the :cpp:func:`lammps_error` function and will dispatch
|
||||
an error through the LAMMPS Error class.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:p integer error_type: constant to select which Error class function to call
|
||||
:p character(len=\*) error_text: error message
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: version()
|
||||
|
||||
This method returns the numeric LAMMPS version like :cpp:func:`lammps_version`
|
||||
|
@ -224,25 +331,243 @@ of the contents of the ``LIBLAMMPS`` Fortran interface to LAMMPS.
|
|||
This method will call :cpp:func:`lammps_file` to have LAMMPS read
|
||||
and process commands from a file.
|
||||
|
||||
:p character(len=*) filename: name of file with LAMMPS commands
|
||||
:p character(len=\*) filename: name of file with LAMMPS commands
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: command(cmd)
|
||||
|
||||
This method will call :cpp:func:`lammps_command` to have LAMMPS
|
||||
execute a single command.
|
||||
|
||||
:p character(len=*) cmd: single LAMMPS command
|
||||
:p character(len=\*) cmd: single LAMMPS command
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: commands_list(cmds)
|
||||
|
||||
This method will call :cpp:func:`lammps_commands_list` to have LAMMPS
|
||||
execute a list of input lines.
|
||||
|
||||
:p character(len=*) cmd(:): list of LAMMPS input lines
|
||||
:p character(len=\*) cmd(:): list of LAMMPS input lines
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: commands_string(str)
|
||||
|
||||
This method will call :cpp:func:`lammps_commands_string` to have LAMMPS
|
||||
execute a block of commands from a string.
|
||||
|
||||
:p character(len=*) str: LAMMPS input in string
|
||||
:p character(len=\*) str: LAMMPS input in string
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: get_natoms()
|
||||
|
||||
This function will call :cpp:func:`lammps_get_natoms` and return the number
|
||||
of atoms in the system.
|
||||
|
||||
:r real(c_double): number of atoms
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: get_thermo(name)
|
||||
|
||||
This function will call :cpp:func:`lammps_get_thermo` and return the value
|
||||
of the corresponding thermodynamic keyword.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
: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`
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: extract_box([boxlo][, boxhi][, xy][, yz][, xz][, pflags][, boxflag])
|
||||
|
||||
This subroutine will call :cpp:func:`lammps_extract_box`. All
|
||||
parameters are optional, though obviously at least one should be
|
||||
present. The parameters *pflags* and *boxflag* are stored in LAMMPS
|
||||
as integers, but should be declared as ``LOGICAL`` variables when
|
||||
calling from Fortran.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:o real(c_double) boxlo [dimension(3),optional]: vector in which to store
|
||||
lower-bounds of simulation box
|
||||
:o real(c_double) boxhi [dimension(3),optional]: vector in which to store
|
||||
upper-bounds of simulation box
|
||||
:o real(c_double) xy [optional]: variable in which to store *xy* tilt factor
|
||||
:o real(c_double) yz [optional]: variable in which to store *yz* tilt factor
|
||||
:o real(c_double) xz [optional]: variable in which to store *xz* tilt factor
|
||||
:o logical pflags [dimension(3),optional]: vector in which to store
|
||||
periodicity flags (``.TRUE.`` means periodic in that dimension)
|
||||
:o logical boxflag [optional]: variable in which to store boolean denoting
|
||||
whether the box will change during a simulation
|
||||
(``.TRUE.`` means box will change)
|
||||
|
||||
.. note::
|
||||
|
||||
Note that a frequent use case of this function is to extract only one or
|
||||
more of the options rather than all seven. For example, assuming "lmp"
|
||||
represents a properly-initialized LAMMPS instance, the following code will
|
||||
extract the periodic box settings into the variable "periodic":
|
||||
|
||||
.. code-block:: Fortran
|
||||
|
||||
! code to start up
|
||||
logical :: periodic(3)
|
||||
! code to initialize LAMMPS / run things / etc.
|
||||
call lmp%extract_box(pflags = periodic)
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: reset_box(boxlo, boxhi, xy, yz, xz)
|
||||
|
||||
This subroutine will call :cpp:func:`lammps_reset_box`. All parameters
|
||||
are required.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:p real(c_double) boxlo [dimension(3)]: vector of three doubles containing
|
||||
the lower box boundary
|
||||
:p real(c_double) boxhi [dimension(3)]: vector of three doubles containing
|
||||
the upper box boundary
|
||||
:p real(c_double) xy: *x--y* tilt factor
|
||||
:p real(c_double) yz: *y--z* tilt factor
|
||||
:p real(c_double) xz: *x--z* tilt factor
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: memory_usage(meminfo)
|
||||
|
||||
This subroutine will call :cpp:func:`lammps_memory_usage` and store the
|
||||
result in the three-element array *meminfo*.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:p real(c_double) meminfo [dimension(3)]: vector of three doubles in which
|
||||
to store memory usage data
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: get_mpi_comm()
|
||||
|
||||
This function returns a Fortran representation of the LAMMPS "world"
|
||||
communicator.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:r integer: Fortran integer equivalent to the MPI communicator LAMMPS is
|
||||
using
|
||||
|
||||
.. note::
|
||||
|
||||
The C library interface currently returns type ``int`` instead of
|
||||
type ``MPI_Fint``, which is the C type corresponding to Fortran
|
||||
``INTEGER`` types of the default kind. On most compilers, these
|
||||
are the same anyway, but this interface exchanges values this way
|
||||
to avoid warning messages.
|
||||
|
||||
.. note::
|
||||
|
||||
The `MPI_F08` module, which defines Fortran 2008 bindings for MPI,
|
||||
is not directly supported by this function. However, you should be
|
||||
able to convert between the two using the `MPI_VAL` member of the
|
||||
communicator. For example,
|
||||
|
||||
.. code-block:: fortran
|
||||
|
||||
USE MPI_F08
|
||||
USE LIBLAMMPS
|
||||
TYPE (LAMMPS) :: lmp
|
||||
TYPE (MPI_Comm) :: comm
|
||||
! ... [commands to set up LAMMPS/etc.]
|
||||
comm%MPI_VAL = lmp%get_mpi_comm()
|
||||
|
||||
should assign an `MPI_F08` communicator properly.
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: extract_setting(keyword)
|
||||
|
||||
Query LAMMPS about global settings. See the documentation for the
|
||||
:cpp:func:`lammps_extract_setting` function from the C library.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
: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
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: extract_global(name)
|
||||
|
||||
This function calls :cpp:func:`lammps_extract_global` and returns
|
||||
either a string or a pointer to internal global LAMMPS data,
|
||||
depending on the data requested through *name*.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
Note that this function actually does not return a value, but rather
|
||||
associates the pointer on the left side of the assignment to point to
|
||||
internal LAMMPS data (with the exception of string data, which are
|
||||
copied and returned as ordinary Fortran strings). Pointers must be of
|
||||
the correct data type to point to said data (typically
|
||||
``INTEGER(c_int)``, ``INTEGER(c_int64_t)``, or ``REAL(c_double)``)
|
||||
and have compatible kind and rank. The pointer being associated with
|
||||
LAMMPS data is type-, kind-, and rank-checked at run-time via an
|
||||
overloaded assignment operator. The pointers returned by this
|
||||
function are generally persistent; therefore it is not necessary to
|
||||
call the function again, unless a :doc:`clear` command has been
|
||||
issued, which wipes out and recreates the contents of the
|
||||
:cpp:class:`LAMMPS <LAMMPS_NS::LAMMPS>` class.
|
||||
|
||||
For example,
|
||||
|
||||
.. code-block:: fortran
|
||||
|
||||
PROGRAM demo
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int64_t
|
||||
USE LIBLAMMPS
|
||||
TYPE(lammps) :: lmp
|
||||
INTEGER(c_int), POINTER :: nlocal
|
||||
INTEGER(c_int64_t), POINTER :: ntimestep
|
||||
CHARACTER(LEN=10) :: units
|
||||
REAL(c_double), POINTER :: dt
|
||||
lmp = lammps()
|
||||
! other commands
|
||||
nlocal = lmp%extract_global('nlocal')
|
||||
ntimestep = lmp%extract_global('ntimestep')
|
||||
dt = lmp%extract_global('dt')
|
||||
units = lmp%extract_global('units')
|
||||
! more commands
|
||||
lmp.close(.TRUE.)
|
||||
END PROGRAM demo
|
||||
|
||||
would extract the number of atoms on this processor, the current time step,
|
||||
the size of the current time step, and the units being used into the
|
||||
variables *nlocal*, *ntimestep*, *dt*, and *units*, respectively.
|
||||
|
||||
.. note::
|
||||
|
||||
if this function returns a string, the string must have
|
||||
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
|
||||
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
|
||||
:r polymorphic: pointer to LAMMPS data. The left-hand side of the assignment
|
||||
should be either a string (if expecting string data) or a C-compatible
|
||||
pointer (e.g., ``INTEGER (c_int), POINTER :: nlocal``) to the extracted
|
||||
property. If expecting vector data, the pointer should have dimension ":".
|
||||
|
||||
.. warning::
|
||||
|
||||
Modifying the data in the location pointed to by the returned pointer
|
||||
may lead to inconsistent internal data and thus may cause failures or
|
||||
crashes or bogus simulations. In general it is thus usually better
|
||||
to use a LAMMPS input command that sets or changes these parameters.
|
||||
Those will take care of all side effects and necessary updates of
|
||||
settings derived from such settings.
|
||||
|
|
|
@ -11,6 +11,7 @@ This section documents the following functions:
|
|||
- :cpp:func:`lammps_mpi_finalize`
|
||||
- :cpp:func:`lammps_kokkos_finalize`
|
||||
- :cpp:func:`lammps_python_finalize`
|
||||
- :cpp:func:`lammps_error`
|
||||
|
||||
--------------------
|
||||
|
||||
|
@ -115,3 +116,8 @@ calling program.
|
|||
|
||||
.. doxygenfunction:: lammps_python_finalize
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_error
|
||||
:project: progguide
|
||||
|
|
|
@ -15,21 +15,21 @@ This section documents the following functions:
|
|||
|
||||
--------------------
|
||||
|
||||
The library interface allows extraction of different kinds of
|
||||
information about the active simulation instance and also
|
||||
modifications to it. This enables combining of a LAMMPS simulation
|
||||
with other processing and simulation methods computed by the calling
|
||||
code, or by another code that is coupled to LAMMPS via the library
|
||||
interface. In some cases the data returned is direct reference to the
|
||||
original data inside LAMMPS, cast to a void pointer. In that case the
|
||||
data needs to be cast to a suitable pointer for the calling program to
|
||||
access it, and you may need to know the correct dimensions and
|
||||
lengths. This also means you can directly change those value(s) from
|
||||
the calling program, e.g. to modify atom positions. Of course, this
|
||||
should be done with care. When accessing per-atom data, please note
|
||||
that this data is the per-processor **local** data and is indexed
|
||||
accordingly. Per-atom data can change sizes and ordering at every
|
||||
neighbor list rebuild or atom sort event as atoms migrate between
|
||||
The library interface allows the extraction of different kinds of
|
||||
information about the active simulation instance and also - in some
|
||||
cases - to apply modifications to it. This enables combining of a
|
||||
LAMMPS simulation with other processing and simulation methods computed
|
||||
by the calling code, or by another code that is coupled to LAMMPS via
|
||||
the library interface. In some cases the data returned is direct
|
||||
reference to the original data inside LAMMPS, cast to a void pointer.
|
||||
In that case the data needs to be cast to a suitable pointer for the
|
||||
calling program to access it, and you may need to know the correct
|
||||
dimensions and lengths. This also means you can directly change those
|
||||
value(s) from the calling program, e.g. to modify atom positions. Of
|
||||
course, this should be done with care. When accessing per-atom data,
|
||||
please note that this data is the per-processor **local** data and is
|
||||
indexed accordingly. Per-atom data can change sizes and ordering at
|
||||
every neighbor list rebuild or atom sort event as atoms migrate between
|
||||
sub-domains and processors.
|
||||
|
||||
.. code-block:: C
|
||||
|
|
|
@ -1081,6 +1081,7 @@ filesystems
|
|||
Fily
|
||||
Fincham
|
||||
Finchham
|
||||
Fint
|
||||
fingerprintconstants
|
||||
fingerprintsperelement
|
||||
Finnis
|
||||
|
@ -1093,6 +1094,7 @@ flagHI
|
|||
flaglog
|
||||
flagN
|
||||
flagVF
|
||||
flang
|
||||
fld
|
||||
floralwhite
|
||||
Florez
|
||||
|
|
|
@ -3,9 +3,9 @@ and allows the LAMMPS library interface to be invoked from Fortran codes.
|
|||
It requires a Fortran compiler that supports the Fortran 2003 standard.
|
||||
|
||||
This interface is based on and supersedes the previous Fortran interfaces
|
||||
in the examples/COUPLE/fortran* folders. But is fully supported by the
|
||||
in the examples/COUPLE/fortran* folders, but is fully supported by the
|
||||
LAMMPS developers and included in the documentation and unit testing.
|
||||
|
||||
Details on this Fortran interface and how to build programs using it
|
||||
are in the manual in the doc/html/pg_fortran.html file.
|
||||
are in the manual in the doc/html/Fortran.html file.
|
||||
|
||||
|
|
|
@ -19,117 +19,358 @@
|
|||
! Karl D. Hammond <hammondkd@missouri.edu>
|
||||
! University of Missouri, 2012-2020
|
||||
!
|
||||
! The Fortran module tries to follow the API of the C-library interface
|
||||
! closely, but like the Python wrapper it employs an object oriented
|
||||
! approach. To accommodate the object oriented approach, all exported
|
||||
! subroutine and functions have to be implemented in Fortran to then
|
||||
! call the interfaced C style functions with adapted calling conventions
|
||||
! as needed. The C-library interfaced functions retain their names
|
||||
! starting with "lammps_" while the Fortran versions start with "lmp_".
|
||||
! The Fortran module tries to follow the API of the C library interface
|
||||
! closely, but like the Python wrapper it employs an object-oriented
|
||||
! approach. To accommodate the object-oriented approach, all exported
|
||||
! subroutines and functions have to be implemented in Fortran and
|
||||
! call the interfaced C-style functions with adapted calling conventions
|
||||
! as needed. The C library interface functions retain their names
|
||||
! starting with "lammps_", while the Fortran versions start with "lmp_".
|
||||
!
|
||||
MODULE LIBLAMMPS
|
||||
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_ptr, c_null_ptr, c_loc, &
|
||||
c_int, c_char, c_null_char, c_double, c_size_t, c_f_pointer
|
||||
c_int, c_int64_t, c_char, c_null_char, c_double, c_size_t, c_f_pointer
|
||||
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : ERROR_UNIT
|
||||
|
||||
IMPLICIT NONE
|
||||
PRIVATE
|
||||
PUBLIC :: lammps
|
||||
PUBLIC :: lammps, ASSIGNMENT(=)
|
||||
|
||||
! Data type constants for extracting data from global, atom, compute, and fix
|
||||
!
|
||||
! Must be kept in sync with the equivalent declarations in
|
||||
! src/library.h and python/lammps/constants.py
|
||||
!
|
||||
! NOT part of the API (the part the user sees)
|
||||
INTEGER (c_int), PARAMETER :: &
|
||||
LAMMPS_INT = 0, & ! 32-bit integer (array)
|
||||
LAMMPS_INT_2D = 1, & ! two-dimensional 32-bit integer array
|
||||
LAMMPS_DOUBLE = 2, & ! 64-bit double (array)
|
||||
LAMMPS_DOUBLE_2D = 3, & ! two-dimensional 64-bit double array
|
||||
LAMMPS_INT64 = 4, & ! 64-bit integer (array)
|
||||
LAMMPS_INT64_2D = 5, & ! two-dimensional 64-bit integer array
|
||||
LAMMPS_STRING = 6 ! C-String
|
||||
|
||||
TYPE lammps
|
||||
TYPE(c_ptr) :: handle
|
||||
CONTAINS
|
||||
PROCEDURE :: close => lmp_close
|
||||
PROCEDURE :: error => lmp_error
|
||||
PROCEDURE :: file => lmp_file
|
||||
PROCEDURE :: command => lmp_command
|
||||
PROCEDURE :: commands_list => lmp_commands_list
|
||||
PROCEDURE :: commands_string => lmp_commands_string
|
||||
PROCEDURE :: version => lmp_version
|
||||
PROCEDURE :: get_natoms => lmp_get_natoms
|
||||
PROCEDURE :: get_thermo => lmp_get_thermo
|
||||
PROCEDURE :: extract_box => lmp_extract_box
|
||||
PROCEDURE :: reset_box => lmp_reset_box
|
||||
PROCEDURE :: memory_usage => lmp_memory_usage
|
||||
PROCEDURE :: get_mpi_comm => lmp_get_mpi_comm
|
||||
PROCEDURE :: extract_setting => lmp_extract_setting
|
||||
PROCEDURE :: extract_global => lmp_extract_global
|
||||
PROCEDURE :: version => lmp_version
|
||||
PROCEDURE :: is_running => lmp_is_running
|
||||
END TYPE lammps
|
||||
|
||||
INTERFACE lammps
|
||||
MODULE PROCEDURE lmp_open
|
||||
MODULE PROCEDURE lmp_open
|
||||
END INTERFACE lammps
|
||||
|
||||
! Constants to use in working with lammps_data
|
||||
ENUM, BIND(C)
|
||||
ENUMERATOR :: DATA_INT, DATA_INT_1D, DATA_INT_2D
|
||||
ENUMERATOR :: DATA_INT64, DATA_INT64_1D, DATA_INT64_2D
|
||||
ENUMERATOR :: DATA_DOUBLE, DATA_DOUBLE_1D, DATA_DOUBLE_2D
|
||||
ENUMERATOR :: DATA_STRING
|
||||
END ENUM
|
||||
|
||||
! Derived type for receiving LAMMPS data (in lieu of the ability to type cast
|
||||
! pointers)
|
||||
TYPE lammps_data
|
||||
INTEGER(c_int) :: datatype
|
||||
INTEGER(c_int), POINTER :: i32
|
||||
INTEGER(c_int), DIMENSION(:), POINTER :: i32_vec
|
||||
INTEGER(c_int64_t), POINTER :: i64
|
||||
INTEGER(c_int64_t), DIMENSION(:), POINTER :: i64_vec
|
||||
REAL(c_double), POINTER :: r64
|
||||
REAL(c_double), DIMENSION(:), POINTER :: r64_vec
|
||||
CHARACTER(LEN=:), ALLOCATABLE :: str
|
||||
END TYPE lammps_data
|
||||
|
||||
! This overloads the assignment operator (=) so that assignments of the
|
||||
! form
|
||||
! nlocal = extract_global('nlocal')
|
||||
! which are of the form "pointer to double = type(lammps_data)" result in
|
||||
! re-associating the pointer on the left with the appropriate piece of
|
||||
! LAMMPS data (after checking type-compatibility)
|
||||
INTERFACE ASSIGNMENT(=)
|
||||
MODULE PROCEDURE assign_int_to_lammps_data, assign_int64_to_lammps_data, &
|
||||
assign_intvec_to_lammps_data, &
|
||||
assign_double_to_lammps_data, assign_doublevec_to_lammps_data, &
|
||||
assign_string_to_lammps_data
|
||||
END INTERFACE
|
||||
|
||||
! interface definitions for calling functions in library.cpp
|
||||
INTERFACE
|
||||
FUNCTION lammps_open(argc, argv, comm) BIND(C, name='lammps_open_fortran')
|
||||
IMPORT :: c_ptr, c_int
|
||||
INTEGER(c_int), VALUE, INTENT(in) :: argc, comm
|
||||
TYPE(c_ptr), DIMENSION(*), INTENT(in) :: argv
|
||||
TYPE(c_ptr) :: lammps_open
|
||||
END FUNCTION lammps_open
|
||||
FUNCTION lammps_open(argc, argv, comm) BIND(C,name='lammps_open_fortran')
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
INTEGER(c_int), VALUE, INTENT(IN) :: argc, comm
|
||||
TYPE(c_ptr), DIMENSION(*), INTENT(IN) :: argv
|
||||
TYPE(c_ptr) :: lammps_open
|
||||
END FUNCTION lammps_open
|
||||
|
||||
FUNCTION lammps_open_no_mpi(argc, argv, handle) BIND(C, name='lammps_open_no_mpi')
|
||||
IMPORT :: c_ptr, c_int
|
||||
INTEGER(c_int), VALUE, INTENT(in) :: argc
|
||||
TYPE(c_ptr), DIMENSION(*), INTENT(in) :: argv
|
||||
TYPE(c_ptr), VALUE, INTENT(in) :: handle
|
||||
TYPE(c_ptr) :: lammps_open_no_mpi
|
||||
END FUNCTION lammps_open_no_mpi
|
||||
FUNCTION lammps_open_no_mpi(argc, argv, handle) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
INTEGER(c_int), VALUE, INTENT(IN) :: argc
|
||||
TYPE(c_ptr), DIMENSION(*), INTENT(IN) :: argv
|
||||
TYPE(c_ptr), VALUE, INTENT(IN) :: handle
|
||||
TYPE(c_ptr) :: lammps_open_no_mpi
|
||||
END FUNCTION lammps_open_no_mpi
|
||||
|
||||
SUBROUTINE lammps_close(handle) BIND(C, name='lammps_close')
|
||||
IMPORT :: c_ptr
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
END SUBROUTINE lammps_close
|
||||
SUBROUTINE lammps_close(handle) BIND(C)
|
||||
IMPORT :: c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
END SUBROUTINE lammps_close
|
||||
|
||||
SUBROUTINE lammps_mpi_init() BIND(C, name='lammps_mpi_init')
|
||||
END SUBROUTINE lammps_mpi_init
|
||||
SUBROUTINE lammps_mpi_init() BIND(C)
|
||||
END SUBROUTINE lammps_mpi_init
|
||||
|
||||
SUBROUTINE lammps_mpi_finalize() BIND(C, name='lammps_mpi_finalize')
|
||||
END SUBROUTINE lammps_mpi_finalize
|
||||
SUBROUTINE lammps_mpi_finalize() BIND(C)
|
||||
END SUBROUTINE lammps_mpi_finalize
|
||||
|
||||
SUBROUTINE lammps_kokkos_finalize() BIND(C, name='lammps_kokkos_finalize')
|
||||
END SUBROUTINE lammps_kokkos_finalize
|
||||
SUBROUTINE lammps_kokkos_finalize() BIND(C)
|
||||
END SUBROUTINE lammps_kokkos_finalize
|
||||
|
||||
SUBROUTINE lammps_file(handle, filename) BIND(C, name='lammps_file')
|
||||
IMPORT :: c_ptr
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: filename
|
||||
END SUBROUTINE lammps_file
|
||||
SUBROUTINE lammps_error(handle, error_type, error_text) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
INTEGER(c_int), VALUE :: error_type
|
||||
TYPE(c_ptr), VALUE :: error_text
|
||||
END SUBROUTINE lammps_error
|
||||
|
||||
SUBROUTINE lammps_command(handle, cmd) BIND(C, name='lammps_command')
|
||||
IMPORT :: c_ptr
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: cmd
|
||||
END SUBROUTINE lammps_command
|
||||
SUBROUTINE lammps_file(handle, filename) BIND(C)
|
||||
IMPORT :: c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: filename
|
||||
END SUBROUTINE lammps_file
|
||||
|
||||
SUBROUTINE lammps_commands_list(handle, ncmd, cmds) BIND(C, name='lammps_commands_list')
|
||||
IMPORT :: c_ptr, c_int
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
INTEGER(c_int), VALUE, INTENT(in) :: ncmd
|
||||
TYPE(c_ptr), DIMENSION(*), INTENT(in) :: cmds
|
||||
END SUBROUTINE lammps_commands_list
|
||||
SUBROUTINE lammps_command(handle, cmd) BIND(C)
|
||||
IMPORT :: c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: cmd
|
||||
END SUBROUTINE lammps_command
|
||||
|
||||
SUBROUTINE lammps_commands_string(handle, str) BIND(C, name='lammps_commands_string')
|
||||
IMPORT :: c_ptr
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: str
|
||||
END SUBROUTINE lammps_commands_string
|
||||
SUBROUTINE lammps_commands_list(handle, ncmd, cmds) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
INTEGER(c_int), VALUE, INTENT(IN) :: ncmd
|
||||
TYPE(c_ptr), DIMENSION(*), INTENT(IN) :: cmds
|
||||
END SUBROUTINE lammps_commands_list
|
||||
|
||||
FUNCTION lammps_malloc(size) BIND(C, name='malloc')
|
||||
IMPORT :: c_ptr, c_size_t
|
||||
INTEGER(c_size_t), value :: size
|
||||
TYPE(c_ptr) :: lammps_malloc
|
||||
END FUNCTION lammps_malloc
|
||||
SUBROUTINE lammps_commands_string(handle, str) BIND(C)
|
||||
IMPORT :: c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: str
|
||||
END SUBROUTINE lammps_commands_string
|
||||
|
||||
SUBROUTINE lammps_free(ptr) BIND(C, name='lammps_free')
|
||||
IMPORT :: c_ptr
|
||||
TYPE(c_ptr), VALUE :: ptr
|
||||
END SUBROUTINE lammps_free
|
||||
FUNCTION lammps_get_natoms(handle) BIND(C)
|
||||
IMPORT :: c_ptr, c_double
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
REAL(c_double) :: lammps_get_natoms
|
||||
END FUNCTION lammps_get_natoms
|
||||
|
||||
FUNCTION lammps_version(handle) BIND(C, name='lammps_version')
|
||||
IMPORT :: c_ptr, c_int
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
INTEGER(c_int) :: lammps_version
|
||||
END FUNCTION lammps_version
|
||||
FUNCTION lammps_get_thermo(handle,name) BIND(C)
|
||||
IMPORT :: c_ptr, c_double
|
||||
IMPLICIT NONE
|
||||
REAL(c_double) :: lammps_get_thermo
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
TYPE(c_ptr), VALUE :: name
|
||||
END FUNCTION lammps_get_thermo
|
||||
|
||||
SUBROUTINE lammps_extract_box(handle,boxlo,boxhi,xy,yz,xz,pflags, &
|
||||
boxflag) BIND(C)
|
||||
IMPORT :: c_ptr, c_double, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle, boxlo, boxhi, xy, yz, xz, pflags, &
|
||||
boxflag
|
||||
END SUBROUTINE lammps_extract_box
|
||||
|
||||
SUBROUTINE lammps_reset_box(handle,boxlo,boxhi,xy,yz,xz) BIND(C)
|
||||
IMPORT :: c_ptr, c_double
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
REAL(c_double), DIMENSION(3) :: boxlo, boxhi
|
||||
REAL(c_double), VALUE :: xy, yz, xz
|
||||
END SUBROUTINE lammps_reset_box
|
||||
|
||||
SUBROUTINE lammps_memory_usage(handle,meminfo) BIND(C)
|
||||
IMPORT :: c_ptr, c_double
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
REAL(c_double), DIMENSION(*) :: meminfo
|
||||
END SUBROUTINE lammps_memory_usage
|
||||
|
||||
FUNCTION lammps_get_mpi_comm(handle) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
INTEGER(c_int) :: lammps_get_mpi_comm
|
||||
END FUNCTION lammps_get_mpi_comm
|
||||
|
||||
FUNCTION lammps_extract_setting(handle,keyword) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle, keyword
|
||||
INTEGER(c_int) :: lammps_extract_setting
|
||||
END FUNCTION lammps_extract_setting
|
||||
|
||||
FUNCTION lammps_extract_global_datatype(handle,name) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle, name
|
||||
INTEGER(c_int) :: lammps_extract_global_datatype
|
||||
END FUNCTION lammps_extract_global_datatype
|
||||
|
||||
FUNCTION c_strlen (str) BIND(C,name='strlen')
|
||||
IMPORT :: c_ptr, c_size_t
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: str
|
||||
INTEGER(c_size_t) :: c_strlen
|
||||
END FUNCTION c_strlen
|
||||
|
||||
FUNCTION lammps_extract_global(handle, name) BIND(C)
|
||||
IMPORT :: c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle, name
|
||||
TYPE(c_ptr) :: lammps_extract_global
|
||||
END FUNCTION lammps_extract_global
|
||||
|
||||
!INTEGER (c_int) FUNCTION lammps_extract_atom_datatype
|
||||
|
||||
!(generic) lammps_extract_atom
|
||||
|
||||
!(generic) lammps_extract_compute
|
||||
|
||||
!(generic) lammps_extract_fix
|
||||
|
||||
!(generic) lammps_extract_variable
|
||||
|
||||
!INTEGER (c_int) lammps_set_variable
|
||||
|
||||
!SUBROUTINE lammps_gather_atoms
|
||||
|
||||
!SUBROUTINE lammps_gather_atoms_concat
|
||||
|
||||
!SUBROUTINE lammps_gather_atoms_subset
|
||||
|
||||
!SUBROUTINE lammps_scatter_atoms
|
||||
|
||||
!SUBROUTINE lammps_scatter_atoms_subset
|
||||
|
||||
!SUBROUTINE lammps_gather_bonds
|
||||
|
||||
!SUBROUTINE lammps_gather
|
||||
|
||||
!SUBROUTINE lammps_gather_concat
|
||||
|
||||
!SUBROUTINE lammps_gather_subset
|
||||
|
||||
!SUBROUTINE lammps_scatter_subset
|
||||
|
||||
!(generic / id, type, and image are special) / requires LAMMPS_BIGBIG
|
||||
!INTEGER (C_int) FUNCTION lammps_create_atoms
|
||||
|
||||
!INTEGER (C_int) FUNCTION lammps_find_pair_neighlist
|
||||
|
||||
!INTEGER (C_int) FUNCTION lammps_find_fix_neighlist
|
||||
|
||||
!INTEGER (C_int) FUNCTION lammps_find_compute_neighlist
|
||||
|
||||
!INTEGER (C_int) FUNCTION lammps_neighlist_num_elements
|
||||
|
||||
!SUBROUTINE lammps_neighlist_element_neighbors
|
||||
|
||||
FUNCTION lammps_version(handle) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
INTEGER(c_int) :: lammps_version
|
||||
END FUNCTION lammps_version
|
||||
|
||||
!SUBROUTINE lammps_get_os_info
|
||||
|
||||
!LOGICAL FUNCTION lammps_config_has_mpi_support
|
||||
!LOGICAL FUNCTION lammps_config_has_gzip_support
|
||||
!LOGICAL FUNCTION lammps_config_has_png_support
|
||||
!LOGICAL FUNCTION lammps_config_has_jpeg_support
|
||||
!LOGICAL FUNCTION lammps_config_has_ffmpeg_support
|
||||
!LOGICAL FUNCTION lammps_config_has_exceptions
|
||||
!LOGICAL FUNCTION lammps_config_has_package
|
||||
!INTEGER (C_int) FUNCTION lammps_config_package_count
|
||||
!SUBROUTINE lammps_config_package_name
|
||||
|
||||
!LOGICAL FUNCTION lammps_config_accelerator
|
||||
!LOGICAL FUNCTION lammps_has_gpu_device
|
||||
!SUBROUTINE lammps_get_gpu_device
|
||||
|
||||
!LOGICAL FUNCTION lammps_has_id
|
||||
!INTEGER (C_int) FUNCTION lammps_id_count
|
||||
!SUBROUTINE lammps_id_name
|
||||
|
||||
!INTEGER (C_int) FUNCTION lammps_plugin_count
|
||||
!SUBROUTINE lammps_plugin_name
|
||||
|
||||
!Both of these use LAMMPS_BIGBIG
|
||||
!INTEGER (LAMMPS_imageint) FUNCTION lammps_encode_image_flags
|
||||
!SUBROUTINE lammps_decode_image_flags
|
||||
|
||||
!SUBROUTINE lammps_set_fix_external_callback ! may have trouble....
|
||||
!FUNCTION lammps_fix_external_get_force() ! returns real(c_double) (:)
|
||||
|
||||
!SUBROUTINE lammps_fix_external_set_energy_global
|
||||
!SUBROUTINE lammps_fix_external_set_energy_peratom
|
||||
!SUBROUTINE lammps_fix_external_set_virial_global
|
||||
!SUBROUTINE lammps_fix_external_set_virial_peratom
|
||||
!SUBROUTINE lammps_fix_external_set_vector_length
|
||||
!SUBROUTINE lammps_fix_external_set_vector
|
||||
|
||||
!SUBROUTINE lammps_flush_buffers
|
||||
|
||||
FUNCTION lammps_malloc(size) BIND(C, name='malloc')
|
||||
IMPORT :: c_ptr, c_size_t
|
||||
IMPLICIT NONE
|
||||
INTEGER(c_size_t), VALUE :: size
|
||||
TYPE(c_ptr) :: lammps_malloc
|
||||
END FUNCTION lammps_malloc
|
||||
|
||||
SUBROUTINE lammps_free(ptr) BIND(C)
|
||||
IMPORT :: c_ptr
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: ptr
|
||||
END SUBROUTINE lammps_free
|
||||
|
||||
INTEGER(c_int) FUNCTION lammps_is_running(handle) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
END FUNCTION lammps_is_running
|
||||
|
||||
!SUBROUTINE lammps_force_timeout
|
||||
|
||||
!LOGICAL FUNCTION lammps_has_error
|
||||
|
||||
!INTEGER (c_int) FUNCTION lammps_get_last_error_message
|
||||
|
||||
FUNCTION lammps_get_natoms(handle) BIND(C, name='lammps_get_natoms')
|
||||
IMPORT :: c_ptr, c_double
|
||||
TYPE(c_ptr), VALUE :: handle
|
||||
REAL(c_double) :: lammps_get_natoms
|
||||
END FUNCTION lammps_get_natoms
|
||||
END INTERFACE
|
||||
|
||||
CONTAINS
|
||||
|
@ -138,9 +379,8 @@ CONTAINS
|
|||
! Constructor for the LAMMPS class.
|
||||
! Combined wrapper around lammps_open_fortran() and lammps_open_no_mpi()
|
||||
TYPE(lammps) FUNCTION lmp_open(args, comm)
|
||||
IMPLICIT NONE
|
||||
INTEGER, INTENT(in), OPTIONAL :: comm
|
||||
CHARACTER(len=*), INTENT(in), OPTIONAL :: args(:)
|
||||
INTEGER, INTENT(IN), OPTIONAL :: comm
|
||||
CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: args(:)
|
||||
TYPE(c_ptr), ALLOCATABLE :: argv(:)
|
||||
INTEGER(c_int) :: i, c_comm, argc
|
||||
|
||||
|
@ -173,9 +413,8 @@ CONTAINS
|
|||
|
||||
! Combined Fortran wrapper around lammps_close() and lammps_mpi_finalize()
|
||||
SUBROUTINE lmp_close(self, finalize)
|
||||
IMPLICIT NONE
|
||||
CLASS(lammps) :: self
|
||||
LOGICAL, INTENT(in), OPTIONAL :: finalize
|
||||
LOGICAL, INTENT(IN), OPTIONAL :: finalize
|
||||
|
||||
CALL lammps_close(self%handle)
|
||||
|
||||
|
@ -187,22 +426,20 @@ CONTAINS
|
|||
END IF
|
||||
END SUBROUTINE lmp_close
|
||||
|
||||
INTEGER FUNCTION lmp_version(self)
|
||||
IMPLICIT NONE
|
||||
! equivalent function to lammps_error()
|
||||
SUBROUTINE lmp_error(self, error_type, error_text)
|
||||
CLASS(lammps) :: self
|
||||
INTEGER :: error_type
|
||||
CHARACTER(len=*) :: error_text
|
||||
TYPE(c_ptr) :: str
|
||||
|
||||
lmp_version = lammps_version(self%handle)
|
||||
END FUNCTION lmp_version
|
||||
|
||||
DOUBLE PRECISION FUNCTION lmp_get_natoms(self)
|
||||
IMPLICIT NONE
|
||||
CLASS(lammps) :: self
|
||||
|
||||
lmp_get_natoms = lammps_get_natoms(self%handle)
|
||||
END FUNCTION lmp_get_natoms
|
||||
str = f2c_string(error_text)
|
||||
CALL lammps_error(self%handle, error_type, str)
|
||||
CALL lammps_free(str)
|
||||
END SUBROUTINE lmp_error
|
||||
|
||||
! equivalent function to lammps_file()
|
||||
SUBROUTINE lmp_file(self, filename)
|
||||
IMPLICIT NONE
|
||||
CLASS(lammps) :: self
|
||||
CHARACTER(len=*) :: filename
|
||||
TYPE(c_ptr) :: str
|
||||
|
@ -214,7 +451,6 @@ CONTAINS
|
|||
|
||||
! equivalent function to lammps_command()
|
||||
SUBROUTINE lmp_command(self, cmd)
|
||||
IMPLICIT NONE
|
||||
CLASS(lammps) :: self
|
||||
CHARACTER(len=*) :: cmd
|
||||
TYPE(c_ptr) :: str
|
||||
|
@ -226,9 +462,8 @@ CONTAINS
|
|||
|
||||
! equivalent function to lammps_commands_list()
|
||||
SUBROUTINE lmp_commands_list(self, cmds)
|
||||
IMPLICIT NONE
|
||||
CLASS(lammps) :: self
|
||||
CHARACTER(len=*), INTENT(in), OPTIONAL :: cmds(:)
|
||||
CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: cmds(:)
|
||||
TYPE(c_ptr), ALLOCATABLE :: cmdv(:)
|
||||
INTEGER :: i, ncmd
|
||||
|
||||
|
@ -250,7 +485,6 @@ CONTAINS
|
|||
|
||||
! equivalent function to lammps_commands_string()
|
||||
SUBROUTINE lmp_commands_string(self, str)
|
||||
IMPLICIT NONE
|
||||
CLASS(lammps) :: self
|
||||
CHARACTER(len=*) :: str
|
||||
TYPE(c_ptr) :: tmp
|
||||
|
@ -260,13 +494,274 @@ CONTAINS
|
|||
CALL lammps_free(tmp)
|
||||
END SUBROUTINE lmp_commands_string
|
||||
|
||||
! equivalent function to lammps_get_natoms
|
||||
DOUBLE PRECISION FUNCTION lmp_get_natoms(self)
|
||||
CLASS(lammps) :: self
|
||||
|
||||
lmp_get_natoms = lammps_get_natoms(self%handle)
|
||||
END FUNCTION lmp_get_natoms
|
||||
|
||||
! equivalent function to lammps_get_thermo
|
||||
REAL (C_double) FUNCTION lmp_get_thermo(self,name)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
CHARACTER(LEN=*) :: name
|
||||
TYPE(C_ptr) :: Cname
|
||||
|
||||
Cname = f2c_string(name)
|
||||
lmp_get_thermo = lammps_get_thermo(self%handle, Cname)
|
||||
CALL lammps_free(Cname)
|
||||
END FUNCTION lmp_get_thermo
|
||||
|
||||
! equivalent subroutine to lammps_extract_box
|
||||
SUBROUTINE lmp_extract_box(self, boxlo, boxhi, xy, yz, xz, pflags, boxflag)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
REAL(c_double), INTENT(OUT), TARGET, OPTIONAL :: boxlo(3), boxhi(3)
|
||||
REAL(c_double), INTENT(OUT), TARGET, OPTIONAL :: xy, yz, xz
|
||||
LOGICAL, INTENT(OUT), OPTIONAL :: pflags(3), boxflag
|
||||
INTEGER(c_int), TARGET :: C_pflags(3), C_boxflag
|
||||
TYPE (c_ptr) :: ptr(7)
|
||||
|
||||
ptr = c_null_ptr
|
||||
IF ( PRESENT(boxlo) ) ptr(1) = C_LOC(boxlo(1))
|
||||
IF ( PRESENT(boxhi) ) ptr(2) = C_LOC(boxhi(1))
|
||||
IF ( PRESENT(xy) ) ptr(3) = C_LOC(xy)
|
||||
IF ( PRESENT(yz) ) ptr(4) = C_LOC(yz)
|
||||
IF ( PRESENT(xz) ) ptr(5) = C_LOC(xz)
|
||||
IF ( PRESENT(pflags) ) ptr(6) = C_LOC(C_pflags(1))
|
||||
IF ( PRESENT(boxflag) ) ptr(7) = C_LOC(C_boxflag)
|
||||
CALL lammps_extract_box(self%handle, ptr(1), ptr(2), ptr(3), ptr(4), &
|
||||
ptr(5), ptr(6), ptr(7))
|
||||
IF ( PRESENT(pflags) ) pflags = ( C_pflags /= 0_C_int )
|
||||
IF ( PRESENT(boxflag) ) boxflag = ( C_boxflag /= 0_C_int )
|
||||
END SUBROUTINE lmp_extract_box
|
||||
|
||||
! equivalent function to lammps_reset_box
|
||||
SUBROUTINE lmp_reset_box(self, boxlo, boxhi, xy, yz, xz)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
REAL(C_double), INTENT(IN) :: boxlo(3), boxhi(3), xy, yz, xz
|
||||
|
||||
CALL lammps_reset_box(self%handle, boxlo, boxhi, xy, yz, xz)
|
||||
END SUBROUTINE lmp_reset_box
|
||||
|
||||
! equivalent function to lammps_memory_usage
|
||||
SUBROUTINE lmp_memory_usage(self,meminfo)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
INTEGER, PARAMETER :: MEMINFO_ELEM = 3
|
||||
REAL (c_double), DIMENSION(MEMINFO_ELEM), INTENT(OUT) :: meminfo
|
||||
|
||||
CALL lammps_memory_usage(self%handle,meminfo)
|
||||
END SUBROUTINE lmp_memory_usage
|
||||
|
||||
! equivalent function to lammps_get_mpi_comm
|
||||
INTEGER FUNCTION lmp_get_mpi_comm(self)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
|
||||
lmp_get_mpi_comm = lammps_get_mpi_comm(self%handle)
|
||||
END FUNCTION lmp_get_mpi_comm
|
||||
|
||||
! equivalent function to lammps_extract_setting
|
||||
INTEGER (c_int) FUNCTION lmp_extract_setting(self, keyword)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
CHARACTER(LEN=*), INTENT(IN) :: keyword
|
||||
TYPE(c_ptr) :: Ckeyword
|
||||
|
||||
Ckeyword = f2c_string(keyword)
|
||||
lmp_extract_setting = lammps_extract_setting(self%handle, Ckeyword)
|
||||
CALL lammps_free(Ckeyword)
|
||||
END FUNCTION lmp_extract_setting
|
||||
|
||||
! equivalent function to lammps_extract_global
|
||||
! the assignment is actually overloaded so as to bind the pointers to
|
||||
! lammps data based on the information available from LAMMPS
|
||||
FUNCTION lmp_extract_global(self, name) RESULT (global_data)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
CHARACTER(LEN=*), INTENT(IN) :: name
|
||||
TYPE(lammps_data) :: global_data
|
||||
|
||||
INTEGER(c_int) :: datatype
|
||||
TYPE(c_ptr) :: Cname, Cptr
|
||||
INTEGER(c_size_t) :: length, i
|
||||
CHARACTER(KIND=c_char, LEN=1), DIMENSION(:), POINTER :: Fptr
|
||||
|
||||
! Determine vector length
|
||||
! FIXME Is there a way to get the length of the vector from C rather
|
||||
! than defining it here AND in the Python API?
|
||||
SELECT CASE (name)
|
||||
CASE ('boxlo','boxhi','sublo','subhi','sublo_lambda','subhi_lambda', &
|
||||
'periodicity')
|
||||
length = 3
|
||||
CASE DEFAULT
|
||||
length = 1
|
||||
! string cases are overridden later
|
||||
END SELECT
|
||||
|
||||
Cname = f2c_string(name)
|
||||
datatype = lammps_extract_global_datatype(self%handle, Cname)
|
||||
! above could be c_null_ptr in place of self%handle...doesn't matter
|
||||
Cptr = lammps_extract_global(self%handle, Cname)
|
||||
CALL lammps_free(Cname)
|
||||
|
||||
SELECT CASE (datatype)
|
||||
CASE (LAMMPS_INT)
|
||||
IF ( length == 1 ) THEN
|
||||
global_data%datatype = DATA_INT
|
||||
CALL C_F_POINTER(Cptr, global_data%i32)
|
||||
ELSE
|
||||
global_data%datatype = DATA_INT_1D
|
||||
CALL C_F_POINTER(Cptr, global_data%i32_vec, [length])
|
||||
END IF
|
||||
CASE (LAMMPS_INT64)
|
||||
IF ( length == 1 ) THEN
|
||||
global_data%datatype = DATA_INT64
|
||||
CALL C_F_POINTER(Cptr, global_data%i64)
|
||||
ELSE
|
||||
global_data%datatype = DATA_INT64_1D
|
||||
CALL C_F_POINTER(Cptr, global_data%i64_vec, [length])
|
||||
END IF
|
||||
CASE (LAMMPS_DOUBLE)
|
||||
IF ( length == 1 ) THEN
|
||||
global_data%datatype = DATA_DOUBLE
|
||||
CALL C_F_POINTER(Cptr, global_data%r64)
|
||||
ELSE
|
||||
global_data%datatype = DATA_DOUBLE_1D
|
||||
CALL C_F_POINTER(Cptr, global_data%r64_vec, [length])
|
||||
END IF
|
||||
CASE (LAMMPS_STRING)
|
||||
global_data%datatype = DATA_STRING
|
||||
length = c_strlen(Cptr)
|
||||
CALL C_F_POINTER(Cptr, Fptr, [length])
|
||||
ALLOCATE ( CHARACTER(LEN=length) :: global_data%str )
|
||||
FORALL ( I=1:length )
|
||||
global_data%str(i:i) = Fptr(i)
|
||||
END FORALL
|
||||
CASE DEFAULT
|
||||
! FIXME convert to use symbolic constants later
|
||||
CALL lmp_error(self, 6, 'Unknown pointer type in extract_global')
|
||||
END SELECT
|
||||
END FUNCTION
|
||||
|
||||
! equivalent function to lammps_version()
|
||||
INTEGER FUNCTION lmp_version(self)
|
||||
CLASS(lammps) :: self
|
||||
|
||||
lmp_version = lammps_version(self%handle)
|
||||
END FUNCTION lmp_version
|
||||
|
||||
! equivalent function to lammps_is_running
|
||||
LOGICAL FUNCTION lmp_is_running(self)
|
||||
CLASS(lammps) :: self
|
||||
|
||||
lmp_is_running = ( lammps_is_running(self%handle) /= 0_C_int )
|
||||
END FUNCTION lmp_is_running
|
||||
|
||||
! ----------------------------------------------------------------------
|
||||
! functions to assign user-space pointers to LAMMPS data
|
||||
! ----------------------------------------------------------------------
|
||||
SUBROUTINE assign_int_to_lammps_data (lhs, rhs)
|
||||
INTEGER(c_int), INTENT(OUT), POINTER :: lhs
|
||||
CLASS(lammps_data), INTENT(IN) :: rhs
|
||||
|
||||
IF ( rhs%datatype == DATA_INT ) THEN
|
||||
lhs => rhs%i32
|
||||
ELSE
|
||||
CALL assignment_error(rhs%datatype, 'scalar int')
|
||||
END IF
|
||||
END SUBROUTINE assign_int_to_lammps_data
|
||||
|
||||
SUBROUTINE assign_int64_to_lammps_data (lhs, rhs)
|
||||
INTEGER(c_int64_t), INTENT(OUT), POINTER :: lhs
|
||||
CLASS(lammps_data), INTENT(IN) :: rhs
|
||||
|
||||
IF ( rhs%datatype == DATA_INT64 ) THEN
|
||||
lhs => rhs%i64
|
||||
ELSE
|
||||
CALL assignment_error(rhs%datatype, 'scalar long int')
|
||||
END IF
|
||||
END SUBROUTINE assign_int64_to_lammps_data
|
||||
|
||||
SUBROUTINE assign_intvec_to_lammps_data (lhs, rhs)
|
||||
INTEGER(c_int), DIMENSION(:), INTENT(OUT), POINTER :: lhs
|
||||
CLASS(lammps_data), INTENT(IN) :: rhs
|
||||
|
||||
IF ( rhs%datatype == DATA_INT_1D ) THEN
|
||||
lhs => rhs%i32_vec
|
||||
ELSE
|
||||
CALL assignment_error(rhs%datatype, 'vector of ints')
|
||||
END IF
|
||||
END SUBROUTINE assign_intvec_to_lammps_data
|
||||
|
||||
SUBROUTINE assign_double_to_lammps_data (lhs, rhs)
|
||||
REAL(c_double), INTENT(OUT), POINTER :: lhs
|
||||
CLASS(lammps_data), INTENT(IN) :: rhs
|
||||
|
||||
IF ( rhs%datatype == DATA_DOUBLE ) THEN
|
||||
lhs => rhs%r64
|
||||
ELSE
|
||||
CALL assignment_error(rhs%datatype, 'scalar double')
|
||||
END IF
|
||||
END SUBROUTINE assign_double_to_lammps_data
|
||||
|
||||
SUBROUTINE assign_doublevec_to_lammps_data (lhs, rhs)
|
||||
REAL(c_double), DIMENSION(:), INTENT(OUT), POINTER :: lhs
|
||||
CLASS(lammps_data), INTENT(IN) :: rhs
|
||||
|
||||
IF ( rhs%datatype == DATA_DOUBLE_1D ) THEN
|
||||
lhs => rhs%r64_vec
|
||||
ELSE
|
||||
CALL assignment_error(rhs%datatype, 'vector of doubles')
|
||||
END IF
|
||||
END SUBROUTINE assign_doublevec_to_lammps_data
|
||||
|
||||
SUBROUTINE assign_string_to_lammps_data (lhs, rhs)
|
||||
CHARACTER(LEN=*), INTENT(OUT) :: lhs
|
||||
CLASS(lammps_data), INTENT(IN) :: rhs
|
||||
|
||||
IF ( rhs%datatype == DATA_STRING ) THEN
|
||||
lhs = rhs%str
|
||||
ELSE
|
||||
CALL assignment_error(rhs%datatype, 'string')
|
||||
END IF
|
||||
END SUBROUTINE assign_string_to_lammps_data
|
||||
|
||||
SUBROUTINE assignment_error (type1, type2)
|
||||
INTEGER (c_int) :: type1
|
||||
CHARACTER (LEN=*) :: type2
|
||||
INTEGER, PARAMETER :: ERROR_CODE = 1
|
||||
CHARACTER (LEN=:), ALLOCATABLE :: str1
|
||||
|
||||
SELECT CASE (type1)
|
||||
CASE (DATA_INT)
|
||||
str1 = 'scalar int'
|
||||
CASE (DATA_INT_1D)
|
||||
str1 = 'vector of ints'
|
||||
CASE (DATA_INT_2D)
|
||||
str1 = 'matrix of ints'
|
||||
CASE (DATA_INT64)
|
||||
str1 = 'scalar long int'
|
||||
CASE (DATA_INT64_1D)
|
||||
str1 = 'vector of long ints'
|
||||
CASE (DATA_INT64_2D)
|
||||
str1 = 'matrix of long ints'
|
||||
CASE (DATA_DOUBLE)
|
||||
str1 = 'scalar double'
|
||||
CASE (DATA_DOUBLE_1D)
|
||||
str1 = 'vector of doubles'
|
||||
CASE (DATA_DOUBLE_2D)
|
||||
str1 = 'matrix of doubles'
|
||||
CASE DEFAULT
|
||||
str1 = 'that type'
|
||||
END SELECT
|
||||
WRITE (ERROR_UNIT,'(A)') 'Cannot associate ' // str1 // ' with ' // type2
|
||||
STOP ERROR_CODE
|
||||
END SUBROUTINE assignment_error
|
||||
|
||||
! ----------------------------------------------------------------------
|
||||
! local helper functions
|
||||
! copy fortran string to zero terminated c string
|
||||
! ----------------------------------------------------------------------
|
||||
FUNCTION f2c_string(f_string) RESULT(ptr)
|
||||
CHARACTER (len=*), INTENT(in) :: f_string
|
||||
CHARACTER (len=1, kind=c_char), POINTER :: c_string(:)
|
||||
CHARACTER(LEN=*), INTENT(IN) :: f_string
|
||||
CHARACTER(LEN=1, KIND=c_char), POINTER :: c_string(:)
|
||||
TYPE(c_ptr) :: ptr
|
||||
INTEGER(c_size_t) :: i, n
|
||||
|
||||
|
@ -279,3 +774,5 @@ CONTAINS
|
|||
c_string(n+1) = c_null_char
|
||||
END FUNCTION f2c_string
|
||||
END MODULE LIBLAMMPS
|
||||
|
||||
! vim: ts=2 sts=2 sw=2 et
|
||||
|
|
|
@ -13,29 +13,35 @@
|
|||
|
||||
# various symbolic constants to be used
|
||||
# in certain calls to select data formats
|
||||
LAMMPS_AUTODETECT = None
|
||||
LAMMPS_INT = 0
|
||||
LAMMPS_INT_2D = 1
|
||||
LAMMPS_DOUBLE = 2
|
||||
LAMMPS_DOUBLE_2D = 3
|
||||
LAMMPS_INT64 = 4
|
||||
LAMMPS_INT64_2D = 5
|
||||
LAMMPS_STRING = 6
|
||||
LAMMPS_AUTODETECT = None
|
||||
LAMMPS_INT = 0
|
||||
LAMMPS_INT_2D = 1
|
||||
LAMMPS_DOUBLE = 2
|
||||
LAMMPS_DOUBLE_2D = 3
|
||||
LAMMPS_INT64 = 4
|
||||
LAMMPS_INT64_2D = 5
|
||||
LAMMPS_STRING = 6
|
||||
|
||||
# these must be kept in sync with the enums in library.h
|
||||
LMP_STYLE_GLOBAL = 0
|
||||
LMP_STYLE_ATOM = 1
|
||||
LMP_STYLE_LOCAL = 2
|
||||
LMP_STYLE_GLOBAL = 0
|
||||
LMP_STYLE_ATOM = 1
|
||||
LMP_STYLE_LOCAL = 2
|
||||
|
||||
LMP_TYPE_SCALAR = 0
|
||||
LMP_TYPE_VECTOR = 1
|
||||
LMP_TYPE_ARRAY = 2
|
||||
LMP_SIZE_VECTOR = 3
|
||||
LMP_SIZE_ROWS = 4
|
||||
LMP_SIZE_COLS = 5
|
||||
LMP_TYPE_SCALAR = 0
|
||||
LMP_TYPE_VECTOR = 1
|
||||
LMP_TYPE_ARRAY = 2
|
||||
LMP_SIZE_VECTOR = 3
|
||||
LMP_SIZE_ROWS = 4
|
||||
LMP_SIZE_COLS = 5
|
||||
|
||||
LMP_VAR_EQUAL = 0
|
||||
LMP_VAR_ATOM = 1
|
||||
LMP_ERROR_WARNING = 0
|
||||
LMP_ERROR_ONE = 1
|
||||
LMP_ERROR_ALL = 2
|
||||
LMP_ERROR_WORLD = 4
|
||||
LMP_ERROR_UNIVERSE = 8
|
||||
|
||||
LMP_VAR_EQUAL = 0
|
||||
LMP_VAR_ATOM = 1
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -167,6 +167,8 @@ class lammps(object):
|
|||
self.lib.lammps_flush_buffers.argtypes = [c_void_p]
|
||||
self.lib.lammps_free.argtypes = [c_void_p]
|
||||
|
||||
self.lib.lammps_error.argtypes = [c_void_p, c_int, c_char_p]
|
||||
|
||||
self.lib.lammps_file.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_file.restype = None
|
||||
|
||||
|
@ -486,6 +488,26 @@ class lammps(object):
|
|||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def error(self, error_type, error_text):
|
||||
"""Forward error to the LAMMPS Error class.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_error` function of the C-library interface.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:param error_type:
|
||||
:type error_type: int
|
||||
:param error_text:
|
||||
:type error_text: string
|
||||
"""
|
||||
if error_text: error_text = error_text.encode()
|
||||
else: error_text = "(unknown error)".encode()
|
||||
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_error(self.lmp, error_type, error_text)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def version(self):
|
||||
"""Return a numerical representation of the LAMMPS version in use.
|
||||
|
||||
|
@ -1622,8 +1644,8 @@ class lammps(object):
|
|||
"""Return a string with detailed information about any devices that are
|
||||
usable by the GPU package.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_get_gpu_device_info`
|
||||
function of the C-library interface.
|
||||
This is a wrapper around the :cpp:func:`lammps_get_gpu_device_info`
|
||||
function of the C-library interface.
|
||||
|
||||
:return: GPU device info string
|
||||
:rtype: string
|
||||
|
|
|
@ -416,6 +416,89 @@ void lammps_python_finalize()
|
|||
Python::finalize();
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Call a LAMMPS Error class function
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
This function is a wrapper around functions in the ``Error`` to print an
|
||||
error message and then stop LAMMPS.
|
||||
|
||||
The *error_type* parameter selects which function to call. It is a sum
|
||||
of constants from :cpp:enum:`_LMP_ERROR_CONST`. If the value does not
|
||||
match any valid combination of constants a warning is printed and the
|
||||
function returns.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
* \param error_type parameter to select function in the Error class
|
||||
* \param error_text error message */
|
||||
|
||||
void lammps_error(void *handle, int error_type, const char *error_text)
|
||||
{
|
||||
auto lmp = (LAMMPS *) handle;
|
||||
|
||||
BEGIN_CAPTURE
|
||||
{
|
||||
switch (error_type) {
|
||||
case LMP_ERROR_WARNING:
|
||||
lmp->error->warning("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_ONE:
|
||||
lmp->error->one("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_ALL:
|
||||
lmp->error->all("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_WARNING|LMP_ERROR_WORLD:
|
||||
lmp->error->warning("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_ONE|LMP_ERROR_WORLD:
|
||||
lmp->error->one("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_ALL|LMP_ERROR_WORLD:
|
||||
lmp->error->all("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_WARNING|LMP_ERROR_UNIVERSE:
|
||||
lmp->error->universe_warn("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_ONE|LMP_ERROR_UNIVERSE:
|
||||
lmp->error->universe_one("(library)", 0, error_text);
|
||||
break;
|
||||
case LMP_ERROR_ALL|LMP_ERROR_UNIVERSE:
|
||||
lmp->error->universe_all("(library)", 0, error_text);
|
||||
break;
|
||||
default:
|
||||
auto mesg = fmt::format("Unknown error type {} for message: {}", error_type, error_text);
|
||||
lmp->error->warning("(library)", 0, mesg);
|
||||
}
|
||||
}
|
||||
END_CAPTURE
|
||||
|
||||
#if defined(LAMMPS_EXCEPTIONS)
|
||||
// with enabled exceptions the above code will simply throw an
|
||||
// exception and record the error message. So we have to explicitly
|
||||
// stop here like we do in main.cpp
|
||||
if (lammps_has_error(handle)) {
|
||||
if (error_type & 1) {
|
||||
lammps_kokkos_finalize();
|
||||
lammps_python_finalize();
|
||||
MPI_Abort(lmp->universe->uworld, 1);
|
||||
} else if (error_type & 2) {
|
||||
lammps_kokkos_finalize();
|
||||
lammps_python_finalize();
|
||||
lammps_mpi_finalize();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Library functions to process commands
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -1156,8 +1239,8 @@ Please also see :cpp:func:`lammps_extract_setting`,
|
|||
may lead to inconsistent internal data and thus may cause failures or
|
||||
crashes or bogus simulations. In general it is thus usually better
|
||||
to use a LAMMPS input command that sets or changes these parameters.
|
||||
Those will takes care of all side effects and necessary updates of
|
||||
settings derived from such settings. Where possible a reference to
|
||||
Those will take care of all side effects and necessary updates of
|
||||
settings derived from such settings. Where possible, a reference to
|
||||
such a command or a relevant section of the manual is given below.
|
||||
|
||||
The following tables list the supported names, their data types, length
|
||||
|
|
|
@ -75,6 +75,18 @@ enum _LMP_TYPE_CONST {
|
|||
LMP_SIZE_COLS = 5 /*!< return number of columns */
|
||||
};
|
||||
|
||||
/** Error codes to select the suitable function in the Error class
|
||||
*
|
||||
* Must be kept in sync with the equivalent constants in lammps/constants.py */
|
||||
|
||||
enum _LMP_ERROR_CONST {
|
||||
LMP_ERROR_WARNING = 0, /*!< call Error::warning() */
|
||||
LMP_ERROR_ONE = 1, /*!< called from one MPI rank */
|
||||
LMP_ERROR_ALL = 2, /*!< called from all MPI ranks */
|
||||
LMP_ERROR_WORLD = 4, /*!< error on Comm::world */
|
||||
LMP_ERROR_UNIVERSE = 8 /*!< error on Comm::universe */
|
||||
};
|
||||
|
||||
/* Ifdefs to allow this file to be included in C and C++ programs */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -97,6 +109,8 @@ void lammps_mpi_finalize();
|
|||
void lammps_kokkos_finalize();
|
||||
void lammps_python_finalize();
|
||||
|
||||
void lammps_error(void *handle, int error_type, const char *error_text);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Library functions to process commands
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
|
@ -198,3 +198,32 @@ TEST(lammps_open_fortran, no_args)
|
|||
if (verbose) std::cout << output;
|
||||
MPI_Comm_free(&mycomm);
|
||||
}
|
||||
|
||||
TEST(lammps_open_no_mpi, lammps_error)
|
||||
{
|
||||
const char *args[] = {"liblammps", "-log", "none", "-nocite"};
|
||||
char **argv = (char **)args;
|
||||
int argc = sizeof(args) / sizeof(char *);
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
void *alt_ptr;
|
||||
void *handle = lammps_open_no_mpi(argc, argv, &alt_ptr);
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_EQ(handle, alt_ptr);
|
||||
LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
|
||||
|
||||
EXPECT_EQ(lmp->world, MPI_COMM_WORLD);
|
||||
EXPECT_EQ(lmp->infile, stdin);
|
||||
EXPECT_NE(lmp->screen, nullptr);
|
||||
EXPECT_EQ(lmp->logfile, nullptr);
|
||||
EXPECT_EQ(lmp->citeme, nullptr);
|
||||
EXPECT_EQ(lmp->suffix_enable, 0);
|
||||
|
||||
EXPECT_STREQ(lmp->exename, "liblammps");
|
||||
EXPECT_EQ(lmp->num_package, 0);
|
||||
::testing::internal::CaptureStdout();
|
||||
lammps_error(handle, 0, "test_warning");
|
||||
output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("WARNING: test_warning"));
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,23 @@ if(CMAKE_Fortran_COMPILER)
|
|||
add_executable(test_fortran_commands wrap_commands.cpp test_fortran_commands.f90)
|
||||
target_link_libraries(test_fortran_commands PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain)
|
||||
add_test(NAME FortranCommands COMMAND test_fortran_commands)
|
||||
|
||||
add_executable(test_fortran_get_thermo wrap_get_thermo.cpp test_fortran_get_thermo.f90)
|
||||
target_link_libraries(test_fortran_get_thermo PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain)
|
||||
add_test(NAME FortranGetThermo COMMAND test_fortran_get_thermo)
|
||||
|
||||
add_executable(test_fortran_box wrap_box.cpp test_fortran_box.f90)
|
||||
target_link_libraries(test_fortran_box PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain)
|
||||
add_test(NAME FortranBox COMMAND test_fortran_box)
|
||||
|
||||
add_executable(test_fortran_properties wrap_properties.cpp test_fortran_properties.f90 test_fortran_commands.f90)
|
||||
target_link_libraries(test_fortran_properties PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain)
|
||||
add_test(NAME FortranProperties COMMAND test_fortran_properties)
|
||||
|
||||
add_executable(test_fortran_extract_global wrap_extract_global.cpp test_fortran_extract_global.f90)
|
||||
target_link_libraries(test_fortran_extract_global PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain)
|
||||
add_test(NAME FortranExtractGlobal COMMAND test_fortran_extract_global)
|
||||
|
||||
else()
|
||||
message(STATUS "Skipping Tests for the LAMMPS Fortran Module: no Fortran compiler")
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
MODULE keepbox
|
||||
USE liblammps
|
||||
IMPLICIT NONE
|
||||
TYPE(LAMMPS) :: lmp
|
||||
CHARACTER(len=40), DIMENSION(3), PARAMETER :: demo_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
'region box block 0 $x 0 2 0 2', &
|
||||
'create_box 1 box', &
|
||||
'create_atoms 1 single 1.0 1.0 ${zpos}' ]
|
||||
CHARACTER(len=40), DIMENSION(2), PARAMETER :: cont_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
'create_atoms 1 single &', &
|
||||
' 0.2 0.1 0.1' ]
|
||||
END MODULE keepbox
|
||||
|
||||
FUNCTION f_lammps_with_args() BIND(C, name="f_lammps_with_args")
|
||||
USE ISO_C_BINDING, ONLY: c_ptr
|
||||
USE liblammps
|
||||
USE keepbox, ONLY: lmp
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr) :: f_lammps_with_args
|
||||
|
||||
CHARACTER(len=12), DIMENSION(12), PARAMETER :: args = &
|
||||
[ CHARACTER(len=12) :: 'liblammps', '-log', 'none', &
|
||||
'-echo','screen','-nocite','-var','zpos','1.5','-var','x','2']
|
||||
|
||||
lmp = lammps(args)
|
||||
f_lammps_with_args = lmp%handle
|
||||
END FUNCTION f_lammps_with_args
|
||||
|
||||
SUBROUTINE f_lammps_close() BIND(C, name="f_lammps_close")
|
||||
USE ISO_C_BINDING, ONLY: c_null_ptr
|
||||
USE liblammps
|
||||
USE keepbox, ONLY: lmp
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%close()
|
||||
lmp%handle = c_null_ptr
|
||||
END SUBROUTINE f_lammps_close
|
||||
|
||||
SUBROUTINE f_lammps_box_setup () BIND(C)
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp, demo_input
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%commands_list(demo_input)
|
||||
END SUBROUTINE f_lammps_box_setup
|
||||
|
||||
SUBROUTINE f_lammps_delete_everything() BIND(C)
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%command("delete_atoms group all");
|
||||
END SUBROUTINE f_lammps_delete_everything
|
||||
|
||||
FUNCTION f_lammps_extract_box_xlo () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_extract_box_xlo
|
||||
REAL (c_double) :: boxdim(3)
|
||||
|
||||
CALL lmp%extract_box(boxlo=boxdim)
|
||||
f_lammps_extract_box_xlo = boxdim(1)
|
||||
END FUNCTION f_lammps_extract_box_xlo
|
||||
|
||||
FUNCTION f_lammps_extract_box_xhi () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_extract_box_xhi
|
||||
REAL (c_double) :: boxdim(3)
|
||||
|
||||
CALL lmp%extract_box(boxhi=boxdim)
|
||||
f_lammps_extract_box_xhi = boxdim(1)
|
||||
END FUNCTION f_lammps_extract_box_xhi
|
||||
|
||||
FUNCTION f_lammps_extract_box_ylo () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_extract_box_ylo
|
||||
REAL (c_double) :: boxdim(3)
|
||||
|
||||
CALL lmp%extract_box(boxlo=boxdim)
|
||||
f_lammps_extract_box_ylo = boxdim(2)
|
||||
END FUNCTION f_lammps_extract_box_ylo
|
||||
|
||||
FUNCTION f_lammps_extract_box_yhi () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_extract_box_yhi
|
||||
REAL (c_double) :: boxdim(3)
|
||||
|
||||
CALL lmp%extract_box(boxhi=boxdim)
|
||||
f_lammps_extract_box_yhi = boxdim(2)
|
||||
END FUNCTION f_lammps_extract_box_yhi
|
||||
|
||||
FUNCTION f_lammps_extract_box_zlo () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_extract_box_zlo
|
||||
REAL (c_double) :: boxdim(3)
|
||||
|
||||
CALL lmp%extract_box(boxlo=boxdim)
|
||||
f_lammps_extract_box_zlo = boxdim(2)
|
||||
END FUNCTION f_lammps_extract_box_zlo
|
||||
|
||||
FUNCTION f_lammps_extract_box_zhi () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_extract_box_zhi
|
||||
REAL (c_double) :: boxdim(3)
|
||||
|
||||
CALL lmp%extract_box(boxhi=boxdim)
|
||||
f_lammps_extract_box_zhi = boxdim(2)
|
||||
END FUNCTION f_lammps_extract_box_zhi
|
||||
|
||||
SUBROUTINE f_lammps_reset_box_2x () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double
|
||||
USE liblammps
|
||||
USE keepbox, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: newlo(3), newhi(3), xy, yz, xz
|
||||
|
||||
xy = 0.0_c_double
|
||||
yz = 0.0_c_double
|
||||
xz = 0.0_c_double
|
||||
newlo = [-1.0_c_double, -1.0_c_double, -1.0_c_double]
|
||||
newhi = [3.0_c_double, 3.0_c_double, 3.0_c_double]
|
||||
CALL lmp%reset_box(newlo, newhi, xy, yz, xz)
|
||||
END SUBROUTINE f_lammps_reset_box_2x
|
|
@ -1,5 +1,6 @@
|
|||
MODULE keepcmds
|
||||
USE liblammps
|
||||
IMPLICIT NONE
|
||||
TYPE(LAMMPS) :: lmp
|
||||
CHARACTER(len=40), DIMENSION(3), PARAMETER :: demo_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
|
|
|
@ -0,0 +1,491 @@
|
|||
MODULE keepglobal
|
||||
USE liblammps
|
||||
TYPE(LAMMPS) :: lmp
|
||||
CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: demo_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
'region box block 0 $x 0 3 0 4', &
|
||||
'create_box 1 box', &
|
||||
'create_atoms 1 single 1.0 1.0 ${zpos}' ]
|
||||
CHARACTER(LEN=40), DIMENSION(2), PARAMETER :: cont_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
'create_atoms 1 single &', &
|
||||
' 0.2 0.1 0.1' ]
|
||||
CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: pair_input = &
|
||||
[ CHARACTER(LEN=40) :: &
|
||||
'pair_style lj/cut 2.5', &
|
||||
'pair_coeff 1 1 1.0 1.0', &
|
||||
'mass 1 1.0' ]
|
||||
END MODULE keepglobal
|
||||
|
||||
FUNCTION f_lammps_with_args() BIND(C, name="f_lammps_with_args")
|
||||
USE ISO_C_BINDING, ONLY: c_ptr
|
||||
USE liblammps
|
||||
USE keepglobal, ONLY: lmp
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr) :: f_lammps_with_args
|
||||
CHARACTER(len=12), DIMENSION(12), PARAMETER :: args = &
|
||||
[ CHARACTER(len=12) :: 'liblammps', '-log', 'none', &
|
||||
'-echo','screen','-nocite','-var','zpos','1.5','-var','x','2']
|
||||
|
||||
lmp = lammps(args)
|
||||
f_lammps_with_args = lmp%handle
|
||||
END FUNCTION f_lammps_with_args
|
||||
|
||||
SUBROUTINE f_lammps_close() BIND(C, name="f_lammps_close")
|
||||
USE ISO_C_BINDING, ONLY: c_null_ptr
|
||||
USE liblammps
|
||||
USE keepglobal, ONLY: lmp
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%close()
|
||||
lmp%handle = c_null_ptr
|
||||
END SUBROUTINE f_lammps_close
|
||||
|
||||
SUBROUTINE f_lammps_setup_extract_global () BIND(C)
|
||||
USE LIBLAMMPS
|
||||
USE keepglobal, ONLY : lmp, demo_input, cont_input, pair_input
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%commands_list(demo_input)
|
||||
CALL lmp%commands_list(cont_input)
|
||||
CALL lmp%commands_list(pair_input)
|
||||
CALL lmp%command('run 0')
|
||||
END SUBROUTINE f_lammps_setup_extract_global
|
||||
|
||||
SUBROUTINE f_lammps_setup_full_extract_global () BIND(C)
|
||||
USE LIBLAMMPS
|
||||
USE keepglobal, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
INTERFACE
|
||||
SUBROUTINE f_lammps_setup_extract_global () BIND(C)
|
||||
END SUBROUTINE f_lammps_setup_extract_global
|
||||
END INTERFACE
|
||||
|
||||
CALL lmp%command('atom_style full')
|
||||
CALL f_lammps_setup_extract_global
|
||||
CALL lmp%command('bond_style zero')
|
||||
CALL lmp%command('angle_style zero')
|
||||
CALL lmp%command('dihedral_style zero')
|
||||
CALL lmp%command('run 0')
|
||||
END SUBROUTINE f_lammps_setup_full_extract_global
|
||||
|
||||
FUNCTION f_lammps_extract_global_units () BIND(C) RESULT(success)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE LIBLAMMPS
|
||||
USE keepglobal, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int) :: success
|
||||
CHARACTER (LEN=16) :: units
|
||||
|
||||
! passing strings from Fortran to C is icky, so we do the test here and
|
||||
! report the result instead
|
||||
units = lmp%extract_global('units')
|
||||
IF ( TRIM(units) == 'lj' ) THEN
|
||||
success = 1_C_int
|
||||
ELSE
|
||||
success = 0_C_int
|
||||
END IF
|
||||
END FUNCTION f_lammps_extract_global_units
|
||||
|
||||
FUNCTION f_lammps_extract_global_ntimestep () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: ntimestep
|
||||
INTEGER (C_int) :: f_lammps_extract_global_ntimestep
|
||||
|
||||
ntimestep = lmp%extract_global("ntimestep")
|
||||
f_lammps_extract_global_ntimestep = ntimestep
|
||||
END FUNCTION f_lammps_extract_global_ntimestep
|
||||
FUNCTION f_lammps_extract_global_ntimestep_big () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int64_t), POINTER :: ntimestep
|
||||
INTEGER (C_int64_t) :: f_lammps_extract_global_ntimestep_big
|
||||
|
||||
ntimestep = lmp%extract_global("ntimestep")
|
||||
f_lammps_extract_global_ntimestep_big = ntimestep
|
||||
END FUNCTION f_lammps_extract_global_ntimestep_big
|
||||
|
||||
FUNCTION f_lammps_extract_global_dt () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double), POINTER :: dt
|
||||
REAL (C_double) :: f_lammps_extract_global_dt
|
||||
|
||||
dt = lmp%extract_global("dt")
|
||||
f_lammps_extract_global_dt = dt
|
||||
END FUNCTION f_lammps_extract_global_dt
|
||||
|
||||
SUBROUTINE f_lammps_extract_global_boxlo (C_boxlo) BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double), DIMENSION(3) :: C_boxlo
|
||||
REAL (C_double), DIMENSION(:), POINTER :: boxlo
|
||||
|
||||
boxlo = lmp%extract_global("boxlo")
|
||||
C_boxlo = boxlo
|
||||
END SUBROUTINE f_lammps_extract_global_boxlo
|
||||
|
||||
SUBROUTINE f_lammps_extract_global_boxhi (C_boxhi) BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double), DIMENSION(3) :: C_boxhi
|
||||
REAL (C_double), DIMENSION(:), POINTER :: boxhi
|
||||
|
||||
boxhi = lmp%extract_global("boxhi")
|
||||
C_boxhi = boxhi
|
||||
END SUBROUTINE f_lammps_extract_global_boxhi
|
||||
|
||||
FUNCTION f_lammps_extract_global_boxxlo () BIND(C) RESULT(C_boxxlo)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_boxxlo
|
||||
REAL (C_double), POINTER :: boxxlo
|
||||
|
||||
boxxlo = lmp%extract_global("boxxlo")
|
||||
C_boxxlo = boxxlo
|
||||
END FUNCTION f_lammps_extract_global_boxxlo
|
||||
|
||||
FUNCTION f_lammps_extract_global_boxxhi () BIND(C) RESULT(C_boxxhi)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_boxxhi
|
||||
REAL (C_double), POINTER :: boxxhi
|
||||
|
||||
boxxhi = lmp%extract_global("boxxhi")
|
||||
C_boxxhi = boxxhi
|
||||
END FUNCTION f_lammps_extract_global_boxxhi
|
||||
|
||||
FUNCTION f_lammps_extract_global_boxylo () BIND(C) RESULT(C_boxylo)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_boxylo
|
||||
REAL (C_double), POINTER :: boxylo
|
||||
|
||||
boxylo = lmp%extract_global("boxylo")
|
||||
C_boxylo = boxylo
|
||||
END FUNCTION f_lammps_extract_global_boxylo
|
||||
|
||||
FUNCTION f_lammps_extract_global_boxyhi () BIND(C) RESULT(C_boxyhi)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_boxyhi
|
||||
REAL (C_double), POINTER :: boxyhi
|
||||
|
||||
boxyhi = lmp%extract_global("boxyhi")
|
||||
C_boxyhi = boxyhi
|
||||
END FUNCTION f_lammps_extract_global_boxyhi
|
||||
|
||||
FUNCTION f_lammps_extract_global_boxzlo () BIND(C) RESULT(C_boxzlo)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_boxzlo
|
||||
REAL (C_double), POINTER :: boxzlo
|
||||
|
||||
boxzlo = lmp%extract_global("boxzlo")
|
||||
C_boxzlo = boxzlo
|
||||
END FUNCTION f_lammps_extract_global_boxzlo
|
||||
|
||||
FUNCTION f_lammps_extract_global_boxzhi () BIND(C) RESULT(C_boxzhi)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_boxzhi
|
||||
REAL (C_double), POINTER :: boxzhi
|
||||
|
||||
boxzhi = lmp%extract_global("boxzhi")
|
||||
C_boxzhi = boxzhi
|
||||
END FUNCTION f_lammps_extract_global_boxzhi
|
||||
|
||||
SUBROUTINE f_lammps_extract_global_periodicity (C_periodicity) BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), DIMENSION(3) :: C_periodicity
|
||||
INTEGER (C_int), DIMENSION(:), POINTER :: periodicity
|
||||
|
||||
periodicity = lmp%extract_global("periodicity")
|
||||
C_periodicity = periodicity
|
||||
END SUBROUTINE f_lammps_extract_global_periodicity
|
||||
|
||||
FUNCTION f_lammps_extract_global_triclinic () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: triclinic
|
||||
INTEGER (C_int) :: f_lammps_extract_global_triclinic
|
||||
|
||||
triclinic = lmp%extract_global("triclinic")
|
||||
f_lammps_extract_global_triclinic = triclinic
|
||||
END FUNCTION f_lammps_extract_global_triclinic
|
||||
|
||||
FUNCTION f_lammps_extract_global_xy () BIND(C) RESULT(C_xy)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_xy
|
||||
REAL (C_double), POINTER :: xy
|
||||
|
||||
xy = lmp%extract_global("xy")
|
||||
C_xy = xy
|
||||
END FUNCTION f_lammps_extract_global_xy
|
||||
|
||||
FUNCTION f_lammps_extract_global_xz () BIND(C) RESULT(C_xz)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_xz
|
||||
REAL (C_double), POINTER :: xz
|
||||
|
||||
xz = lmp%extract_global("xz")
|
||||
C_xz = xz
|
||||
END FUNCTION f_lammps_extract_global_xz
|
||||
|
||||
FUNCTION f_lammps_extract_global_yz () BIND(C) RESULT(C_yz)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_yz
|
||||
REAL (C_double), POINTER :: yz
|
||||
|
||||
yz = lmp%extract_global("yz")
|
||||
C_yz = yz
|
||||
END FUNCTION f_lammps_extract_global_yz
|
||||
|
||||
FUNCTION f_lammps_extract_global_natoms () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: natoms
|
||||
INTEGER (C_int) :: f_lammps_extract_global_natoms
|
||||
|
||||
natoms = lmp%extract_global("natoms")
|
||||
f_lammps_extract_global_natoms = natoms
|
||||
END FUNCTION f_lammps_extract_global_natoms
|
||||
FUNCTION f_lammps_extract_global_natoms_big () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int64_t), POINTER :: natoms
|
||||
INTEGER (C_int64_t) :: f_lammps_extract_global_natoms_big
|
||||
|
||||
natoms = lmp%extract_global("natoms")
|
||||
f_lammps_extract_global_natoms_big = natoms
|
||||
END FUNCTION f_lammps_extract_global_natoms_big
|
||||
|
||||
FUNCTION f_lammps_extract_global_nbonds () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: nbonds
|
||||
INTEGER (C_int) :: f_lammps_extract_global_nbonds
|
||||
|
||||
nbonds = lmp%extract_global("nbonds")
|
||||
f_lammps_extract_global_nbonds = nbonds
|
||||
END FUNCTION f_lammps_extract_global_nbonds
|
||||
FUNCTION f_lammps_extract_global_nbonds_big () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int64_t), POINTER :: nbonds
|
||||
INTEGER (C_int64_t) :: f_lammps_extract_global_nbonds_big
|
||||
|
||||
nbonds = lmp%extract_global("nbonds")
|
||||
f_lammps_extract_global_nbonds_big = nbonds
|
||||
END FUNCTION f_lammps_extract_global_nbonds_big
|
||||
|
||||
FUNCTION f_lammps_extract_global_nangles () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: nangles
|
||||
INTEGER (C_int) :: f_lammps_extract_global_nangles
|
||||
|
||||
nangles = lmp%extract_global("nangles")
|
||||
f_lammps_extract_global_nangles = nangles
|
||||
END FUNCTION f_lammps_extract_global_nangles
|
||||
FUNCTION f_lammps_extract_global_nangles_big () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int64_t), POINTER :: nangles
|
||||
INTEGER (C_int64_t) :: f_lammps_extract_global_nangles_big
|
||||
|
||||
nangles = lmp%extract_global("nangles")
|
||||
f_lammps_extract_global_nangles_big = nangles
|
||||
END FUNCTION f_lammps_extract_global_nangles_big
|
||||
|
||||
FUNCTION f_lammps_extract_global_ndihedrals () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: ndihedrals
|
||||
INTEGER (C_int) :: f_lammps_extract_global_ndihedrals
|
||||
|
||||
ndihedrals = lmp%extract_global("ndihedrals")
|
||||
f_lammps_extract_global_ndihedrals = ndihedrals
|
||||
END FUNCTION f_lammps_extract_global_ndihedrals
|
||||
FUNCTION f_lammps_extract_global_ndihedrals_big () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int64_t), POINTER :: ndihedrals
|
||||
INTEGER (C_int64_t) :: f_lammps_extract_global_ndihedrals_big
|
||||
|
||||
ndihedrals = lmp%extract_global("ndihedrals")
|
||||
f_lammps_extract_global_ndihedrals_big = ndihedrals
|
||||
END FUNCTION f_lammps_extract_global_ndihedrals_big
|
||||
|
||||
FUNCTION f_lammps_extract_global_nimpropers () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: nimpropers
|
||||
INTEGER (C_int) :: f_lammps_extract_global_nimpropers
|
||||
|
||||
nimpropers = lmp%extract_global("nimpropers")
|
||||
f_lammps_extract_global_nimpropers = nimpropers
|
||||
END FUNCTION f_lammps_extract_global_nimpropers
|
||||
FUNCTION f_lammps_extract_global_nimpropers_big () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int64_t
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int64_t), POINTER :: nimpropers
|
||||
INTEGER (C_int64_t) :: f_lammps_extract_global_nimpropers_big
|
||||
|
||||
nimpropers = lmp%extract_global("nimpropers")
|
||||
f_lammps_extract_global_nimpropers_big = nimpropers
|
||||
END FUNCTION f_lammps_extract_global_nimpropers_big
|
||||
|
||||
|
||||
FUNCTION f_lammps_extract_global_ntypes () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: ntypes
|
||||
INTEGER (C_int) :: f_lammps_extract_global_ntypes
|
||||
|
||||
ntypes = lmp%extract_global("ntypes")
|
||||
f_lammps_extract_global_ntypes = ntypes
|
||||
END FUNCTION f_lammps_extract_global_ntypes
|
||||
|
||||
FUNCTION f_lammps_extract_global_nlocal () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: nlocal
|
||||
INTEGER (C_int) :: f_lammps_extract_global_nlocal
|
||||
|
||||
nlocal = lmp%extract_global("nlocal")
|
||||
f_lammps_extract_global_nlocal = nlocal
|
||||
END FUNCTION f_lammps_extract_global_nlocal
|
||||
|
||||
FUNCTION f_lammps_extract_global_nghost () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: nghost
|
||||
INTEGER (C_int) :: f_lammps_extract_global_nghost
|
||||
|
||||
nghost = lmp%extract_global("nghost")
|
||||
f_lammps_extract_global_nghost = nghost
|
||||
END FUNCTION f_lammps_extract_global_nghost
|
||||
|
||||
FUNCTION f_lammps_extract_global_nmax () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int), POINTER :: nmax
|
||||
INTEGER (C_int) :: f_lammps_extract_global_nmax
|
||||
|
||||
nmax = lmp%extract_global("nmax")
|
||||
f_lammps_extract_global_nmax = nmax
|
||||
END FUNCTION f_lammps_extract_global_nmax
|
||||
|
||||
FUNCTION f_lammps_extract_global_boltz () BIND(C) RESULT(C_k_B)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_k_B
|
||||
REAL (C_double), POINTER :: k_B
|
||||
|
||||
k_B = lmp%extract_global("boltz")
|
||||
C_k_B = k_B
|
||||
END FUNCTION f_lammps_extract_global_boltz
|
||||
|
||||
FUNCTION f_lammps_extract_global_hplanck () BIND(C) RESULT(C_h)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: C_h
|
||||
REAL (C_double), POINTER :: h
|
||||
|
||||
h = lmp%extract_global("boltz")
|
||||
C_h = h
|
||||
END FUNCTION f_lammps_extract_global_hplanck
|
||||
|
||||
FUNCTION f_lammps_extract_global_angstrom () BIND(C) RESULT(Angstrom)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: Angstrom
|
||||
REAL (C_double), POINTER :: A
|
||||
|
||||
A = lmp%extract_global("angstrom")
|
||||
Angstrom = A
|
||||
END FUNCTION f_lammps_extract_global_angstrom
|
||||
|
||||
FUNCTION f_lammps_extract_global_femtosecond () BIND(C) RESULT(fs)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE keepglobal, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
REAL (C_double) :: fs
|
||||
REAL (C_double), POINTER :: femtosecond
|
||||
|
||||
femtosecond = lmp%extract_global("femtosecond")
|
||||
fs = femtosecond
|
||||
END FUNCTION f_lammps_extract_global_femtosecond
|
|
@ -0,0 +1,174 @@
|
|||
MODULE keepthermo
|
||||
USE liblammps
|
||||
IMPLICIT NONE
|
||||
TYPE(LAMMPS) :: lmp
|
||||
CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: demo_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
'region box block 0 $x 0 3 0 4', &
|
||||
'create_box 1 box', &
|
||||
'create_atoms 1 single 1.0 1.0 ${zpos}' ]
|
||||
CHARACTER(LEN=40), DIMENSION(2), PARAMETER :: cont_input = &
|
||||
[ CHARACTER(len=40) :: &
|
||||
'create_atoms 1 single &', &
|
||||
' 0.2 0.1 0.1' ]
|
||||
CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: pair_input = &
|
||||
[ CHARACTER(LEN=40) :: &
|
||||
'pair_style lj/cut 2.5', &
|
||||
'pair_coeff 1 1 1.0 1.0', &
|
||||
'mass 1 1.0' ]
|
||||
END MODULE keepthermo
|
||||
|
||||
FUNCTION f_lammps_with_args() BIND(C)
|
||||
USE ISO_C_BINDING, ONLY: c_ptr
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY: lmp
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr) :: f_lammps_with_args
|
||||
|
||||
CHARACTER(len=12), DIMENSION(12), PARAMETER :: args = &
|
||||
[ CHARACTER(len=12) :: 'liblammps', '-log', 'none', &
|
||||
'-echo','screen','-nocite','-var','zpos','1.5','-var','x','2']
|
||||
|
||||
lmp = lammps(args)
|
||||
f_lammps_with_args = lmp%handle
|
||||
END FUNCTION f_lammps_with_args
|
||||
|
||||
SUBROUTINE f_lammps_close() BIND(C)
|
||||
USE ISO_C_BINDING, ONLY: c_null_ptr
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY: lmp
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%close()
|
||||
lmp%handle = c_null_ptr
|
||||
END SUBROUTINE f_lammps_close
|
||||
|
||||
SUBROUTINE f_lammps_get_thermo_setup () BIND(C)
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp, demo_input, cont_input, pair_input
|
||||
IMPLICIT NONE
|
||||
|
||||
CALL lmp%commands_list(demo_input)
|
||||
CALL lmp%commands_list(cont_input)
|
||||
CALL lmp%commands_list(pair_input)
|
||||
END SUBROUTINE f_lammps_get_thermo_setup
|
||||
|
||||
FUNCTION f_lammps_get_thermo_natoms () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_natoms
|
||||
|
||||
f_lammps_get_thermo_natoms = lmp%get_thermo('atoms')
|
||||
END FUNCTION f_lammps_get_thermo_natoms
|
||||
|
||||
FUNCTION f_lammps_get_thermo_dt () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_dt
|
||||
|
||||
f_lammps_get_thermo_dt = lmp%get_thermo('dt')
|
||||
END FUNCTION f_lammps_get_thermo_dt
|
||||
|
||||
FUNCTION f_lammps_get_thermo_vol () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_vol
|
||||
|
||||
f_lammps_get_thermo_vol = lmp%get_thermo('vol')
|
||||
END FUNCTION f_lammps_get_thermo_vol
|
||||
|
||||
FUNCTION f_lammps_get_thermo_lx () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_lx
|
||||
|
||||
f_lammps_get_thermo_lx = lmp%get_thermo('lx')
|
||||
END FUNCTION f_lammps_get_thermo_lx
|
||||
|
||||
FUNCTION f_lammps_get_thermo_ly () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_ly
|
||||
|
||||
f_lammps_get_thermo_ly = lmp%get_thermo('ly')
|
||||
END FUNCTION f_lammps_get_thermo_ly
|
||||
|
||||
FUNCTION f_lammps_get_thermo_lz () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_lz
|
||||
|
||||
f_lammps_get_thermo_lz = lmp%get_thermo('lz')
|
||||
END FUNCTION f_lammps_get_thermo_lz
|
||||
|
||||
FUNCTION f_lammps_get_thermo_xlo () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_xlo
|
||||
|
||||
f_lammps_get_thermo_xlo = lmp%get_thermo('xlo')
|
||||
END FUNCTION f_lammps_get_thermo_xlo
|
||||
|
||||
FUNCTION f_lammps_get_thermo_xhi () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_xhi
|
||||
|
||||
f_lammps_get_thermo_xhi = lmp%get_thermo('xhi')
|
||||
END FUNCTION f_lammps_get_thermo_xhi
|
||||
|
||||
FUNCTION f_lammps_get_thermo_ylo () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_ylo
|
||||
|
||||
f_lammps_get_thermo_ylo = lmp%get_thermo('ylo')
|
||||
END FUNCTION f_lammps_get_thermo_ylo
|
||||
|
||||
FUNCTION f_lammps_get_thermo_yhi () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_yhi
|
||||
|
||||
f_lammps_get_thermo_yhi = lmp%get_thermo('yhi')
|
||||
END FUNCTION f_lammps_get_thermo_yhi
|
||||
|
||||
FUNCTION f_lammps_get_thermo_zlo () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_zlo
|
||||
|
||||
f_lammps_get_thermo_zlo = lmp%get_thermo('zlo')
|
||||
END FUNCTION f_lammps_get_thermo_zlo
|
||||
|
||||
FUNCTION f_lammps_get_thermo_zhi () BIND (C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_double
|
||||
USE liblammps
|
||||
USE keepthermo, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (c_double) :: f_lammps_get_thermo_zhi
|
||||
|
||||
f_lammps_get_thermo_zhi = lmp%get_thermo('zhi')
|
||||
END FUNCTION f_lammps_get_thermo_zhi
|
|
@ -0,0 +1,52 @@
|
|||
FUNCTION f_lammps_version () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE liblammps
|
||||
USE keepcmds, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int) :: f_lammps_version
|
||||
|
||||
f_lammps_version = lmp%version()
|
||||
END FUNCTION f_lammps_version
|
||||
|
||||
SUBROUTINE f_lammps_memory_usage (meminfo) BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double
|
||||
USE liblammps
|
||||
USE keepcmds, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
REAL (C_double), DIMENSION(3), INTENT(OUT) :: meminfo
|
||||
|
||||
CALL lmp%memory_usage(meminfo)
|
||||
END SUBROUTINE f_lammps_memory_usage
|
||||
|
||||
FUNCTION f_lammps_get_mpi_comm () BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int
|
||||
USE liblammps
|
||||
USE keepcmds, ONLY : lmp
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int) :: f_lammps_get_mpi_comm
|
||||
|
||||
f_lammps_get_mpi_comm = lmp%get_mpi_comm()
|
||||
END FUNCTION f_lammps_get_mpi_comm
|
||||
|
||||
FUNCTION f_lammps_extract_setting (Cstr) BIND(C)
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int, C_char
|
||||
USE keepcmds, ONLY : lmp
|
||||
USE LIBLAMMPS
|
||||
IMPLICIT NONE
|
||||
INTEGER (C_int) :: f_lammps_extract_setting
|
||||
CHARACTER (KIND=C_char, LEN=1), DIMENSION(*), INTENT(IN) :: Cstr
|
||||
INTEGER :: strlen, i
|
||||
CHARACTER (LEN=:), ALLOCATABLE :: Fstr
|
||||
|
||||
i = 1
|
||||
DO WHILE (Cstr(i) /= ACHAR(0))
|
||||
i = i + 1
|
||||
END DO
|
||||
strlen = i
|
||||
allocate ( CHARACTER(LEN=strlen) :: Fstr)
|
||||
FORALL (i=1:strlen)
|
||||
Fstr(i:i) = Cstr(i)
|
||||
END FORALL
|
||||
f_lammps_extract_setting = lmp%extract_setting(Fstr)
|
||||
deallocate (Fstr)
|
||||
END FUNCTION f_lammps_extract_setting
|
|
@ -0,0 +1,64 @@
|
|||
// unit tests for extracting box dimensions fom a LAMMPS instance through the Fortran wrapper
|
||||
|
||||
#include "lammps.h"
|
||||
#include <mpi.h>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// prototypes for fortran reverse wrapper functions
|
||||
extern "C" {
|
||||
void *f_lammps_with_args();
|
||||
void f_lammps_close();
|
||||
void f_lammps_box_setup();
|
||||
double f_lammps_extract_box_xlo();
|
||||
double f_lammps_extract_box_xhi();
|
||||
double f_lammps_extract_box_ylo();
|
||||
double f_lammps_extract_box_yhi();
|
||||
double f_lammps_extract_box_zlo();
|
||||
double f_lammps_extract_box_zhi();
|
||||
void f_lammps_delete_everything();
|
||||
void f_lammps_reset_box_2x();
|
||||
}
|
||||
|
||||
class LAMMPS_commands : public ::testing::Test {
|
||||
protected:
|
||||
LAMMPS_NS::LAMMPS *lmp;
|
||||
LAMMPS_commands() = default;
|
||||
~LAMMPS_commands() override = default;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp = (LAMMPS_NS::LAMMPS *)f_lammps_with_args();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 8).c_str(), "LAMMPS (");
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
f_lammps_close();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 16).c_str(), "Total wall time:");
|
||||
lmp = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_commands, get_thermo)
|
||||
{
|
||||
f_lammps_box_setup();
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_xlo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_xhi(), 2.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_ylo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_yhi(), 2.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_zlo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_zhi(), 2.0);
|
||||
f_lammps_delete_everything();
|
||||
f_lammps_reset_box_2x();
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_xlo(),-1.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_xhi(), 3.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_ylo(),-1.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_yhi(), 3.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_zlo(),-1.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_box_zhi(), 3.0);
|
||||
};
|
|
@ -0,0 +1,177 @@
|
|||
// unit tests for extracting global data from a LAMMPS instance through the
|
||||
// Fortran wrapper
|
||||
|
||||
#include "lammps.h"
|
||||
#include "library.h"
|
||||
#include <mpi.h>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// prototypes for Fortran reverse wrapper functions
|
||||
extern "C" {
|
||||
void *f_lammps_with_args();
|
||||
void f_lammps_close();
|
||||
void f_lammps_setup_extract_global();
|
||||
void f_lammps_setup_full_extract_global();
|
||||
int f_lammps_extract_global_units();
|
||||
int f_lammps_extract_global_ntimestep();
|
||||
int64_t f_lammps_extract_global_ntimestep_big();
|
||||
double f_lammps_extract_global_dt();
|
||||
void f_lammps_extract_global_boxlo(double[3]);
|
||||
void f_lammps_extract_global_boxhi(double[3]);
|
||||
double f_lammps_extract_global_boxxlo();
|
||||
double f_lammps_extract_global_boxylo();
|
||||
double f_lammps_extract_global_boxzlo();
|
||||
double f_lammps_extract_global_boxxhi();
|
||||
double f_lammps_extract_global_boxyhi();
|
||||
double f_lammps_extract_global_boxzhi();
|
||||
void f_lammps_extract_global_periodicity(int[3]);
|
||||
int f_lammps_extract_global_triclinic();
|
||||
double f_lammps_extract_global_xy();
|
||||
double f_lammps_extract_global_yz();
|
||||
double f_lammps_extract_global_xz();
|
||||
int f_lammps_extract_global_natoms();
|
||||
int64_t f_lammps_extract_global_natoms_big();
|
||||
int f_lammps_extract_global_nbonds();
|
||||
int64_t f_lammps_extract_global_nbonds_big();
|
||||
int f_lammps_extract_global_nangles();
|
||||
int64_t f_lammps_extract_global_nangles_big();
|
||||
int f_lammps_extract_global_ndihedrals();
|
||||
int64_t f_lammps_extract_global_ndihedrals_big();
|
||||
int f_lammps_extract_global_nimpropers();
|
||||
int64_t f_lammps_extract_global_nimpropers_big();
|
||||
int f_lammps_extract_global_ntypes();
|
||||
int f_lammps_extract_global_nlocal();
|
||||
int f_lammps_extract_global_nghost();
|
||||
int f_lammps_extract_global_nmax();
|
||||
double f_lammps_extract_global_boltz();
|
||||
double f_lammps_extract_global_hplanck();
|
||||
double f_lammps_extract_global_angstrom();
|
||||
double f_lammps_extract_global_femtosecond();
|
||||
}
|
||||
|
||||
class LAMMPS_extract_global : public ::testing::Test {
|
||||
protected:
|
||||
LAMMPS_NS::LAMMPS *lmp;
|
||||
LAMMPS_extract_global() = default;
|
||||
~LAMMPS_extract_global() override = default;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp = (LAMMPS_NS::LAMMPS *)f_lammps_with_args();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 8).c_str(), "LAMMPS (");
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
f_lammps_close();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 16).c_str(), "Total wall time:");
|
||||
lmp = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_extract_global, units)
|
||||
{
|
||||
f_lammps_setup_extract_global();
|
||||
EXPECT_EQ(f_lammps_extract_global_units(), 1);
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_extract_global, ntimestep)
|
||||
{
|
||||
f_lammps_setup_extract_global();
|
||||
#ifdef LAMMPS_SMALLSMALL
|
||||
EXPECT_EQ(f_lammps_extract_global_ntimestep(), 0);
|
||||
#else
|
||||
EXPECT_EQ(f_lammps_extract_global_ntimestep_big(), 0l);
|
||||
#endif
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_extract_global, dt)
|
||||
{
|
||||
f_lammps_setup_extract_global();
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_dt(), 0.005);
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_extract_global, boxprops)
|
||||
{
|
||||
f_lammps_setup_extract_global();
|
||||
double boxlo[3], boxhi[3];
|
||||
f_lammps_extract_global_boxlo(boxlo);
|
||||
EXPECT_DOUBLE_EQ(boxlo[0], 0.0);
|
||||
EXPECT_DOUBLE_EQ(boxlo[1], 0.0);
|
||||
EXPECT_DOUBLE_EQ(boxlo[2], 0.0);
|
||||
f_lammps_extract_global_boxhi(boxhi);
|
||||
EXPECT_DOUBLE_EQ(boxhi[0], 2.0);
|
||||
EXPECT_DOUBLE_EQ(boxhi[1], 3.0);
|
||||
EXPECT_DOUBLE_EQ(boxhi[2], 4.0);
|
||||
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boxxlo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boxxhi(), 2.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boxylo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boxyhi(), 3.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boxzlo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boxzhi(), 4.0);
|
||||
|
||||
int periodicity[3];
|
||||
f_lammps_extract_global_periodicity(periodicity);
|
||||
EXPECT_EQ(periodicity[0], 1);
|
||||
EXPECT_EQ(periodicity[1], 1);
|
||||
EXPECT_EQ(periodicity[2], 1);
|
||||
|
||||
EXPECT_EQ(f_lammps_extract_global_triclinic(), 0);
|
||||
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_xy(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_yz(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_xz(), 0.0);
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_extract_global, atomprops)
|
||||
{
|
||||
f_lammps_setup_extract_global();
|
||||
#ifdef LAMMPS_SMALLSMALL
|
||||
EXPECT_EQ(f_lammps_extract_global_natoms(), 2);
|
||||
EXPECT_EQ(f_lammps_extract_global_nbonds(), 0);
|
||||
EXPECT_EQ(f_lammps_extract_global_nangles(), 0);
|
||||
EXPECT_EQ(f_lammps_extract_global_ndihedrals(), 0);
|
||||
#else
|
||||
EXPECT_EQ(f_lammps_extract_global_natoms_big(), 2l);
|
||||
EXPECT_EQ(f_lammps_extract_global_nbonds_big(), 0l);
|
||||
EXPECT_EQ(f_lammps_extract_global_nangles_big(), 0l);
|
||||
EXPECT_EQ(f_lammps_extract_global_ndihedrals_big(), 0l);
|
||||
#endif
|
||||
|
||||
EXPECT_EQ(f_lammps_extract_global_ntypes(), 1);
|
||||
EXPECT_EQ(f_lammps_extract_global_nlocal(), 2);
|
||||
EXPECT_EQ(f_lammps_extract_global_nghost(), 41);
|
||||
EXPECT_EQ(f_lammps_extract_global_nmax(), 16384);
|
||||
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_boltz(), 1.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_hplanck(), 1.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_angstrom(), 1.0);
|
||||
|
||||
EXPECT_DOUBLE_EQ(f_lammps_extract_global_femtosecond(), 1.0);
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_extract_global, fullprops)
|
||||
{
|
||||
if (! lammps_has_style(lmp, "atom", "full")) GTEST_SKIP();
|
||||
// This is not currently the world's most convincing test....
|
||||
f_lammps_setup_full_extract_global();
|
||||
#ifdef LAMMPS_SMALLSMALL
|
||||
EXPECT_EQ(f_lammps_extract_global_natoms(), 2);
|
||||
EXPECT_EQ(f_lammps_extract_global_nbonds(), 0);
|
||||
EXPECT_EQ(f_lammps_extract_global_nangles(), 0);
|
||||
EXPECT_EQ(f_lammps_extract_global_ndihedrals(), 0);
|
||||
#else
|
||||
EXPECT_EQ(f_lammps_extract_global_natoms_big(), 2l);
|
||||
EXPECT_EQ(f_lammps_extract_global_nbonds_big(), 0l);
|
||||
EXPECT_EQ(f_lammps_extract_global_nangles_big(), 0l);
|
||||
EXPECT_EQ(f_lammps_extract_global_ndihedrals_big(), 0l);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// unit tests for getting thermodynamic output from a LAMMPS instance through the Fortran wrapper
|
||||
|
||||
#include "lammps.h"
|
||||
#include <mpi.h>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// prototypes for fortran reverse wrapper functions
|
||||
extern "C" {
|
||||
void *f_lammps_with_args();
|
||||
void f_lammps_close();
|
||||
void f_lammps_get_thermo_setup();
|
||||
double f_lammps_get_thermo_natoms();
|
||||
double f_lammps_get_thermo_dt();
|
||||
double f_lammps_get_thermo_vol();
|
||||
double f_lammps_get_thermo_lx();
|
||||
double f_lammps_get_thermo_ly();
|
||||
double f_lammps_get_thermo_lz();
|
||||
double f_lammps_get_thermo_xlo();
|
||||
double f_lammps_get_thermo_xhi();
|
||||
double f_lammps_get_thermo_ylo();
|
||||
double f_lammps_get_thermo_yhi();
|
||||
double f_lammps_get_thermo_zlo();
|
||||
double f_lammps_get_thermo_zhi();
|
||||
}
|
||||
|
||||
class LAMMPS_thermo : public ::testing::Test {
|
||||
protected:
|
||||
LAMMPS_NS::LAMMPS *lmp;
|
||||
LAMMPS_thermo() = default;
|
||||
~LAMMPS_thermo() override = default;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp = (LAMMPS_NS::LAMMPS *)f_lammps_with_args();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 8).c_str(), "LAMMPS (");
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
f_lammps_close();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 16).c_str(), "Total wall time:");
|
||||
lmp = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_thermo, get_thermo)
|
||||
{
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_natoms(), 0.0);
|
||||
f_lammps_get_thermo_setup();
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_natoms(), 2.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_dt(), 0.005);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_vol(), 24.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_lx(), 2.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_ly(), 3.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_lz(), 4.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_xlo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_xhi(), 2.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_ylo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_yhi(), 3.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_zlo(), 0.0);
|
||||
EXPECT_DOUBLE_EQ(f_lammps_get_thermo_zhi(), 4.0);
|
||||
};
|
|
@ -0,0 +1,109 @@
|
|||
// unit tests for getting LAMMPS properties through the Fortran wrapper
|
||||
|
||||
#include "lammps.h"
|
||||
//#include <cstdio> // for stdin, stdout
|
||||
#include "library.h"
|
||||
#include <mpi.h>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// prototypes for fortran reverse wrapper functions
|
||||
extern "C" {
|
||||
void *f_lammps_with_args();
|
||||
void f_lammps_close();
|
||||
int f_lammps_version();
|
||||
void f_lammps_memory_usage(double*);
|
||||
int f_lammps_get_mpi_comm();
|
||||
int f_lammps_extract_setting(const char*);
|
||||
}
|
||||
|
||||
class LAMMPS_properties : public ::testing::Test {
|
||||
protected:
|
||||
LAMMPS_NS::LAMMPS *lmp;
|
||||
LAMMPS_properties() = default;
|
||||
~LAMMPS_properties() override = default;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp = (LAMMPS_NS::LAMMPS *)f_lammps_with_args();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 8).c_str(), "LAMMPS (");
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
::testing::internal::CaptureStdout();
|
||||
f_lammps_close();
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
EXPECT_STREQ(output.substr(0, 16).c_str(), "Total wall time:");
|
||||
lmp = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_properties, version)
|
||||
{
|
||||
EXPECT_LT(20200917, f_lammps_version());
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_properties, memory_usage)
|
||||
{
|
||||
// copied from c-library, with a two-character modification
|
||||
double meminfo[3];
|
||||
f_lammps_memory_usage(meminfo);
|
||||
EXPECT_GT(meminfo[0], 0.0);
|
||||
#if defined(__linux__) || defined(_WIN32)
|
||||
EXPECT_GE(meminfo[1], 0.0);
|
||||
#endif
|
||||
#if (defined(__linux__) || defined(__APPLE__) || defined(_WIN32)) && !defined(__INTEL_LLVM_COMPILER)
|
||||
EXPECT_GT(meminfo[2], 0.0);
|
||||
#endif
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_properties, get_mpi_comm)
|
||||
{
|
||||
int f_comm = f_lammps_get_mpi_comm();
|
||||
if ( lammps_config_has_mpi_support() )
|
||||
EXPECT_GE(f_comm, 0);
|
||||
else
|
||||
EXPECT_EQ(f_comm, -1);
|
||||
};
|
||||
|
||||
TEST_F(LAMMPS_properties, extract_setting)
|
||||
{
|
||||
#if defined(LAMMPS_SMALLSMALL)
|
||||
EXPECT_EQ(f_lammps_extract_setting("bigint"), 4);
|
||||
#else
|
||||
EXPECT_EQ(f_lammps_extract_setting("bigint"), 8);
|
||||
#endif
|
||||
#if defined(LAMMPS_BIGBIG)
|
||||
EXPECT_EQ(f_lammps_extract_setting("tagint"), 8);
|
||||
EXPECT_EQ(f_lammps_extract_setting("imageint"), 8);
|
||||
#else
|
||||
EXPECT_EQ(f_lammps_extract_setting("tagint"), 4);
|
||||
EXPECT_EQ(f_lammps_extract_setting("imageint"), 4);
|
||||
#endif
|
||||
|
||||
EXPECT_EQ(f_lammps_extract_setting("box_exist"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("dimension"), 3);
|
||||
EXPECT_EQ(f_lammps_extract_setting("world_size"), 1);
|
||||
EXPECT_EQ(f_lammps_extract_setting("world_rank"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("universe_size"), 1);
|
||||
EXPECT_EQ(f_lammps_extract_setting("universe_rank"), 0);
|
||||
EXPECT_GT(f_lammps_extract_setting("nthreads"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("newton_pair"), 1);
|
||||
EXPECT_EQ(f_lammps_extract_setting("newton_bond"), 1);
|
||||
|
||||
EXPECT_EQ(f_lammps_extract_setting("ntypes"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("nbondtypes"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("nangletypes"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("ndihedraltypes"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("nimpropertypes"), 0);
|
||||
|
||||
EXPECT_EQ(f_lammps_extract_setting("molecule_flag"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("q_flag"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("mu_flag"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("rmass_flag"), 0);
|
||||
EXPECT_EQ(f_lammps_extract_setting("UNKNOWN"), -1);
|
||||
|
||||
};
|
|
@ -45,11 +45,21 @@ class PythonOpen(unittest.TestCase):
|
|||
|
||||
def testWithArgs(self):
|
||||
"""Create LAMMPS instance with a few arguments"""
|
||||
lmp=lammps(name=self.machine,
|
||||
cmdargs=['-nocite','-sf','opt','-log','none'])
|
||||
lmp=lammps(name=self.machine,cmdargs=['-nocite','-sf','opt','-log','none'])
|
||||
self.assertIsNot(lmp.lmp,None)
|
||||
self.assertEqual(lmp.opened,1)
|
||||
|
||||
def testError(self):
|
||||
"""Print warning message through LAMMPS Error class"""
|
||||
lmp=lammps(name=self.machine,cmdargs=['-nocite','-log','none','-screen','tmp.error.output'])
|
||||
lmp.error(0,'test_warning')
|
||||
lmp.close()
|
||||
with open('tmp.error.output','r') as f:
|
||||
output = f.read()
|
||||
self.assertTrue('LAMMPS' in output)
|
||||
self.assertTrue('Total wall time' in output)
|
||||
self.assertTrue('WARNING: test_warning' in output)
|
||||
|
||||
def testContextManager(self):
|
||||
"""Automatically clean up LAMMPS instance"""
|
||||
with lammps(name=self.machine) as lmp:
|
||||
|
|
Loading…
Reference in New Issue