implemented scatter, gather, and friends; wrote and updated documentation

This commit is contained in:
Karl Hammond
2022-12-02 17:19:42 -06:00
parent 43dca96ca4
commit 71f086e159
3 changed files with 764 additions and 32 deletions

View File

@ -298,6 +298,16 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS.
:ftype scatter_atoms_subset: subroutine
:f gather_bonds: :f:subr:`gather_bonds`
:ftype gather_bonds: subroutine
:f gather: :f:subr:`gather`
:ftype gather: subroutine
:f gather_concat: :f:subr:`gather_concat`
:ftype gather_concat: subroutine
:f gather_subset: :f:subr:`gather_subset`
:ftype gather_subset: subroutine
:f scatter: :f:subr:`scatter`
:ftype scatter: subroutine
:f scatter_subset: :f:subr:`scatter_subset`
:ftype scatter_subset: subroutine
:f create_atoms: :f:subr:`create_atoms`
:ftype create_atoms: subroutine
:f find_pair_neighlist: :f:func:`find_pair_neighlist`
@ -1194,8 +1204,8 @@ Procedures Bound to the :f:type:`lammps` Derived Type
.. f:function:: extract_variable(name[,group])
This function calls :cpp:func:`lammps_extract_variable` and returns a scalar,
vector, or string containing the value of the variable identified by
This function calls :cpp:func:`lammps_extract_variable` 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,
@ -1276,15 +1286,19 @@ Procedures Bound to the :f:type:`lammps` Derived Type
length (*count* :math:`\times` *natoms*), as queried by
:f:func:`extract_setting`.
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 real(c_double) data [dimension(:),allocatable]: array into which to store
:p polymorphic 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.
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.
:to: :cpp:func:`lammps_gather_atoms`
.. note::
@ -1324,15 +1338,19 @@ Procedures Bound to the :f:type:`lammps` Derived Type
:f:func:`gather_atoms`; for a similar array but for a subset of atoms, see
:f:func:`gather_atoms_subset`.
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 real(c_double) data [dimension(:),allocatable]: array into which to store
:p polymorphic 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.
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.
:to: :cpp:func:`lammps_gather_atoms_concat`
--------
@ -1346,7 +1364,7 @@ Procedures Bound to the :f:type:`lammps` Derived Type
.. versionadded:: 3Nov2022
This subroutine gathers data for the requested atom IDs and stores them in a
one-dimensional array allocated by the user. The data will be ordered by
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
:f:func:`gather_atoms` or :f:func:`gather_atoms_concat`.
@ -1359,6 +1377,8 @@ Procedures Bound to the :f:type:`lammps` Derived Type
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
@ -1366,10 +1386,12 @@ Procedures Bound to the :f:type:`lammps` Derived Type
*x*/*y*/*z* components.
:p integer(c_int) ids [dimension(:)]: atom IDs corresponding to the atoms
to be gathered
:p real(c_double) data [dimension(:),allocatable]: array into which to store
:p polymorphic 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.
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.
:to: :cpp:func:`lammps_gather_atoms_subset`
--------
@ -1443,7 +1465,7 @@ Procedures Bound to the :f:type:`lammps` Derived Type
.. versionadded:: 3Nov2022
This function copies the list of all bonds into an allocated array.
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
@ -1482,6 +1504,173 @@ Procedures Bound to the :f:type:`lammps` Derived Type
--------
.. f:subroutine:: gather(self, name, count, data)
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:: TBD
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
:cpp:func:`lammps_gather_concat`; for a similar array but for a subset of
atoms, see :cpp:func:`lammps_gather_subset`.
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), :math:`\dots`]); *data* must be ``ALLOCATABLE`` and
will be allocated to length (*count*\ :math:`{}\times{}`\ *natoms*), as
queried by :f:func:`extract_setting`.
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 :f:subr:`gather_atoms`.
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 propert/atom vectors with
*count*\ :math:`{}> 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: :cpp:func:`lammps_gather`
--------
.. f:subroutine:: gather_concat(self, name, count, data)
Gather the named per-atom, per-atom fix, per-atom compute, or fix
property/atom-based entities from all processes, unordered.
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 :f:subr:`gather_atoms_concat` or :f:subr:`gather_concat` with
*name* set to ``id``. If you have consecutive IDs and want the data to be in
order, use :f:subr:`gather`; for a similar array but for a subset of
atoms, use :f:subr:`gather_subset`.
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), :math:`\dots`]); *data* must be ``ALLOCATABLE`` and
will be allocated to length (*count* :math:`\times` *natoms*), as queried by
:f:func:`extract_setting`.
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 propert/atom vectors with
*count*\ :math:`{}> 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 polymorphic 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. It should have type
``INTEGER(c_int)`` if expecting integer data and ``REAL(c_double)`` if
expecting floating-point data.
:to: :cpp:func:`lammps_gather_concat`
--------
.. f:subroutine:: gather_subset(name, count, ids, data)
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.
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 :f:subr:`gather` or
:f:subr:`gather_concat`.
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), :math:`\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*\ :math:`{} > 1`)
: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: :cpp:func:`lammps_scatter_subset`
--------
.. f:subroutine:: scatter(name, data)
This function calls :cpp:func:`lammps_scatter` to scatter the named
atom-based entities in *data* to all processes.
*This function is not yet documented, as the underlying C routine has not
been thoroughly tested yet.*
--------
.. f:subroutine:: scatter_subset(name, ids, data)
This function calls :cpp:func:`lammps_scatter_subset` 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:: TBD
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 :f:subr:`scatter` 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 propert/atom vectors with
*count*\ :math:`{}> 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: :cpp:func:`lammps_scatter_subset`
--------
.. f:subroutine:: create_atoms([id,] type, x, [v,] [image,] [bexpand])
This method calls :cpp:func:`lammps_create_atoms` to create additional atoms

