diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 60ac3f70c0..42e6d12ffb 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -379,6 +379,13 @@ foreach(PKG_WITH_INCL KSPACE PYTHON VORONOI USER-COLVARS USER-MOLFILE USER-NETCD endif() endforeach() +# optionally enable building script wrappers using swig +option(WITH_SWIG "Build scripting language wrappers with SWIG" OFF) +if(WITH_SWIG) + get_filename_component(LAMMPS_SWIG_DIR ${LAMMPS_SOURCE_DIR}/../tools/swig ABSOLUTE) + add_subdirectory(${LAMMPS_SWIG_DIR} swig) +endif() + set(CMAKE_TUNE_FLAGS "${CMAKE_TUNE_DEFAULT}" CACHE STRING "Compiler and machine specific optimization flags (compilation only)") separate_arguments(CMAKE_TUNE_FLAGS) foreach(_FLAG ${CMAKE_TUNE_FLAGS}) diff --git a/cmake/presets/mingw-cross.cmake b/cmake/presets/mingw-cross.cmake index d187586df8..32b17d43c2 100644 --- a/cmake/presets/mingw-cross.cmake +++ b/cmake/presets/mingw-cross.cmake @@ -23,7 +23,7 @@ set(DOWNLOAD_VORO ON CACHE BOOL "" FORCE) set(DOWNLOAD_EIGEN3 ON CACHE BOOL "" FORCE) set(LAMMPS_MEMALIGN "0" CACHE STRING "" FORCE) set(CMAKE_TUNE_FLAGS "-Wno-missing-include-dirs" CACHE STRING "" FORCE) -set(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-stdcall-fixup" CACHE STRING "" FORCE) -set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-stdcall-fixup" CACHE STRING "" FORCE) +set(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-stdcall-fixup,--as-needed,-lssp" CACHE STRING "" FORCE) +set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-stdcall-fixup,--as-needed,-lssp" CACHE STRING "" FORCE) set(BUILD_TOOLS ON CACHE BOOL "" FORCE) set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/lammps-installer") diff --git a/doc/src/Modify_compute.rst b/doc/src/Modify_compute.rst index 8fad775b3a..e910d6f8e2 100644 --- a/doc/src/Modify_compute.rst +++ b/doc/src/Modify_compute.rst @@ -53,5 +53,5 @@ in two stages: the callback function is registered with the pair style and then called from the Pair::ev_tally() function, which is called for each pair after force and energy has been computed for this pair. Then the tallied values are retrieved with the standard compute_scalar or -compute_vector or compute_peratom methods. The USER-TALLY package -provides *examples*\ _compute_tally.html for utilizing this mechanism. +compute_vector or compute_peratom methods. The :doc:`compute styles in the USER-TALLY package ` +provide *examples* for utilizing this mechanism. diff --git a/doc/src/Python_examples.rst b/doc/src/Python_examples.rst index 60184bc450..7466b52ba9 100644 --- a/doc/src/Python_examples.rst +++ b/doc/src/Python_examples.rst @@ -21,7 +21,7 @@ distribution. +------------------------+--------------------------------------------------------------------+ | ``gui.py`` | GUI go/stop/temperature-slider to control LAMMPS | +------------------------+--------------------------------------------------------------------+ -| ``plot.py`` | real-time temperature plot with GnuPlot via Pizza.py | +| ``plot.py`` | real-time temperature plot with GnuPlot via Pizza.py | +------------------------+--------------------------------------------------------------------+ | ``viz_TOOL.py`` | real-time viz via some viz package | +------------------------+--------------------------------------------------------------------+ diff --git a/doc/src/Tools.rst b/doc/src/Tools.rst index 78cb6ea32e..8f0c06adec 100644 --- a/doc/src/Tools.rst +++ b/doc/src/Tools.rst @@ -94,6 +94,7 @@ Miscellaneous tools * :ref:`kate ` * :ref:`LAMMPS shell ` * :ref:`singularity ` + * :ref:`SWIG interface ` * :ref:`vim ` ---------- @@ -559,6 +560,8 @@ More details about this are in the `readline documentation `_ offers a mostly automated way to +incorporate compiled code modules into scripting languages. It +processes the function prototypes in C and generates wrappers for a wide +variety of scripting languages from it. Thus it can also be applied to +the :doc:`C language library interface ` of LAMMPS so that +build a wrapper that allows to call LAMMPS from programming languages +like: C#/Mono, Lua, Java, JavaScript, Perl, Python, R, Ruby, Tcl, and +more. + +What is included +^^^^^^^^^^^^^^^^ + +We provide here an "interface file", ``lammps.i``, that has the content +of the ``library.h`` file adapted so SWIG can process it. That will +create wrappers for all the functions that are present in the LAMMPS C +library interface. Please note that not all kinds of C functions can be +automatically translated, so you would have to add custom functions to +be able to utilize those where the automatic translation does not work. +A few functions for converting pointers and accessing arrays are +predefined. We provide the file here on an "as is" basis to help people +getting started, but not as a fully tested and supported feature of the +LAMMPS distribution. Any contributions to complete this are, of course, +welcome. Please also note, that for the case of creating a Python wrapper, +a fully supported :doc:`Ctypes based lammps module ` +already exists. That module is designed to be object oriented while +SWIG will generate a 1:1 translation of the functions in the interface file. + +Building the wrapper +^^^^^^^^^^^^^^^^^^^^ + +When using CMake, the build steps for building a wrapper +module are integrated for the languages: Java, Lua, +Perl5, Python, Ruby, and Tcl. These require that the +LAMMPS library is build as a shared library and all +necessary development headers and libraries are present. + +.. code-block:: bash + + -D WITH_SWIG=on # to enable building any SWIG wrapper + -D BUILD_SWIG_JAVA=on # to enable building the Java wrapper + -D BUILD_SWIG_LUA=on # to enable building the Lua wrapper + -D BUILD_SWIG_PERL5=on # to enable building the Perl 5.x wrapper + -D BUILD_SWIG_PYTHON=on # to enable building the Python wrapper + -D BUILD_SWIG_RUBY=on # to enable building the Ruby wrapper + -D BUILD_SWIG_TCL=on # to enable building the Tcl wrapper + + +Manual building allows a little more flexibility. E.g. one can choose +the name of the module and build and use a dynamically loaded object +for Tcl with: + +.. code-block:: bash + + $ swig -tcl -module tcllammps lammps.i + $ gcc -fPIC -shared $(pkgconf --cflags tcl) -o tcllammps.so \ + lammps_wrap.c -L ../src/ -llammps + $ tclsh + +Or one can build an extended Tcl shell command with the wrapped +functions included with: + +.. code-block:: bash + + $ swig -tcl -module tcllmps lammps_shell.i + $ gcc -o tcllmpsh lammps_wrap.c -Xlinker -export-dynamic \ + -DHAVE_CONFIG_H $(pkgconf --cflags tcl) \ + $(pkgconf --libs tcl) -L ../src -llammps + +In both cases it is assumed that the LAMMPS library was compiled +as a shared library in the ``src`` folder. Otherwise the last +part of the commands needs to be adjusted. + +Utility functions +^^^^^^^^^^^^^^^^^ + +Definitions for several utility functions required to manage and access +data passed or returned as pointers are included in the ``lammps.i`` +file. So most of the functionality of the library interface should be +accessible. What works and what does not depends a bit on the +individual language for which the wrappers are built and how well SWIG +supports those. The `SWIG documentation `_ +has very detailed instructions and recommendations. + +Usage examples +^^^^^^^^^^^^^^ + +The ``tools/swig`` folder has multiple shell scripts, ``run__example.sh`` +that will create a small example script and demonstrate how to load +the wrapper and run LAMMPS through it in the corresponding programming +language. + +For illustration purposes below is a part of the Tcl example script. + +.. code-block:: tcl + + % load ./tcllammps.so + % set lmp [lammps_open_no_mpi 0 NULL NULL] + % lammps_command $lmp "units real" + % lammps_command $lmp "lattice fcc 2.5" + % lammps_command $lmp "region box block -5 5 -5 5 -5 5" + % lammps_command $lmp "create_box 1 box" + % lammps_command $lmp "create_atoms 1 box" + % + % set dt [doublep_value [voidp_to_doublep [lammps_extract_global $lmp dt]]] + % puts "LAMMPS version $ver" + % puts [format "Number of created atoms: %g" [lammps_get_natoms $lmp]] + % puts "Current size of timestep: $dt" + % puts "LAMMPS version: [lammps_version $lmp]" + % lammps_close $lmp + +---------- + .. _vim: vim tool diff --git a/doc/src/compute_angle.rst b/doc/src/compute_angle.rst index d028cdec99..f3e5ee93c0 100644 --- a/doc/src/compute_angle.rst +++ b/doc/src/compute_angle.rst @@ -24,8 +24,8 @@ Description """"""""""" Define a computation that extracts the angle energy calculated by each -of the angle sub-styles used in the "angle_style -hybrid" angle_hybrid.html command. These values are made accessible +of the angle sub-styles used in the doc:`angle_style hybrid ` +command. These values are made accessible for output or further processing by other commands. The group specified for this command is ignored. diff --git a/doc/src/fix_nh_uef.rst b/doc/src/fix_nh_uef.rst index 1c1e7a11d2..74e61472c6 100644 --- a/doc/src/fix_nh_uef.rst +++ b/doc/src/fix_nh_uef.rst @@ -222,9 +222,9 @@ Default """"""" The default keyword values specific to this fix are exy = xyz, strain -= 0 0. The remaining defaults are the same as for *fix -npt*\ _fix_nh.html except tchain = 1. The reason for this change is -given in :doc:`fix nvt/sllod `. += 0 0. The remaining defaults are the same as for :doc:`fix npt ` +except tchain = 1. The reason for this change is given in +:doc:`fix nvt/sllod `. ---------- diff --git a/doc/src/pair_eam.rst b/doc/src/pair_eam.rst index e2b6957032..7d0c191375 100644 --- a/doc/src/pair_eam.rst +++ b/doc/src/pair_eam.rst @@ -345,9 +345,9 @@ given by \rho_{\alpha\beta} (r_{ij})\right) + \frac{1}{2} \sum_{j \neq i} \phi_{\alpha\beta} (r_{ij}) -where :math:`\rho_{\alpha\beta}` refers to the density contributed +where :math:`\rho_{\alpha\beta}` refers to the density contributed by a neighbor atom J of element :math:`\beta` at the site of atom I -of element :math:`\alpha`. +of element :math:`\alpha`. This has the same form as the EAM formula above, except that rho is now a functional specific to the elements of both atoms I and J, so that different elements can contribute differently to the total @@ -408,7 +408,7 @@ each with the following format: The units of these quantities in line 1 are the same as for *setfl* files. Note that the rho(r) arrays in Finnis/Sinclair can be -asymmetric (:math:`\rho_{\alpha\beta} (r) \neq \rho_{\beta\alpha} (r)` ) +asymmetric (:math:`\rho_{\alpha\beta} (r) \neq \rho_{\beta\alpha} (r)` ) so there are Nelements\^2 of them listed in the file. Following the Nelements sections, Nr values for each pair potential diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 2c17f93df4..3ef0b904eb 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1713,6 +1713,7 @@ lsfftw ltbbmalloc lubricateU lucy +Lua Luding Lussetti Lustig @@ -3035,6 +3036,7 @@ taubi tb tchain Tchain +Tcl Tcom tcsh tdamp diff --git a/examples/COUPLE/README b/examples/COUPLE/README index 5a9f297b0f..a7053ade2f 100644 --- a/examples/COUPLE/README +++ b/examples/COUPLE/README @@ -11,11 +11,11 @@ library. See these sections of the LAMMPS manual for details: -Build LAMMPS as a library (doc/Build_basics.html) -Link LAMMPS as a library to another code (doc/Build_link.html) -Coupling LAMMPS to other codes (doc/Howto_couple.html) -Using LAMMPS in client/server mode (doc/Howto_client_server.html) -Library interface to LAMMPS (doc/Howto_library.html) +Build LAMMPS as a library (doc/html/Build_basics.html) +Link LAMMPS as a library to another code (doc/html/Build_link.html) +Coupling LAMMPS to other codes (doc/html/Howto_couple.html) +Using LAMMPS in client/server mode (doc/html/Howto_client_server.html) +Library interface to LAMMPS (doc/html/Howto_library.html) The library interface to LAMMPS is in src/library.cpp. Routines can be easily added to this file so an external program can perform the @@ -25,23 +25,23 @@ LAMMPS tasks desired. These are the sub-directories included in this directory: -simple simple example of driver code calling LAMMPS as a lib -multiple example of driver code calling multiple instances of LAMMPS +simple simple example of driver code calling LAMMPS as a lib +multiple example of driver code calling multiple instances of LAMMPS plugin example for loading LAMMPS at runtime from a shared library lammps_mc client/server coupling of Monte Carlo client with LAMMPS server for energy evaluation lammps_nwchem client/server coupling of LAMMPS client with NWChem quantum DFT as server for quantum forces -lammps_quest MD with quantum forces, coupling to Quest DFT code -lammps_spparks grain-growth Monte Carlo with strain via MD, - coupling to SPPARKS kinetic MC code +lammps_quest MD with quantum forces, coupling to Quest DFT code +lammps_spparks grain-growth Monte Carlo with strain via MD, + coupling to SPPARKS kinetic MC code lammps_vasp client/server coupling of LAMMPS client with VASP quantum DFT as server for quantum forces -library collection of useful inter-code communication routines +library collection of useful inter-code communication routines fortran a simple wrapper on the LAMMPS library API that - can be called from Fortran + can be called from Fortran fortran2 a more sophisticated wrapper on the LAMMPS library API that - can be called from Fortran + can be called from Fortran fortran_dftb wrapper written by Nir Goldman (LLNL), as an extension to fortran2, used for calling LAMMPS from Fortran DFTB+ tight-binding code diff --git a/examples/COUPLE/lammps_mc/README b/examples/COUPLE/lammps_mc/README index c201a6351c..4aed39dc8e 100644 --- a/examples/COUPLE/lammps_mc/README +++ b/examples/COUPLE/lammps_mc/README @@ -1,8 +1,8 @@ Sample Monte Carlo (MC) wrapper on LAMMPS via client/server coupling -See the MESSAGE package (doc/Section_messages.html#MESSAGE) -and Section_howto.html#howto10 for more details on how -client/server coupling works in LAMMPS. +See the MESSAGE package documentation Build_extras.html#message +and Build_extras.html#message for more details on how client/server +coupling works in LAMMPS. In this dir, the mc.cpp/h files are a standalone "client" MC code. It should be run on a single processor, though it could become a parallel @@ -94,18 +94,18 @@ background. File mode of messaging: % mpirun -np 1 mc in.mc file tmp.couple -% mpirun -np 1 lmp_mpi -v mode file < in.mc.server +% mpirun -np 1 lmp_mpi -v mode file -in in.mc.server % mpirun -np 1 mc in.mc file tmp.couple -% mpirun -np 4 lmp_mpi -v mode file < in.mc.server +% mpirun -np 4 lmp_mpi -v mode file -in in.mc.server ZMQ mode of messaging: % mpirun -np 1 mc in.mc zmq localhost:5555 -% mpirun -np 1 lmp_mpi -v mode zmq < in.mc.server +% mpirun -np 1 lmp_mpi -v mode zmq -in in.mc.server % mpirun -np 1 mc in.mc zmq localhost:5555 -% mpirun -np 4 lmp_mpi -v mode zmq < in.mc.server +% mpirun -np 4 lmp_mpi -v mode zmq -in in.mc.server -------------- diff --git a/examples/COUPLE/lammps_nwchem/README b/examples/COUPLE/lammps_nwchem/README index cb5c5b58cf..fc0f0cf868 100644 --- a/examples/COUPLE/lammps_nwchem/README +++ b/examples/COUPLE/lammps_nwchem/README @@ -1,7 +1,7 @@ Sample LAMMPS MD wrapper on NWChem via client/server coupling -See the MESSAGE package (doc/Section_messages.html#MESSAGE) and -Section_howto.html#howto10 for more details on how client/server +See the MESSAGE package documentation Build_extras.html#message +and Build_extras.html#message for more details on how client/server coupling works in LAMMPS. In this dir, the nwchem_wrap.py is a wrapper on the NWChem electronic @@ -182,16 +182,16 @@ background. File mode of messaging: -% mpirun -np 1 lmp_mpi -v mode file < in.client.W +% mpirun -np 1 lmp_mpi -v mode file -in in.client.W % python nwchem_wrap.py file pw w.nw -% mpirun -np 2 lmp_mpi -v mode file < in.client.h2o +% mpirun -np 2 lmp_mpi -v mode file -in in.client.h2o % python nwchem_wrap.py file ao h2o.nw ZMQ mode of messaging: -% mpirun -np 1 lmp_mpi -v mode zmq < in.client.W +% mpirun -np 1 lmp_mpi -v mode zmq -in in.client.W % python nwchem_wrap.py zmq pw w.nw -% mpirun -np 2 lmp_mpi -v mode zmq < in.client.h2o +% mpirun -np 2 lmp_mpi -v mode zmq -in in.client.h2o % python nwchem_wrap.py zmq ao h2o.nw diff --git a/examples/COUPLE/lammps_spparks/README b/examples/COUPLE/lammps_spparks/README index fc31de5f0b..c8365ae8e8 100644 --- a/examples/COUPLE/lammps_spparks/README +++ b/examples/COUPLE/lammps_spparks/README @@ -16,11 +16,11 @@ Lennard-Jones sigma between particles of different types that is larger than the sigma between particles of the same type (interior to grains). -lmpspk.cpp main program - it links LAMMPS and SPPARKS as libraries -in.spparks SPPARKS input script, without the run command -lmppath.h contains path to LAMMPS home directory -spkpath.h contains path to SPPARKS home directory +lmpspk.cpp main program + it links LAMMPS and SPPARKS as libraries +in.spparks SPPARKS input script, without the run command +lmppath.h contains path to LAMMPS home directory +spkpath.h contains path to SPPARKS home directory After editing the Makefile, lmppath.h, and spkpath.h to make them suitable for your box, type: diff --git a/examples/COUPLE/lammps_vasp/README b/examples/COUPLE/lammps_vasp/README index e942d52535..d81a5326e6 100644 --- a/examples/COUPLE/lammps_vasp/README +++ b/examples/COUPLE/lammps_vasp/README @@ -1,8 +1,8 @@ Sample LAMMPS MD wrapper on VASP quantum DFT via client/server coupling -See the MESSAGE package (doc/Section_messages.html#MESSAGE) and -Section_howto.html#howto10 for more details on how client/server +See the MESSAGE package documentation Build_extras.html#message +and Build_extras.html#message for more details on how client/server coupling works in LAMMPS. In this dir, the vasp_wrap.py is a wrapper on the VASP quantum DFT @@ -134,16 +134,16 @@ background. File mode of messaging: -% mpirun -np 1 lmp_mpi -v mode file < in.client.W +% mpirun -np 1 lmp_mpi -v mode file -in in.client.W % python vasp_wrap.py file POSCAR_W -% mpirun -np 2 lmp_mpi -v mode file < in.client.W +% mpirun -np 2 lmp_mpi -v mode file -in in.client.W % python vasp_wrap.py file POSCAR_W ZMQ mode of messaging: -% mpirun -np 1 lmp_mpi -v mode zmq < in.client.W +% mpirun -np 1 lmp_mpi -v mode zmq -in in.client.W % python vasp_wrap.py zmq POSCAR_W -% mpirun -np 2 lmp_mpi -v mode zmq < in.client.W +% mpirun -np 2 lmp_mpi -v mode zmq -in in.client.W % python vasp_wrap.py zmq POSCAR_W diff --git a/examples/README b/examples/README index 2ec7dc7a82..7eaa63bbd1 100644 --- a/examples/README +++ b/examples/README @@ -179,7 +179,7 @@ the same simulation in different unit systems. The USER directory contains subdirectories of user-provided example scripts for ser packages. See the README files in those directories -for more info. See the doc/Section_start.html file for more info +for more info. See the doc/html/Build_package.html file for more info about installing and building user packages. The VISCOSITY directory has example scripts for computing the diff --git a/examples/USER/misc/ipi/README b/examples/USER/misc/ipi/README index c3ecdea88d..d093cea4c5 100644 --- a/examples/USER/misc/ipi/README +++ b/examples/USER/misc/ipi/README @@ -36,7 +36,7 @@ In a separate terminal, then, you should run LAMMPS compiled to provide fix_ipi functionalities. ```bash - $LAMMPS < in.graphene + $LAMMPS -in in.graphene ``` You can run multiple instances of LAMMPS if you want to exploit the diff --git a/examples/message/README b/examples/message/README index 6cd99d5c09..6db735803e 100644 --- a/examples/message/README +++ b/examples/message/README @@ -11,9 +11,8 @@ LAMMPS as the server, e.g. a quantum code computing quantum forces, so that ab initio MD could be performed. See an example of the latter in examples/COUPLE/lammps_vasp. -See the doc pages for the "MESSAGE package" -(Package_details.html#PKG-MESSAGE) and "Howto client/server" -(Howto_client_server.html) for more details on how client/server +See the MESSAGE package documentation Build_extras.html#message +and Build_extras.html#message for more details on how client/server coupling works in LAMMPS. -------------- @@ -30,7 +29,7 @@ You can also run the in.message scripts with an NPT integrator instead of NVE, if you comment/uncomment the correct lines. The client and server script define a "mode" variable -which can be set to file, zmq, mpi/one, or mpi/two, +which can be set to file, zmq, mpi/one, or mpi/two, as illustrated below. -------------- @@ -38,8 +37,8 @@ as illustrated below. To run this problem in the traditional way (no client/server coupling) do one of these: -% lmp_serial < in.message -% mpirun -np 4 lmp_mpi < in.message +% lmp_serial -in in.message +% mpirun -np 4 lmp_mpi -in in.message Or run with in.message.tilt. @@ -87,14 +86,14 @@ runs listed below. File or ZMQ or mpi/two modes of messaging: -% mpirun -np 1 lmp_mpi -v mode file -log log.client < in.message.client & -% mpirun -np 2 lmp_mpi -v mode file -log log.server < in.message.server +% mpirun -np 1 lmp_mpi -v mode file -log log.client -in in.message.client & +% mpirun -np 2 lmp_mpi -v mode file -log log.server -in in.message.server -% mpirun -np 4 lmp_mpi -v mode zmq -log log.client < in.message.client & -% mpirun -np 1 lmp_mpi -v mode zmq -log log.server < in.message.server +% mpirun -np 4 lmp_mpi -v mode zmq -log log.client -in in.message.client & +% mpirun -np 1 lmp_mpi -v mode zmq -log log.server -in in.message.server -% mpirun -np 2 lmp_mpi -v mode mpitwo -log log.client < in.message.client & -% mpirun -np 4 lmp_mpi -v mode mpitwo -log log.server < in.message.server +% mpirun -np 2 lmp_mpi -v mode mpitwo -log log.client -in in.message.client & +% mpirun -np 4 lmp_mpi -v mode mpitwo -log log.server -in in.message.server Or run with in.message.tilt.client/server. Don't run the tilt files with the "file" mode; they run too slow. diff --git a/examples/peptide/README b/examples/peptide/README deleted file mode 100644 index a4338e09df..0000000000 --- a/examples/peptide/README +++ /dev/null @@ -1,8 +0,0 @@ -If you get bogus, large energies on timestep 0 when you run this -example in.peptide, you likely have a machine/compiler problem with -the pair_style "long" potentials which use Coulombic tabling by -default. - -See the "Additional build tips" sub-section of the manual in -Section_start.html in the "Making LAMMPS" section for details and -suggestions on how to work around this issue. diff --git a/src/USER-MISC/README b/src/USER-MISC/README index ffb1210efa..f98268762f 100644 --- a/src/USER-MISC/README +++ b/src/USER-MISC/README @@ -6,7 +6,7 @@ More information about each feature can be found by reading its doc page in the LAMMPS doc directory. The doc page which lists all LAMMPS input script commands is as follows: -doc/Section_commands.html, subsection 3.5 +doc/Commands_all.html User-contributed features are listed at the bottom of the fix, compute, pair, etc sections. diff --git a/tools/README b/tools/README index e98e552b61..af9a699145 100644 --- a/tools/README +++ b/tools/README @@ -46,6 +46,7 @@ replica tool to reorder LAMMPS replica trajectories according to singularity Singularity container descriptions suitable for LAMMPS development smd convert Smooth Mach Dynamics triangles to VTK spin perform a cubic polynomial interpolation of a GNEB MEP +swig SWIG generated script language wrappers for the LAMMPS C library interface valgrind suppression files for use with valgrind's memcheck tool vim add-ons to VIM editor for editing LAMMPS input scripts xmgrace a collection of scripts to generate xmgrace plots diff --git a/tools/swig/CMakeLists.txt b/tools/swig/CMakeLists.txt new file mode 100644 index 0000000000..b17b8c23e4 --- /dev/null +++ b/tools/swig/CMakeLists.txt @@ -0,0 +1,100 @@ +# CMake configuration for generating script language interfaces with SWIG + +# set minimum CMake version required and switch to new policies for SWIG +cmake_minimum_required(VERSION 3.14) +if(POLICY CMP0078) + cmake_policy(SET CMP0078 NEW) +endif() +if(POLICY CMP0086) + cmake_policy(SET CMP0086 NEW) +endif() +enable_language(C) + +# some of the find_package() scripts trigger developer warnings +# even though they are bundled with CMake; Suppress them +set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS TRUE) + +if(NOT BUILD_SHARED_LIBS) + message(FATAL_ERROR "Option BUILD_SHARED_LIBS must be enabled to use SWIG wrappers") +endif() + +find_package(SWIG REQUIRED) +include(${SWIG_USE_FILE}) + +option(BUILD_SWIG_JAVA "Build Java JNI wrapper with SWIG" OFF) +option(BUILD_SWIG_LUA "Build Lua wrapper with SWIG" OFF) +option(BUILD_SWIG_PERL5 "Build Perl5 wrapper with SWIG" OFF) +option(BUILD_SWIG_PYTHON "Build Python wrapper with SWIG" OFF) +option(BUILD_SWIG_RUBY "Build Ruby wrapper with SWIG" OFF) +option(BUILD_SWIG_TCL "Build Tcl wrapper with SWIG" OFF) + +set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES + pllammps.pm __pycache__ log.lammps + example.class example.java example.lua example.pl example.py example.rb example.tcl example.tcllmp + javalammps.class javalammpsJNI.class javalammps.java javalammpsJNI.java + _LMP_DATATYPE_CONST.class _LMP_STYLE_CONST.class _LMP_TYPE_CONST.class + _LMP_DATATYPE_CONST.java _LMP_STYLE_CONST.java _LMP_TYPE_CONST.java + SWIGTYPE_p_double.class SWIGTYPE_p_int.class SWIGTYPE_p_p_char.class SWIGTYPE_p_p_double.class + SWIGTYPE_p_p_int.class SWIGTYPE_p_p_void.class SWIGTYPE_p_void.class + SWIGTYPE_p_double.java SWIGTYPE_p_int.java SWIGTYPE_p_p_char.java SWIGTYPE_p_p_double.java + SWIGTYPE_p_p_int.java SWIGTYPE_p_p_void.java SWIGTYPE_p_void.java) + +if(BUILD_SWIG_JAVA) + set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME javalammps) + swig_add_library(javalammps TYPE MODULE LANGUAGE java SOURCES lammps.i) + find_package(JNI REQUIRED) + target_include_directories(javalammps PRIVATE ${JNI_INCLUDE_DIRS}) + swig_link_libraries(javalammps PRIVATE lammps ${JNI_LIBRARIES}) + configure_file(run_java_example.sh run_java_example.sh COPYONLY) +endif() + +if(BUILD_SWIG_LUA) + set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME lualammps) + swig_add_library(lualammps TYPE MODULE LANGUAGE lua SOURCES lammps.i) + find_package(Lua REQUIRED) + target_include_directories(lualammps PRIVATE ${LUA_INCLUDE_PATH}) + swig_link_libraries(lualammps PRIVATE lammps ${LUA_LIBRARY}) + configure_file(run_lua_example.sh run_lua_example.sh COPYONLY) +endif() + +if(BUILD_SWIG_PERL5) + set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME pllammps) + swig_add_library(pllammps TYPE MODULE LANGUAGE perl5 SOURCES lammps.i) + find_package(PerlLibs REQUIRED 5.0) + target_compile_definitions(pllammps PRIVATE _LARGEFILE64_SOURCE) + target_include_directories(pllammps PRIVATE ${PERL_INCLUDE_PATH}) + swig_link_libraries(pllammps PRIVATE lammps ${PERL_LIBRARY}) + configure_file(run_perl_example.sh run_perl_example.sh COPYONLY) +endif() + +if(BUILD_SWIG_PYTHON) + set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME pylammps) + swig_add_library(pylammps TYPE MODULE LANGUAGE python SOURCES lammps.i) + find_package(Python REQUIRED COMPONENTS Development) + swig_link_libraries(pylammps PRIVATE lammps Python::Python) + configure_file(run_python_example.sh run_python_example.sh COPYONLY) +endif() + +if(BUILD_SWIG_RUBY) + set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME rubylammps) + swig_add_library(rubylammps TYPE MODULE LANGUAGE ruby SOURCES lammps.i) + find_package(Ruby REQUIRED) + target_include_directories(rubylammps PRIVATE ${RUBY_INCLUDE_DIRS}) + swig_link_libraries(rubylammps PRIVATE lammps ${RUBY_LIBRARY}) + configure_file(run_ruby_example.sh run_ruby_example.sh COPYONLY) +endif() + +if(BUILD_SWIG_TCL) + set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME tcllammps) + swig_add_library(tcllammps TYPE MODULE LANGUAGE tcl SOURCES lammps.i) + find_package(TCL REQUIRED) + target_include_directories(tcllammps PRIVATE ${TCL_INCLUDE_PATH}) + swig_link_libraries(tcllammps PRIVATE lammps ${TCL_LIBRARY}) + configure_file(run_tcl_example.sh run_tcl_example.sh COPYONLY) + set_property(SOURCE lammps_shell.i PROPERTY SWIG_MODULE_NAME tcllmpsh) + swig_add_library(libtcllmpsh TYPE STATIC LANGUAGE tcl SOURCES lammps_shell.i) + add_executable(tcllmpsh tcldummy.c) + target_include_directories(tcllmpsh PRIVATE ${TCL_INCLUDE_PATH}) + target_link_libraries(tcllmpsh PRIVATE libtcllmpsh lammps ${TCL_LIBRARY}) +endif() + diff --git a/tools/swig/README b/tools/swig/README new file mode 100644 index 0000000000..77950bbb9f --- /dev/null +++ b/tools/swig/README @@ -0,0 +1,36 @@ +SWIG generated script library wrappers + +The SWIG tool ( http://swig.org ) offers a mostly automated way to +incorporate compiled code modules into scripting languages. It +processes the function prototypes in C and generates wrappers for a wide +variety of scripting languages from it. + +We provide here an "interface file", "lammps.i", that has the content of +the "library.h" file adapted so SWIG can process it. Please note that +not all kinds of C functions can be automatically translated, so you +would have to add custom functions to be able to utilize them. A few +functions for converting pointers and accessing arrays are predefined. +We provide the files here on an "as is" basis to help people getting +started, but not as a fully tested and supported feature of the +distribution. Any contributions to complete this are, of course, +welcome. + +In the case of Python, a fully supported and complete wrapper already +exists in the "lammps" module in the "python" folder. This wrapper is +based on Ctypes and is object oriented while SWIG will generate a 1:1 +translation of the functions in the interface file. + +When using the CMake build system, steps for building wrapper modules +are integrated for the languages: Java, Lua, Perl5, Python, Ruby, and +Tcl and can be selected during the configuration step. These require +that the LAMMPS library is build as a shared library and all necessary +development headers and libraries of the selected script languages are +present. To demonstrate the resulting wrappers, several example shell +scripts (run_*_example.sh) are provided that contain commands to create +an example script file and to demonstrate the use of the wrapped library +functions in the respective programming language. + +For details on how to build and adjust wrappers for individual +languages please refer to the SWIG documentation at http://swig.org/doc.html + +This functionality has been tested on Fedora 32 with SWIG 4.0.1. diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i new file mode 100644 index 0000000000..e28240b8ef --- /dev/null +++ b/tools/swig/lammps.i @@ -0,0 +1,255 @@ +%include "cpointer.i" +%include "carrays.i" +%include "cdata.i" +%include "cstring.i" + +%pointer_functions(int, int_p); +%pointer_functions(int, int64_p); +%pointer_functions(double, double_p); + +%array_functions(char, char_1d); +%array_functions(int, int_1d); +%array_functions(double, double_1d); + +%pointer_cast(void *, int *, void_p_to_int_p); +%pointer_cast(void *, int **, void_p_to_int2d_p); +%pointer_cast(void *, int *, void_p_to_int64_p); +%pointer_cast(void *, int **, void_p_to_int64_2d_p); +%pointer_cast(void *, double *, void_p_to_double_p); +%pointer_cast(void *, double **, void_p_to_double_2d_p); + +%cstring_output_maxsize(char *buffer, int buf_size); + +%{ + +enum _LMP_DATATYPE_CONST { + 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 */ +}; + +/** Style constants for extracting data from computes and fixes. + * + * Must be kept in sync with the equivalent constants in lammps.py */ + +enum _LMP_STYLE_CONST { + LMP_STYLE_GLOBAL=0, /*!< return global data */ + LMP_STYLE_ATOM =1, /*!< return per-atom data */ + LMP_STYLE_LOCAL =2 /*!< return local data */ +}; + +/** Type and size constants for extracting data from computes and fixes. + * + * Must be kept in sync with the equivalent constants in lammps.py */ + +enum _LMP_TYPE_CONST { + LMP_TYPE_SCALAR=0, /*!< return scalar */ + LMP_TYPE_VECTOR=1, /*!< return vector */ + LMP_TYPE_ARRAY =2, /*!< return array */ + LMP_SIZE_VECTOR=3, /*!< return length of vector */ + LMP_SIZE_ROWS =4, /*!< return number of rows */ + LMP_SIZE_COLS =5 /*!< return number of columns */ +}; + +/* + extern void *lammps_open(int argc, char **argv, MPI_Comm comm, void **ptr); +*/ +extern void *lammps_open_no_mpi(int argc, char **argv, void **ptr); +extern void *lammps_open_fortran(int argc, char **argv, int f_comm); +extern void lammps_close(void *handle); +extern void lammps_mpi_init(); +extern void lammps_mpi_finalize(); +extern void lammps_free(void *ptr); +extern void lammps_file(void *handle, const char *file); +extern char *lammps_command(void *handle, const char *cmd); +extern void lammps_commands_list(void *handle, int ncmd, const char **cmds); +extern void lammps_commands_string(void *handle, const char *str); +extern int lammps_version(void *handle); +extern void lammps_get_os_info(char *buffer, int buf_size); +extern void lammps_memory_usage(void *handle, double *meminfo); +extern int lammps_get_mpi_comm(void *handle); +extern double lammps_get_natoms(void *handle); +extern double lammps_get_thermo(void *handle, const char *keyword); +extern void lammps_extract_box(void *handle, double *boxlo, double *boxhi, + double *xy, double *yz, double *xz, + int *pflags, int *boxflag); +extern void lammps_reset_box(void *handle, double *boxlo, double *boxhi, + double xy, double yz, double xz); +extern int lammps_extract_setting(void *handle, const char *keyword); +extern void *lammps_extract_global(void *handle, const char *name); +extern void *lammps_extract_atom(void *handle, const char *name); +extern int lammps_extract_global_datatype(void *handle, const char *name); +extern int lammps_extract_atom_datatype(void *handle, const char *name); +extern int lammps_create_atoms(void *handle, int n, int *id, int *type, + double *x, double *v, int *image, int bexpand); +/* + extern int lammps_create_atoms(void *handle, int n, int64_t *id, int *type, */ +extern void *lammps_extract_compute(void *handle, char *id, int, int); +extern void *lammps_extract_fix(void *handle, char *, int, int, int, int); +extern void *lammps_extract_variable(void *handle, char *, char *); +extern int lammps_set_variable(void *, char *, char *); +extern void lammps_gather(void *, char *, int, int, void *); +extern void lammps_gather_concat(void *, char *, int, int, void *); +extern void lammps_gather_subset(void *, char *, int, int, int, int *, void *); +extern void lammps_scatter(void *, char *, int, int, void *); +extern void lammps_scatter_subset(void *, char *, int, int, int, int *, void *); +extern void lammps_gather_atoms(void *, char *, int, int, void *); +extern void lammps_gather_atoms_concat(void *, char *, int, int, void *); +extern void lammps_gather_atoms_subset(void *, char *, int, int, int, int *, void *); +extern void lammps_scatter_atoms(void *, char *, int, int, void *); +extern void lammps_scatter_atoms_subset(void *, char *, int, int, int, int *, void *); +extern int lammps_config_has_mpi_support(); +extern int lammps_config_has_package(const char *); +extern int lammps_config_package_count(); +extern int lammps_config_package_name(int, char *, int); +extern int lammps_config_has_gzip_support(); +extern int lammps_config_has_png_support(); +extern int lammps_config_has_jpeg_support(); +extern int lammps_config_has_ffmpeg_support(); +extern int lammps_config_has_exceptions(); +extern int lammps_has_style(void *, const char *, const char *); +extern int lammps_style_count(void *, const char *); +extern int lammps_style_name(void *, const char *, int, char *buffer, int buf_size); +extern int lammps_has_id(void *, const char *, const char *); +extern int lammps_id_count(void *, const char *); +extern int lammps_id_name(void *, const char *, int, char *buffer, int buf_size); +extern int lammps_find_pair_neighlist(void*, char *, int, int, int); +extern int lammps_find_fix_neighlist(void*, char *, int); +extern int lammps_find_compute_neighlist(void*, char *, int); +extern int lammps_neighlist_num_elements(void*, int); +extern void lammps_neighlist_element_neighbors(void *, int, int, int *, int *, int ** ); +/* +extern int lammps_encode_image_flags(int ix, int iy, int iz); +extern void lammps_decode_image_flags(int image, int *flags); +extern int64_t lammps_encode_image_flags(int ix, int iy, int iz); +extern void lammps_decode_image_flags(int64_t image, int *flags); +extern void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); +extern void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); +extern void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); +extern void lammps_fix_external_set_energy_global(void *, char *, double); +extern void lammps_fix_external_set_virial_global(void *, char *, double *); +*/ +extern int lammps_is_running(void *handle); +extern void lammps_force_timeout(void *handle); +extern int lammps_has_error(void *handle); +extern int lammps_get_last_error_message(void *handle, char *buffer, int buf_size); +%} + +enum _LMP_DATATYPE_CONST { + 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 */ +}; + +/** Style constants for extracting data from computes and fixes. + * + * Must be kept in sync with the equivalent constants in lammps.py */ + +enum _LMP_STYLE_CONST { + LMP_STYLE_GLOBAL=0, /*!< return global data */ + LMP_STYLE_ATOM =1, /*!< return per-atom data */ + LMP_STYLE_LOCAL =2 /*!< return local data */ +}; + +/** Type and size constants for extracting data from computes and fixes. + * + * Must be kept in sync with the equivalent constants in lammps.py */ + +enum _LMP_TYPE_CONST { + LMP_TYPE_SCALAR=0, /*!< return scalar */ + LMP_TYPE_VECTOR=1, /*!< return vector */ + LMP_TYPE_ARRAY =2, /*!< return array */ + LMP_SIZE_VECTOR=3, /*!< return length of vector */ + LMP_SIZE_ROWS =4, /*!< return number of rows */ + LMP_SIZE_COLS =5 /*!< return number of columns */ +}; + +/* extern void *lammps_open(int argc, char **argv, MPI_Comm comm, void **ptr); */ +extern void *lammps_open_no_mpi(int argc, char **argv, void **ptr); +extern void *lammps_open_fortran(int argc, char **argv, int f_comm); +extern void lammps_close(void *handle); +extern void lammps_mpi_init(); +extern void lammps_mpi_finalize(); +extern void lammps_free(void *ptr); +extern void lammps_file(void *handle, const char *file); +extern char *lammps_command(void *handle, const char *cmd); +extern void lammps_commands_list(void *handle, int ncmd, const char **cmds); +extern void lammps_commands_string(void *handle, const char *str); +extern int lammps_version(void *handle); +extern void lammps_get_os_info(char *buffer, int buf_size); +extern void lammps_memory_usage(void *handle, double *meminfo); +extern int lammps_get_mpi_comm(void *handle); +extern double lammps_get_natoms(void *handle); +extern double lammps_get_thermo(void *handle, const char *keyword); +extern void lammps_extract_box(void *handle, double *boxlo, double *boxhi, + double *xy, double *yz, double *xz, + int *pflags, int *boxflag); +extern void lammps_reset_box(void *handle, double *boxlo, double *boxhi, + double xy, double yz, double xz); +extern int lammps_extract_setting(void *handle, const char *keyword); +extern void *lammps_extract_global(void *handle, const char *name); +extern void *lammps_extract_atom(void *handle, const char *name); +extern int lammps_extract_global_datatype(void *handle, const char *name); +extern int lammps_extract_atom_datatype(void *handle, const char *name); +extern int lammps_create_atoms(void *handle, int n, int *id, int *type, + double *x, double *v, int *image, int bexpand); +/* +extern int lammps_create_atoms(void *handle, int n, int64_t *id, int *type, */ +extern void *lammps_extract_compute(void *handle, char *id, int, int); +extern void *lammps_extract_fix(void *handle, char *, int, int, int, int); +extern void *lammps_extract_variable(void *handle, char *, char *); +extern int lammps_set_variable(void *, char *, char *); +extern void lammps_gather(void *, char *, int, int, void *); +extern void lammps_gather_concat(void *, char *, int, int, void *); +extern void lammps_gather_subset(void *, char *, int, int, int, int *, void *); +extern void lammps_scatter(void *, char *, int, int, void *); +extern void lammps_scatter_subset(void *, char *, int, int, int, int *, void *); +extern void lammps_gather_atoms(void *, char *, int, int, void *); +extern void lammps_gather_atoms_concat(void *, char *, int, int, void *); +extern void lammps_gather_atoms_subset(void *, char *, int, int, int, int *, void *); +extern void lammps_scatter_atoms(void *, char *, int, int, void *); +extern void lammps_scatter_atoms_subset(void *, char *, int, int, int, int *, void *); +extern int lammps_config_has_mpi_support(); +extern int lammps_config_has_package(const char *); +extern int lammps_config_package_count(); +extern int lammps_config_package_name(int, char *, int); +extern int lammps_config_has_gzip_support(); +extern int lammps_config_has_png_support(); +extern int lammps_config_has_jpeg_support(); +extern int lammps_config_has_ffmpeg_support(); +extern int lammps_config_has_exceptions(); +extern int lammps_has_style(void *, const char *, const char *); +extern int lammps_style_count(void *, const char *); +extern int lammps_style_name(void *, const char *, int, char *buffer, int buf_size); +extern int lammps_has_id(void *, const char *, const char *); +extern int lammps_id_count(void *, const char *); +extern int lammps_id_name(void *, const char *, int, char *buffer, int buf_size); +extern int lammps_find_pair_neighlist(void*, char *, int, int, int); +extern int lammps_find_fix_neighlist(void*, char *, int); +extern int lammps_find_compute_neighlist(void*, char *, int); +extern int lammps_neighlist_num_elements(void*, int); +extern void lammps_neighlist_element_neighbors(void *, int, int, int *, int *, int ** ); +/* +extern int lammps_encode_image_flags(int ix, int iy, int iz); +extern void lammps_decode_image_flags(int image, int *flags); +extern int64_t lammps_encode_image_flags(int ix, int iy, int iz); +extern void lammps_decode_image_flags(int64_t image, int *flags); +extern void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); +extern void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); +extern void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); +extern void lammps_fix_external_set_energy_global(void *, char *, double); +extern void lammps_fix_external_set_virial_global(void *, char *, double *); +*/ +extern int lammps_is_running(void *handle); +extern void lammps_force_timeout(void *handle); +extern int lammps_has_error(void *handle); +extern int lammps_get_last_error_message(void *handle, char *buffer, int buf_size); + diff --git a/tools/swig/lammps_shell.i b/tools/swig/lammps_shell.i new file mode 100644 index 0000000000..d6b6dbccf3 --- /dev/null +++ b/tools/swig/lammps_shell.i @@ -0,0 +1,2 @@ +%include "tclsh.i" +%include "lammps.i" diff --git a/tools/swig/run_java_example.sh b/tools/swig/run_java_example.sh new file mode 100755 index 0000000000..2f5b28bdce --- /dev/null +++ b/tools/swig/run_java_example.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +if [ ! -f libjavalammps.so ] +then \ + echo "Need to compile 'libjavalammps.so' first for this script to work" + exit 1 +fi + +cat > example.java < example.lua < example.pl < example.py < example.rb < example.tcl < example.tcllmp <