Finished extract_compute and its unit tests and documentation

This commit is contained in:
Karl Hammond
2022-09-25 23:54:18 -05:00
parent 26e269aacd
commit bada1fb348
3 changed files with 276 additions and 65 deletions

View File

@ -452,7 +452,7 @@ Procedures Bound to the lammps Derived Type
.. note:: .. note::
The `MPI_F08` module, which defines Fortran 2008 bindings for MPI, The ``MPI_F08`` module, which defines Fortran 2008 bindings for MPI,
is not directly supported by this function. However, you should be is not directly supported by this function. However, you should be
able to convert between the two using the `MPI_VAL` member of the able to convert between the two using the `MPI_VAL` member of the
communicator. For example, communicator. For example,
@ -461,12 +461,12 @@ Procedures Bound to the lammps Derived Type
USE MPI_F08 USE MPI_F08
USE LIBLAMMPS USE LIBLAMMPS
TYPE (LAMMPS) :: lmp TYPE (lammps) :: lmp
TYPE (MPI_Comm) :: comm TYPE (MPI_Comm) :: comm
! ... [commands to set up LAMMPS/etc.] ! ... [commands to set up LAMMPS/etc.]
comm%MPI_VAL = lmp%get_mpi_comm() comm%MPI_VAL = lmp%get_mpi_comm()
should assign an `MPI_F08` communicator properly. should assign an ``MPI_F08`` communicator properly.
-------- --------
@ -505,12 +505,12 @@ Procedures Bound to the lammps Derived Type
.. code-block:: fortran .. code-block:: fortran
PROGRAM demo PROGRAM demo
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int64_t USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int64_t, c_int, c_double
USE LIBLAMMPS USE LIBLAMMPS
TYPE(lammps) :: lmp TYPE(lammps) :: lmp
INTEGER(C_int), POINTER :: nlocal => NULL() INTEGER(c_int), POINTER :: nlocal => NULL()
INTEGER(C_int64_t), POINTER :: ntimestep => NULL() INTEGER(c_int64_t), POINTER :: ntimestep => NULL()
REAL(C_double), POINTER :: dt => NULL() REAL(c_double), POINTER :: dt => NULL()
CHARACTER(LEN=10) :: units CHARACTER(LEN=10) :: units
lmp = lammps() lmp = lammps()
! other commands ! other commands
@ -540,7 +540,7 @@ Procedures Bound to the lammps Derived Type
pointer (e.g., ``INTEGER (c_int), POINTER :: nlocal``) to the extracted pointer (e.g., ``INTEGER (c_int), POINTER :: nlocal``) to the extracted
property. If expecting vector data, the pointer should have dimension ":". property. If expecting vector data, the pointer should have dimension ":".
.. warning:: .. warning::
Modifying the data in the location pointed to by the returned pointer Modifying the data in the location pointed to by the returned pointer
may lead to inconsistent internal data and thus may cause failures, may lead to inconsistent internal data and thus may cause failures,
@ -560,14 +560,14 @@ Procedures Bound to the lammps Derived Type
Note that this function actually does not return a pointer, but rather Note that this function actually does not return a pointer, but rather
associates the pointer on the left side of the assignment to point associates the pointer on the left side of the assignment to point
to internal LAMMPS data. Pointers must be of the correct type, kind, and to internal LAMMPS data. Pointers must be of the correct type, kind, and
rank (e.g., integer(C_int), dimension(:) for "type", "mask", or "tag"; rank (e.g., ``INTEGER(c_int), DIMENSION(:)`` for "type", "mask", or "tag";
integer(C_int64_t), dimension(:) for "tag" if LAMMPS was compiled ``INTEGER(c_int64_t), DIMENSION(:)`` for "tag" if LAMMPS was compiled
with the -DLAMMPS_BIGBIG flag; real(C_double), dimension(:,:) for "x", "v", with the ``-DLAMMPS_BIGBIG`` flag; ``REAL(c_double), DIMENSION(:,:)`` for
or "f"; and so forth). The pointer being associated with LAMMPS data is "x", "v", or "f"; and so forth). The pointer being associated with LAMMPS
type-, kind-, and rank-checked at run-time. Pointers returned by this data is type-, kind-, and rank-checked at run-time. Pointers returned by
function are generally persistent; therefore, it is not necessary to call this function are generally persistent; therefore, it is not necessary to
the function again unless the underlying LAMMPS data are destroyed, such as call the function again unless the underlying LAMMPS data are destroyed,
through the :doc:`clear` command. such as through the :doc:`clear` command.
:p character(len=\*) name: string with the name of the property to extract :p character(len=\*) name: string with the name of the property to extract
:r polymorphic: pointer to LAMMPS data. The left-hand side of the assignment :r polymorphic: pointer to LAMMPS data. The left-hand side of the assignment
@ -576,7 +576,7 @@ Procedures Bound to the lammps Derived Type
property. If expecting vector data, the pointer should have dimension ":"; property. If expecting vector data, the pointer should have dimension ":";
if expecting matrix data, the pointer should have dimension ":,:". if expecting matrix data, the pointer should have dimension ":,:".
.. note:: .. admonition:: Array index order
Two-dimensional arrays returned from :f:func:`extract_atom` will be Two-dimensional arrays returned from :f:func:`extract_atom` will be
**transposed** from equivalent arrays in C, and they will be indexed **transposed** from equivalent arrays in C, and they will be indexed
@ -596,12 +596,12 @@ Procedures Bound to the lammps Derived Type
.. code-block:: Fortran .. code-block:: Fortran
TYPE(lammps) :: lmp TYPE(lammps) :: lmp
REAL(C_double), DIMENSION(:,:), POINTER :: x REAL(c_double), DIMENSION(:,:), POINTER :: x => NULL()
! more code to setup, etc. ! more code to setup, etc.
x = lmp%extract_atom("x") x = lmp%extract_atom("x")
print '(f0.6)', x(2,6) print '(f0.6)', x(2,6)
will print the *y*-coordinate of the third atom on this processor 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 (note the transposition of the two indices). This is not a choice, but
rather a consequence of the different conventions adopted by the Fortran rather a consequence of the different conventions adopted by the Fortran
and C standards decades ago. and C standards decades ago.
@ -612,7 +612,7 @@ Procedures Bound to the lammps Derived Type
.. code-block:: Fortran .. code-block:: Fortran
REAL(C_double), DIMENSION(:,:), POINTER :: x, x0 REAL(c_double), DIMENSION(:,:), POINTER :: x, x0
x = lmp%extract_atom("x") x = lmp%extract_atom("x")
x0(0:,0:) => x x0(0:,0:) => x
@ -621,6 +621,109 @@ Procedures Bound to the lammps Derived Type
-------- --------
.. f:function:: extract_compute(id, style, type)
This function calls :c:func:`lammps_extract_compute` and returns a pointer
to LAMMPS data tied to the :cpp:class:`Compute` 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.
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,
.. code-block:: Fortran
TYPE(lammps) :: lmp
REAL(c_double), DIMENSION(:), POINTER :: COM
! code to setup, create atoms, etc.
CALL lmp%compute('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 :cpp:class:`Compute` class.
.. admonition:: Array index order
Two-dimensional arrays returned from :f:func:`extract_compute` will be
**transposed** from equivalent arrays in C, and they will be indexed
from 1 instead of 0. See the similar note under
:f:func:`extract_atom` for further details.
The following combinations are possible (assuming ``lmp`` is the name of
your LAMMPS instance):
.. list-table::
:header-rows: 1
:widths: auto
* - Style
- Type
- Pointer 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)
.. 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::
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.
--------
.. f:function:: version() .. f:function:: version()
This method returns the numeric LAMMPS version like This method returns the numeric LAMMPS version like