View File

@ -135,7 +135,24 @@ MODULE LIBLAMMPS
PROCEDURE, PRIVATE :: lmp_gather_bonds_big
GENERIC :: gather_bonds => lmp_gather_bonds_small, &
lmp_gather_bonds_big
!
PROCEDURE, PRIVATE :: lmp_gather_int
PROCEDURE, PRIVATE :: lmp_gather_double
GENERIC :: gather => lmp_gather_int, lmp_gather_double
PROCEDURE, PRIVATE :: lmp_gather_concat_int
PROCEDURE, PRIVATE :: lmp_gather_concat_double
GENERIC :: gather_concat => lmp_gather_concat_int, &
lmp_gather_concat_double
PROCEDURE, PRIVATE :: lmp_gather_subset_int
PROCEDURE, PRIVATE :: lmp_gather_subset_double
GENERIC :: gather_subset => lmp_gather_subset_int, &
lmp_gather_subset_double
PROCEDURE, PRIVATE :: lmp_scatter_int
PROCEDURE, PRIVATE :: lmp_scatter_double
GENERIC :: scatter => lmp_scatter_int, lmp_scatter_double
PROCEDURE, PRIVATE :: lmp_scatter_subset_int
PROCEDURE, PRIVATE :: lmp_scatter_subset_double
GENERIC :: scatter_subset => lmp_scatter_subset_int, &
lmp_scatter_subset_double
PROCEDURE, PRIVATE :: lmp_create_atoms_int
PROCEDURE, PRIVATE :: lmp_create_atoms_bigbig
GENERIC :: create_atoms => lmp_create_atoms_int, &
@ -552,13 +569,42 @@ MODULE LIBLAMMPS
TYPE(c_ptr), VALUE :: handle, data
END SUBROUTINE lammps_gather_bonds
!SUBROUTINE lammps_gather
SUBROUTINE lammps_gather(handle, name, type, count, data) BIND(C)
IMPORT :: c_ptr, c_int
IMPLICIT NONE
TYPE(c_ptr), VALUE :: handle, name, data
INTEGER(c_int), VALUE :: type, count
END SUBROUTINE lammps_gather
!SUBROUTINE lammps_gather_concat
SUBROUTINE lammps_gather_concat(handle, name, type, count, data) BIND(C)
IMPORT :: c_ptr, c_int
IMPLICIT NONE
TYPE(c_ptr), VALUE :: handle, name, data
INTEGER(c_int), VALUE :: type, count
END SUBROUTINE lammps_gather_concat
!SUBROUTINE lammps_gather_subset
SUBROUTINE lammps_gather_subset(handle, name, type, count, ndata, ids, &
data) BIND(C)
IMPORT :: c_ptr, c_int
IMPLICIT NONE
TYPE(c_ptr), VALUE :: handle, name, ids, data
INTEGER(c_int), VALUE :: type, count, ndata
END SUBROUTINE lammps_gather_subset
!SUBROUTINE lammps_scatter_subset
SUBROUTINE lammps_scatter(handle, name, type, count, data) BIND(C)
IMPORT :: c_ptr, c_int
IMPLICIT NONE
TYPE(c_ptr), VALUE :: handle, name, data
INTEGER(c_int), VALUE :: type, count
END SUBROUTINE lammps_scatter
SUBROUTINE lammps_scatter_subset(handle, name, type, count, ndata, ids, &
data) BIND(C)
IMPORT :: c_ptr, c_int
IMPLICIT NONE
TYPE(c_ptr), VALUE :: handle, name, ids, data
INTEGER(c_int), VALUE :: count, ndata, type
END SUBROUTINE lammps_scatter_subset
FUNCTION lammps_create_atoms(handle, n, id, type, x, v, image, bexpand) &
BIND(C)
@ -1622,7 +1668,7 @@ CONTAINS
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather_atoms_subset requires "count" to be 1 or 3 &
&[Fortran/gather_atoms]')
&[Fortran/gather_atoms_subset]')
END IF
ndata = SIZE(ids, KIND=c_int)
@ -1652,7 +1698,7 @@ CONTAINS
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather_atoms_subset requires "count" to be 1 or 3 &
&[Fortran/gather_atoms]')
&[Fortran/gather_atoms_subset]')
END IF
ndata = SIZE(ids, KIND=c_int)
@ -1746,7 +1792,8 @@ CONTAINS
Ccount = SIZE(data, KIND=c_int) / Cndata
IF (Ccount /= 1 .AND. Ccount /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'scatter_atoms_subset requires either 1 or 3 data per atom')
'scatter_atoms_subset requires either 1 or 3 data per atom &
&[Fortran/scatter_atoms_subset]')
END IF
Cname = f2c_string(name)
@ -1771,7 +1818,8 @@ CONTAINS
Ccount = SIZE(data, KIND=c_int) / Cndata
IF (Ccount /= 1 .AND. Ccount /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'scatter_atoms_subset requires either 1 or 3 data per atom')
'scatter_atoms_subset requires either 1 or 3 data per atom &
&[Fortran/scatter_atoms_subset]')
END IF
Cname = f2c_string(name)
@ -1792,7 +1840,7 @@ CONTAINS
IF (SIZE_TAGINT /= 4_c_int) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'Incompatible integer kind in gather_bonds [Fortran API]')
'Incompatible integer kind in gather_bonds [Fortran/gather_bonds]')
END IF
IF (ALLOCATED(data)) DEALLOCATE(data)
IF (SIZE_BIGINT == 4_c_int) THEN
@ -1815,7 +1863,7 @@ CONTAINS
IF (SIZE_TAGINT /= 8_c_int) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'Incompatible integer kind in gather_bonds [Fortran API]')
'Incompatible integer kind in gather_bonds [Fortran/gather_bonds]')
END IF
nbonds = lmp_extract_global(self, 'nbonds')
IF (ALLOCATED(data)) DEALLOCATE(data)
@ -1824,6 +1872,314 @@ CONTAINS
CALL lammps_gather_bonds(self%handle, Cdata)
END SUBROUTINE lmp_gather_bonds_big
! equivalent function to lammps_gather (for int data)
SUBROUTINE lmp_gather_int(self, name, count, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), INTENT(IN) :: count
INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET, INTENT(OUT) :: data
TYPE(c_ptr) :: Cdata, Cname
INTEGER(c_int) :: natoms
INTEGER(c_int), PARAMETER :: Ctype = 0_c_int
REAL(c_double) :: dnatoms
CHARACTER(LEN=100) :: error_msg
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather requires "count" to be 1 or 3 [Fortran/gather]')
END IF
dnatoms = lmp_get_natoms(self)
IF (dnatoms > HUGE(1_c_int)) THEN
WRITE(error_msg,'(A,1X,I0,1X,A)') &
'Cannot use library function gather with more than', &
HUGE(0_c_int), 'atoms [Fortran/gather]'
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
END IF
natoms = NINT(dnatoms, c_int)
Cname = f2c_string(name)
IF (ALLOCATED(data)) DEALLOCATE(data)
ALLOCATE(data(natoms*count))
Cdata = C_LOC(data(1))
CALL lammps_gather(self%handle, Cname, Ctype, count, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_gather_int
! equivalent function to lammps_gather_atoms (for doubles)
SUBROUTINE lmp_gather_double(self, name, count, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), INTENT(IN) :: count
REAL(c_double), DIMENSION(:), ALLOCATABLE, TARGET, INTENT(OUT) :: data
TYPE(c_ptr) :: Cdata, Cname
INTEGER(c_int) :: natoms
INTEGER(c_int), PARAMETER :: Ctype = 1_c_int
REAL(c_double) :: dnatoms
CHARACTER(LEN=100) :: error_msg
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather requires "count" to be 1 or 3 [Fortran/gather]')
END IF
dnatoms = lmp_get_natoms(self)
IF (dnatoms > HUGE(1_c_int)) THEN
WRITE(error_msg,'(A,1X,I0,1X,A)') &
'Cannot use library function gather with more than', &
HUGE(0_c_int), 'atoms [Fortran/gather]'
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
END IF
natoms = NINT(dnatoms, c_int)
Cname = f2c_string(name)
IF (ALLOCATED(data)) DEALLOCATE(data)
ALLOCATE(data(natoms*count))
Cdata = C_LOC(data(1))
CALL lammps_gather(self%handle, Cname, Ctype, count, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_gather_double
! equivalent function to lammps_gather_concat (for ints)
SUBROUTINE lmp_gather_concat_int(self, name, count, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), INTENT(IN) :: count
INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET, INTENT(OUT) :: data
TYPE(c_ptr) :: Cdata, Cname
INTEGER(c_int) :: natoms
INTEGER(c_int), PARAMETER :: Ctype = 0_c_int
REAL(c_double) :: dnatoms
CHARACTER(LEN=100) :: error_msg
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather_concat requires "count" to be 1 or 3 [Fortran/gather_concat]')
END IF
dnatoms = lmp_get_natoms(self)
IF (dnatoms > HUGE(1_c_int)) THEN
WRITE(error_msg,'(A,1X,I0,1X,A)') &
'Cannot use library function gather_concat with more than', &
HUGE(0_c_int), 'atoms [Fortran/gather_concat]'
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
END IF
natoms = NINT(dnatoms, c_int)
Cname = f2c_string(name)
IF (ALLOCATED(data)) DEALLOCATE(data)
ALLOCATE(data(natoms*count))
Cdata = C_LOC(data(1))
CALL lammps_gather_concat(self%handle, Cname, Ctype, count, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_gather_concat_int
! equivalent function to lammps_gather_concat (for doubles)
SUBROUTINE lmp_gather_concat_double(self, name, count, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), INTENT(IN) :: count
REAL(c_double), DIMENSION(:), ALLOCATABLE, TARGET, INTENT(OUT) :: data
TYPE(c_ptr) :: Cdata, Cname
INTEGER(c_int) :: natoms
INTEGER(c_int), PARAMETER :: Ctype = 1_c_int
REAL(c_double) :: dnatoms
CHARACTER(LEN=100) :: error_msg
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather_concat requires "count" to be 1 or 3 [Fortran/gather_concat]')
END IF
dnatoms = lmp_get_natoms(self)
IF (dnatoms > HUGE(1_c_int)) THEN
WRITE(error_msg,'(A,1X,I0,1X,A)') &
'Cannot use library function gather_concat with more than', &
HUGE(0_c_int), 'atoms [Fortran/gather_concat]'
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
END IF
natoms = NINT(dnatoms, c_int)
Cname = f2c_string(name)
IF (ALLOCATED(data)) DEALLOCATE(data)
ALLOCATE(data(natoms*count))
Cdata = C_LOC(data(1))
CALL lammps_gather_concat(self%handle, Cname, Ctype, count, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_gather_concat_double
! equivalent function to lammps_gather_subset (for integers)
SUBROUTINE lmp_gather_subset_int(self, name, count, ids, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), INTENT(IN) :: count
INTEGER(c_int), DIMENSION(:), TARGET, INTENT(IN) :: ids
INTEGER(c_int), DIMENSION(:), ALLOCATABLE, TARGET, INTENT(OUT) :: data
INTEGER(c_int) :: ndata
TYPE(c_ptr) :: Cdata, Cname, Cids
INTEGER(c_int), PARAMETER :: Ctype = 0_c_int
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather_subset requires "count" to be 1 or 3 [Fortran/gather_subset]')
END IF
ndata = SIZE(ids, KIND=c_int)
Cname = f2c_string(name)
IF (ALLOCATED(data)) DEALLOCATE(data)
ALLOCATE(data(ndata*count))
data = -1_c_int
Cdata = C_LOC(data(1))
Cids = C_LOC(ids(1))
CALL lammps_gather_subset(self%handle, Cname, Ctype, count, &
ndata, Cids, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_gather_subset_int
! equivalent function to lammps_gather_subset (for doubles)
SUBROUTINE lmp_gather_subset_double(self, name, count, ids, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), INTENT(IN) :: count
INTEGER(c_int), DIMENSION(:), TARGET, INTENT(IN) :: ids
REAL(c_double), DIMENSION(:), ALLOCATABLE, TARGET, INTENT(OUT) :: data
INTEGER(c_int) :: ndata
TYPE(c_ptr) :: Cdata, Cname, Cids
INTEGER(c_int), PARAMETER :: Ctype = 1_c_int
IF (count /= 1 .AND. count /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'gather_subset requires "count" to be 1 or 3 [Fortran/gather_subset]')
END IF
ndata = SIZE(ids, KIND=c_int)
Cname = f2c_string(name)
IF (ALLOCATED(data)) DEALLOCATE(data)
ALLOCATE(data(ndata*count))
Cdata = C_LOC(data(1))
Cids = C_LOC(ids(1))
CALL lammps_gather_subset(self%handle, Cname, Ctype, count, &
ndata, Cids, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_gather_subset_double
! equivalent function to lammps_scatter (for integers)
SUBROUTINE lmp_scatter_int(self, name, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), DIMENSION(:), TARGET :: data
INTEGER(c_int) :: natoms, Ccount
INTEGER(c_int), PARAMETER :: Ctype = 0_c_int
TYPE(c_ptr) :: Cname, Cdata
REAL(c_double) :: dnatoms
CHARACTER(LEN=100) :: error_msg
dnatoms = lmp_get_natoms(self)
IF (dnatoms > HUGE(1_c_int)) THEN
WRITE(error_msg,'(A,1X,I0,1X,A)') &
'Cannot use library function scatter with more than', &
HUGE(0_c_int), 'atoms [Fortran/scatter]'
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
END IF
natoms = NINT(dnatoms, c_int)
Cname = f2c_string(name)
Cdata = C_LOC(data(1))
Ccount = SIZE(data) / natoms
IF (Ccount /= 1 .AND. Ccount /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'lammps_scatter requires either 1 or 3 data per atom')
END IF
CALL lammps_scatter(self%handle, Cname, Ctype, Ccount, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_scatter_int
! equivalent function to lammps_scatter (for doubles)
SUBROUTINE lmp_scatter_atoms_double(self, name, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
REAL(c_double), DIMENSION(:), TARGET :: data
INTEGER(c_int) :: natoms, Ccount
INTEGER(c_int), PARAMETER :: Ctype = 1_c_int
TYPE(c_ptr) :: Cname, Cdata
REAL(c_double) :: dnatoms
CHARACTER(LEN=100) :: error_msg
dnatoms = lmp_get_natoms(self)
IF (dnatoms > HUGE(1_c_int)) THEN
WRITE(error_msg,'(A,1X,I0,1X,A)') &
'Cannot use library function scatter with more than', &
HUGE(0_c_int), 'atoms [Fortran/scatter]'
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
END IF
natoms = NINT(dnatoms, c_int)
Cname = f2c_string(name)
Cdata = C_LOC(data(1))
Ccount = SIZE(data) / natoms
IF (Ccount /= 1 .AND. Ccount /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'scatter requires either 1 or 3 data per atom [Fortran/scatter]')
END IF
CALL lammps_scatter(self%handle, Cname, Ctype, Ccount, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_scatter_double
! equivalent function to lammps_scatter_subset (for integers)
SUBROUTINE lmp_scatter_subset_int(self, name, ids, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), DIMENSION(:), TARGET :: ids
INTEGER(c_int), DIMENSION(:), TARGET :: data
INTEGER(c_int), PARAMETER :: Ctype = 0_c_int
INTEGER(c_int) :: Cndata, Ccount
TYPE(c_ptr) :: Cdata, Cname, Cids
Cndata = SIZE(ids, KIND=c_int)
Ccount = SIZE(data, KIND=c_int) / Cndata
IF (Ccount /= 1 .AND. Ccount /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'scatter_subset requires either 1 or 3 data per atom &
&[Fortran/scatter_subset]')
END IF
Cname = f2c_string(name)
Cdata = C_LOC(data(1))
Cids = C_LOC(ids(1))
CALL lammps_scatter_subset(self%handle, Cname, Ctype, Ccount, &
Cndata, Cids, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_scatter_subset_int
! equivalent function to lammps_scatter_subset (for doubles)
SUBROUTINE lmp_scatter_subset_double(self, name, ids, data)
CLASS(lammps), INTENT(IN) :: self
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER(c_int), DIMENSION(:), TARGET :: ids
REAL(c_double), DIMENSION(:), TARGET :: data
INTEGER(c_int), PARAMETER :: Ctype = 1_c_int
INTEGER(c_int) :: Cndata, Ccount
TYPE(c_ptr) :: Cdata, Cname, Cids
Cndata = SIZE(ids, KIND=c_int)
Ccount = SIZE(data, KIND=c_int) / Cndata
IF (Ccount /= 1 .AND. Ccount /= 3) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'scatter_subset requires either 1 or 3 data per atom')
END IF
Cname = f2c_string(name)
Cdata = C_LOC(data(1))
Cids = C_LOC(ids(1))
CALL lammps_scatter_subset(self%handle, Cname, Ctype, Ccount, &
Cndata, Cids, Cdata)
CALL lammps_free(Cname)
END SUBROUTINE lmp_scatter_subset_double
! equivalent function to lammps_create_atoms (int ids or id absent)
SUBROUTINE lmp_create_atoms_int(self, id, type, x, v, image, bexpand)
CLASS(lammps), INTENT(IN) :: self

View File

@ -685,7 +685,7 @@ void lammps_commands_string(void *handle, const char *str)
\verbatim embed:rst
This number may be very large when running large simulations across
multiple processors. Depending on compile time choices, LAMMPS may be
multiple processes. Depending on compile time choices, LAMMPS may be
using either 32-bit or a 64-bit integer to store this number. For
portability this function returns thus a double precision
floating point number, which can represent up to a 53-bit signed
@ -2263,7 +2263,7 @@ int lammps_set_variable(void *handle, char *name, char *str)
// Library functions for scatter/gather operations of data
// ----------------------------------------------------------------------
/** Gather the named atom-based entity for all atoms across all processors,
/** Gather the named atom-based entity for all atoms across all processes,
* in order.
*
\verbatim embed:rst
@ -2282,6 +2282,8 @@ x[0][2], x[1][0], x[1][1], x[1][2], x[2][0], :math:`\dots`);
*natoms*), as queried by :cpp:func:`lammps_get_natoms`,
:cpp:func:`lammps_extract_global`, or :cpp:func:`lammps_extract_setting`.
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle pointer to a previously created LAMMPS instance
@ -2415,7 +2417,7 @@ void lammps_gather_atoms(void *handle, char *name, int type, int count, void *da
END_CAPTURE
}
/** Gather the named atom-based entity for all atoms across all processors,
/** Gather the named atom-based entity for all atoms across all processes,
* unordered.
*
\verbatim embed:rst
@ -2432,12 +2434,14 @@ of atoms, use :cpp:func:`lammps_gather_atoms_subset`.
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[10][0], x[10][1], x[10][2],
is 3, then *data* might be something like x[10][0], x[10][1], x[10][2],
x[2][0], x[2][1], x[2][2], x[4][0], :math:`\dots`); *data* must be
pre-allocated by the caller to length (*count* :math:`\times` *natoms*), as
queried by :cpp:func:`lammps_get_natoms`,
:cpp:func:`lammps_extract_global`, or :cpp:func:`lammps_extract_setting`.
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle: pointer to a previously created LAMMPS instance
@ -2599,6 +2603,8 @@ x[100][2], x[57][0], x[57][1], x[57][2], x[210][0], :math:`\dots`);
*data* must be pre-allocated by the caller to length
(*count* :math:`\times` *ndata*).
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle: pointer to a previously created LAMMPS instance
@ -2745,20 +2751,22 @@ void lammps_gather_atoms_subset(void *handle, char *name, int type, int count,
END_CAPTURE
}
/** Scatter the named atom-based entities in *data* to all processors.
/** Scatter the named atom-based entities in *data* to all processes.
*
\verbatim embed:rst
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
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 :cpp:func:`lammps_scatter_atoms_subset` 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[0][0], x[0][1], x[0][2], x[1][0], x[1][1], x[1][2], x[2][0],
:math:`\dots`); *data* must be of length (*count* :math:`\times` *natoms*).
*data* = {x[0][0], x[0][1], x[0][2], x[1][0], x[1][1], x[1][2], x[2][0],
:math:`\dots`}); *data* must be of length (*count* :math:`\times` *natoms*).
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
@ -2768,7 +2776,7 @@ atom ID (e.g., if *name* is *x* and *count* = 3, then
* \param 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 have
* a single image flag packed into (*x*,*y*,*z*) components.
* \param data per-atom values packed in a 1-dimensional array of length
* \param data per-atom values packed in a one-dimensional array of length
* *natoms* \* *count*.
*
*/
@ -2879,12 +2887,12 @@ void lammps_scatter_atoms(void *handle, char *name, int type, int count, void *d
}
/** Scatter the named atom-based entities in *data* from a subset of atoms
* to all processors.
* to all processes.
*
\verbatim embed:rst
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
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 :cpp:func:`lammps_scatter_atoms` to scatter data for all atoms, in order.
@ -2895,6 +2903,8 @@ to be the array {x[1][0], x[1][1], x[1][2], x[100][0], x[100][1], x[100][2],
x[57][0], x[57][1], x[57][2]}, then *count* = 3, *ndata* = 3, and *ids* would
be {1, 100, 57}.
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle: pointer to a previously created LAMMPS instance
@ -3146,6 +3156,43 @@ void lammps_gather_bonds(void *handle, void *data)
END_CAPTURE
}
/** 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.
*
\verbatim embed:rst
This subroutine gathers data from all processes and stores them in a one-dimensional array
allocated by the user. 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
:cpp:func:`lammps_gather_concat`; for a similar array but for a subset of atoms, see
:cpp:func:`lammps_gather_subset`.
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[0][0], x[0][1], x[0][2], x[1][0], x[1][1], x[1][2], x[2][0],
:math:`\dots`}); *data* must be pre-allocated by the caller to the correct length
(*count*\ :math:`{}\times{}`\ *natoms*), as queried by :cpp:func:`lammps_get_natoms`,
:cpp:func:`lammps_extract_global`, or :cpp:func:`lammps_extract_setting`.
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.
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle pointer to a previously created LAMMPS instance
* \param 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)
* \param type 0 for ``int`` values, 1 for ``double`` values
* \param 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.
* \param data per-atom values packed into a one-dimensional array of length
* *natoms* \* *count*.
*
*/
/* ----------------------------------------------------------------------
Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France)
gather the named atom-based entity for all atoms
@ -3381,6 +3428,44 @@ void lammps_gather(void *handle, char *name, int type, int count, void *data)
END_CAPTURE
}
/** Gather the named per-atom, per-atom fix, per-atom compute, or fix property/atom-based entities
* from all processes, unordered.
*
\verbatim embed:rst
This subroutine gathers data for all atoms and stores them in a one-dimensional array allocated by
the user. 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
:cpp:func:`lammps_gather_atoms_concat` or :cpp:func:`lammps_gather_concat` with *name* set to
``id``. If you have consecutive IDs and want the data to be in order, use
:cpp:func:`lammps_gather`; for a similar array but for a subset of atoms, use
:cpp:func:`lammps_gather_subset`.
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[10][0], x[10][1], x[10][2], x[2][0], x[2][1], x[2][2], x[4][0], :math:`\dots`}); *data* must be
pre-allocated by the caller to length (*count* :math:`\times` *natoms*), as queried by
:cpp:func:`lammps_get_natoms`, :cpp:func:`lammps_extract_global`, or
:cpp:func:`lammps_extract_setting`.
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle: pointer to a previously created LAMMPS instance
* \param 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)
* \param type: 0 for ``int`` values, 1 for ``double`` values
* \param 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.
* \param data: per-atom values packed into a one-dimensional array of length
* *natoms* \* *count*.
*
*/
/* ----------------------------------------------------------------------
Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France)
gather the named atom-based entity for all atoms
@ -3633,6 +3718,41 @@ void lammps_gather_concat(void *handle, char *name, int type, int count, void *d
END_CAPTURE
}
/** 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.
*
\verbatim embed:rst
This subroutine gathers data for the requested atom IDs and stores them in a one-dimensional array
allocated by the user. 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
:cpp:func:`lammps_gather` or :cpp:func:`lammps_gather_concat`.
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[100][0], x[100][1], x[100][2], x[57][0], x[57][1], x[57][2], x[210][0],
:math:`\dots`}); *ids* must be provided by the user with length *ndata*, and *data* must be
pre-allocated by the caller to length (*count*\ :math:`{}\times{}`\ *ndata*).
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle: pointer to a previously created LAMMPS instance
* \param 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)
* \param type 0 for ``int`` values, 1 for ``double`` values
* \param 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.
* \param ndata: number of atoms for which to return data (can be all of them)
* \param ids: list of *ndata* atom IDs for which to return data
* \param data per-atom values packed into a one-dimensional array of length
* *ndata* \* *count*.
*
*/
/* ----------------------------------------------------------------------
Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France)
gather the named atom-based entity for all atoms
@ -3884,6 +4004,37 @@ void lammps_gather_subset(void *handle, char *name,
END_CAPTURE
}
/** Scatter the named per-atom, per-atom fix, per-atom compute, or fix property/atom-based
* entity in *data* to all processes.
*
\verbatim embed:rst
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 :cpp:func:`lammps_scatter_subset` 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[0][0], x[0][1], x[0][2], x[1][0], x[1][1],
x[1][2], x[2][0], :math:`\dots`}); *data* must be of length (*count* :math:`\times` *natoms*).
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle pointer to a previously created LAMMPS instance
* \param 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)
* \param type 0 for ``int`` values, 1 for ``double`` values
* \param 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 have
* a single image flag packed into (*x*,*y*,*z*) components.
* \param data per-atom values packed in a one-dimensional array of length
* *natoms* \* *count*.
*
*/
/* ----------------------------------------------------------------------
Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France)
scatter the named atom-based entity in data to all atoms
@ -4103,6 +4254,42 @@ void lammps_scatter(void *handle, char *name, int type, int count, void *data)
END_CAPTURE
}
/** 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.
*
\verbatim embed:rst
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 :cpp:func:`lammps_scatter` 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][0], x[1][1], x[1][2], x[100][0], x[100][1], x[100][2],
x[57][0], x[57][1], x[57][2]}, then *count* = 3, *ndata* = 3, and *ids* would
be {1, 100, 57}.
This function is not compatible with ``-DLAMMPS_BIGBIG``.
\endverbatim
*
* \param handle: pointer to a previously created LAMMPS instance
* \param 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)
* \param type: 0 for ``int`` values, 1 for ``double`` values
* \param 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
* single image flags unpacked into (*x*,*y*,*z*)
* \param ndata: number of atoms listed in *ids* and *data* arrays
* \param ids: list of *ndata* atom IDs to scatter data to
* \param data per-atom values packed in a 1-dimensional array of length
* *ndata* \* *count*.
*
*/
/* ----------------------------------------------------------------------
Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France)
scatter the named atom-based entity in data to a subset of atoms