# The `LIBLAMMPS`{.interpreted-text role="f:mod"} Fortran Module The `LIBLAMMPS`{.interpreted-text role="f:mod"} module provides an interface to call LAMMPS from Fortran. It is based on the LAMMPS C library interface and requires a fully 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 other than those in the C library interface and the LAMMPS Fortran module itself. While C libraries have a defined binary interface (ABI) and can thus be used from multiple compiler versions from different vendors as long as they are compatible with the hosting operating system, the same is not true for Fortran programs. Thus, the LAMMPS Fortran module needs to be compiled alongside the code using it from the source code in `fortran/lammps.f90` *and* with the same compiler used to build the rest of the Fortran code that interfaces to LAMMPS. When linking, you also need to [link to the LAMMPS library](Build_link). A typical command line for a simple program using the Fortran interface would be: ``` bash 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-parallelized program. Otherwise, using the plain Fortran compiler (gfortran, ifort, flang, etc.) will suffice, since there are no direct references to MPI library features, definitions and subroutine calls; MPI communicators are referred to by their integer index representation as required by the Fortran MPI interface. It may be necessary to link to additional libraries, depending on how LAMMPS was configured and whether the LAMMPS library [was compiled as a static or dynamic library](Build_link). If the LAMMPS library itself has been compiled with MPI support, the resulting executable will be able to run LAMMPS in parallel with `mpirun`, `mpiexec`, or equivalent. This may be either on the \"world\" communicator or a sub-communicator created by the calling Fortran code. If, on the other hand, the LAMMPS library has been compiled **without** MPI support, each LAMMPS instance will run independently using just one processor. 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`{.interpreted-text role="f:mod"} module that would need to be imported by the calling Fortran code in order to uses the Fortran interface. A working example can be found together with equivalent examples in C and C++ in the `examples/COUPLE/simple` folder of the LAMMPS distribution. ::: {.admonition .note} Fortran compiler compatibility A fully Fortran 2003 compatible Fortran compiler is required. This means that currently only GNU Fortran 9 and later are compatible and thus the default compilers of Red Hat or CentOS 7 and Ubuntu 18.04 LTS and not compatible. Either newer compilers need to be installed or the Linux updated. ::: ------------------------------------------------------------------------ # Creating or deleting a LAMMPS object With the Fortran interface, the creation of a `LAMMPS `{.interpreted-text role="cpp:class"}\_\_ instance is included in the constructor for creating the `lammps`{.interpreted-text role="f:func"} derived type. To import the definition of that type and its type-bound procedures, you need to add a `USE LIBLAMMPS` statement. Internally, it will call either `lammps_open_fortran`{.interpreted-text role="cpp:func"} or `lammps_open_no_mpi`{.interpreted-text role="cpp:func"} from the C library API to create the class instance. All arguments are optional and `lammps_mpi_init`{.interpreted-text role="cpp:func"} will be called automatically if it is needed. Similarly, a possible call to `lammps_mpi_finalize`{.interpreted-text role="cpp:func"} is integrated into the `close`{.interpreted-text role="f:func"} function and triggered with the optional logical argument set to `.TRUE.`. Here is a simple example: ``` fortran PROGRAM testlib USE LIBLAMMPS ! include the LAMMPS library interface IMPLICIT NONE TYPE(lammps) :: lmp ! derived type to hold LAMMPS instance CHARACTER(LEN=12), PARAMETER :: args(3) = & [ CHARACTER(LEN=12) :: 'liblammps', '-log', 'none' ] ! create a LAMMPS instance (and initialize MPI) lmp = lammps(args) ! get and print numerical version code PRINT*, 'LAMMPS Version: ', lmp%version() ! delete LAMMPS instance (and shutdown MPI) CALL lmp%close(.TRUE.) END PROGRAM testlib ``` It is also possible to pass command line flags from Fortran to C/C++ and thus make the resulting executable behave similarly to the standalone executable (it will ignore the [-in/-i]{.title-ref} 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 version of the previous example: ``` fortran PROGRAM testlib2 USE LIBLAMMPS ! include the LAMMPS library interface IMPLICIT NONE TYPE(lammps) :: lmp ! derived type to hold LAMMPS instance CHARACTER(LEN=128), ALLOCATABLE :: command_args(:) INTEGER :: i, argc ! copy command line flags to `command_args()` argc = COMMAND_ARGUMENT_COUNT() ALLOCATE(command_args(0:argc)) DO i=0, argc CALL GET_COMMAND_ARGUMENT(i, command_args(i)) END DO ! create a LAMMPS instance (and initialize MPI) lmp = lammps(command_args) ! get and print numerical version code PRINT*, 'Program name: ', command_args(0) PRINT*, 'LAMMPS Version: ', lmp%version() ! delete LAMMPS instance (and shuts down MPI) CALL lmp%close(.TRUE.) DEALLOCATE(command_args) END PROGRAM testlib2 ``` ------------------------------------------------------------------------ # 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 to pass individual or multiple commands from strings or lists of strings. This is done similarly to how it is implemented in the [C library interface](Library_execute). Before handing off the calls to the C library interface, the corresponding Fortran versions of the calls (`file`{.interpreted-text role="f:func"}, `command`{.interpreted-text role="f:func"}, `commands_list`{.interpreted-text role="f:func"}, and `commands_string`{.interpreted-text role="f:func"}) have to make copies of the strings passed as arguments so that they can be modified to be compatible with the requirements of strings in C without affecting the original strings. Those copies are automatically deleted after the functions return. Below is a small demonstration of the uses of the different functions. ``` fortran PROGRAM testcmd USE LIBLAMMPS TYPE(lammps) :: lmp CHARACTER(LEN=512) :: cmds CHARACTER(LEN=40), ALLOCATABLE :: cmdlist(:) CHARACTER(LEN=10) :: trimmed INTEGER :: i lmp = lammps() CALL lmp%file('in.melt') CALL lmp%command('variable zpos index 1.0') ! define 10 groups of 10 atoms each ALLOCATE(cmdlist(10)) DO i=1, 10 WRITE(trimmed,'(I10)') 10*i WRITE(cmdlist(i),'(A,I1,A,I10,A,A)') & 'group g', i-1, ' id ', 10*(i-1)+1, ':', ADJUSTL(trimmed) END DO CALL lmp%commands_list(cmdlist) ! run multiple commands from multi-line string cmds = 'clear' // NEW_LINE('A') // & 'region box block 0 2 0 2 0 2' // NEW_LINE('A') // & 'create_box 1 box' // NEW_LINE('A') // & 'create_atoms 1 single 1.0 1.0 ${zpos}' CALL lmp%commands_string(cmds) CALL lmp%close(.TRUE.) END PROGRAM testcmd ``` ------------------------------------------------------------------------ # Accessing system properties The C library interface allows the [extraction of different kinds of information](Library_properties) about the active simulation instance and also\-\--in some cases\-\--to apply modifications to it, and the Fortran interface provides access to the same data using Fortran-style, C-interoperable data types. In some cases, the Fortran library interface makes pointers to internal LAMMPS data structures accessible; when accessing them through the library interfaces, special care is needed to avoid data corruption and crashes. Please see the documentation of the individual type-bound procedures for details. Below is an example demonstrating some of the possible uses. ``` fortran PROGRAM testprop USE LIBLAMMPS USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t, c_int USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT TYPE(lammps) :: lmp INTEGER(KIND=c_int64_t), POINTER :: natoms, ntimestep, bval REAL(KIND=c_double), POINTER :: dt, dval INTEGER(KIND=c_int), POINTER :: nfield, typ, ival INTEGER(KIND=c_int) :: i CHARACTER(LEN=11) :: key REAL(KIND=c_double) :: pe, ke lmp = lammps() CALL lmp%file('in.sysinit') natoms = lmp%extract_global('natoms') WRITE(OUTPUT_UNIT,'(A,I0,A)') 'Running a simulation with ', natoms, ' atoms' WRITE(OUTPUT_UNIT,'(I0,A,I0,A,I0,A)') lmp%extract_setting('nlocal'), & ' local and ', lmp%extract_setting('nghost'), ' ghost atoms. ', & lmp%extract_setting('ntypes'), ' atom types' CALL lmp%command('run 2 post no') ntimestep = lmp%last_thermo('step', 0) nfield = lmp%last_thermo('num', 0) WRITE(OUTPUT_UNIT,'(A,I0,A,I0)') 'Last thermo output on step: ', ntimestep, & ', number of fields: ', nfield DO i=1, nfield key = lmp%last_thermo('keyword',i) typ = lmp%last_thermo('type',i) IF (typ == lmp%dtype%i32) THEN ival = lmp%last_thermo('data',i) WRITE(OUTPUT_UNIT,*) key, ':', ival ELSE IF (typ == lmp%dtype%i64) THEN bval = lmp%last_thermo('data',i) WRITE(OUTPUT_UNIT,*) key, ':', bval ELSE IF (typ == lmp%dtype%r64) THEN dval = lmp%last_thermo('data',i) WRITE(OUTPUT_UNIT,*) key, ':', dval END IF END DO dt = lmp%extract_global('dt') ntimestep = lmp%extract_global('ntimestep') WRITE(OUTPUT_UNIT,'(A,I0,A,F4.1,A)') 'At step: ', ntimestep, & ' Changing timestep from', dt, ' to 0.5' dt = 0.5_c_double CALL lmp%command('run 2 post no') WRITE(OUTPUT_UNIT,'(A,I0)') 'At step: ', ntimestep pe = lmp%get_thermo('pe') ke = lmp%get_thermo('ke') WRITE(OUTPUT_UNIT,*) 'PE = ', pe WRITE(OUTPUT_UNIT,*) 'KE = ', ke CALL lmp%close(.TRUE.) END PROGRAM testprop ``` ------------------------------------------------------------------------ # The `LIBLAMMPS`{.interpreted-text role="f:mod"} module API Below are the detailed descriptions of definitions and interfaces of the contents of the `LIBLAMMPS`{.interpreted-text role="f:mod"} Fortran interface to LAMMPS. > Derived type that is the general class of the Fortran interface. It > holds a reference to the > `LAMMPS `{.interpreted-text role="cpp:class"}\_\_ > class instance to which any of the included calls are forwarded. > > f handle > > : reference to the LAMMPS class > > ftype handle > > : c_ptr > > f style > > : derived type to access lammps style constants > > ftype style > > : type(lammps_style) > > f type > > : derived type to access lammps type constants > > ftype type > > : type(lammps_type) > > f dtype > > : derived type to access lammps data type constants > > ftype dtype > > : type(lammps_dtype) > > f close > > : `close`{.interpreted-text role="f:subr"} > > ftype close > > : subroutine > > f subroutine error > > : `error`{.interpreted-text role="f:subr"} > > ftype error > > : subroutine > > f file > > : `file`{.interpreted-text role="f:subr"} > > ftype file > > : subroutine > > f command > > : `command`{.interpreted-text role="f:subr"} > > ftype command > > : subroutine > > f commands_list > > : `commands_list`{.interpreted-text role="f:subr"} > > ftype commands_list > > : subroutine > > f commands_string > > : `commands_string`{.interpreted-text role="f:subr"} > > ftype commands_string > > : subroutine > > f get_natoms > > : `get_natoms`{.interpreted-text role="f:func"} > > ftype get_natoms > > : function > > f get_thermo > > : `get_thermo`{.interpreted-text role="f:func"} > > ftype get_thermo > > : function > > f last_thermo > > : `last_thermo`{.interpreted-text role="f:func"} > > ftype last_thermo > > : function > > f extract_box > > : `extract_box`{.interpreted-text role="f:subr"} > > ftype extract_box > > : subroutine > > f reset_box > > : `reset_box`{.interpreted-text role="f:subr"} > > ftype reset_box > > : subroutine > > f memory_usage > > : `memory_usage`{.interpreted-text role="f:subr"} > > ftype memory_usage > > : subroutine > > f get_mpi_comm > > : `get_mpi_comm`{.interpreted-text role="f:func"} > > ftype get_mpi_comm > > : function > > f extract_setting > > : `extract_setting`{.interpreted-text role="f:func"} > > ftype extract_setting > > : function > > f extract_global > > : `extract_global`{.interpreted-text role="f:func"} > > ftype extract_global > > : function > > f extract_atom > > : `extract_atom`{.interpreted-text role="f:func"} > > ftype extract_atom > > : function > > f extract_compute > > : `extract_compute`{.interpreted-text role="f:func"} > > ftype extract_compute > > : function > > f extract_fix > > : `extract_fix`{.interpreted-text role="f:func"} > > ftype extract_fix > > : function > > f extract_variable > > : `extract_variable`{.interpreted-text role="f:func"} > > ftype extract_variable > > : function > > f set_variable > > : `set_variable`{.interpreted-text role="f:subr"} > > ftype set_variable > > : subroutine > > f gather_atoms > > : `gather_atoms`{.interpreted-text role="f:subr"} > > ftype gather_atoms > > : subroutine > > f gather_atoms_concat > > : `gather_atoms_concat`{.interpreted-text role="f:subr"} > > ftype gather_atoms_concat > > : subroutine > > f gather_atoms_subset > > : `gather_atoms_subset`{.interpreted-text role="f:subr"} > > ftype gather_atoms_subset > > : subroutine > > f scatter_atoms > > : `scatter_atoms`{.interpreted-text role="f:subr"} > > ftype scatter_atoms > > : subroutine > > f scatter_atoms_subset > > : `scatter_atoms_subset`{.interpreted-text role="f:subr"} > > ftype scatter_atoms_subset > > : subroutine > > f gather_bonds > > : `gather_bonds`{.interpreted-text role="f:subr"} > > ftype gather_bonds > > : subroutine > > f gather_angles > > : `gather_angles`{.interpreted-text role="f:subr"} > > ftype gather_angles > > : subroutine > > f gather_dihedrals > > : `gather_dihedrals`{.interpreted-text role="f:subr"} > > ftype gather_dihedrals > > : subroutine > > f gather_impropers > > : `gather_impropers`{.interpreted-text role="f:subr"} > > ftype gather_impropers > > : subroutine > > f gather > > : `gather`{.interpreted-text role="f:subr"} > > ftype gather > > : subroutine > > f gather_concat > > : `gather_concat`{.interpreted-text role="f:subr"} > > ftype gather_concat > > : subroutine > > f gather_subset > > : `gather_subset`{.interpreted-text role="f:subr"} > > ftype gather_subset > > : subroutine > > f scatter > > : `scatter`{.interpreted-text role="f:subr"} > > ftype scatter > > : subroutine > > f scatter_subset > > : `scatter_subset`{.interpreted-text role="f:subr"} > > ftype scatter_subset > > : subroutine > > f create_atoms > > : `create_atoms`{.interpreted-text role="f:subr"} > > ftype create_atoms > > : subroutine > > f find_pair_neighlist > > : `find_pair_neighlist`{.interpreted-text role="f:func"} > > ftype find_pair_neighlist > > : function > > f find_fix_neighlist > > : `find_fix_neighlist`{.interpreted-text role="f:func"} > > ftype find_fix_neighlist > > : function > > f find_compute_neighlist > > : `find_compute_neighlist`{.interpreted-text role="f:func"} > > ftype find_compute_neighlist > > : function > > f neighlist_num_elements > > : `neighlist_num_elements`{.interpreted-text role="f:func"} > > ftype neighlist_num_elements > > : function > > f neighlist_element_neighbors > > : `neighlist_element_neighbors`{.interpreted-text role="f:subr"} > > ftype neighlist_element_neighbors > > : subroutine > > f version > > : `version`{.interpreted-text role="f:func"} > > ftype version > > : function > > f get_os_info > > : `get_os_info`{.interpreted-text role="f:subr"} > > ftype get_os_info > > : subroutine > > f config_has_mpi_support > > : `config_has_mpi_support`{.interpreted-text role="f:func"} > > ftype config_has_mpi_support > > : function > > f config_has_gzip_support > > : `config_has_gzip_support`{.interpreted-text role="f:func"} > > ftype config_has_gzip_support > > : function > > f config_has_png_support > > : `config_has_png_support`{.interpreted-text role="f:func"} > > ftype config_has_png_support > > : function > > f config_has_jpeg_support > > : `config_has_jpeg_support`{.interpreted-text role="f:func"} > > ftype config_has_jpeg_support > > : function > > f config_has_ffmpeg_support > > : `config_has_ffmpeg_support`{.interpreted-text role="f:func"} > > ftype config_has_ffmpeg_support > > : function > > f config_has_exceptions > > : `config_has_exceptions`{.interpreted-text role="f:func"} > > ftype config_has_exceptions > > : function > > f config_has_package > > : `config_has_package`{.interpreted-text role="f:func"} > > ftype config_has_package > > : function > > f config_package_count > > : `config_package_count`{.interpreted-text role="f:func"} > > ftype config_package_count > > : function > > f config_package_name > > : `config_package_name`{.interpreted-text role="f:func"} > > ftype config_package_name > > : function > > f installed_packages > > : `installed_packages`{.interpreted-text role="f:subr"} > > ftype installed_packages > > : subroutine > > f config_accelerator > > : `config_accelerator`{.interpreted-text role="f:func"} > > ftype config_accelerator > > : function > > f has_gpu_device > > : `has_gpu_device`{.interpreted-text role="f:func"} > > ftype has_gpu_device > > : function > > f get_gpu_device_info > > : `get_gpu_device_info`{.interpreted-text role="f:subr"} > > ftype get_gpu_device_info > > : subroutine > > f has_style > > : `has_style`{.interpreted-text role="f:func"} > > ftype has_style > > : function > > f style_count > > : `style_count`{.interpreted-text role="f:func"} > > ftype style_count > > : function > > f style_name > > : `style_name`{.interpreted-text role="f:func"} > > ftype style_name > > : function > > f has_id > > : `has_id`{.interpreted-text role="f:func"} > > ftype has_id > > : function > > f id_count > > : `id_count`{.interpreted-text role="f:func"} > > ftype id_count > > : function > > f id_name > > : `id_name`{.interpreted-text role="f:subr"} > > ftype id_name > > : subroutine > > f plugin_count > > : `plugin_count`{.interpreted-text role="f:func"} > > ftype plugin_count > > : function > > f plugin_name > > : `plugin_name`{.interpreted-text role="f:subr"} > > ftype plugin_count > > : subroutine > > f encode_image_flags > > : `encode_image_flags`{.interpreted-text role="f:func"} > > ftype encode_image_flags > > : function > > f decode_image_flags > > : `decode_image_flags`{.interpreted-text role="f:subr"} > > ftype decode_image_flags > > : subroutine > > f set_fix_external_callback > > : `set_fix_external_callback`{.interpreted-text role="f:subr"} > > ftype set_fix_external_callback > > : subroutine > > f fix_external_get_force > > : `fix_external_get_force`{.interpreted-text role="f:func"} > > ftype fix_external_get_force > > : function > > f fix_external_set_energy_global > > : `fix_external_set_energy_global`{.interpreted-text role="f:subr"} > > ftype fix_external_set_energy_global > > : subroutine > > f fix_external_set_virial_global > > : `fix_external_set_virial_global`{.interpreted-text role="f:subr"} > > ftype fix_external_set_virial_global > > : subroutine > > f fix_external_set_energy_peratom > > : `fix_external_set_energy_peratom`{.interpreted-text role="f:subr"} > > ftype fix_external_set_energy_peratom > > : subroutine > > f fix_external_set_virial_peratom > > : `fix_external_set_virial_peratom`{.interpreted-text role="f:subr"} > > ftype fix_external_set_virial_peratom > > : subroutine > > f fix_external_set_vector_length > > : `fix_external_set_vector_length`{.interpreted-text role="f:subr"} > > ftype fix_external_set_vector_length > > : subroutine > > f fix_external_set_vector > > : `fix_external_set_vector`{.interpreted-text role="f:subr"} > > ftype fix_external_set_vector > > : subroutine > > f flush_buffers > > : `flush_buffers`{.interpreted-text role="f:subr"} > > ftype flush_buffers > > : subroutine > > f is_running > > : `is_running`{.interpreted-text role="f:func"} > > ftype is_running > > : function > > f force_timeout > > : `force_timeout`{.interpreted-text role="f:subr"} > > ftype force_timeout > > : subroutine > > f has_error > > : `has_error`{.interpreted-text role="f:func"} > > ftype has_error > > : function > > f get_last_error_message > > : `get_last_error_message`{.interpreted-text role="f:subr"} > > ftype get_last_error_message > > : subroutine ------------------------------------------------------------------------ > This is the constructor for the Fortran class and will forward the > arguments to a call to either `lammps_open_fortran`{.interpreted-text > role="cpp:func"} or `lammps_open_no_mpi`{.interpreted-text > role="cpp:func"}. If the LAMMPS library has been compiled with MPI > support, it will also initialize MPI, if it has not already been > initialized before. > > The *args* argument with the list of command line parameters is > optional and so it the *comm* argument with the MPI communicator. If > *comm* is not provided, `MPI_COMM_WORLD` is assumed. For more details > please see the documentation of `lammps_open`{.interpreted-text > role="cpp:func"}. > > o args > > : arguments as list of strings > > otype args > > : character(len=\*),dimension(:),optional > > o comm > > : MPI communicator > > otype comm > > : integer,optional > > to > > : `lammps_open_fortran`{.interpreted-text role="cpp:func"} > > to > > : `lammps_open_no_mpi`{.interpreted-text role="cpp:func"} > > r lammps > > : an instance of the `lammps`{.interpreted-text role="f:type"} > derived type > > :::: note > ::: title > Note > ::: > > The `MPI_F08`{.interpreted-text role="f:mod"} 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`{.interpreted-text role="f:mod"} and `MPI`{.interpreted-text > role="f:mod"} 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 > > ``` fortran > PROGRAM testmpi > USE LIBLAMMPS > USE MPI_F08 > TYPE(lammps) :: lmp > lmp = lammps(comm=MPI_COMM_SELF%MPI_VAL) > END PROGRAM testmpi > ``` > :::: > This derived type is there to provide a convenient interface for the > style constants used with `extract_compute`{.interpreted-text > role="f:func"}, `extract_fix`{.interpreted-text role="f:func"}, and > `extract_variable`{.interpreted-text role="f:func"}. Assuming your > LAMMPS instance is called `lmp`, these constants will be > `lmp%style%global`, `lmp%style%atom`, and `lmp%style%local`. These > values are identical to the values described in > `_LMP_STYLE_CONST`{.interpreted-text role="cpp:enum"} for the C > library interface. > > f integer(c_int) global > > : used to request global data > > f integer(c_int) atom > > : used to request per-atom data > > f integer(c_int) local > > : used to request local data > This derived type is there to provide a convenient interface for the > type constants used with `extract_compute`{.interpreted-text > role="f:func"}, `extract_fix`{.interpreted-text role="f:func"}, and > `extract_variable`{.interpreted-text role="f:func"}. Assuming your > LAMMPS instance is called `lmp`, these constants will be > `lmp%type%scalar`, `lmp%type%vector`, and `lmp%type%array`. These > values are identical to the values described in > `_LMP_TYPE_CONST`{.interpreted-text role="cpp:enum"} for the C library > interface. > > f integer(c_int) scalar > > : used to request scalars > > f integer(c_int) vector > > : used to request vectors > > f integer(c_int) array > > : used to request arrays (matrices) ## Procedures Bound to the `lammps`{.interpreted-text role="f:type"} Derived Type > This method will close down the LAMMPS instance through calling > `lammps_close`{.interpreted-text role="cpp:func"}. If the *finalize* > argument is present and has a value of `.TRUE.`, then this subroutine > also calls `lammps_kokkos_finalize`{.interpreted-text role="cpp:func"} > and `lammps_mpi_finalize`{.interpreted-text role="cpp:func"}. > > o finalize > > : shut down the MPI environment of the LAMMPS library if `.TRUE.`. > > otype finalize > > : logical,optional > > to > > : `lammps_close`{.interpreted-text role="cpp:func"} > > to > > : `lammps_mpi_finalize`{.interpreted-text role="cpp:func"} > > to > > : `lammps_kokkos_finalize`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This method is a wrapper around the `lammps_error`{.interpreted-text > role="cpp:func"} function and will dispatch an error through the > LAMMPS Error class. > > ::: versionadded > 3Nov2022 > ::: > > p error_type > > : constant to select which Error class function to call > > ptype error_type > > : integer(c_int) > > p character(len=\*) error_text > > : error message > > to > > : `lammps_error`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This method will call `lammps_file`{.interpreted-text role="cpp:func"} > to have LAMMPS read and process commands from a file. > > p character(len=\*) filename > > : name of file with LAMMPS commands > > to > > : `lammps_file`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This method will call `lammps_command`{.interpreted-text > role="cpp:func"} to have LAMMPS execute a single command. > > p character(len=\*) cmd > > : single LAMMPS command > > to > > : `lammps_command`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This method will call `lammps_commands_list`{.interpreted-text > role="cpp:func"} to have LAMMPS execute a list of input lines. > > :p character(len=\*) cmd \[dimension(:)\]: list of LAMMPS input lines > :to: `lammps_commands_list`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This method will call `lammps_commands_string`{.interpreted-text > role="cpp:func"} to have LAMMPS execute a block of commands from a > string. > > p character(len=\*) str > > : LAMMPS input in string > > to > > : `lammps_commands_string`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function will call `lammps_get_natoms`{.interpreted-text > role="cpp:func"} and return the number of atoms in the system. > > to > > : `lammps_get_natoms`{.interpreted-text role="cpp:func"} > > r real(c_double) natoms > > : number of atoms > > :::: note > ::: title > Note > ::: > > If you would prefer to get the number of atoms in its native format > (i.e., as a 32- or 64-bit integer, depending on how LAMMPS was > compiled), this can be extracted with > `extract_global`{.interpreted-text role="f:func"}. > :::: ------------------------------------------------------------------------ > This function will call `lammps_get_thermo`{.interpreted-text > role="cpp:func"} and return the value of the corresponding > thermodynamic keyword. > > ::: versionadded > 3Nov2022 > ::: > > p character(len=\*) name > > : string with the name of the thermo keyword > > to > > : `lammps_get_thermo`{.interpreted-text role="cpp:func"} > > r value \[real(c_double)\] > > : value of the requested thermo property or > [0.0_c_double]{.title-ref} ------------------------------------------------------------------------ > This function will call `lammps_last_thermo`{.interpreted-text > role="cpp:func"} and returns either a string or a pointer to a cached > copy of LAMMPS last thermodynamic output, depending on the data > requested through *what*. Note that *index* uses 1-based indexing to > access thermo output columns. > > ::: versionadded > 15Jun2023 > ::: > > 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)`). The > pointer being associated with LAMMPS data is type-checked at run-time > via an overloaded assignment operator. The pointers returned by this > function point to temporary, read-only data that may be overwritten at > any time, so their target values need to be copied to local storage if > they are supposed to persist. > > For example, > > ``` fortran > PROGRAM thermo > USE LIBLAMMPS > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t, c_int > TYPE(lammps) :: lmp > INTEGER(KIND=c_int64_t), POINTER :: ntimestep, bval > REAL(KIND=c_double), POINTER :: dval > INTEGER(KIND=c_int), POINTER :: nfield, typ, ival > INTEGER(KIND=c_int) :: i > CHARACTER(LEN=11) :: key > > lmp = lammps() > CALL lmp%file('in.sysinit') > > ntimestep = lmp%last_thermo('step', 0) > nfield = lmp%last_thermo('num', 0) > PRINT*, 'Last thermo output on step: ', ntimestep, ' Number of fields: ', nfield > DO i=1, nfield > key = lmp%last_thermo('keyword',i) > typ = lmp%last_thermo('type',i) > IF (typ == lmp%dtype%i32) THEN > ival = lmp%last_thermo('data',i) > PRINT*, key, ':', ival > ELSE IF (typ == lmp%dtype%i64) THEN > bval = lmp%last_thermo('data',i) > PRINT*, key, ':', bval > ELSE IF (typ == lmp%dtype%r64) THEN > dval = lmp%last_thermo('data',i) > PRINT*, key, ':', dval > END IF > END DO > CALL lmp%close(.TRUE.) > END PROGRAM thermo > ``` > > would extract the last timestep where thermo output was done and the > number of columns it printed. Then it loops over the columns to print > out column header keywords and the corresponding data. > > :::: note > ::: title > Note > ::: > > If `last_thermo`{.interpreted-text role="f:func"} returns a string, > the string must have a 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. If you use an allocatable string, the string **must be > allocated** prior to calling this function. > :::: > > p character(len=\*) what > > : string with the name of the thermo keyword > > p integer(c_int) index > > : 1-based column index > > to > > : `lammps_last_thermo`{.interpreted-text role="cpp:func"} > > r pointer \[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. > > :::: warning > ::: title > Warning > ::: > > Modifying the data in the location pointed to by the returned pointer > may lead to inconsistent internal data and thus may cause failures, > crashes, or bogus simulations. In general, it is much better to use a > LAMMPS input command that sets or changes these parameters. Using an > input command will take care of all side effects and necessary updates > of settings derived from such settings. > :::: ------------------------------------------------------------------------ > This subroutine will call `lammps_extract_box`{.interpreted-text > role="cpp:func"}. 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 > 3Nov2022 > ::: > > 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 pflags > > : vector in which to store periodicity flags (`.TRUE.` means > periodic in that dimension) > > otype pflags > > : logical,dimension(3),optional > > o boxflag > > : variable in which to store boolean denoting whether the box will > change during a simulation (`.TRUE.` means box will change) > > otype boxflag > > : logical,optional > > to > > : `lammps_extract_box`{.interpreted-text role="cpp:func"} :::: note ::: title 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\": ``` fortran ! code to start up LOGICAL :: periodic(3) ! code to initialize LAMMPS / run things / etc. CALL lmp%extract_box(pflags = periodic) ``` :::: ------------------------------------------------------------------------ > This subroutine will call `lammps_reset_box`{.interpreted-text > role="cpp:func"}. All parameters are required. > > ::: versionadded > 3Nov2022 > ::: > > 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 > > to > > : `lammps_reset_box`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This subroutine will call `lammps_memory_usage`{.interpreted-text > role="cpp:func"} and store the result in the three-element array > *meminfo*. > > ::: versionadded > 3Nov2022 > ::: > > p real(c_double) meminfo \[dimension(3)\] > > : vector of three doubles in which to store memory usage data > > to > > : `lammps_memory_usage`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function returns a Fortran representation of the LAMMPS \"world\" > communicator. > > ::: versionadded > 3Nov2022 > ::: > > to > > : `lammps_get_mpi_comm`{.interpreted-text role="cpp:func"} > > r comm > > : Fortran integer equivalent to the MPI communicator LAMMPS is using > > rtype comm > > : integer > > :::: note > ::: title > 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 > ::: title > Note > ::: > > The `MPI_F08`{.interpreted-text role="f:mod"} 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]{.title-ref} member of the communicator. For example, > > ``` 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`{.interpreted-text role="f:mod"} > communicator properly. > :::: ------------------------------------------------------------------------ > Query LAMMPS about global settings. See the documentation for the > `lammps_extract_setting`{.interpreted-text role="cpp:func"} function > from the C library. > > ::: versionadded > 3Nov2022 > ::: > > p character(len=\*) keyword > > : string containing the name of the thermo keyword > > to > > : `lammps_extract_setting`{.interpreted-text role="cpp:func"} > > r integer(c_int) setting > > : value of the queried setting or $-1$ if unknown ------------------------------------------------------------------------ > This function calls `lammps_extract_global`{.interpreted-text > role="cpp:func"} and returns either a string or a pointer to internal > global LAMMPS data, depending on the data requested through *name*. > > ::: versionadded > 3Nov2022 > ::: > > 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 [clear]{.title-ref} command has been issued, > which wipes out and recreates the contents of the > `LAMMPS `{.interpreted-text role="cpp:class"}\_\_ > class. > > For example, > > ``` fortran > PROGRAM demo > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int64_t, c_int, c_double > USE LIBLAMMPS > TYPE(lammps) :: lmp > INTEGER(c_int), POINTER :: nlocal => NULL() > INTEGER(c_int64_t), POINTER :: ntimestep => NULL() > REAL(c_double), POINTER :: dt => NULL() > CHARACTER(LEN=10) :: units > 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 > ::: title > Note > ::: > > If `extract_global`{.interpreted-text role="f:func"} returns a string, > the string must have a 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. If you use an allocatable string, the string **must be > allocated** prior to calling this function, but you can automatically > reallocate it to the correct length after the function returns, viz., > > > > > > > PROGRAM test > > > > : USE LIBLAMMPS TYPE(lammps) :: lmp CHARACTER(LEN=:), ALLOCATABLE > > :: str lmp = lammps() CALL lmp%command(\'units metal\') > > ALLOCATE(CHARACTER(LEN=80) :: str) str = > > lmp%extract_global(\'units\') str = TRIM(str) ! re-allocates to > > length len_trim(str) here PRINT\*, LEN(str), LEN_TRIM(str) > > > > END PROGRAM test > > will print the number 5 (the length of the word \"metal\") twice. > :::: > > p character(len=\*) name > > : string with the name of the property to extract > > to > > : `lammps_extract_global`{.interpreted-text role="cpp:func"} > > r pointer \[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 > ::: title > Warning > ::: > > Modifying the data in the location pointed to by the returned pointer > may lead to inconsistent internal data and thus may cause failures, > crashes, or bogus simulations. In general, it is much better to use a > LAMMPS input command that sets or changes these parameters. Using an > input command will take care of all side effects and necessary updates > of settings derived from such settings. > :::: ------------------------------------------------------------------------ > This function calls `lammps_extract_atom`{.interpreted-text > role="cpp:func"} and returns a pointer to LAMMPS data tied to the > `Atom`{.interpreted-text role="cpp:class"} class, depending on the > data requested through *name*. > > ::: versionadded > 3Nov2022 > ::: > > Note that this function actually does not return a pointer, but rather > associates the pointer on the left side of the assignment to point to > internal LAMMPS data. Pointers must be of the correct type, kind, and > rank (e.g., `INTEGER(c_int), DIMENSION(:)` for \"type\", \"mask\", or > \"id\"; `INTEGER(c_int64_t), DIMENSION(:)` for \"id\" if LAMMPS was > compiled with the `-DLAMMPS_BIGBIG` flag; > `REAL(c_double), DIMENSION(:,:)` for \"x\", \"v\", or \"f\"; and so > forth). The pointer being associated with LAMMPS data is type-, kind-, > and rank-checked at run-time. > > p character(len=\*) name > > : string with the name of the property to extract > > to > > : `lammps_extract_atom`{.interpreted-text role="cpp:func"} > > r pointer > > : pointer to LAMMPS data. The left-hand side of the assignment > should be a C-interoperable pointer of appropriate kind and rank > (e.g., `INTEGER(c_int), POINTER :: mask(:)`) to the extracted > property. If expecting vector data, the pointer should have > dimension \":\"; if expecting matrix data, the pointer should have > dimension \":,:\". > > rtype pointer > > : polymorphic > > :::: warning > ::: title > Warning > ::: > > Pointers returned by this function are generally not persistent, as > per-atom data may be redistributed, reallocated, and reordered at > every re-neighboring operation. It is advisable to re-bind pointers > using `extract_atom`{.interpreted-text role="f:func"} between runs. > :::: > > ::: admonition > Array index order > > Two-dimensional arrays returned from `extract_atom`{.interpreted-text > role="f:func"} will be **transposed** from equivalent arrays in C, and > they will be indexed from 1 instead of 0. For example, in C, > > ``` c > void *lmp; > double **x; > /* more code to setup, etc. */ > x = lammps_extract_atom(lmp, "x"); > printf("%f\n", x[5][1]); > ``` > > will print the *y*-coordinate of the sixth atom on this processor. > Conversely, > > ``` fortran > TYPE(lammps) :: lmp > REAL(c_double), DIMENSION(:,:), POINTER :: x => NULL() > ! more code to setup, etc. > x = lmp%extract_atom("x") > PRINT '(f0.6)', x(2,6) > ``` > > will print the *y*-coordinate of the sixth atom on this processor > (note the transposition of the two indices). This is not a choice, but > rather a consequence of the different conventions adopted by the > Fortran and C standards decades ago: in C, the block of data > > 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 > > interpreted as a $4\times4$ matrix would be > > $$\begin{aligned} > \begin{bmatrix} > 1 & 2 & 3 & 4 \\ > 5 & 6 & 7 & 8 \\ > 9 & 10 & 11 & 12 \\ > 13 & 14 & 15 & 16 > \end{bmatrix}, > \end{aligned}$$ > > that is, in row-major order. In Fortran, the same block of data is > interpreted in column-major order, namely, > > $$\begin{aligned} > \begin{bmatrix} > 1 & 5 & 9 & 13 \\ > 2 & 6 & 10 & 14 \\ > 3 & 7 & 11 & 15 \\ > 4 & 8 & 12 & 16 > \end{bmatrix}. > \end{aligned}$$ > > This difference in interpretation of the same block of data by the two > languages means, in effect, that matrices from C or C++ will be > transposed when interpreted in Fortran. > ::: > > :::: note > ::: title > Note > ::: > > If you would like the indices to start at 0 instead of 1 (which > follows typical notation in C and C++, but not Fortran), you can > create another pointer and associate it thus: > > ``` fortran > REAL(c_double), DIMENSION(:,:), POINTER :: x, x0 > x = lmp%extract_atom("x") > x0(0:,0:) => x > ``` > > The above would cause the dimensions of *x* to be (1:3, 1:nmax) and > those of *x0* to be (0:2, 0:nmax$-$``{=html}1). > :::: ------------------------------------------------------------------------ > This function calls `lammps_extract_compute`{.interpreted-text > role="cpp:func"} and returns a pointer to LAMMPS data tied to the > `Compute`{.interpreted-text role="cpp:class"} class, specifically data > provided by the compute identified by *id*. Computes may provide > global, per-atom, or local data, and those data may be a scalar, a > vector, or an array. Since computes may provide multiple kinds of > data, the user is required to specify which set of data is to be > returned through the *style* and *type* variables. > > ::: versionadded > 3Nov2022 > ::: > > 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. Pointers must be of the correct data type to > point to said data (i.e., `REAL(c_double)`) and have compatible rank. > The pointer being associated with LAMMPS data is type-, kind-, and > rank-checked at run-time via an overloaded assignment operator. > > For example, > > ``` fortran > TYPE(lammps) :: lmp > REAL(c_double), DIMENSION(:), POINTER :: COM > ! code to setup, create atoms, etc. > CALL lmp%command('compute COM all com') > COM = lmp%extract_compute('COM', lmp%style%global, lmp%style%type) > ``` > > will bind the variable *COM* to the center of mass of the atoms > created in your simulation. The vector in this case has length 3; the > length (or, in the case of array data, the number of rows and columns) > is determined for you based on data from the > `Compute`{.interpreted-text role="cpp:class"} class. > > ::: admonition > Array index order > > Two-dimensional arrays returned from > `extract_compute`{.interpreted-text role="f:func"} will be > **transposed** from equivalent arrays in C, and they will be indexed > from 1 instead of 0. See the note at `extract_atom`{.interpreted-text > role="f:func"} for further details. > ::: > > The following combinations are possible (assuming `lmp` is the name of > your LAMMPS instance): > > Style Type Type to assign to Returned data > -------------------- ------------------- ------------------------------------------- ----------------- > `lmp%style%global` `lmp%type%scalar` `REAL(c_double), POINTER` Global scalar > `lmp%style%global` `lmp%type%vector` `REAL(c_double), DIMENSION(:), POINTER` Global vector > `lmp%style%global` `lmp%type%array` `REAL(c_double), DIMENSION(:,:), POINTER` Global array > `lmp%style%atom` `lmp%type%vector` `REAL(c_double), DIMENSION(:), POINTER` Per-atom vector > `lmp%style%atom` `lmp%type%array` `REAL(c_double), DIMENSION(:,:), POINTER` Per-atom array > `lmp%style%local` `lmp%type%vector` `REAL(c_double), DIMENSION(:), POINTER` Local vector > `lmp%style%local` `lmp%type%array` `REAL(c_double), DIMENSION(:,:), POINTER` Local array > > p character(len=\*) id > > : compute ID from which to extract data > > p integer(c_int) style > > : value indicating the style of data to extract (global, per-atom, > or local) > > p integer(c_int) type > > : value indicating the type of data to extract (scalar, vector, or > array) > > to > > : `lammps_extract_compute`{.interpreted-text role="cpp:func"} > > r pointer > > : pointer to LAMMPS data. The left-hand side of the assignment > should be a C-compatible pointer (e.g., > `REAL(c_double), POINTER :: x`) to the extracted property. If > expecting vector data, the pointer should have dimension \":\"; if > expecting array (matrix) data, the pointer should have dimension > \":,:\". > > rtype pointer > > : polymorphic > > :::: note > ::: title > Note > ::: > > If the compute\'s data are not already computed for the current step, > the compute will be invoked. LAMMPS cannot easily check at that time > if it is valid to invoke a compute, so it may fail with an error. The > caller has to check to avoid such an error. > :::: > > :::: warning > ::: title > Warning > ::: > > The pointers returned by this function are generally not persistent, > since the computed data may be re-distributed, re-allocated, and > re-ordered at every invocation. It is advisable to re-invoke this > function before the data are accessed or make a copy if the data are > to be used after other LAMMPS commands have been issued. Do **not** > modify the data returned by this function. > :::: ------------------------------------------------------------------------ > This function calls `lammps_extract_fix`{.interpreted-text > role="cpp:func"} and returns a pointer to LAMMPS data tied to the > `Fix`{.interpreted-text role="cpp:class"} class, specifically data > provided by the fix identified by *id*. Fixes may provide global, > per-atom, or local data, and those data may be a scalar, a vector, or > an array. Since many fixes provide multiple kinds of data, the user is > required to specify which set of data is to be returned through the > *style* and *type* variables. > > ::: versionadded > 3Nov2022 > ::: > > Global data are calculated at the time they are requested and are only > available element-by-element. As such, the user is expected to provide > the *nrow* variable to specify which element of a global vector or the > *nrow* and *ncol* variables to specify which element of a global array > the user wishes LAMMPS to return. The *ncol* variable is optional for > global scalar or vector data, and both *nrow* and *ncol* are optional > when a global scalar is requested, as well as when per-atom or local > data are requested. The following combinations are possible (assuming > `lmp` is the name of your LAMMPS instance): > > Style Type nrow ncol Type to assign to Returned data > -------------------- ------------------- ---------- ---------- ------------------------------------------- -------------------------- > `lmp%style%global` `lmp%type%scalar` Ignored Ignored `REAL(c_double)` Global scalar > `lmp%style%global` `lmp%type%vector` Required Ignored `REAL(c_double)` Element of global vector > `lmp%style%global` `lmp%type%array` Required Required `REAL(c_double)` Element of global array > `lmp%style%atom` `lmp%type%scalar` (not allowed) > `lmp%style%atom` `lmp%type%vector` Ignored Ignored `REAL(c_double), DIMENSION(:), POINTER` Per-atom vector > `lmp%style%atom` `lmp%type%array` Ignored Ignored `REAL(c_double), DIMENSION(:,:), POINTER` Per-atom array > `lmp%style%local` `lmp%type%scalar` (not allowed) > `lmp%style%local` `lmp%type%vector` Ignored Ignored `REAL(c_double), DIMENSION(:), POINTER` Per-atom vector > `lmp%style%local` `lmp%type%array` Ignored Ignored `REAL(c_double), DIMENSION(:,:), POINTER` Per-atom array > > In the case of global data, this function returns a value of type > `REAL(c_double)`. For per-atom or local data, this function does not > return a value but instead associates the pointer on the left side of > the assignment to point to internal LAMMPS data. Pointers must be of > the correct type and kind to point to said data (i.e., > `REAL(c_double)`) and have compatible rank. The pointer being > associated with LAMMPS data is type-, kind-, and rank-checked at > run-time via an overloaded assignment operator. > > For example, > > ``` fortran > TYPE(lammps) :: lmp > REAL(c_double) :: dr, dx, dy, dz > ! more code to set up, etc. > lmp%command('fix george all recenter 2 2 2') > ! more code > dr = lmp%extract_fix("george", lmp%style%global, lmp%style%scalar) > dx = lmp%extract_fix("george", lmp%style%global, lmp%style%vector, 1) > dy = lmp%extract_fix("george", lmp%style%global, lmp%style%vector, 2) > dz = lmp%extract_fix("george", lmp%style%global, lmp%style%vector, 3) > ``` > > will extract the global scalar calculated by [fix > recenter](fix_recenter) into the variable *dr* and the three elements > of the global vector calculated by fix recenter into the variables > *dx*, *dy*, and *dz*, respectively. > > If asked for per-atom or local data, > `extract_compute`{.interpreted-text role="f:func"} returns a pointer > to actual LAMMPS data. The pointer so returned will have the > appropriate size to match the internal data, and will be > type/kind/rank-checked at the time of the assignment. For example, > > ``` fortran > TYPE(lammps) :: lmp > REAL(c_double), DIMENSION(:), POINTER :: r > ! more code to set up, etc. > lmp%command('fix state all store/state 0 x y z') > ! more code > r = lmp%extract_fix('state', lmp%style%atom, lmp%type%array) > ``` > > will bind the pointer *r* to internal LAMMPS data representing the > per-atom array computed by [fix store/state](fix_store_state) when > three inputs are specified. Similarly, > > ``` fortran > TYPE(lammps) :: lmp > REAL(c_double), DIMENSION(:), POINTER :: x > ! more code to set up, etc. > lmp%command('fix state all store/state 0 x') > ! more code > x = lmp%extract_fix('state', lmp%style%atom, lmp%type%vector) > ``` > > will associate the pointer *x* with internal LAMMPS data corresponding > to the per-atom vector computed by [fix store/state](fix_store_state) > when only one input is specified. Similar examples with > `lmp%style%atom` replaced by `lmp%style%local` will extract local data > from fixes that define local vectors and/or arrays. > > :::: warning > ::: title > Warning > ::: > > The pointers returned by this function for per-atom or local data are > generally not persistent, since the computed data may be > redistributed, reallocated, and reordered at every invocation of the > fix. It is thus advisable to re-invoke this function before the data > are accessed or to make a copy if the data are to be used after other > LAMMPS commands have been issued. > :::: > > :::: note > ::: title > Note > ::: > > LAMMPS cannot easily check if it is valid to access the data, so it > may fail with an error. The caller has to avoid such an error. > :::: > > p character(len=\*) id > > : string with the name of the fix from which to extract data > > p integer(c_int) style > > : value indicating the style of data to extract (global, per-atom, > or local) > > p integer(c_int) type > > : value indicating the type of data to extract (scalar, vector, or > array) > > p integer(c_int) nrow > > : row index (used only for global vectors and arrays) > > p integer(c_int) ncol > > : column index (only used for global arrays) > > to > > : `lammps_extract_fix`{.interpreted-text role="cpp:func"} > > r data > > : LAMMPS data (for global data) or a pointer to LAMMPS data (for > per-atom or local data). The left-hand side of the assignment > should be of type `REAL(c_double)` and have appropriate rank > (i.e., `DIMENSION(:)` if expecting per-atom or local vector data > and `DIMENSION(:,:)` if expecting per-atom or local array data). > If expecting local or per-atom data, it should have the `POINTER` > attribute, but if expecting global data, it should be an ordinary > (non-`POINTER`) variable. > > rtype data > > : polymorphic > > ::: admonition > Array index order > > Two-dimensional global, per-atom, or local array data from > `extract_fix`{.interpreted-text role="f:func"} will be **transposed** > from equivalent arrays in C (or in the ordinary LAMMPS interface > accessed through thermodynamic output), and they will be indexed from > 1, not 0. This is true even for global data, which are returned as > scalars\-\--this is done primarily so the interface is consistent, as > there is no choice but to transpose the indices for per-atom or local > array data. See the similar note under > `extract_atom`{.interpreted-text role="f:func"} for further details. > ::: ------------------------------------------------------------------------ > This function calls `lammps_extract_variable`{.interpreted-text > role="cpp:func"} and returns a scalar, vector, or string containing > the value of the variable identified by *name*. When the variable is > an *equal*-style variable (or one compatible with that style such as > *internal*), the variable is evaluated and the corresponding value > returned. When the variable is an *atom*-style variable, the variable > is evaluated and a vector of values is returned. With all other > variables, a string is returned. The *group* argument is only used for > *atom* style variables and is ignored otherwise. If *group* is absent > for *atom*-style variables, the group is assumed to be \"all\". > > ::: versionadded > 3Nov2022 > ::: > > This function returns the values of the variables, not pointers to > them. Vectors pointing to *atom*-style variables should be of type > `REAL(c_double)`, be of rank 1 (i.e., `DIMENSION(:)`), and have the > `ALLOCATABLE` attribute. > > :::: note > ::: title > Note > ::: > > Unlike the C library interface, the Fortran interface does not require > you to deallocate memory when you are through; this is done for you, > behind the scenes. > :::: > > For example, > > ``` fortran > TYPE(lammps) :: lmp > REAL(c_double) :: area > ! more code to set up, etc. > lmp%command('variable A equal lx*ly') > ! more code > area = lmp%extract_variable("A") > ``` > > will extract the *x*\--*y* cross-sectional area of the simulation into > the variable *area*. > > p character(len=\*) name > > : variable name to evaluate > > o character(len=\*) group \[optional\] > > : group for which to extract per-atom data (if absent, use \"all\") > > to > > : `lammps_extract_variable`{.interpreted-text role="cpp:func"} > > r data > > : scalar of type `REAL(c_double)` (for *equal*-style variables and > others that are *equal*-compatible), vector of type > `REAL(c_double), DIMENSION(:), ALLOCATABLE` for *atom*- or > *vector*-style variables, or `CHARACTER(LEN=*)` for *string*-style > and compatible variables. Strings whose length is too short to > hold the result will be truncated. Allocatable strings must be > allocated before this function is called; see note at > `extract_global`{.interpreted-text role="f:func"} regarding > allocatable strings. Allocatable arrays (for *atom*- and > *vector*-style data) will be reallocated on assignment. > > rtype data > > : polymorphic :::: note ::: title Note ::: LAMMPS cannot easily check if it is valid to access the data referenced by the variables (e.g., computes, fixes, or thermodynamic info), so it may fail with an error. The caller has to make certain that the data are extracted only when it is safe to evaluate the variable and thus an error and crash are avoided. :::: ------------------------------------------------------------------------ > Set the value of a string-style variable. > > ::: versionadded > 3Nov2022 > ::: > > This function assigns a new value from the string *str* to the > string-style variable *name*. If *name* does not exist or is not a > string-style variable, an error is generated. > > p character(len=\*) name > > : name of the variable > > p character(len=\*) str > > : new value to assign to the variable > > to > > : `lammps_set_variable`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_gather_atoms`{.interpreted-text > role="cpp:func"} to gather the named atom-based entity for all atoms > on all processors and return it in the vector *data*. The vector > *data* will be ordered by atom ID, which requires consecutive atom IDs > (1 to *natoms*). > > ::: versionadded > 3Nov2022 > ::: > > If you need a similar array but have non-consecutive atom IDs, see > `gather_atoms_concat`{.interpreted-text role="f:func"}; for a similar > array but for a subset of atoms, see > `gather_atoms_subset`{.interpreted-text role="f:func"}. > > The *data* array will be ordered in groups of *count* values, sorted > by atom ID (e.g., if *name* is *x* and *count* = 3, then *data* = > \[*x*(1,1), *x*(2,1), *x*(3,1), *x*(1,2), *x*(2,2), *x*(3,2), > *x*(1,3), $\dots$\]); *data* must be `ALLOCATABLE` and will be > allocated to length (*count* $\times$ *natoms*), as queried by > `get_natoms`{.interpreted-text role="f:func"}. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., *x* or *mask*) > > p integer(c_int) count > > : number of per-atom values you expect per atom (e.g., 1 for *type*, > *mask*, or *charge*; 3 for *x*, *v*, or *f*). Use *count* = 3 with > *image* if you want a single image flag unpacked into > *x*/\*y\*/\*z\* components. > > p data > > : array into which to store the data. Array *must* have the > `ALLOCATABLE` attribute and be of rank 1 (i.e., `DIMENSION(:)`). > If this array is already allocated, it will be reallocated to fit > the length of the incoming data. It should have type > `INTEGER(c_int)` if expecting integer data and `REAL(c_double)` if > expecting floating-point data. > > ptype data > > : polymorphic,dimension(:),allocatable > > to > > : `lammps_gather_atoms`{.interpreted-text role="cpp:func"} > > :::: note > ::: title > Note > ::: > > If you want data from this function to be accessible as a > two-dimensional array, you can declare a rank-2 pointer and reassign > it, like so: > > ``` fortran > USE, INTRINSIC :: ISO_C_BINDING > USE LIBLAMMPS > TYPE(lammps) :: lmp > REAL(c_double), DIMENSION(:), ALLOCATABLE, TARGET :: xdata > REAL(c_double), DIMENSION(:,:), POINTER :: x > ! other code to set up, etc. > CALL lmp%gather_atoms('x',3,xdata) > x(1:3,1:size(xdata)/3) => xdata > ``` > > You can then access the *y*-component of atom 3 with `x(2,3)`. See the > note about array index order at `extract_atom`{.interpreted-text > role="f:func"}. > :::: ------------------------------------------------------------------------ > This function calls `lammps_gather_atoms_concat`{.interpreted-text > role="cpp:func"} to gather the named atom-based entity for all atoms > on all processors and return it in the vector *data*. > > ::: versionadded > 3Nov2022 > ::: > > The vector *data* will not be ordered by atom ID, and there is no > restriction on the IDs being consecutive. If you need the IDs, you can > do another `gather_atoms_concat`{.interpreted-text role="f:func"} with > *name* set to `id`. > > If you need a similar array but have consecutive atom IDs, see > `gather_atoms`{.interpreted-text role="f:func"}; for a similar array > but for a subset of atoms, see `gather_atoms_subset`{.interpreted-text > role="f:func"}. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., *x* or *mask*) > > p integer(c_int) count > > : number of per-atom values you expect per atom (e.g., 1 for *type*, > *mask*, or *charge*; 3 for *x*, *v*, or *f*). Use *count* = 3 with > *image* if you want a single image flag unpacked into > *x*/\*y\*/\*z\* components. > > p data > > : array into which to store the data. Array *must* have the > `ALLOCATABLE` attribute and be of rank 1 (i.e., `DIMENSION(:)`). > If this array is already allocated, it will be reallocated to fit > the length of the incoming data. It should have type > `INTEGER(c_int)` if expecting integer data and `REAL(c_double)` if > expecting floating-point data. > > ptype data > > : polymorphic,dimension(:),allocatable > > to > > : `lammps_gather_atoms_concat`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_gather_atoms_subset`{.interpreted-text > role="cpp:func"} to gather the named atom-based entity for the atoms > in the array *ids* from all processors and return it in the vector > *data*. > > ::: versionadded > 3Nov2022 > ::: > > This subroutine gathers data for the requested atom IDs and stores > them in a one-dimensional allocatable array. The data will be ordered > by atom ID, but there is no requirement that the IDs be consecutive. > If you wish to return a similar array for *all* the atoms, use > `gather_atoms`{.interpreted-text role="f:func"} or > `gather_atoms_concat`{.interpreted-text role="f:func"}. > > The *data* array will be in groups of *count* values, sorted by atom > ID in the same order as the array *ids* (e.g., if *name* is *x*, > *count* = 3, and *ids* is \[100, 57, 210\], then *data* might look > like \[*x*(1,100), *x*(2,100), *x*(3,100), *x*(1,57), *x*(2,57), > *x*(3,57), *x*(1,210), $\dots$\]; *ids* must be provided by the user, > and *data* must be of rank 1 (i.e., `DIMENSION(:)`) and have the > `ALLOCATABLE` attribute. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., *x* or *mask*) > > p integer(c_int) count > > : number of per-atom values you expect per atom (e.g., 1 for *type*, > *mask*, or *charge*; 3 for *x*, *v*, or *f*). Use *count* = 3 with > *image* if you want a single image flag unpacked into > *x*/\*y\*/\*z\* components. > > > > :p integer(c_int) ids \[dimension(:)\]: atom IDs corresponding to the atoms > > : to be gathered > > :p data: array into which to store > > : the data. Array *must* have the `ALLOCATABLE` attribute and be of > rank 1 (i.e., `DIMENSION(:)`). If this array is already allocated, > it will be reallocated to fit the length of the incoming data. It > should have type `INTEGER(c_int)` if expecting integer data and > `REAL(c_double)` if expecting floating-point data. > > > > ptype data > > : polymorphic,dimension(:),allocatable > > to > > : `lammps_gather_atoms_subset`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_scatter_atoms`{.interpreted-text > role="cpp:func"} to scatter the named atom-based entities in *data* to > all processors. > > ::: versionadded > 3Nov2022 > ::: > > This subroutine takes data stored in a one-dimensional array supplied > by the user and scatters them to all atoms on all processors. The data > must be ordered by atom ID, with the requirement that the IDs be > consecutive. Use `scatter_atoms_subset`{.interpreted-text > role="f:func"} to scatter data for some (or all) atoms, in any order. > > The *data* array needs to be ordered in groups of *count* values, > sorted by atom ID (e.g., if *name* is *x* and *count* = 3, then *data* > = \[*x*(1,1), *x*(2,1), *x*(3,1), *x*(1,2), *x*(2,2), *x*(3,2), > *x*(1,3), $\dots$\]); *data* must be of length *natoms* or > 3\*\*natoms\*. > > p character(len=\*) name > > : quantity to be scattered (e.g., *x* or *charge*) > > p data > > : per-atom values packed in a one-dimensional array containing the > data to be scattered. This array must have length *natoms* (e.g., > for *type* or *charge*) or length *natoms*${}\times 3$ (e.g., for > *x* or *f*). The array *data* must be rank 1 (i.e., > `DIMENSION(:)`) and be of type `INTEGER(c_int)` (e.g., for *mask* > or *type*) or of type `REAL(c_double)` (e.g., for *x* or *charge* > or *f*). > > ptype data > > : polymorphic,dimension(:) > > to > > : `lammps_scatter_atoms`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_scatter_atoms_subset`{.interpreted-text > role="cpp:func"} to scatter the named atom-based entities in *data* to > all processors. > > ::: versionadded > 3Nov2022 > ::: > > This subroutine takes data stored in a one-dimensional array supplied > by the user and scatters them to a subset of atoms on all processors. > The array *data* contains data associated with atom IDs, but there is > no requirement that the IDs be consecutive, as they are provided in a > separate array, *ids*. Use `scatter_atoms`{.interpreted-text > role="f:func"} to scatter data for all atoms, in order. > > The *data* array needs to be organized in groups of 1 or 3 values, > depending on which quantity is being scattered, with the groups in the > same order as the array *ids*. For example, if you want *data* to be > the array \[*x*(1,1), *x*(2,1), *x*(3,1), *x*(1,100), *x*(2,100), > *x*(3,100), *x*(1,57), *x*(2,57), *x*(3,57)\], then *ids* would be > \[1, 100, 57\] and *name* would be *x*. > > p character(len=\*) name > > : quantity to be scattered (e.g., *x* or *charge*) > > > > :p integer(c_int) ids \[dimension(:)\]: atom IDs corresponding to the atoms > > : being scattered > > :p data: per-atom values packed into a > > : one-dimensional array containing the data to be scattered. This > array must have either the same length as *ids* (for *mask*, > *type*, etc.) or three times its length (for *x*, *f*, etc.); the > array must be rank 1 and be of type `INTEGER(c_int)` (e.g., for > *mask* or *type*) or of type `REAL(c_double)` (e.g., for *charge*, > *x*, or *f*). > > > > ptype data > > : polymorphic,dimension(:) > > to > > : `lammps_scatter_atoms_subset`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather type and constituent atom information for all bonds. > > ::: versionadded > 3Nov2022 > ::: > > This function copies the list of all bonds into an allocatable array. > The array will be filled with (bond type, bond atom 1, bond atom 2) > for each bond. The array is allocated to the right length (i.e., three > times the number of bonds). The array *data* must be of the same type > as the LAMMPS `tagint` type, which is equivalent to either > `INTEGER(c_int)` or `INTEGER(c_int64_t)`, depending on whether > `-DLAMMPS_BIGBIG` was used when LAMMPS was built. If the supplied > array does not match, an error will result at run-time. > > An example of how to use this routine is below: > > ``` fortran > PROGRAM bonds > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int > USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT > USE LIBLAMMPS > IMPLICIT NONE > INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET :: bonds > INTEGER(c_int), DIMENSION(:,:), POINTER :: bonds_array > TYPE(lammps) :: lmp > INTEGER :: i > ! other commands to initialize LAMMPS, create bonds, etc. > CALL lmp%gather_bonds(bonds) > bonds_array(1:3, 1:SIZE(bonds)/3) => bonds > DO i = 1, SIZE(bonds)/3 > WRITE(OUTPUT_UNIT,'(A,1X,I4,A,I4,1X,I4)') 'bond', bonds_array(1,i), & > '; type = ', bonds_array(2,i), bonds_array(3,i) > END DO > END PROGRAM bonds > ``` > > p data > > : array into which to copy the result. \*The `KIND` parameter is > either `c_int` or, if LAMMPS was compiled with `-DLAMMPS_BIGBIG`, > kind `c_int64_t`. > > ptype data > > : integer(kind=\*),allocatable > > to > > : `lammps_gather_bonds`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather type and constituent atom information for all angles. > > ::: versionadded > 8Feb2023 > ::: > > This function copies the list of all angles into an allocatable array. > The array will be filled with (angle type, angle atom 1, angle atom 2, > angle atom 3) for each angle. The array is allocated to the right > length (i.e., four times the number of angles). The array *data* must > be of the same type as the LAMMPS `tagint` type, which is equivalent > to either `INTEGER(c_int)` or `INTEGER(c_int64_t)`, depending on > whether `-DLAMMPS_BIGBIG` was used when LAMMPS was built. If the > supplied array does not match, an error will result at run-time. > > An example of how to use this routine is below: > > ``` fortran > PROGRAM angles > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int > USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT > USE LIBLAMMPS > IMPLICIT NONE > INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET :: angles > INTEGER(c_int), DIMENSION(:,:), POINTER :: angles_array > TYPE(lammps) :: lmp > INTEGER :: i > ! other commands to initialize LAMMPS, create angles, etc. > CALL lmp%gather_angles(angles) > angles_array(1:4, 1:SIZE(angles)/4) => angles > DO i = 1, SIZE(angles)/4 > WRITE(OUTPUT_UNIT,'(A,1X,I4,A,I4,1X,I4,1X,I4)') 'angle', angles_array(1,i), & > '; type = ', angles_array(2,i), angles_array(3,i), angles_array(4,i) > END DO > END PROGRAM angles > ``` > > p data > > : array into which to copy the result. \*The `KIND` parameter is > either `c_int` or, if LAMMPS was compiled with `-DLAMMPS_BIGBIG`, > kind `c_int64_t`. > > ptype data > > : integer(kind=\*),allocatable > > to > > : `lammps_gather_angles`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather the named per-atom, per-atom fix, per-atom compute, or fix > property/atom-based entities from all processes, in order by atom ID. > > ::: versionadded > 22Dec2022 > ::: > > This subroutine gathers data from all processes and stores them in a > one-dimensional allocatable array. The array *data* will be ordered by > atom ID, which requires consecutive IDs (1 to *natoms*). If you need a > similar array but for non-consecutive atom IDs, see > `lammps_gather_concat`{.interpreted-text role="cpp:func"}; for a > similar array but for a subset of atoms, see > `lammps_gather_subset`{.interpreted-text role="cpp:func"}. > > The *data* array will be ordered in groups of *count* values, sorted > by atom ID (e.g., if *name* is *x*, then *data* is \[x(1,1), x(2,1), > x(3,1), x(1,2), x(2,2), x(3,2), x(1,3), $\dots$\]); *data* must be > `ALLOCATABLE` and will be allocated to length > (*count*${}\times{}$\*natoms\*), as queried by > `get_natoms`{.interpreted-text role="f:func"}. > > This function will return an error if fix or compute data are > requested and the fix or compute ID given does not have per-atom data. > See the note about re-interpreting the vector as a matrix at > `gather_atoms`{.interpreted-text role="f:subr"}. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., \"x\" or \"mask\" for atom properties, > \"f_id\" for per-atom fix data, \"c_id\" for per-atom compute > data, \"d_name\" or \"i_name\" for fix property/atom vectors with > *count* = 1, \"d2_name\" or \"i2_name\" for fix property/atom > vectors with *count*${}> 1$) > > p integer(c_int) count > > : number of per-atom values (e.g., 1 for *type* or *charge*, 3 for > *x* or *f*); use *count* = 3 with *image* if you want the image > flags unpacked into (*x*,\*y\*,\*z\*) components. > > > > :p real(c_double) data \[dimension(:),allocatable\]: array into which to store > > : the data. Array *must* have the `ALLOCATABLE` attribute and be of > rank 1 (i.e., `DIMENSION(:)`). If this array is already allocated, > it will be reallocated to fit the length of the incoming data. > > > > to > > : `lammps_gather`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather type and constituent atom information for all dihedrals. > > ::: versionadded > 8Feb2023 > ::: > > This function copies the list of all dihedrals into an allocatable > array. The array will be filled with (dihedral type, dihedral atom 1, > dihedral atom 2, dihedral atom 3, dihedral atom 4) for each dihedral. > The array is allocated to the right length (i.e., five times the > number of dihedrals). The array *data* must be of the same type as the > LAMMPS `tagint` type, which is equivalent to either `INTEGER(c_int)` > or `INTEGER(c_int64_t)`, depending on whether `-DLAMMPS_BIGBIG` was > used when LAMMPS was built. If the supplied array does not match, an > error will result at run-time. > > An example of how to use this routine is below: > > ``` fortran > PROGRAM dihedrals > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int > USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT > USE LIBLAMMPS > IMPLICIT NONE > INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET :: dihedrals > INTEGER(c_int), DIMENSION(:,:), POINTER :: dihedrals_array > TYPE(lammps) :: lmp > INTEGER :: i > ! other commands to initialize LAMMPS, create dihedrals, etc. > CALL lmp%gather_dihedrals(dihedrals) > dihedrals_array(1:5, 1:SIZE(dihedrals)/5) => dihedrals > DO i = 1, SIZE(dihedrals)/5 > WRITE(OUTPUT_UNIT,'(A,1X,I4,A,I4,1X,I4,1X,I4,1X,I4)') 'dihedral', dihedrals_array(1,i), & > '; type = ', dihedrals_array(2,i), dihedrals_array(3,i), dihedrals_array(4,i), dihedrals_array(5,i) > END DO > END PROGRAM dihedrals > ``` > > p data > > : array into which to copy the result. \*The `KIND` parameter is > either `c_int` or, if LAMMPS was compiled with `-DLAMMPS_BIGBIG`, > kind `c_int64_t`. > > ptype data > > : integer(kind=\*),allocatable > > to > > : `lammps_gather_dihedrals`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather type and constituent atom information for all impropers. > > ::: versionadded > 8Feb2023 > ::: > > This function copies the list of all impropers into an allocatable > array. The array will be filled with (improper type, improper atom 1, > improper atom 2, improper atom 3, improper atom 4) for each improper. > The array is allocated to the right length (i.e., five times the > number of impropers). The array *data* must be of the same type as the > LAMMPS `tagint` type, which is equivalent to either `INTEGER(c_int)` > or `INTEGER(c_int64_t)`, depending on whether `-DLAMMPS_BIGBIG` was > used when LAMMPS was built. If the supplied array does not match, an > error will result at run-time. > > An example of how to use this routine is below: > > ``` fortran > PROGRAM impropers > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int > USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT > USE LIBLAMMPS > IMPLICIT NONE > INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET :: impropers > INTEGER(c_int), DIMENSION(:,:), POINTER :: impropers_array > TYPE(lammps) :: lmp > INTEGER :: i > ! other commands to initialize LAMMPS, create impropers, etc. > CALL lmp%gather_impropers(impropers) > impropers_array(1:5, 1:SIZE(impropers)/5) => impropers > DO i = 1, SIZE(impropers)/5 > WRITE(OUTPUT_UNIT,'(A,1X,I4,A,I4,1X,I4,1X,I4,1X,I4)') 'improper', impropers_array(1,i), & > '; type = ', impropers_array(2,i), impropers_array(3,i), impropers_array(4,i), impropers_array(5,i) > END DO > END PROGRAM impropers > ``` > > p data > > : array into which to copy the result. \*The `KIND` parameter is > either `c_int` or, if LAMMPS was compiled with `-DLAMMPS_BIGBIG`, > kind `c_int64_t`. > > ptype data > > : integer(kind=\*),allocatable > > to > > : `lammps_gather_impropers`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather the named per-atom, per-atom fix, per-atom compute, or fix > property/atom-based entities from all processes, unordered. > > ::: versionadded > 22Dec2022 > ::: > > This subroutine gathers data for all atoms and stores them in a > one-dimensional allocatable array. The data will be a concatenation of > chunks from each processor\'s owned atoms, in whatever order the atoms > are in on each processor. This process has no requirement that the > atom IDs be consecutive. If you need the ID of each atom, you can do > another call to either `gather_atoms_concat`{.interpreted-text > role="f:subr"} or `gather_concat`{.interpreted-text role="f:subr"} > with *name* set to `id`. If you have consecutive IDs and want the data > to be in order, use `gather`{.interpreted-text role="f:subr"}; for a > similar array but for a subset of atoms, use > `gather_subset`{.interpreted-text role="f:subr"}. > > The *data* array will be in groups of *count* values, with *natoms* > groups total, but not in order by atom ID (e.g., if *name* is *x* and > *count* is 3, then *data* might be something like \[x(1,11), x(2,11), > x(3,11), x(1,3), x(2,3), x(3,3), x(1,5), $\dots$\]); *data* must be > `ALLOCATABLE` and will be allocated to length (*count* $\times$ > *natoms*), as queried by `get_natoms`{.interpreted-text > role="f:func"}. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., \"x\" or \"mask\" for atom properties, > \"f_id\" for per-atom fix data, \"c_id\" for per-atom compute > data, \"d_name\" or \"i_name\" for fix property/atom vectors with > *count* = 1, \"d2_name\" or \"i2_name\" for fix property/atom > vectors with *count*${}> 1$) > > p integer(c_int) count > > : number of per-atom values you expect per atom (e.g., 1 for *type*, > *mask*, or *charge*; 3 for *x*, *v*, or *f*). Use *count* = 3 with > *image* if you want a single image flag unpacked into > *x*/\*y\*/\*z\* components. > > p data > > : array into which to store the data. Array *must* have the > `ALLOCATABLE` attribute and be of rank 1 (i.e., `DIMENSION(:)`). > If this array is already allocated, it will be reallocated to fit > the length of the incoming data. It should have type > `INTEGER(c_int)` if expecting integer data and `REAL(c_double)` if > expecting floating-point data. > > ptype data > > : polymorphic,dimension(:),allocatable > > to > > : `lammps_gather_concat`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Gather the named per-atom, per-atom fix, per-atom compute, or fix > property/atom-based entities from all processes for a subset of atoms. > > ::: versionadded > 22Dec2022 > ::: > > This subroutine gathers data for the requested atom IDs and stores > them in a one-dimensional allocatable array. The data will be ordered > by atom ID, but there is no requirement that the IDs be consecutive. > If you wish to return a similar array for *all* the atoms, use > `gather`{.interpreted-text role="f:subr"} or > `gather_concat`{.interpreted-text role="f:subr"}. > > The *data* array will be in groups of *count* values, sorted by atom > ID in the same order as the array *ids* (e.g., if *name* is *x*, > *count* = 3, and *ids* is \[100, 57, 210\], then *data* might look > like \[*x*(1,100), *x*(2,100), *x*(3,100), *x*(1,57), *x*(2,57), > *x*(3,57), *x*(1,210), $\dots$\]); *ids* must be provided by the user, > and *data* must have the `ALLOCATABLE` attribute and be of rank 1 > (i.e., `DIMENSION(:)`). If *data* is already allocated, it will be > reallocated to fit the length of the incoming data. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : quantity to be scattered > > > > :p integer(c_int) ids \[dimension(:)\]: atom IDs corresponding to the atoms > > : being scattered (e.g., \"x\" or \"f\" for atom properties, > \"f_id\" for per-atom fix data, \"c_id\" for per-atom compute > data, \"d_name\" or \"i_name\" for fix property/atom vectors with > *count* = 1, \"d2_name\" or \"i2_name\" for fix property/atom > vectors with *count*${} > 1$) > > :p integer(c_int) count: number of per-atom values you expect per atom > > : (e.g., 1 for *type*, *mask*, or *charge*; 3 for *x*, *v*, or *f*). > Use *count* = 3 with *image* if you want a single image flag > unpacked into *x*/\*y\*/\*z\* components. > > :p data: per-atom values packed into a one-dimensional array containing the > > : data to be scattered. This array must have the `ALLOCATABLE` > attribute and will be allocated either to the same length as *ids* > (for *mask*, *type*, etc.) or to three times its length (for *x*, > *f*, etc.); the array must be rank 1 and be of type > `INTEGER(c_int)` (e.g., for *mask* or *type*) or of type > `REAL(c_double)` (e.g., for *charge*, *x*, or *f*). > > > > ptype data > > : polymorphic,dimension(:),allocatable > > to > > : `lammps_gather_subset`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_scatter`{.interpreted-text > role="cpp:func"} to scatter the named per-atom, per-atom fix, per-atom > compute, or fix property/atom-based entity in *data* to all processes. > > ::: versionadded > 22Dec2022 > ::: > > This subroutine takes data stored in a one-dimensional array supplied > by the user and scatters them to all atoms on all processes. The data > must be ordered by atom ID, with the requirement that the IDs be > consecutive. Use `scatter_subset`{.interpreted-text role="f:subr"} to > scatter data for some (or all) atoms, unordered. > > The *data* array needs to be ordered in groups of *count* values, > sorted by atom ID (e.g., if *name* is *x* and *count* = 3, then *data* > = \[*x*(1,1), *x*(2,1), *x*(3,1), *x*(1,2), *x*(2,2), *x*(3,2), > *x*(1,3), $\dots$\]); *data* must be of length (*count* $\times$ > *natoms*). > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., \"x\" or \"f\" for atom properties, > \"f_id\" for per-atom fix data, \"c_id\" for per-atom compute > data, \"d_name\" or \"i_name\" for fix property/atom vectors with > *count* = 1, \"d2_name\" or \"i2_name\" for fix property/atom > vectors with *count*${} > 1$) > > p data > > : per-atom values packed in a one-dimensional array; *data* should > be of type `INTEGER(c_int)` or `REAL(c_double)`, depending on the > type of data being scattered, and be of rank 1 (i.e., > `DIMENSION(:)`). > > ptype data > > : polymorphic,dimension(:) > > to > > : `lammps_scatter`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_scatter_subset`{.interpreted-text > role="cpp:func"} to scatter the named per-atom, per-atom fix, per-atom > compute, or fix property/atom-based entities in *data* from a subset > of atoms to all processes. > > ::: versionadded > 22Dec2022 > ::: > > This subroutine takes data stored in a one-dimensional array supplied > by the user and scatters them to a subset of atoms on all processes. > The array *data* contains data associated with atom IDs, but there is > no requirement that the IDs be consecutive, as they are provided in a > separate array. Use `scatter`{.interpreted-text role="f:subr"} to > scatter data for all atoms, in order. > > The *data* array needs to be organized in groups of *count* values, > with the groups in the same order as the array *ids*. For example, if > you want *data* to be the array \[x(1,1), x(2,1), x(3,1), x(1,100), > x(2,100), x(3,100), x(1,57), x(2,57), x(3,57)\], then *count* = 3 and > *ids* = \[1, 100, 57\]. > > This function is not compatible with `-DLAMMPS_BIGBIG`. > > p character(len=\*) name > > : desired quantity (e.g., \"x\" or \"mask\" for atom properties, > \"f_id\" for per-atom fix data, \"c_id\" for per-atom compute > data, \"d_name\" or \"i_name\" for fix property/atom vectors with > *count* = 1, \"d2_name\" or \"i2_name\" for fix property/atom > vectors with *count*${}> 1$) > > p integer(c_int) ids > > : list of atom IDs to scatter data for > > > > :p polymorphic data \[dimension(:)\]: per-atom values packed in a > > : one-dimensional array of length *size(ids)* \* *count*. > > > > to > > : `lammps_scatter_subset`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This method calls `lammps_create_atoms`{.interpreted-text > role="cpp:func"} to create additional atoms from a given list of > coordinates and a list of atom types. Additionally, the atom IDs, > velocities, and image flags may be provided. > > ::: versionadded > 3Nov2022 > ::: > > p integer(c_int) type \[dimension(N)\] > > : vector of $N$ atom types (required/see note below) > > p real(c_double) x \[dimension(3N)\] > > : vector of $3N\ x/y/z$ positions of the new atoms, arranged as > $[x_1,y_1,z_1,x_2,y_2,\dotsc]$ (required/see note below) > > o integer(kind=\*) id \[dimension(N),optional\] > > : vector of $N$ atom IDs; if absent, LAMMPS will generate them for > you. \*The `KIND` parameter should be `c_int` unless LAMMPS was > compiled with `-DLAMMPS_BIGBIG`, in which case it should be > `c_int64_t`. > > o real(c_double) v \[dimension(3N),optional\] > > : vector of $3N$ *x*/\*y\*/\*z\* velocities of the new atoms, > arranged as $[v_{1,x},v_{1,y},v_{1,z},v_{2,x}, \dotsc]$; if > absent, they will be set to zero > > o integer(kind=\*) image \[dimension(N),optional\] > > : vector of $N$ image flags; if absent, they are set to zero. \*The > `KIND` parameter should be `c_int` unless LAMMPS was compiled with > `-DLAMMPS_BIGBIG`, in which case it should be `c_int64_t`. See > note below. > > o bexpand > > : if `.TRUE.`, atoms outside of shrink-wrap boundaries will be > created, not dropped, and the box dimensions will be extended. > Default is `.FALSE.` > > otype bexpand > > : logical,optional > > to > > : `lammps_create_atoms`{.interpreted-text role="cpp:func"} > > :::: note > ::: title > Note > ::: > > The *type* and *x* arguments are required, but they are declared > `OPTIONAL` in the module because making them mandatory would require > *id* to be present as well. To have LAMMPS generate the ids for you, > use a call something like > > ``` fortran > lmp%create_atoms(type=new_types, x=new_xs) > ``` > :::: > > :::: note > ::: title > Note > ::: > > When LAMMPS has been compiled with `-DLAMMPS_BIGBIG`, it is not > possible to include the *image* parameter but omit the *id* parameter. > Either *id* must be present, or both *id* and *image* must be absent. > This is required because having all arguments be optional in both > generic functions creates an ambiguous interface. This limitation does > not exist if LAMMPS was not compiled with `-DLAMMPS_BIGBIG`. > :::: ------------------------------------------------------------------------ > Find index of a neighbor list requested by a pair style. > > ::: versionadded > 3Nov2022 > ::: > > This function determines which of the available neighbor lists for > pair styles matches the given conditions. It first matches the style > name. If *exact* is `.TRUE.`, the name must match exactly; if > `.FALSE.`, a regular expression or sub-string match is done. If the > pair style is *hybrid* or *hybrid/overlay*, the style is matched > against the sub-styles instead. If the same pair style is used > multiple times as a sub-style, the *nsub* argument must be $> 0$; this > argument represents the *n*th instance of the sub-style (same as for > the [pair_coeff](pair_coeff) command, for example). In that case, > *nsub*${} = 0$ will not produce a match, and the function will return > $-1$. > > The final condition to be checked is the request ID (\*reqid\*). This > will usually be zero, but some pair styles request multiple neighbor > lists and set the request ID to a value greater than zero. > > p character(len=\*) style > > : String used to search for pair style instance. > > o exact > > : Flag to control whether style should match exactly or only a > regular expression/sub-string match is applied. Default: `.TRUE.`. > > otype exact > > : logical,optional > > o integer(c_int) nsub \[optional\] > > : Match *nsub*th hybrid sub-style instance of the same style. > Default: 0. > > o integer(c_int) reqid \[optional\] > > : Request ID to identify the neighbor list in case there are > multiple requests from the same pair style instance. Default: 0. > > to > > : `lammps_find_pair_neighlist`{.interpreted-text role="cpp:func"} > > r integer(c_int) index > > : Neighbor list index if found, otherwise $-1$. ------------------------------------------------------------------------ > Find index of a neighbor list requested by a fix. > > ::: versionadded > 3Nov2022 > ::: > > The neighbor list request from a fix is identified by the fix ID and > the request ID. The request ID is typically zero, but will be $>0$ for > fixes with multiple neighbor list requests. > > p character(len=\*) id > > : Identifier of fix instance > > o integer(c_int) reqid \[optional\] > > : request ID to identify the neighbor list in cases in which there > are multiple requests from the same fix. Default: 0. > > to > > : `lammps_find_fix_neighlist`{.interpreted-text role="cpp:func"} > > r index > > : neighbor list index if found, otherwise $-1$ > > rtype index > > : integer(c_int) ------------------------------------------------------------------------ > Find index of a neighbor list requested by a compute. > > ::: versionadded > 3Nov2022 > ::: > > The neighbor list request from a compute is identified by the compute > ID and the request ID. The request ID is typically zero, but will be > $> 0$ in case a compute has multiple neighbor list requests. > > p character(len=\*) id > > : Identifier of compute instance. > > o integer(c_int) reqid \[optional\] > > : request ID to identify the neighbor list in cases in which there > are multiple requests from the same compute. Default: 0. > > to > > : `lammps_find_compute_neighlist`{.interpreted-text role="cpp:func"} > > r index > > : neighbor list index if found, otherwise $-1$. > > rtype index > > : integer(c_int) ------------------------------------------------------------------------ > Return the number of entries in the neighbor list with the given > index. > > ::: versionadded > 3Nov2022 > ::: > > p integer(c_int) idx > > : neighbor list index > > to > > : `lammps_neighlist_num_elements`{.interpreted-text role="cpp:func"} > > r inum > > : number of entries in neighbor list, or $-1$ if *idx* is not a > valid index. > > rtype inum > > : integer(c_int) > > to > > : `lammps_neighlist_num_elements`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Return atom local index, number of neighbors, and array of neighbor > local atom indices of a neighbor list entry. > > ::: versionadded > 3Nov2022 > ::: > > p integer(c_int) idx > > : index of this neighbor list in the list of all neighbor lists > > p integer(c_int) element > > : index of this neighbor list entry > > p integer(c_int) iatom > > : local atom index (i.e., in the range \[1,nlocal+nghost\]; -1 if > invalid or element value > > > > :p integer(c_int) neighbors \[dimension(:),pointer\]: pointer to an array of > > : neighboring atom local indices > > > > to > > : `lammps_neighlist_element_neighbors`{.interpreted-text > role="cpp:func"} ------------------------------------------------------------------------ > This method returns the numeric LAMMPS version like > `lammps_version`{.interpreted-text role="cpp:func"} does. > > to > > : `lammps_version`{.interpreted-text role="cpp:func"} > > r version > > : LAMMPS version > > rtype version > > : integer ------------------------------------------------------------------------ > This function can be used to retrieve detailed information about the > hosting operating system and compiler/runtime environment. > > ::: versionadded > 3Nov2022 > ::: > > A suitable buffer has to be provided. The assembled text will be > truncated so as not to overflow this buffer. The string is typically a > few hundred bytes long. > > p character(len=\*) buffer > > : string that will house the information. > > to > > : `lammps_get_os_info`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function is used to query whether LAMMPS was compiled with a real > MPI library or in serial. > > ::: versionadded > 3Nov2022 > ::: > > to > > : `lammps_config_has_mpi_support`{.interpreted-text role="cpp:func"} > > r has_mpi > > : `.FALSE.` when compiled with STUBS, `.TRUE.` if complied with MPI. > > rtype has_mpi > > : logical ------------------------------------------------------------------------ > Check if the LAMMPS library supports reading or writing compressed > files via a pipe to gzip or similar compression programs. > > ::: versionadded > 3Nov2022 > ::: > > Several LAMMPS commands (e.g., [read_data]{.title-ref}, > [write_data]{.title-ref}, [dump styles atom, custom, and xyz](dump)) > support reading and writing compressed files via creating a pipe to > the `gzip` program. This function checks whether this feature was > [enabled at compile time](gzip). It does **not** check whether `gzip` > or any other supported compression programs themselves are installed > and usable. > > to > > : `lammps_config_has_gzip_support`{.interpreted-text > role="cpp:func"} > > r has_gzip > > : > > rtype has_gzip > > : logical ------------------------------------------------------------------------ > Check if the LAMMPS library supports writing PNG format images. > > ::: versionadded > 3Nov2022 > ::: > > The LAMMPS [dump style image](dump_image) supports writing multiple > image file formats. Most of them, however, need support from an > external library, and using that has to be [enabled at compile > time](graphics). This function checks whether support for the [PNG > image file > format](https://en.wikipedia.org/wiki/Portable_Network_Graphics)\_ is > available in the current LAMMPS library. > > to > > : `lammps_config_has_png_support`{.interpreted-text role="cpp:func"} > > r has_png > > : > > rtype has_png > > : logical ------------------------------------------------------------------------ > Check if the LAMMPS library supports writing JPEG format images. > > ::: versionadded > 3Nov2022 > ::: > > The LAMMPS [dump style image](dump_image) supports writing multiple > image file formats. Most of them, however, need support from an > external library, and using that has to be [enabled at compile > time](graphics). This function checks whether support for the [JPEG > image file format](https://jpeg.org/jpeg/)\_ is available in the > current LAMMPS library. > > to > > : `lammps_config_has_jpeg_support`{.interpreted-text > role="cpp:func"} > > r has_jpeg > > : > > rtype has_jpeg > > : logical ------------------------------------------------------------------------ > Check if the LAMMPS library supports creating movie files via a pipe > to ffmpeg. > > ::: versionadded > 3Nov2022 > ::: > > The LAMMPS [dump style movie](dump_image) supports generating movies > from images on-the-fly via creating a pipe to the > [ffmpeg](https://ffmpeg.org/)\_ program. This function checks whether > this feature was [enabled at compile time](graphics). It does **not** > check whether the `ffmpeg` itself is installed and usable. > > to > > : `lammps_config_has_ffmpeg_support`{.interpreted-text > role="cpp:func"} > > r has_ffmpeg > > : > > rtype has_ffmpeg > > : logical ------------------------------------------------------------------------ > Check whether LAMMPS errors will throw C++ exceptions. > > ::: versionadded > 3Nov2022 > ::: > > In case of an error, LAMMPS will either abort or throw a C++ > exception. The latter has to be [enabled at compile time](exceptions). > This function checks if exceptions were enabled. > > When using the library interface with C++ exceptions enabled, the > library interface functions will \"catch\" them, and the error status > can then be checked by calling `has_error`{.interpreted-text > role="f:func"}. The most recent error message can be retrieved via > `get_last_error_message`{.interpreted-text role="f:func"}. This can > allow one to restart a calculation or delete and recreate the LAMMPS > instance when a C++ exception occurs. One application of using > exceptions this way is the [lammps_shell]{.title-ref}. If C++ > exceptions are disabled and an error happens during a call to LAMMPS > or the Fortran API, the application will terminate. > > to > > : `lammps_config_has_exceptions`{.interpreted-text role="cpp:func"} > > r has_exceptions > > : > > rtype has_exceptions > > : logical ------------------------------------------------------------------------ > Check whether a specific package has been included in LAMMPS > > ::: versionadded > 3Nov2022 > ::: > > This function checks whether the LAMMPS library in use includes the > specific [LAMMPS package](Packages) provided as argument. > > to > > : `lammps_config_has_package`{.interpreted-text role="cpp:func"} > > r has_package > > : > > rtype has_package > > : logical ------------------------------------------------------------------------ > Count the number of installed packages in the LAMMPS library. > > ::: versionadded > 3Nov2022 > ::: > > This function counts how many [LAMMPS packages](Packages) are included > in the LAMMPS library in use. It directly calls the C library function > `lammps_config_package_count`{.interpreted-text role="cpp:func"}. > > to > > : `lammps_config_package_count`{.interpreted-text role="cpp:func"} > > r integer(c_int) npackages > > : number of packages installed ------------------------------------------------------------------------ > Get the name of a package in the list of installed packages in the > LAMMPS library. > > ::: versionadded > 3Nov2022 > ::: > > This subroutine copies the name of the package with the index *idx* > into the provided string *buffer*. If the name of the package exceeds > the length of the buffer, it will be truncated accordingly. If the > index is out of range, *buffer* is set to an empty string. > > p integer(c_int) idx > > : index of the package in the list of included packages > $(0 \le idx < \text{package count})$ > > p character(len=\*) buffer > > : string to hold the name of the package > > to > > : `lammps_config_package_name`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Obtain a list of the names of enabled packages in the LAMMPS shared > library and store it in *package*. > > ::: versionadded > 3Nov2022 > ::: > > This function is analogous to the `installed_packages > `{.interpreted-text > role="py:meth"}\_\_ function in the Python API. The optional argument > *length* sets the length of each string in the vector *package* > (default: 31). > > :p character(len=:) package \[dimension(:),allocatable\]: list of packages; > > : *must* have the `ALLOCATABLE` attribute and be of rank 1 (i.e., > `DIMENSION(:)`) with allocatable length. > > > > o length > > : length of each string in the list. Default: 31. > > otype length > > : integer,optional > > to > > : `lammps_config_package_count`{.interpreted-text role="cpp:func"} > > to > > : `lammps_config_package_name`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_config_accelerator`{.interpreted-text > role="cpp:func"} to check the availability of compile time settings of > included [accelerator packages](Speed_packages) in LAMMPS. > > ::: versionadded > 3Nov2022 > ::: > > Supported packages names are \"GPU\", \"KOKKOS\", \"INTEL\", and > \"OPENMP\". Supported categories are \"api\" with possible settings > \"cuda\", \"hip\", \"phi\", \"pthreads\", \"opencl\", \"openmp\", and > \"serial\"; and \"precision\" with possible settings \"double\", > \"mixed\", and \"single\". > > p character(len=\*) package > > : string with the name of the accelerator package > > p character(len=\*) category > > : string with the name of the setting > > p character(len=\*) setting > > : string with the name of the specific setting > > to > > : `lammps_config_accelerator`{.interpreted-text role="cpp:func"} > > r available > > : `.TRUE.` if the combination of package, category, and setting is > available, otherwise `.FALSE.`. > > rtype available > > : logical ------------------------------------------------------------------------ > Checks for the presence of a viable GPU package device. > > ::: versionadded > 3Nov2022 > ::: > > This function calls `lammps_has_gpu_device`{.interpreted-text > role="cpp:func"}, which checks at runtime whether an accelerator > device is present that can be used with the [GPU package](Speed_gpu). > > More detailed information about the available device or devices can be > obtained by calling the `get_gpu_device_info`{.interpreted-text > role="f:subr"} subroutine. > > to > > : `lammps_has_gpu_device`{.interpreted-text role="cpp:func"} > > r available > > : `.TRUE.` if a viable device is available, `.FALSE.` if not. > > rtype available > > : logical ------------------------------------------------------------------------ > Get GPU package device information. > > ::: versionadded > 3Nov2022 > ::: > > Calls `lammps_get_gpu_device_info`{.interpreted-text role="cpp:func"} > to retrieve detailed information about any accelerator devices that > are viable for use with the [GPU package](Speed_gpu). It will fill > *buffer* with a string that is equivalent to the output of the > `nvc_get_device` or `ocl_get_device` or `hip_get_device` tools that > are compiled alongside LAMMPS if the GPU package is enabled. > > A suitable-length Fortran string has to be provided. The assembled > text will be truncated so as not to overflow this buffer. This string > can be several kilobytes long if multiple devices are present. > > p character(len=\*) buffer > > : string into which to copy the information. > > to > > : `lammps_get_gpu_device_info`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Check whether a specific style has been included in LAMMPS. > > ::: versionadded > 3Nov2022 > ::: > > This function calls `lammps_has_style`{.interpreted-text > role="cpp:func"} to check whether the LAMMPS library in use includes > the specific style *name* associated with a specific *category* > provided as arguments. Please see `lammps_has_style`{.interpreted-text > role="cpp:func"} for a list of valid categories. > > p character(len=\*) category > > : category of the style > > p character(len=\*) name > > : name of the style > > to > > : `lammps_has_style`{.interpreted-text role="cpp:func"} > > r has_style > > : `.TRUE.` if included, `.FALSE.` if not. > > rtype has_style > > : logical ------------------------------------------------------------------------ > Count the number of styles of *category* in the LAMMPS library. > > ::: versionadded > 3Nov2022 > ::: > > This function counts how many styles in the provided *category* are > included in the LAMMPS library currently in use. Please see > `lammps_has_style`{.interpreted-text role="cpp:func"} for a list of > valid categories. > > p character(len=\*) category > > : category of styles to count > > to > > : `lammps_style_count`{.interpreted-text role="cpp:func"} > > r integer(c_int) count > > : number of styles in *category* ------------------------------------------------------------------------ > Look up the name of a style by index in the list of styles of a given > category in the LAMMPS library. > > ::: versionadded > 3Nov2022 > ::: > > This function calls `lammps_style_name`{.interpreted-text > role="cpp:func"} and copies the name of the *category* style with > index *idx* into the provided string *buffer*. The length of *buffer* > must be long enough to contain the name of the style; if it is too > short, the name will be truncated accordingly. If *idx* is out of > range, *buffer* will be the empty string and a warning will be issued. > > p character(len=\*) category > > : category of styles > > p integer(c_int) idx > > : index of the style in the list of *category* styles > $(1 \leq idx \leq \text{style count})$ > > p character(len\*) buffer > > : string buffer to copy the name of the style into > > to > > : `lammps_style_name`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function checks if the current LAMMPS instance a *category* ID of > the given *name* exists. Valid categories are: *compute*, *dump*, > *fix*, *group*, *molecule*, *region*, and *variable*. > > ::: versionadded > 3Nov2022 > ::: > > p character(len=\*) category > > : category of the ID > > p character(len=\*) name > > : name of the ID > > to > > : `lammps_has_id`{.interpreted-text role="cpp:func"} > > r has_id > > : `.TRUE.` if *category* style *name* exists, `.FALSE.` if not. > > rtype has_id > > : logical ------------------------------------------------------------------------ > This function counts how many IDs in the provided *category* are > defined in the current LAMMPS instance. Please see > `has_id`{.interpreted-text role="f:func"} for a list of valid > categories. > > ::: versionadded > 3Nov2022 > ::: > > p character(len=\*) category > > : category of the ID > > to > > : `lammps_id_count`{.interpreted-text role="cpp:func"} > > r count > > : number of IDs in *category* > > rtype count > > : integer(c_int) ------------------------------------------------------------------------ > Look up the name of an ID by index in the list of IDs of a given > category. > > ::: versionadded > 3Nov2022 > ::: > > This function copies the name of the *category* ID with the index > *idx* into the provided string *buffer*. The length of the buffer must > be long enough to hold the string; if the name of the style exceeds > the length of the buffer, it will be truncated accordingly. If > *buffer* is `ALLOCATABLE`, it must be allocated *before* the function > is called. If *idx* is out of range, *buffer* is set to an empty > string and a warning is issued. > > p character(len=\*) category > > : category of IDs > > p integer(c_int) idx > > : index of the ID in the list of *category* styles > ($0 \leq idx < count$) > > p character(len=\*) buffer > > : string into which to copy the name of the style > > to > > : `lammps_id_name`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > This function counts the number of loaded plugins. > > ::: versionadded > 3Nov2022 > ::: > > to > > : `lammps_plugin_count`{.interpreted-text role="cpp:func"} > > r n > > : number of loaded plugins > > rtype n > > : integer(c_int) ------------------------------------------------------------------------ > Look up the style and name of a plugin by its index in the list of > plugins. > > ::: versionadded > 3Nov2022 > ::: > > This function copies the name of the *style* plugin with the index > *idx* into the provided C-style string buffer. The length of the > buffer must be provided as *buf_size* argument. If the name of the > style exceeds the length of the buffer, it will be truncated > accordingly. If the index is out of range, both strings are set to the > empty string and a warning is printed. > > p integer(c_int) idx > > : index of the plugin in the list all or *style* plugins > > p character(len=\*) stylebuf > > : string into which to copy the style of the plugin > > p character(len=\*) namebuf > > : string into which to copy the style of the plugin > > to > > : `lammps_plugin_name`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Encodes three integer image flags into a single imageint. > > ::: versionadded > 3Nov2022 > ::: > > This function performs the bit-shift, addition, and bit-wise OR > operations necessary to combine the values of three integers > representing the image flags in the $x$-, $y$-, and $z$-directions. > Unless LAMMPS is compiled with `-DLAMMPS_BIGBIG`, those integers are > limited to 10-bit signed integers $[-512,512)$. If `-DLAMMPS_BIGBIG` > was used when compiling, then the return value is of kind `c_int64_t` > instead of kind `c_int`, and the valid range for the individual image > flags becomes $[-1048576,1048575)$ (i.e., the range of a 21-bit signed > integer). There is no check on whether the arguments conform to these > requirements; values out of range will simply be wrapped back into the > interval. > > p integer(c_int) ix > > : image flag in $x$-direction > > p integer(c_int) iy > > : image flag in $y$-direction > > p integer(c_int) iz > > : image flag in $z$-direction > > r integer(kind=\*) imageint > > : encoded image flag. \*The `KIND` parameter is `c_int` unless > LAMMPS was built with `-DLAMMPS_BIGBIG`, in which case it is > `c_int64_t`. > > :::: note > ::: title > Note > ::: > > The fact that the programmer does not know the `KIND` parameter of the > return value until compile time means that it is impossible to define > an interface that works for both sizes of `imageint`. One side effect > of this is that you must assign the return value of this function to a > variable; it cannot be used as the argument to another function or as > part of an array constructor. For example, > > ``` fortran > my_images = [lmp%encode_image_flags(0,0,0), lmp%encode_image_flags(1,0,0)] > ``` > > will *not* work; instead, do something like > > ``` fortran > my_images(1) = lmp%encode_image_flags(0,0,0) > my_images(2) = lmp%encode_image_flags(1,0,0) > ``` > :::: ------------------------------------------------------------------------ > This function does the reverse operation of > `encode_image_flags`{.interpreted-text role="f:func"}: it takes the > image flag and performs the bit-shift and bit-masking operations to > decode it and stores the resulting three integers into the array > *flags*. > > ::: versionadded > 3Nov2022 > ::: > > p integer(kind=\*) image > > : encoded image flag. \*The `KIND` parameter is either `c_int` or, > if LAMMPS was compiled with `-DLAMMPS_BIGBIG`, `c_int64_t`. Kind > compatibility is checked at run-time. > > p integer(c_int) flags \[dimension(3)\] > > : three-element vector where the decoded image flags will be stored. ------------------------------------------------------------------------ > Set the callback function for a [fix external](fix_external) instance > with the given ID. > > ::: versionadded > 22Dec2022 > ::: > > Fix [external](fix_external) allows programs that are running LAMMPS > through its library interface to modify certain LAMMPS properties on > specific time steps, similar to the way other fixes do. > > This subroutine sets the callback function for use with the > \"pf/callback\" mode. The function should have Fortran language > bindings with the following interface, which depends on how LAMMPS was > compiled: > > ``` fortran > ABSTRACT INTERFACE > SUBROUTINE external_callback(caller, timestep, ids, x, fexternal) > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double, c_int64_t > CLASS(*), INTENT(INOUT) :: caller > INTEGER(c_bigint), INTENT(IN) :: timestep > INTEGER(c_tagint), DIMENSION(:), INTENT(IN) :: ids > REAL(c_double), DIMENSION(:,:), INTENT(IN) :: x > REAL(c_double), DIMENSION(:,:), INTENT(OUT) :: fexternal > END SUBROUTINE external_callback > END INTERFACE > ``` > > where `c_bigint` is `c_int` if `-DLAMMPS_SMALLSMALL` was used and > `c_int64_t` otherwise; and `c_tagint` is `c_int64_t` if > `-DLAMMPS_BIGBIG` was used and `c_int` otherwise. > > The argument *caller* to `set_fix_external_callback`{.interpreted-text > role="f:subr"} is unlimited polymorphic (i.e., it can be any Fortran > object you want to pass to the calling function) and will be available > as the first argument to the callback function. It can be your LAMMPS > instance, which you might need if the callback function needs access > to the library interface. The argument must be a scalar; to pass > non-scalar data, wrap those data in a derived type and pass an > instance of the derived type to *caller*. > > The array *ids* is an array of length *nlocal* (as accessed from the > `Atom`{.interpreted-text role="cpp:class"} class or through > `extract_global`{.interpreted-text role="f:func"}). The arrays *x* and > *fexternal* are $3 \times {}$\*nlocal\* arrays; these are transposed > from what they would look like in C (see note about array index order > at `extract_atom`{.interpreted-text role="f:func"}). > > The callback mechanism is one of two ways that forces can be applied > to a simulation with the help of [fix external](fix_external). The > alternative is *array* mode, where one calls > `fix_external_get_force`{.interpreted-text role="f:func"}. > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and couple it with external > programs. > > p character(len=\*) id > > : ID of [fix external](fix_external) instance > > p callback > > : subroutine [fix external](fix_external) should call > > ptype callback > > : external > > p class(\*) caller \[optional\] > > : object you wish to pass to the callback procedure (must be a > scalar; see note) > > to > > : `lammps_set_fix_external_callback`{.interpreted-text > role="cpp:func"} > > :::: note > ::: title > Note > ::: > > The interface for your callback function must match types precisely > with the abstract interface block given above. **The compiler probably > will not be able to check this for you.** In particular, the first > argument (\"caller\") must be of type `CLASS(*)` or you will probably > get a segmentation fault or at least a misinterpretation of whatever > is in memory there. You can resolve the object using the `SELECT TYPE` > construct. An example callback function (assuming LAMMPS was compiled > with `-DLAMMPS_SMALLBIG`) that applies something akin to Hooke\'s Law > (with each atom having a different *k* value) is shown below. > > ``` fortran > MODULE stuff > USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double, c_int64_t > USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : error_unit > IMPLICIT NONE > > TYPE shield > REAL(c_double), DIMENSION(:,:), ALLOCATABLE :: k > ! assume k gets allocated to dimension(3,nlocal) at some point > ! and assigned values > END TYPE shield > > SUBROUTINE my_callback(caller, timestep, ids, x, fexternal) > CLASS(*), INTENT(INOUT) :: caller > INTEGER(c_int), INTENT(IN) :: timestep > INTEGER(c_int64_t), INTENT(IN) :: ids > REAL(c_double), INTENT(IN) :: x(:,:) > REAL(c_double), INTENT(OUT) :: fexternal(:,:) > > SELECT TYPE (caller) > TYPE IS (shield) > fexternal = - caller%k * x > CLASS DEFAULT > WRITE(error_unit,*) 'UH OH...' > END SELECT > END SUBROUTINE my_callback > END MODULE stuff > > ! then, when assigning the callback function, do this: > PROGRAM example > USE LIBLAMMPS > USE stuff > TYPE(lammps) :: lmp > TYPE(shield) :: my_shield > lmp = lammps() > CALL lmp%command('fix ext all external pf/callback 1 1') > CALL lmp%set_fix_external_callback('ext', my_callback, my_shield) > END PROGRAM example > ``` > :::: ------------------------------------------------------------------------ > Get pointer to the force array storage in a fix external instance with > the given ID. > > ::: versionadded > 22Dec2022 > ::: > > Fix [external](fix_external) allows programs that are running LAMMPS > through its library interfaces to add or modify certain LAMMPS > properties on specific time steps, similar to the way other fixes do. > > This function provides access to the per-atom force storage in a fix > external instance with the given fix-ID to be added to the individual > atoms when using the \"pf/array\" mode. The *fexternal* array can be > accessed like other \"native\" per-atom arrays accessible via the > `extract_atom`{.interpreted-text role="f:func"} function. Please note > that the array stores the forces for *local* atoms for each MPI rank, > in the order determined by the neighbor list build. Because the > underlying data structures can change as well as the order of atom as > they migrate between MPI processes because of the domain decomposition > parallelization, this function should be always called immediately > before the forces are going to be set to get an up-to-date pointer. > You can use, for example, `extract_setting`{.interpreted-text > role="f:func"} to obtain the number of local atoms > [nlocal]{.title-ref} and then assume the dimensions of the returned > force array as `REAL(c_double) :: force(3,nlocal)`. > > This function is an alternative to the callback mechanism in fix > external set up by `set_fix_external_callback`{.interpreted-text > role="f:subr"}. The main difference is that this mechanism can be used > when forces are to be pre-computed and the control alternates between > LAMMPS and the external driver, while the callback mechanism can call > an external subroutine to compute the force when the fix is triggered > and needs them. > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external program. > > p character(len=\*) id > > : ID of [fix external](fix_external) instance > > to > > : `lammps_fix_external_get_force`{.interpreted-text role="cpp:func"} > > r fexternal > > : pointer to the per-atom force array allocated by the fix > > rtype fexternal > > : real(c_double),dimension(3,nlocal) ------------------------------------------------------------------------ > Set the global energy contribution for a [fix external](fix_external) > instance with the given ID. > > ::: versionadded > 22Dec2022 > ::: > > This is a companion function to > `set_fix_external_callback`{.interpreted-text role="f:func"} and > `fix_external_get_force`{.interpreted-text role="f:func"} that also > sets the contribution to the global energy from the external program. > The value of the *eng* argument will be stored in the fix and applied > on the current and all following time steps until changed by another > call to this function. The energy is in energy units as determined by > the current [units](units) settings and is the **total** energy of the > contribution. Thus, when running in parallel, all MPI processes have > to call this function with the **same** value, and this will be > returned as a scalar property of the fix external instance when > accessed in LAMMPS input commands or from variables. > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external program. > > p character(len=\*) id > > : fix ID of fix external instance > > p real(c_double) eng > > : total energy to be added to the global energy > > to > > : `lammps_fix_external_set_energy_global`{.interpreted-text > role="cpp:func"} ------------------------------------------------------------------------ > Set the global virial contribution for a fix external instance with > the given ID. > > ::: versionadded > 22Dec2022 > ::: > > This is a companion function to > `set_fix_external_callback`{.interpreted-text role="f:subr"} and > `fix_external_get_force`{.interpreted-text role="f:func"} to set the > contribution to the global virial from an external program. > > The six values of the *virial* array will be stored in the fix and > applied on the current and all following time steps until changed by > another call to this function. The components of the virial need to be > stored in the following order: *xx*, *yy*, *zz*, *xy*, *xz*, *yz*. In > LAMMPS, the virial is stored internally as > [stress\*volume]{.title-ref} in units of > [pressure\*volume]{.title-ref} as determined by the current > [units](units) settings and is the **total** contribution. Thus, when > running in parallel, all MPI processes have to call this function with > the **same** value, and this will then be added by fix external. > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external code. > > p character(len=\*) id > > : fix ID of fix external instance > > p real(c_double) virial \[dimension(6)\] > > : the six global stress tensor components to be added to the global > virial > > to > > : `lammps_fix_external_set_virial_global`{.interpreted-text > role="cpp:func"} ------------------------------------------------------------------------ > Set the per-atom energy contribution for a fix external instance with > the given ID. > > ::: versionadded > 22Dec2022 > ::: > > This is a companion function to > `set_fix_external_callback`{.interpreted-text role="f:subr"} to set > the per-atom energy contribution due to the fix from the external > program as part of the callback function. For this to work, the LAMMPS > object must be passed as part of the *caller* argument when > registering the callback function, or the callback function must > otherwise have access to the LAMMPS object, such as through a > module-based pointer. > > :::: note > ::: title > Note > ::: > > This function is fully independent from > `fix_external_set_energy_global`{.interpreted-text role="f:subr"} and > will **NOT** add any contributions to the global energy tally and will > **NOT** check whether the sum of the contributions added here are > consistent with the global added energy. > :::: > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external code. > > p character(len=\*) id > > : fix ID of the fix external instance > > > > :p real(c_double) eng \[dimension(:)\]: array of length *nlocal* containing > > : the energy to add to the per-atom energy > > > > to > > : `lammps_fix_external_set_energy_peratom`{.interpreted-text > role="cpp:func"} ------------------------------------------------------------------------ > This is a companion function to > `set_fix_external_callback`{.interpreted-text role="f:subr"} to set > the per-atom virial contribution due to the fix from the external > program as part of the callback function. For this to work, the LAMMPS > object must be passed as the *caller* argument when registering the > callback function. > > ::: versionadded > 22Dec2022 > ::: > > :::: note > ::: title > Note > ::: > > This function is fully independent from > `fix_external_set_virial_global`{.interpreted-text role="f:subr"} and > will **NOT** add any contributions to the global virial tally and > **NOT** check whether the sum of the contributions added here are > consistent with the global added virial. > :::: > > The order and units of the per-atom stress tensor elements are the > same as for the global virial. The type and dimensions of the per-atom > virial array must be `REAL(c_double), DIMENSION(6,nlocal)`. > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external program. > > p character(len=\*) id > > : fix ID of fix external instance > > :p real(c_double) virial \[dimension(:,:)\]: an array of $6 \times{}$ > *nlocal* components to be added to the per-atom virial :to: > `lammps_set_virial_peratom`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Set the vector length for a global vector stored with fix external for > analysis. > > ::: versionadded > 22Dec2022 > ::: > > This is a companion function to > `set_fix_external_callback`{.interpreted-text role="f:subr"} and > `fix_external_get_force`{.interpreted-text role="f:func"} to set the > length of a global vector of properties that will be stored with the > fix via `fix_external_set_vector`{.interpreted-text role="f:subr"}. > > This function needs to be called **before** a call to > `fix_external_set_vector`{.interpreted-text role="f:subr"} and > **before** a run or minimize command. When running in parallel, it > must be called from **all** MPI processes with the same length > argument. > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external program. > > p character(len=\*) id > > : fix ID of fix external instance > > p integer(c_int) length > > : length of the global vector to be stored with the fix > > to > > : `lammps_fix_external_set_vector_length`{.interpreted-text > role="cpp:func"} ------------------------------------------------------------------------ > Store a global vector value for a fix external instance with the given > ID. > > ::: versionadded > 22Dec2022 > ::: > > This is a companion function to > `set_fix_external_callback`{.interpreted-text role="f:subr"} and > `fix_external_get_force`{.interpreted-text role="f:func"} to set the > values of a global vector of properties that will be stored with the > fix and can be accessed from within LAMMPS input commands (e.g., fix > ave/time or variables) when used in a vector context. > > This function needs to be called **after** a call to > `fix_external_set_vector_length`{.interpreted-text role="f:subr"} and > **before** a run or minimize command. When running in parallel, it > must be called from **all** MPI processes with the **same** *idx* and > *val* parameters. The variable *val* is assumed to be extensive. > > :::: note > ::: title > Note > ::: > > The index in the *idx* parameter is 1-based (i.e., the first element > is set with *idx*${} = 1$, and the last element of the vector with > *idx*${} = N$, where $N$ is the value of the *length* parameter of the > call to `fix_external_set_vector_length`{.interpreted-text > role="f:subr"}). > :::: > > Please see the documentation for [fix external](fix_external) for more > information about how to use the fix and how to couple it with an > external code. > > p character(len=\*) id > > : ID of fix external instance > > p integer(c_int) idx > > : 1-based index in global vector > > p integer(c_int) val > > : value to be stored in global vector at index *idx* > > to > > : `lammps_fix_external_set_vector`{.interpreted-text > role="cpp:func"} ------------------------------------------------------------------------ > This function calls `lammps_flush_buffers`{.interpreted-text > role="cpp:func"}, which flushes buffered output to be written to > screen and logfile. This can simplify capturing output from LAMMPS > library calls. > > ::: versionadded > 3Nov2022 > ::: > > to > > : `lammps_flush_buffers`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Check if LAMMPS is currently inside a run or minimization. > > ::: versionadded > 3Nov2022 > ::: > > This function can be used from signal handlers or multi-threaded > applications to determine if the LAMMPS instance is currently active. > > to > > : `lammps_is_running`{.interpreted-text role="cpp:func"} > > r is_running > > : `.FALSE.` if idle or `.TRUE.` if active > > rtype is_running > > : logical ------------------------------------------------------------------------ > Force a timeout to stop an ongoing run cleanly. > > ::: versionadded > 3Nov2022 > ::: > > This function can be used from signal handlers or multi-threaded > applications to terminate an ongoing run cleanly. > > to > > : `lammps_force_timeout`{.interpreted-text role="cpp:func"} ------------------------------------------------------------------------ > Check if there is a (new) error message available. > > ::: versionadded > 3Nov2022 > ::: > > This function can be used to query if an error inside of LAMMPS has > thrown a [C++ exception](exceptions). > > :::: note > ::: title > Note > ::: > > This function will always report \"no error\" when the LAMMPS library > has been compiled without `-DLAMMPS_EXCEPTIONS`, which turns fatal > errors aborting LAMMPS into C++ exceptions. You can use the library > function `lammps_config_has_exceptions`{.interpreted-text > role="cpp:func"} to check if this is the case. > :::: > > to > > : `lammps_has_error`{.interpreted-text role="cpp:func"} > > r has_error > > : `.TRUE.` if there is an error. > > rtype has_error > > : logical ------------------------------------------------------------------------ > Copy the last error message into the provided buffer. > > ::: versionadded > 3Nov2022 > ::: > > This function can be used to retrieve the error message that was set > in the event of an error inside of LAMMPS that resulted in a [C++ > exception](exceptions). A suitable buffer for a string has to be > provided. If the internally-stored error message is longer than the > string, it will be truncated accordingly. The optional argument > *status* indicates the kind of error: a \"1\" indicates an error that > occurred on all MPI ranks and is often recoverable, while a \"2\" > indicates an abort that would happen only in a single MPI rank and > thus may not be recoverable, as other MPI ranks may be waiting on the > failing MPI rank(s) to send messages. > > :::: note > ::: title > Note > ::: > > This function will do nothing when the LAMMPS library has been > compiled without `-DLAMMPS_EXCEPTIONS`, which turns errors aborting > LAMMPS into C++ exceptions. You can use the function > `config_has_exceptions`{.interpreted-text role="f:func"} to check > whether this is the case. > :::: > > p character(len=\*) buffer > > : string buffer to copy the error message into > > o integer(c_int) status \[optional\] > > : 1 when all ranks had the error, 2 on a single-rank error. > > to > > : `lammps_get_last_error_message`{.interpreted-text role="cpp:func"}