View File

@ -29,8 +29,9 @@
! !
MODULE LIBLAMMPS MODULE LIBLAMMPS
USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_ptr, c_null_ptr, c_loc, & USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_ptr, c_null_ptr, c_associated, &
c_int, c_int64_t, c_char, c_null_char, c_double, c_size_t, c_f_pointer c_loc, c_int, c_int64_t, c_char, c_null_char, c_double, c_size_t, &
c_f_pointer
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : ERROR_UNIT USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : ERROR_UNIT
IMPLICIT NONE IMPLICIT NONE
@ -59,7 +60,12 @@ MODULE LIBLAMMPS
LMP_TYPE_ARRAY = 2, & ! request array LMP_TYPE_ARRAY = 2, & ! request array
LMP_SIZE_VECTOR = 3, & ! request size of vector LMP_SIZE_VECTOR = 3, & ! request size of vector
LMP_SIZE_ROWS = 4, & ! request rows (actually columns) LMP_SIZE_ROWS = 4, & ! request rows (actually columns)
LMP_SIZE_COLS = 5 ! request colums (actually rows) LMP_SIZE_COLS = 5, & ! request colums (actually rows)
LMP_ERROR_WARNING = 0, & ! call Error::warning()
LMP_ERROR_ONE = 1, & ! call Error::one() (from this MPI rank)
LMP_ERROR_ALL = 2, & ! call Error::all() (from all MPI ranks)
LMP_ERROR_WORLD = 4, & ! error on comm->world
LMP_ERROR_UNIVERSE = 8 ! error on comm->universe
! "Constants" to use with extract_compute and friends ! "Constants" to use with extract_compute and friends
TYPE lammps_style TYPE lammps_style
@ -112,13 +118,13 @@ MODULE LIBLAMMPS
! pointers) ! pointers)
TYPE lammps_data TYPE lammps_data
INTEGER(c_int) :: datatype INTEGER(c_int) :: datatype
INTEGER(c_int), POINTER :: i32 INTEGER(c_int), POINTER :: i32 => NULL()
INTEGER(c_int), DIMENSION(:), POINTER :: i32_vec INTEGER(c_int), DIMENSION(:), POINTER :: i32_vec => NULL()
INTEGER(c_int64_t), POINTER :: i64 INTEGER(c_int64_t), POINTER :: i64 => NULL()
INTEGER(c_int64_t), DIMENSION(:), POINTER :: i64_vec INTEGER(c_int64_t), DIMENSION(:), POINTER :: i64_vec => NULL()
REAL(c_double), POINTER :: r64 REAL(c_double), POINTER :: r64 => NULL()
REAL(c_double), DIMENSION(:), POINTER :: r64_vec REAL(c_double), DIMENSION(:), POINTER :: r64_vec => NULL()
REAL(c_double), DIMENSION(:,:), POINTER :: r64_mat REAL(c_double), DIMENSION(:,:), POINTER :: r64_mat => NULL()
CHARACTER(LEN=:), ALLOCATABLE :: str CHARACTER(LEN=:), ALLOCATABLE :: str
END TYPE lammps_data END TYPE lammps_data
@ -684,8 +690,8 @@ CONTAINS
global_data%str(i:i) = Fptr(i) global_data%str(i:i) = Fptr(i)
END FORALL END FORALL
CASE DEFAULT CASE DEFAULT
! FIXME convert to use symbolic constants later CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
CALL lmp_error(self, 6, 'Unknown pointer type in extract_global') 'Unknown pointer type in extract_global')
END SELECT END SELECT
END FUNCTION END FUNCTION
@ -703,6 +709,7 @@ CONTAINS
INTEGER :: nrows, ncols INTEGER :: nrows, ncols
REAL(c_double), DIMENSION(:), POINTER :: dummy REAL(c_double), DIMENSION(:), POINTER :: dummy
TYPE(c_ptr), DIMENSION(:), POINTER :: Catomptr TYPE(c_ptr), DIMENSION(:), POINTER :: Catomptr
CHARACTER(LEN=:), ALLOCATABLE :: error_msg
nmax = lmp_extract_setting(self, 'nmax') nmax = lmp_extract_setting(self, 'nmax')
ntypes = lmp_extract_setting(self, 'ntypes') ntypes = lmp_extract_setting(self, 'ntypes')
@ -745,13 +752,18 @@ CONTAINS
! Catomptr(1) now points to the first element of the array ! Catomptr(1) now points to the first element of the array
CALL C_F_POINTER(Catomptr(1), peratom_data%r64_mat, [nrows,ncols]) CALL C_F_POINTER(Catomptr(1), peratom_data%r64_mat, [nrows,ncols])
CASE (-1) CASE (-1)
WRITE(ERROR_UNIT,'(A)') 'ERROR: per-atom property "' // name // & CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'" not found.' 'per-atom property ' // name // 'not found in extract_setting')
STOP 2 ! WRITE(ERROR_UNIT,'(A)') 'ERROR: per-atom property "' // name // &
! '" not found.'
! STOP 2
CASE DEFAULT CASE DEFAULT
WRITE(ERROR_UNIT,'(A,I0,A)') 'ERROR: return value ', datatype, & WRITE(error_msg,'(A,I0,A)') 'return value ', datatype, &
' from lammps_extract_atom_datatype not known' ' from lammps_extract_atom_datatype not known [Fortran/extract_atom]'
STOP 1 CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, error_msg)
! WRITE(ERROR_UNIT,'(A,I0,A)') 'ERROR: return value ', datatype, &
! ' from lammps_extract_atom_datatype not known'
! STOP 1
END SELECT END SELECT
END FUNCTION lmp_extract_atom END FUNCTION lmp_extract_atom
@ -768,18 +780,26 @@ CONTAINS
TYPE(c_ptr) :: Cid, Cptr, Ctemp TYPE(c_ptr) :: Cid, Cptr, Ctemp
INTEGER :: nrows, ncols, length INTEGER :: nrows, ncols, length
INTEGER(c_int), POINTER :: temp INTEGER(c_int), POINTER :: temp
TYPE(c_ptr), DIMENSION(:), POINTER :: Ccomputeptr
Cid = f2c_string(id) Cid = f2c_string(id)
Cptr = lammps_extract_compute(self%handle, Cid, style, type) Cptr = lammps_extract_compute(self%handle, Cid, style, type)
IF ( .NOT. C_ASSOCIATED(Cptr) ) THEN
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'Pointer from LAMMPS is NULL [Fortran/extract_compute]')
END IF
! Remember that rows and columns in C are transposed in Fortran! ! Remember that rows and columns in C are transposed in Fortran!
SELECT CASE (type) SELECT CASE (type)
CASE (LMP_TYPE_SCALAR) CASE (LMP_TYPE_SCALAR)
compute_data%datatype = DATA_DOUBLE
length = 1 length = 1
nrows = 1 nrows = 1
ncols = 1 ncols = 1
CALL C_F_POINTER(Cptr, compute_data%r64) CALL C_F_POINTER(Cptr, compute_data%r64)
CASE (LMP_TYPE_VECTOR) CASE (LMP_TYPE_VECTOR)
compute_data%datatype = DATA_DOUBLE_1D
IF (style == LMP_STYLE_ATOM) THEN IF (style == LMP_STYLE_ATOM) THEN
length = self%extract_setting('nmax') length = self%extract_setting('nmax')
ELSE ELSE
@ -789,11 +809,12 @@ CONTAINS
END IF END IF
CALL C_F_POINTER(Cptr, compute_data%r64_vec, [length]) CALL C_F_POINTER(Cptr, compute_data%r64_vec, [length])
CASE (LMP_TYPE_ARRAY) CASE (LMP_TYPE_ARRAY)
compute_data%datatype = DATA_DOUBLE_2D
IF (style == LMP_STYLE_ATOM) THEN IF (style == LMP_STYLE_ATOM) THEN
nrows = self%extract_setting('nmax') ncols = self%extract_setting('nmax')
Ctemp = lammps_extract_compute(self%handle,Cid,style,LMP_SIZE_ROWS) Ctemp = lammps_extract_compute(self%handle,Cid,style,LMP_SIZE_COLS)
CALL C_F_POINTER(Ctemp, temp) CALL C_F_POINTER(Ctemp, temp)
ncols = temp nrows = temp
ELSE ELSE
Ctemp = lammps_extract_compute(self%handle,Cid,style,LMP_SIZE_ROWS) Ctemp = lammps_extract_compute(self%handle,Cid,style,LMP_SIZE_ROWS)
CALL C_F_POINTER(Ctemp, temp) CALL C_F_POINTER(Ctemp, temp)
@ -802,11 +823,16 @@ CONTAINS
CALL C_F_POINTER(Ctemp, temp) CALL C_F_POINTER(Ctemp, temp)
nrows = temp nrows = temp
END IF END IF
CALL C_F_POINTER(Cptr, compute_data%r64_mat, [nrows, ncols]) ! First, we dereference the void** pointer to point to a void* pointer
CALL C_F_POINTER(Cptr, Ccomputeptr, [ncols])
! Ccomputeptr(1) now points to the first element of the array
CALL C_F_POINTER(Ccomputeptr(1), compute_data%r64_mat, [nrows, ncols])
CASE DEFAULT CASE DEFAULT
WRITE(ERROR_UNIT,'(A,I0,A)') 'ERROR: unknown type value ', type, & CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
'passed to extract_compute' 'unknown type value passed to extract_compute')
STOP 1 !WRITE(ERROR_UNIT,'(A,I0,A)') 'ERROR: unknown type value ', type, &
! 'passed to extract_compute'
!STOP 1
END SELECT END SELECT
CALL lammps_free(Cid) CALL lammps_free(Cid)
END FUNCTION lmp_extract_compute END FUNCTION lmp_extract_compute
@ -944,6 +970,8 @@ CONTAINS
CASE DEFAULT CASE DEFAULT
str1 = 'that type' str1 = 'that type'
END SELECT END SELECT
!CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, 'cannot associate ' &
! // str1 // ' with ' // type2 // ' [Fortran API]')
WRITE (ERROR_UNIT,'(A)') 'ERROR (Fortran API): cannot associate ' & WRITE (ERROR_UNIT,'(A)') 'ERROR (Fortran API): cannot associate ' &
// str1 // ' with ' // type2 // str1 // ' with ' // type2
STOP ERROR_CODE STOP ERROR_CODE

View File

@ -6,10 +6,11 @@ MODULE keepcompute
'region box block 0 $x 0 3 0 4', & 'region box block 0 $x 0 3 0 4', &
'create_box 1 box', & 'create_box 1 box', &
'create_atoms 1 single 1.0 1.0 ${zpos}' ] 'create_atoms 1 single 1.0 1.0 ${zpos}' ]
CHARACTER(LEN=40), DIMENSION(2), PARAMETER :: cont_input = & CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: cont_input = &
[ CHARACTER(len=40) :: & [ CHARACTER(len=40) :: &
'create_atoms 1 single &', & 'create_atoms 1 single &', &
' 0.2 0.1 0.1' ] ' 0.2 0.1 0.1', &
'create_atoms 1 single 0.5 0.5 0.5' ]
CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: pair_input = & CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: pair_input = &
[ CHARACTER(LEN=40) :: & [ CHARACTER(LEN=40) :: &
'pair_style lj/cut 2.5', & 'pair_style lj/cut 2.5', &
@ -51,11 +52,13 @@ SUBROUTINE f_lammps_setup_extract_compute () BIND(C)
CALL lmp%commands_list(pair_input) CALL lmp%commands_list(pair_input)
CALL lmp%command("compute peratompe all pe/atom") ! per-atom vector CALL lmp%command("compute peratompe all pe/atom") ! per-atom vector
call lmp%command("compute stress all stress/atom thermo_temp") ! per-atom array call lmp%command("compute stress all stress/atom thermo_temp") ! per-atom array
CALL lmp%command("compute COM all com") ! global vector
CALL lmp%command("compute totalpe all reduce sum c_peratompe") ! global scalar CALL lmp%command("compute totalpe all reduce sum c_peratompe") ! global scalar
CALL lmp%command("compute 1 all rdf 100") ! global array CALL lmp%command("compute COM all com") ! global vector
CALL lmp%command("compute RDF all rdf 100") ! global array
CALL lmp%command("compute pairdist all pair/local dist") ! local vector CALL lmp%command("compute pairdist all pair/local dist") ! local vector
CALL lmp%command("compute pairlocal all pair/local dist dx dy dz") ! local array CALL lmp%command("compute pairlocal all pair/local dist dx dy dz") ! local array
CALL lmp%command("thermo_style custom step pe c_totalpe c_COM[1]")
CALL lmp%command("run 0") ! must be here, otherwise will SEGFAULT
END SUBROUTINE f_lammps_setup_extract_compute END SUBROUTINE f_lammps_setup_extract_compute
FUNCTION f_lammps_extract_compute_peratom_vector (i) BIND(C) FUNCTION f_lammps_extract_compute_peratom_vector (i) BIND(C)
@ -70,3 +73,80 @@ FUNCTION f_lammps_extract_compute_peratom_vector (i) BIND(C)
vector = lmp%extract_compute('peratompe', lmp%style%atom, lmp%type%vector) vector = lmp%extract_compute('peratompe', lmp%style%atom, lmp%type%vector)
f_lammps_extract_compute_peratom_vector = vector(i) f_lammps_extract_compute_peratom_vector = vector(i)
END FUNCTION f_lammps_extract_compute_peratom_vector END FUNCTION f_lammps_extract_compute_peratom_vector
FUNCTION f_lammps_extract_compute_peratom_array (i,j) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int
USE LIBLAMMPS
USE keepcompute, ONLY : lmp
IMPLICIT NONE
INTEGER(C_int), INTENT(IN), VALUE :: i, j
REAL(C_double) :: f_lammps_extract_compute_peratom_array
REAL(C_double), DIMENSION(:,:), POINTER :: array => NULL()
array = lmp%extract_compute('stress', lmp%style%atom, lmp%type%array)
f_lammps_extract_compute_peratom_array = array(i,j)
END FUNCTION f_lammps_extract_compute_peratom_array
FUNCTION f_lammps_extract_compute_global_scalar () BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int
USE LIBLAMMPS
USE keepcompute, ONLY : lmp
IMPLICIT NONE
REAL(C_double) :: f_lammps_extract_compute_global_scalar
REAL(C_double), POINTER :: scalar
scalar = lmp%extract_compute('totalpe', lmp%style%global, lmp%type%scalar)
f_lammps_extract_compute_global_scalar = scalar
END FUNCTION f_lammps_extract_compute_global_scalar
FUNCTION f_lammps_extract_compute_global_vector (i) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int
USE LIBLAMMPS
USE keepcompute, ONLY : lmp
IMPLICIT NONE
INTEGER(c_int), INTENT(IN), VALUE :: i
REAL(C_double) :: f_lammps_extract_compute_global_vector
REAL(C_double), DIMENSION(:), POINTER :: vector
vector = lmp%extract_compute('COM', lmp%style%global, lmp%type%vector)
f_lammps_extract_compute_global_vector = vector(i)
END FUNCTION f_lammps_extract_compute_global_vector
FUNCTION f_lammps_extract_compute_global_array (i,j) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int
USE LIBLAMMPS
USE keepcompute, ONLY : lmp
IMPLICIT NONE
INTEGER(c_int), INTENT(IN), VALUE :: i, j
REAL(C_double) :: f_lammps_extract_compute_global_array
REAL(C_double), DIMENSION(:,:), POINTER :: array
array = lmp%extract_compute('RDF', lmp%style%global, lmp%type%array)
f_lammps_extract_compute_global_array = array(i,j)
END FUNCTION f_lammps_extract_compute_global_array
FUNCTION f_lammps_extract_compute_local_vector (i) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int
USE LIBLAMMPS
USE keepcompute, ONLY : lmp
IMPLICIT NONE
INTEGER(c_int), INTENT(IN), VALUE :: i
REAL(C_double) :: f_lammps_extract_compute_local_vector
REAL(C_double), DIMENSION(:), POINTER :: vector
vector = lmp%extract_compute('pairdist', lmp%style%local, lmp%type%vector)
f_lammps_extract_compute_local_vector = vector(i)
END FUNCTION f_lammps_extract_compute_local_vector
FUNCTION f_lammps_extract_compute_local_array (i, j) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int
USE LIBLAMMPS
USE keepcompute, ONLY : lmp
IMPLICIT NONE
INTEGER(c_int), INTENT(IN), VALUE :: i, j
REAL(C_double) :: f_lammps_extract_compute_local_array
REAL(C_double), DIMENSION(:,:), POINTER :: array
array = lmp%extract_compute('pairlocal', lmp%style%local, lmp%type%array)
f_lammps_extract_compute_local_array = array(i,j)
END FUNCTION f_lammps_extract_compute_local_array