Merge pull request #3781 from akohlmey/collected-small-fixes
Collected small changes and fixes
This commit is contained in:
@ -52,7 +52,7 @@ can be translated to different output format using the `Sphinx
|
||||
incorporates programmer documentation extracted from the LAMMPS C++
|
||||
sources through the `Doxygen <https://doxygen.nl/>`_ program. Currently
|
||||
the translation to HTML, PDF (via LaTeX), ePUB (for many e-book readers)
|
||||
and MOBI (for Amazon Kindle(tm) readers) are supported. For that to work a
|
||||
and MOBI (for Amazon Kindle readers) are supported. For that to work a
|
||||
Python interpreter version 3.8 or later, the ``doxygen`` tools and
|
||||
internet access to download additional files and tools are required.
|
||||
This download is usually only required once or after the documentation
|
||||
|
||||
@ -203,40 +203,62 @@ Below is an example demonstrating some of the possible uses.
|
||||
|
||||
.. code-block:: fortran
|
||||
|
||||
PROGRAM testprop
|
||||
USE LIBLAMMPS
|
||||
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t
|
||||
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT
|
||||
TYPE(lammps) :: lmp
|
||||
INTEGER(KIND=c_int64_t), POINTER :: natoms
|
||||
REAL(KIND=c_double), POINTER :: dt
|
||||
INTEGER(KIND=c_int64_t), POINTER :: ntimestep
|
||||
REAL(KIND=c_double) :: pe, ke
|
||||
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'
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
PRINT*, 'PE = ', pe
|
||||
PRINT*, 'KE = ', ke
|
||||
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
|
||||
|
||||
CALL lmp%close(.TRUE.)
|
||||
END PROGRAM testprop
|
||||
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
|
||||
|
||||
---------------
|
||||
|
||||
@ -262,6 +284,8 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS.
|
||||
: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: :f:subr:`close`
|
||||
:ftype close: subroutine
|
||||
:f subroutine error: :f:subr:`error`
|
||||
@ -278,6 +302,8 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS.
|
||||
:ftype get_natoms: function
|
||||
:f get_thermo: :f:func:`get_thermo`
|
||||
:ftype get_thermo: function
|
||||
:f last_thermo: :f:func:`last_thermo`
|
||||
:ftype last_thermo: function
|
||||
:f extract_box: :f:subr:`extract_box`
|
||||
:ftype extract_box: subroutine
|
||||
:f reset_box: :f:subr:`reset_box`
|
||||
@ -587,6 +613,96 @@ Procedures Bound to the :f:type:`lammps` Derived Type
|
||||
|
||||
--------
|
||||
|
||||
.. f:function:: last_thermo(what, index)
|
||||
|
||||
This function will call :cpp:func:`lammps_last_thermo` 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:: TBD
|
||||
|
||||
Note that this function actually does not return a value, but rather
|
||||
associates the pointer on the left side of the assignment to point to
|
||||
internal LAMMPS data (with the exception of string data, which are
|
||||
copied and returned as ordinary Fortran strings). Pointers must be
|
||||
of the correct data type to point to said data (typically
|
||||
``INTEGER(c_int)``, ``INTEGER(c_int64_t)``, or ``REAL(c_double)``).
|
||||
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,
|
||||
|
||||
.. code-block:: 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::
|
||||
|
||||
If :f:func:`last_thermo` 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: :cpp:func:`lammps_last_thermo`
|
||||
: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::
|
||||
|
||||
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.
|
||||
|
||||
--------
|
||||
|
||||
.. f:subroutine:: extract_box([boxlo][, boxhi][, xy][, yz][, xz][, pflags][, boxflag])
|
||||
|
||||
This subroutine will call :cpp:func:`lammps_extract_box`. All
|
||||
@ -764,13 +880,14 @@ Procedures Bound to the :f:type:`lammps` Derived Type
|
||||
|
||||
.. note::
|
||||
|
||||
If :f:func:`extract_global` returns a string, the string must have length
|
||||
greater than or equal to the length of the string (not including the
|
||||
terminal ``NULL`` character) that LAMMPS returns. If the variable's
|
||||
length is too short, the string will be truncated. As usual in Fortran,
|
||||
strings are padded with spaces at the end. 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
|
||||
If :f:func:`extract_global` 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.,
|
||||
|
||||
.. code-block :: fortran
|
||||
|
||||
@ -69,15 +69,13 @@ SPC/E with rigid bonds.
|
||||
timestep 1.0
|
||||
fix rigid all shake 0.0001 10 10000 b 1 a 1
|
||||
minimize 0.0 0.0 1000 10000
|
||||
run 0 post no
|
||||
reset_timestep 0
|
||||
velocity all create 300.0 5463576
|
||||
fix integrate all nvt temp 300.0 300.0 1.0
|
||||
fix integrate all nvt temp 300.0 300.0 100.0
|
||||
|
||||
thermo_style custom step temp press etotal density pe ke
|
||||
thermo 1000
|
||||
run 20000 upto
|
||||
write_data tip4p.data nocoeff
|
||||
write_data spce.data nocoeff
|
||||
|
||||
.. _spce_molecule:
|
||||
.. code-block::
|
||||
|
||||
@ -128,11 +128,11 @@ TIP3P with rigid bonds.
|
||||
|
||||
fix rigid all shake 0.001 10 10000 b 1 a 1
|
||||
minimize 0.0 0.0 1000 10000
|
||||
run 0 post no
|
||||
|
||||
reset_timestep 0
|
||||
timestep 1.0
|
||||
velocity all create 300.0 5463576
|
||||
fix integrate all nvt temp 300 300 1.0
|
||||
fix integrate all nvt temp 300 300 100.0
|
||||
|
||||
thermo_style custom step temp press etotal pe
|
||||
|
||||
|
||||
@ -180,17 +180,17 @@ file changed):
|
||||
|
||||
fix rigid all shake 0.001 10 10000 b 1 a 1
|
||||
minimize 0.0 0.0 1000 10000
|
||||
run 0 post no
|
||||
|
||||
reset_timestep 0
|
||||
timestep 1.0
|
||||
velocity all create 300.0 5463576
|
||||
fix integrate all nvt temp 300 300 1.0
|
||||
fix integrate all nvt temp 300 300 100.0
|
||||
|
||||
thermo_style custom step temp press etotal pe
|
||||
|
||||
thermo 1000
|
||||
run 20000
|
||||
write_data tip3p.data nocoeff
|
||||
write_data tip4p-implicit.data nocoeff
|
||||
|
||||
Below is the code for a LAMMPS input file using the explicit method and
|
||||
a TIP4P molecule file. Because of using :doc:`fix rigid/nvt/small
|
||||
@ -203,6 +203,7 @@ rigid/nvt/small can identify rigid bodies by their molecule ID:
|
||||
|
||||
units real
|
||||
atom_style charge
|
||||
atom_modify map array
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 3 box
|
||||
|
||||
@ -219,14 +220,14 @@ rigid/nvt/small can identify rigid bodies by their molecule ID:
|
||||
molecule water tip4p.mol
|
||||
create_atoms 0 random 33 34564 NULL mol water 25367 overlap 1.33
|
||||
|
||||
timestep 0.1
|
||||
fix integrate all rigid/nvt/small molecule temp 300.0 300.0 1.0
|
||||
timestep 0.5
|
||||
fix integrate all rigid/nvt/small molecule temp 300.0 300.0 100.0
|
||||
velocity all create 300.0 5463576
|
||||
|
||||
thermo_style custom step temp press etotal density pe ke
|
||||
thermo 1000
|
||||
run 20000
|
||||
write_data tip4p.data nocoeff
|
||||
write_data tip4p-explicit.data nocoeff
|
||||
|
||||
.. _tip4p_molecule:
|
||||
.. code-block::
|
||||
|
||||
@ -91,6 +91,7 @@ ID:
|
||||
|
||||
units real
|
||||
atom_style charge
|
||||
atom_modify map array
|
||||
region box block -5 5 -5 5 -5 5
|
||||
create_box 3 box
|
||||
|
||||
@ -107,8 +108,8 @@ ID:
|
||||
molecule water tip5p.mol
|
||||
create_atoms 0 random 33 34564 NULL mol water 25367 overlap 1.33
|
||||
|
||||
timestep 0.20
|
||||
fix integrate all rigid/nvt/small molecule temp 300.0 300.0 1.0
|
||||
timestep 0.5
|
||||
fix integrate all rigid/nvt/small molecule temp 300.0 300.0 100.0
|
||||
reset_timestep 0
|
||||
velocity all create 300.0 5463576
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ This section documents the following functions:
|
||||
|
||||
- :cpp:func:`lammps_get_natoms`
|
||||
- :cpp:func:`lammps_get_thermo`
|
||||
- :cpp:func:`lammps_last_thermo`
|
||||
- :cpp:func:`lammps_extract_box`
|
||||
- :cpp:func:`lammps_reset_box`
|
||||
- :cpp:func:`lammps_memory_usage`
|
||||
@ -81,6 +82,11 @@ subdomains and processors.
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_last_thermo
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_extract_box
|
||||
:project: progguide
|
||||
|
||||
|
||||
@ -753,9 +753,13 @@ run, this option is ignored since the output is already balanced.
|
||||
----------
|
||||
|
||||
The *thermo* keyword only applies the dump styles *netcdf* and *yaml*.
|
||||
It triggers writing of :doc:`thermo <thermo>` information to the dump file
|
||||
alongside per-atom data. The values included in the dump file are
|
||||
identical to the values specified by :doc:`thermo_style <thermo_style>`.
|
||||
It triggers writing of :doc:`thermo <thermo>` information to the dump
|
||||
file alongside per-atom data. The values included in the dump file are
|
||||
cached values from the last thermo output and include the exact same the
|
||||
values as specified by the :doc:`thermo_style <thermo_style>` command.
|
||||
Because these are cached values, they are only up-to-date when dump
|
||||
output is on a timestep that also has thermo output. Dump style *yaml*
|
||||
will skip thermo output on incompatible steps.
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ Syntax
|
||||
.. parsed-literal::
|
||||
|
||||
*cutoff* value = I J Cutoff
|
||||
I, J = atom types
|
||||
I, J = atom types (see asterisk form below)
|
||||
Cutoff = Bond-order cutoff value for this pair of atom types
|
||||
*element* value = Element1, Element2, ...
|
||||
*position* value = posfreq filepos
|
||||
@ -49,7 +49,7 @@ Examples
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
fix 1 all reaxff/species 10 10 100 species.out
|
||||
fix 1 all reaxff/species 1 2 20 species.out cutoff 1 1 0.40 cutoff 1 2 0.55
|
||||
fix 1 all reaxff/species 1 2 20 species.out cutoff 1 1 0.40 cutoff 1 2*3 0.55
|
||||
fix 1 all reaxff/species 1 100 100 species.out element Au O H position 1000 AuOH.pos
|
||||
fix 1 all reaxff/species 1 100 100 species.out delete species.del masslimit 0 50
|
||||
|
||||
@ -88,13 +88,24 @@ If the filename ends with ".gz", the output file is written in gzipped
|
||||
format. A gzipped dump file will be about 3x smaller than the text version,
|
||||
but will also take longer to write.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
Support for wildcards added
|
||||
|
||||
Optional keyword *cutoff* can be assigned to change the minimum
|
||||
bond-order values used in identifying chemical bonds between pairs of
|
||||
atoms. Bond-order cutoffs should be carefully chosen, as bond-order
|
||||
cutoffs that are too small may include too many bonds (which will
|
||||
result in an error), while cutoffs that are too large will result in
|
||||
fragmented molecules. The default cutoff of 0.3 usually gives good
|
||||
results.
|
||||
cutoffs that are too small may include too many bonds (which will result
|
||||
in an error), while cutoffs that are too large will result in fragmented
|
||||
molecules. The default cutoff of 0.3 usually gives good results. A
|
||||
wildcard asterisk can be used in place of or in conjunction with the I,J
|
||||
arguments to set the bond-order cutoff for multiple pairs of atom types.
|
||||
This takes the form "\*" or "\*n" or "n\*" or "m\*n". If :math:`N` is
|
||||
the number of atom types, then an asterisk with no numeric values means
|
||||
all types from 1 to :math:`N`. A leading asterisk means all types from
|
||||
1 to n (inclusive). A trailing asterisk means all types from n to
|
||||
:math:`N` (inclusive). A middle asterisk means all types from m to n
|
||||
(inclusive).
|
||||
|
||||
The optional keyword *element* can be used to specify the chemical
|
||||
symbol printed for each LAMMPS atom type. The number of symbols must
|
||||
|
||||
@ -1481,7 +1481,7 @@ commands
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
# delete_atoms random fraction 0.5 yes all NULL 49839
|
||||
# run 0
|
||||
# run 0 post no
|
||||
variable t equal temp # this thermo keyword invokes a temperature compute
|
||||
print "Temperature of system = $t"
|
||||
run 1000
|
||||
|
||||
@ -3742,6 +3742,7 @@ Umin
|
||||
un
|
||||
unary
|
||||
uncomment
|
||||
uncommented
|
||||
uncompress
|
||||
uncompute
|
||||
underprediction
|
||||
|
||||
@ -90,6 +90,7 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib)
|
||||
|
||||
ADDSYM(get_natoms);
|
||||
ADDSYM(get_thermo);
|
||||
ADDSYM(last_thermo);
|
||||
|
||||
ADDSYM(extract_box);
|
||||
ADDSYM(reset_box);
|
||||
|
||||
@ -133,6 +133,7 @@ struct _liblammpsplugin {
|
||||
|
||||
double (*get_natoms)(void *);
|
||||
double (*get_thermo)(void *, const char *);
|
||||
void *(*last_thermo)(void *, const char *, int);
|
||||
|
||||
void (*extract_box)(void *, double *, double *,
|
||||
double *, double *, double *, int *, int *);
|
||||
|
||||
@ -87,10 +87,15 @@ MODULE LIBLAMMPS
|
||||
INTEGER(c_int) :: scalar, vector, array
|
||||
END TYPE lammps_type
|
||||
|
||||
TYPE lammps_dtype
|
||||
INTEGER(c_int) :: i32, i64, r64, str
|
||||
END TYPE lammps_dtype
|
||||
|
||||
TYPE lammps
|
||||
TYPE(c_ptr) :: handle = c_null_ptr
|
||||
TYPE(lammps_style) :: style
|
||||
TYPE(lammps_type) :: type
|
||||
TYPE(lammps_dtype) :: dtype
|
||||
CONTAINS
|
||||
PROCEDURE :: close => lmp_close
|
||||
PROCEDURE :: error => lmp_error
|
||||
@ -100,6 +105,7 @@ MODULE LIBLAMMPS
|
||||
PROCEDURE :: commands_string => lmp_commands_string
|
||||
PROCEDURE :: get_natoms => lmp_get_natoms
|
||||
PROCEDURE :: get_thermo => lmp_get_thermo
|
||||
PROCEDURE :: last_thermo => lmp_last_thermo
|
||||
PROCEDURE :: extract_box => lmp_extract_box
|
||||
PROCEDURE :: reset_box => lmp_reset_box
|
||||
PROCEDURE :: memory_usage => lmp_memory_usage
|
||||
@ -243,7 +249,7 @@ MODULE LIBLAMMPS
|
||||
END TYPE lammps_data_baseclass
|
||||
|
||||
! Derived type for receiving LAMMPS data (in lieu of the ability to type cast
|
||||
! pointers). Used for extract_compute, extract_atom
|
||||
! pointers). Used for extract_compute, extract_atom, last_thermo
|
||||
TYPE, EXTENDS(lammps_data_baseclass) :: lammps_data
|
||||
INTEGER(c_int), POINTER :: i32 => NULL()
|
||||
INTEGER(c_int), DIMENSION(:), POINTER :: i32_vec => NULL()
|
||||
@ -439,6 +445,15 @@ MODULE LIBLAMMPS
|
||||
TYPE(c_ptr), INTENT(IN), VALUE :: name
|
||||
END FUNCTION lammps_get_thermo
|
||||
|
||||
FUNCTION lammps_last_thermo(handle,what,index) BIND(C)
|
||||
IMPORT :: c_ptr, c_int
|
||||
IMPLICIT NONE
|
||||
TYPE(c_ptr) :: lammps_last_thermo
|
||||
TYPE(c_ptr), INTENT(IN), VALUE :: handle
|
||||
TYPE(c_ptr), INTENT(IN), VALUE :: what
|
||||
INTEGER(c_int), INTENT(IN), VALUE :: index
|
||||
END FUNCTION lammps_last_thermo
|
||||
|
||||
SUBROUTINE lammps_extract_box(handle,boxlo,boxhi,xy,yz,xz,pflags, &
|
||||
boxflag) BIND(C)
|
||||
IMPORT :: c_ptr, c_double, c_int
|
||||
@ -995,6 +1010,10 @@ CONTAINS
|
||||
lmp_open%type%scalar = LMP_TYPE_SCALAR
|
||||
lmp_open%type%vector = LMP_TYPE_VECTOR
|
||||
lmp_open%type%array = LMP_TYPE_ARRAY
|
||||
lmp_open%dtype%i32 = LAMMPS_INT
|
||||
lmp_open%dtype%i64 = LAMMPS_INT64
|
||||
lmp_open%dtype%r64 = LAMMPS_DOUBLE
|
||||
lmp_open%dtype%str = LAMMPS_STRING
|
||||
|
||||
! Assign constants for bigint and tagint for use elsewhere
|
||||
SIZE_TAGINT = lmp_extract_setting(lmp_open, 'tagint')
|
||||
@ -1103,6 +1122,65 @@ CONTAINS
|
||||
CALL lammps_free(Cname)
|
||||
END FUNCTION lmp_get_thermo
|
||||
|
||||
! equivalent function to lammps_last_thermo
|
||||
FUNCTION lmp_last_thermo(self,what,index) RESULT(thermo_data)
|
||||
CLASS(lammps), INTENT(IN), TARGET :: self
|
||||
CHARACTER(LEN=*), INTENT(IN) :: what
|
||||
INTEGER(c_int) :: index
|
||||
TYPE(lammps_data) :: thermo_data, type_data
|
||||
INTEGER(c_int) :: datatype
|
||||
TYPE(c_ptr) :: Cname, Cptr
|
||||
|
||||
! set data type for known cases
|
||||
SELECT CASE (what)
|
||||
CASE ('step')
|
||||
IF (SIZE_BIGINT == 4_c_int) THEN
|
||||
datatype = LAMMPS_INT
|
||||
ELSE
|
||||
datatype = LAMMPS_INT64
|
||||
END IF
|
||||
CASE ('num')
|
||||
datatype = LAMMPS_INT
|
||||
CASE ('type')
|
||||
datatype = LAMMPS_INT
|
||||
CASE ('keyword')
|
||||
datatype = LAMMPS_STRING
|
||||
CASE ('data')
|
||||
Cname = f2c_string('type')
|
||||
Cptr = lammps_last_thermo(self%handle,Cname,index-1)
|
||||
type_data%lammps_instance => self
|
||||
type_data%datatype = DATA_INT
|
||||
CALL C_F_POINTER(Cptr, type_data%i32)
|
||||
datatype = type_data%i32
|
||||
CALL lammps_free(Cname)
|
||||
CASE DEFAULT
|
||||
datatype = -1
|
||||
END SELECT
|
||||
|
||||
Cname = f2c_string(what)
|
||||
Cptr = lammps_last_thermo(self%handle,Cname,index-1)
|
||||
CALL lammps_free(Cname)
|
||||
|
||||
thermo_data%lammps_instance => self
|
||||
SELECT CASE (datatype)
|
||||
CASE (LAMMPS_INT)
|
||||
thermo_data%datatype = DATA_INT
|
||||
CALL C_F_POINTER(Cptr, thermo_data%i32)
|
||||
CASE (LAMMPS_INT64)
|
||||
thermo_data%datatype = DATA_INT64
|
||||
CALL C_F_POINTER(Cptr, thermo_data%i64)
|
||||
CASE (LAMMPS_DOUBLE)
|
||||
thermo_data%datatype = DATA_DOUBLE
|
||||
CALL C_F_POINTER(Cptr, thermo_data%r64)
|
||||
CASE (LAMMPS_STRING)
|
||||
thermo_data%datatype = DATA_STRING
|
||||
thermo_data%str = c2f_string(Cptr)
|
||||
CASE DEFAULT
|
||||
CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, &
|
||||
'Unknown pointer type in last_thermo')
|
||||
END SELECT
|
||||
END FUNCTION lmp_last_thermo
|
||||
|
||||
! equivalent subroutine to lammps_extract_box
|
||||
SUBROUTINE lmp_extract_box(self, boxlo, boxhi, xy, yz, xz, pflags, boxflag)
|
||||
CLASS(lammps), INTENT(IN) :: self
|
||||
|
||||
@ -272,6 +272,9 @@ class lammps(object):
|
||||
self.lib.lammps_get_thermo.argtypes = [c_void_p, c_char_p]
|
||||
self.lib.lammps_get_thermo.restype = c_double
|
||||
|
||||
self.lib.lammps_last_thermo.argtypes = [c_void_p, c_char_p, c_int]
|
||||
self.lib.lammps_last_thermo.restype = c_void_p
|
||||
|
||||
self.lib.lammps_encode_image_flags.restype = self.c_imageint
|
||||
|
||||
self.lib.lammps_config_has_package.argtypes = [c_char_p]
|
||||
@ -503,9 +506,9 @@ class lammps(object):
|
||||
def error(self, error_type, error_text):
|
||||
"""Forward error to the LAMMPS Error class.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_error` function of the C-library interface.
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
.. versionadded:: TBD
|
||||
This is a wrapper around the :cpp:func:`lammps_error` function of the C-library interface.
|
||||
|
||||
:param error_type:
|
||||
:type error_type: int
|
||||
@ -744,6 +747,56 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def last_thermo(self):
|
||||
"""Get a dictionary of the last thermodynamic output
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_last_thermo`
|
||||
function of the C-library interface. It collects the cached thermo
|
||||
data from the last timestep into a dictionary. The return value
|
||||
is None, if there has not been any thermo output yet.
|
||||
|
||||
:return: value of thermo keyword
|
||||
:rtype: dict or None
|
||||
"""
|
||||
|
||||
rv = dict()
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0)
|
||||
mystep = cast(ptr, POINTER(self.c_bigint)).contents.value
|
||||
if mystep < 0:
|
||||
return None
|
||||
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("num".encode()), 0)
|
||||
nfield = cast(ptr, POINTER(c_int)).contents.value
|
||||
|
||||
for i in range(nfield):
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("keyword".encode()), i)
|
||||
kw = cast(ptr, c_char_p).value.decode()
|
||||
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("type".encode()), i)
|
||||
typ = cast(ptr, POINTER(c_int)).contents.value
|
||||
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("data".encode()), i)
|
||||
|
||||
if typ == LAMMPS_DOUBLE:
|
||||
val = cast(ptr, POINTER(c_double)).contents.value
|
||||
elif typ == LAMMPS_INT:
|
||||
val = cast(ptr, POINTER(c_int)).contents.value
|
||||
elif typ == LAMMPS_INT64:
|
||||
val = cast(ptr, POINTER(c_int64)).contents.value
|
||||
else:
|
||||
# we should not get here
|
||||
raise TypeError("Unknown LAMMPS data type " + str(typ))
|
||||
rv[kw] = val
|
||||
|
||||
return rv
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_setting(self, name):
|
||||
"""Query LAMMPS about global settings that can be expressed as an integer.
|
||||
|
||||
@ -1289,6 +1342,8 @@ class lammps(object):
|
||||
def gather_bonds(self):
|
||||
"""Retrieve global list of bonds
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_gather_bonds`
|
||||
function of the C-library interface.
|
||||
|
||||
@ -1296,8 +1351,6 @@ class lammps(object):
|
||||
flat list of ctypes integer values with the bond type, bond atom1,
|
||||
bond atom2 for each bond.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:return: a tuple with the number of bonds and a list of c_int or c_long
|
||||
:rtype: (int, 3*nbonds*c_tagint)
|
||||
"""
|
||||
@ -1312,6 +1365,8 @@ class lammps(object):
|
||||
def gather_angles(self):
|
||||
"""Retrieve global list of angles
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_gather_angles`
|
||||
function of the C-library interface.
|
||||
|
||||
@ -1319,8 +1374,6 @@ class lammps(object):
|
||||
flat list of ctypes integer values with the angle type, angle atom1,
|
||||
angle atom2, angle atom3 for each angle.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:return: a tuple with the number of angles and a list of c_int or c_long
|
||||
:rtype: (int, 4*nangles*c_tagint)
|
||||
"""
|
||||
@ -1335,6 +1388,8 @@ class lammps(object):
|
||||
def gather_dihedrals(self):
|
||||
"""Retrieve global list of dihedrals
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_gather_dihedrals`
|
||||
function of the C-library interface.
|
||||
|
||||
@ -1342,8 +1397,6 @@ class lammps(object):
|
||||
flat list of ctypes integer values with the dihedral type, dihedral atom1,
|
||||
dihedral atom2, dihedral atom3, dihedral atom4 for each dihedral.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:return: a tuple with the number of dihedrals and a list of c_int or c_long
|
||||
:rtype: (int, 5*ndihedrals*c_tagint)
|
||||
"""
|
||||
@ -1358,6 +1411,8 @@ class lammps(object):
|
||||
def gather_impropers(self):
|
||||
"""Retrieve global list of impropers
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_gather_impropers`
|
||||
function of the C-library interface.
|
||||
|
||||
@ -1365,8 +1420,6 @@ class lammps(object):
|
||||
flat list of ctypes integer values with the improper type, improper atom1,
|
||||
improper atom2, improper atom3, improper atom4 for each improper.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:return: a tuple with the number of impropers and a list of c_int or c_long
|
||||
:rtype: (int, 5*nimpropers*c_tagint)
|
||||
"""
|
||||
@ -1605,13 +1658,13 @@ class lammps(object):
|
||||
def is_running(self):
|
||||
""" Report whether being called from a function during a run or a minimization
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
Various LAMMPS commands must not be called during an ongoing
|
||||
run or minimization. This property allows to check for that.
|
||||
This is a wrapper around the :cpp:func:`lammps_is_running`
|
||||
function of the library interface.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
:return: True when called during a run otherwise false
|
||||
:rtype: bool
|
||||
"""
|
||||
@ -1622,12 +1675,13 @@ class lammps(object):
|
||||
def force_timeout(self):
|
||||
""" Trigger an immediate timeout, i.e. a "soft stop" of a run.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
This function allows to cleanly stop an ongoing run or minimization
|
||||
at the next loop iteration.
|
||||
This is a wrapper around the :cpp:func:`lammps_force_timeout`
|
||||
function of the library interface.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
"""
|
||||
self.lib.lammps_force_timeout(self.lmp)
|
||||
|
||||
@ -1710,11 +1764,11 @@ class lammps(object):
|
||||
def has_package(self, name):
|
||||
""" Report if the named package has been enabled in the LAMMPS shared library.
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_config_has_package`
|
||||
function of the library interface.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:param name: name of the package
|
||||
:type name: string
|
||||
|
||||
@ -1854,11 +1908,11 @@ class lammps(object):
|
||||
def has_id(self, category, name):
|
||||
"""Returns whether a given ID name is available in a given category
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
This is a wrapper around the function :cpp:func:`lammps_has_id`
|
||||
of the library interface.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
:param category: name of category
|
||||
:type category: string
|
||||
:param name: name of the ID
|
||||
@ -1874,11 +1928,11 @@ class lammps(object):
|
||||
def available_ids(self, category):
|
||||
"""Returns a list of IDs available for a given category
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
This is a wrapper around the functions :cpp:func:`lammps_id_count()`
|
||||
and :cpp:func:`lammps_id_name()` of the library interface.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
:param category: name of category
|
||||
:type category: string
|
||||
|
||||
@ -1901,11 +1955,11 @@ class lammps(object):
|
||||
def available_plugins(self, category):
|
||||
"""Returns a list of plugins available for a given category
|
||||
|
||||
.. versionadded:: 10Mar2021
|
||||
|
||||
This is a wrapper around the functions :cpp:func:`lammps_plugin_count()`
|
||||
and :cpp:func:`lammps_plugin_name()` of the library interface.
|
||||
|
||||
.. versionadded:: 10Mar2021
|
||||
|
||||
:return: list of style/name pairs of loaded plugins
|
||||
:rtype: list
|
||||
"""
|
||||
@ -1970,11 +2024,11 @@ class lammps(object):
|
||||
def fix_external_get_force(self, fix_id):
|
||||
"""Get access to the array with per-atom forces of a fix external instance with a given fix ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_get_force` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:return: requested data
|
||||
@ -1989,11 +2043,11 @@ class lammps(object):
|
||||
def fix_external_set_energy_global(self, fix_id, eng):
|
||||
"""Set the global energy contribution for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_energy_global` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param eng: potential energy value to be added by fix external
|
||||
@ -2008,11 +2062,11 @@ class lammps(object):
|
||||
def fix_external_set_virial_global(self, fix_id, virial):
|
||||
"""Set the global virial contribution for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_virial_global` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param eng: list of 6 floating point numbers with the virial to be added by fix external
|
||||
@ -2028,11 +2082,11 @@ class lammps(object):
|
||||
def fix_external_set_energy_peratom(self, fix_id, eatom):
|
||||
"""Set the per-atom energy contribution for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_energy_peratom` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param eatom: list of potential energy values for local atoms to be added by fix external
|
||||
@ -2051,11 +2105,11 @@ class lammps(object):
|
||||
def fix_external_set_virial_peratom(self, fix_id, vatom):
|
||||
"""Set the per-atom virial contribution for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_virial_peratom` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param vatom: list of natoms lists with 6 floating point numbers to be added by fix external
|
||||
@ -2083,11 +2137,11 @@ class lammps(object):
|
||||
def fix_external_set_vector_length(self, fix_id, length):
|
||||
"""Set the vector length for a global vector stored with fix external for analysis
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_vector_length` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param length: length of the global vector
|
||||
@ -2101,11 +2155,11 @@ class lammps(object):
|
||||
def fix_external_set_vector(self, fix_id, idx, val):
|
||||
"""Store a global vector value for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_vector` function
|
||||
of the C-library interface.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param idx: 1-based index of the value in the global vector
|
||||
|
||||
@ -262,12 +262,12 @@ class numpy_wrapper:
|
||||
def gather_bonds(self):
|
||||
"""Retrieve global list of bonds as NumPy array
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_bonds() <lammps.lammps.gather_bonds()>`
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:return: the requested data as a 2d-integer numpy array
|
||||
:rtype: numpy.array(nbonds,3)
|
||||
"""
|
||||
@ -280,12 +280,12 @@ class numpy_wrapper:
|
||||
def gather_angles(self):
|
||||
""" Retrieve global list of angles as NumPy array
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_angles() <lammps.lammps.gather_angles()>`
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:return: the requested data as a 2d-integer numpy array
|
||||
:rtype: numpy.array(nangles,4)
|
||||
"""
|
||||
@ -298,12 +298,12 @@ class numpy_wrapper:
|
||||
def gather_dihedrals(self):
|
||||
""" Retrieve global list of dihedrals as NumPy array
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_dihedrals() <lammps.lammps.gather_dihedrals()>`
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:return: the requested data as a 2d-integer numpy array
|
||||
:rtype: numpy.array(ndihedrals,5)
|
||||
"""
|
||||
@ -316,12 +316,12 @@ class numpy_wrapper:
|
||||
def gather_impropers(self):
|
||||
""" Retrieve global list of impropers as NumPy array
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This is a wrapper around :py:meth:`lammps.gather_impropers() <lammps.lammps.gather_impropers()>`
|
||||
It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` list.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
:return: the requested data as a 2d-integer numpy array
|
||||
:rtype: numpy.array(nimpropers,5)
|
||||
"""
|
||||
@ -334,13 +334,13 @@ class numpy_wrapper:
|
||||
def fix_external_get_force(self, fix_id):
|
||||
"""Get access to the array with per-atom forces of a fix external instance with a given fix ID.
|
||||
|
||||
.. versionchanged:: 28Jul2021
|
||||
|
||||
This function is a wrapper around the
|
||||
:py:meth:`lammps.fix_external_get_force() <lammps.lammps.fix_external_get_force()>`
|
||||
method. It behaves the same as the original method, but returns a NumPy array instead
|
||||
of a ``ctypes`` pointer.
|
||||
|
||||
.. versionchanged:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:return: requested data
|
||||
@ -356,13 +356,13 @@ class numpy_wrapper:
|
||||
def fix_external_set_energy_peratom(self, fix_id, eatom):
|
||||
"""Set the per-atom energy contribution for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This function is an alternative to
|
||||
:py:meth:`lammps.fix_external_set_energy_peratom() <lammps.lammps.fix_external_set_energy_peratom()>`
|
||||
method. It behaves the same as the original method, but accepts a NumPy array
|
||||
instead of a list as argument.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param eatom: per-atom potential energy
|
||||
@ -383,13 +383,13 @@ class numpy_wrapper:
|
||||
def fix_external_set_virial_peratom(self, fix_id, vatom):
|
||||
"""Set the per-atom virial contribution for a fix external instance with the given ID.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This function is an alternative to
|
||||
:py:meth:`lammps.fix_external_set_virial_peratom() <lammps.lammps.fix_external_set_virial_peratom()>`
|
||||
method. It behaves the same as the original method, but accepts a NumPy array
|
||||
instead of a list as argument.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param eatom: per-atom potential energy
|
||||
|
||||
@ -90,8 +90,7 @@ ComputeXRD::ComputeXRD(LAMMPS *lmp, int narg, char **arg) :
|
||||
ztype[i] = j;
|
||||
}
|
||||
}
|
||||
if (ztype[i] == XRDmaxType + 1)
|
||||
error->all(FLERR,"Compute XRD: Invalid ASF atom type");
|
||||
if (ztype[i] == XRDmaxType + 1) error->all(FLERR,"Compute XRD: Invalid ASF atom type {}", arg[iarg]);
|
||||
iarg++;
|
||||
}
|
||||
|
||||
|
||||
@ -60,21 +60,29 @@ void DumpYAML::write_header(bigint ndump)
|
||||
std::string thermo_data;
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
thermo_data += "thermo:\n - keywords: [ ";
|
||||
for (int i = 0; i < th->nfield; ++i) thermo_data += fmt::format("{}, ", th->keyword[i]);
|
||||
thermo_data += "]\n - data: [ ";
|
||||
// output thermo data only on timesteps where it was computed
|
||||
if (update->ntimestep == *th->get_timestep()) {
|
||||
int nfield = *th->get_nfield();
|
||||
const auto &keywords = th->get_keywords();
|
||||
const auto &fields = th->get_fields();
|
||||
|
||||
for (int i = 0; i < th->nfield; ++i) {
|
||||
th->call_vfunc(i);
|
||||
if (th->vtype[i] == Thermo::FLOAT)
|
||||
thermo_data += fmt::format("{}, ", th->dvalue);
|
||||
else if (th->vtype[i] == Thermo::INT)
|
||||
thermo_data += fmt::format("{}, ", th->ivalue);
|
||||
else if (th->vtype[i] == Thermo::BIGINT)
|
||||
thermo_data += fmt::format("{}, ", th->bivalue);
|
||||
thermo_data += "thermo:\n - keywords: [ ";
|
||||
for (int i = 0; i < nfield; ++i) thermo_data += fmt::format("{}, ", keywords[i]);
|
||||
thermo_data += "]\n - data: [ ";
|
||||
|
||||
for (int i = 0; i < nfield; ++i) {
|
||||
if (fields[i].type == multitype::DOUBLE)
|
||||
thermo_data += fmt::format("{}, ", fields[i].data.d);
|
||||
else if (fields[i].type == multitype::INT)
|
||||
thermo_data += fmt::format("{}, ", fields[i].data.i);
|
||||
else if (fields[i].type == multitype::BIGINT)
|
||||
thermo_data += fmt::format("{}, ", fields[i].data.b);
|
||||
else
|
||||
thermo_data += ", ";
|
||||
}
|
||||
thermo_data += "]\n";
|
||||
MPI_Barrier(world);
|
||||
}
|
||||
thermo_data += "]\n";
|
||||
MPI_Barrier(world);
|
||||
}
|
||||
|
||||
if (comm->me == 0) {
|
||||
@ -85,7 +93,7 @@ void DumpYAML::write_header(bigint ndump)
|
||||
|
||||
fmt::print(fp, "natoms: {}\n", ndump);
|
||||
fputs("boundary: [ ", fp);
|
||||
for (const auto bflag : boundary) {
|
||||
for (const auto &bflag : boundary) {
|
||||
if (bflag == ' ') continue;
|
||||
fmt::print(fp, "{}, ", bflag);
|
||||
}
|
||||
|
||||
@ -175,7 +175,8 @@ void FixElectronStopping::post_force(int /*vflag*/)
|
||||
if (energy < Ecut) continue;
|
||||
if (energy < elstop_ranges[0][0]) continue;
|
||||
if (energy > elstop_ranges[0][table_entries - 1])
|
||||
error->one(FLERR, "Atom kinetic energy too high for fix electron/stopping");
|
||||
error->one(FLERR, "Fix electron/stopping: kinetic energy too high for atom {}: {} vs {}",
|
||||
atom->tag[i], energy, elstop_ranges[0][table_entries - 1]);
|
||||
|
||||
if (region) {
|
||||
// Only apply in the given region
|
||||
|
||||
@ -94,7 +94,7 @@ namespace Granular_NS {
|
||||
void coeffs_to_local() override;
|
||||
void mix_coeffs(double *, double *) override;
|
||||
private:
|
||||
int mixed_coefficients;
|
||||
int mixed_coefficients;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -110,7 +110,7 @@ namespace Granular_NS {
|
||||
protected:
|
||||
double k, cohesion;
|
||||
double F_pulloff, Fne;
|
||||
int mixed_coefficients;
|
||||
int mixed_coefficients;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -129,7 +129,7 @@ namespace Granular_NS {
|
||||
protected:
|
||||
double k, cohesion;
|
||||
double Emix, F_pulloff, Fne;
|
||||
int mixed_coefficients;
|
||||
int mixed_coefficients;
|
||||
};
|
||||
|
||||
} // namespace Granular_NS
|
||||
|
||||
@ -980,9 +980,9 @@ void CommKokkos::borders()
|
||||
} else {
|
||||
atomKK->sync(Host,ALL_MASK);
|
||||
k_sendlist.sync<LMPHostType>();
|
||||
CommBrick::borders();
|
||||
k_sendlist.modify<LMPHostType>();
|
||||
atomKK->modified(Host,ALL_MASK);
|
||||
atomKK->modified(Host,ALL_MASK); // needed here for atom map
|
||||
CommBrick::borders();
|
||||
}
|
||||
|
||||
if (comm->nprocs == 1 && !ghost_velocity && !forward_comm_classic)
|
||||
|
||||
@ -195,6 +195,7 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) :
|
||||
type_nc_real = NC_FLOAT;
|
||||
|
||||
thermo = false;
|
||||
thermo_warn = true;
|
||||
thermovar = nullptr;
|
||||
|
||||
framei = 0;
|
||||
@ -223,7 +224,7 @@ void DumpNetCDF::openfile()
|
||||
|
||||
if (thermo && !singlefile_opened) {
|
||||
delete[] thermovar;
|
||||
thermovar = new int[output->thermo->nfield];
|
||||
thermovar = new int[*output->thermo->get_nfield()];
|
||||
}
|
||||
|
||||
// now the computes and fixes have been initialized, so we can query
|
||||
@ -321,8 +322,11 @@ void DumpNetCDF::openfile()
|
||||
// perframe variables
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
for (int i = 0; i < th->nfield; i++) {
|
||||
NCERRX( nc_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() );
|
||||
const auto &keywords = th->get_keywords();
|
||||
const int nfield = *th->get_nfield();
|
||||
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,21 +437,17 @@ void DumpNetCDF::openfile()
|
||||
// perframe variables
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
for (int i = 0; i < th->nfield; i++) {
|
||||
if (th->vtype[i] == Thermo::FLOAT) {
|
||||
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), type_nc_real, 1, dims,
|
||||
&thermovar[i]), th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::INT) {
|
||||
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims,
|
||||
&thermovar[i]), th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::BIGINT) {
|
||||
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
|
||||
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims,
|
||||
&thermovar[i]), th->keyword[i].c_str() );
|
||||
#else
|
||||
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims,
|
||||
&thermovar[i]), th->keyword[i].c_str() );
|
||||
#endif
|
||||
const auto &fields = th->get_fields();
|
||||
const auto &keywords = th->get_keywords();
|
||||
const int nfield = *th->get_nfield();
|
||||
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
if (fields[i].type == multitype::DOUBLE) {
|
||||
NCERRX( nc_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::INT) {
|
||||
NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::BIGINT) {
|
||||
NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -606,19 +606,30 @@ void DumpNetCDF::write()
|
||||
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
for (int i = 0; i < th->nfield; i++) {
|
||||
th->call_vfunc(i);
|
||||
|
||||
// will output current thermo data only on timesteps where it was computed.
|
||||
// warn (once) about using cached copy from old timestep.
|
||||
|
||||
if (thermo_warn && (update->ntimestep != *th->get_timestep())) {
|
||||
thermo_warn = false;
|
||||
if (comm->me == 0) {
|
||||
error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n"
|
||||
" Dump netcdf always stores thermo data from last thermo output",
|
||||
id, *th->get_timestep(), update->ntimestep);
|
||||
}
|
||||
}
|
||||
|
||||
const auto &keywords = th->get_keywords();
|
||||
const auto &fields = th->get_fields();
|
||||
int nfield = *th->get_nfield();
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
if (filewriter) {
|
||||
if (th->vtype[i] == Thermo::FLOAT) {
|
||||
NCERRX( nc_put_var1_double(ncid, thermovar[i], start,
|
||||
&th->dvalue),
|
||||
th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::INT) {
|
||||
NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
|
||||
th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::BIGINT) {
|
||||
NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue),
|
||||
th->keyword[i].c_str() );
|
||||
if (fields[i].type == multitype::DOUBLE) {
|
||||
NCERRX( nc_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::INT) {
|
||||
NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::BIGINT) {
|
||||
NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ class DumpNetCDF : public DumpCustom {
|
||||
|
||||
int type_nc_real; // netcdf type to use for real variables: float or double
|
||||
bool thermo; // write thermo output to netcdf file
|
||||
bool thermo_warn; // warn (once) that thermo output is on incompatible step
|
||||
|
||||
bigint n_buffer; // size of buffer
|
||||
bigint *int_buffer; // buffer for passing data to netcdf
|
||||
|
||||
@ -192,6 +192,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) :
|
||||
type_nc_real = NC_FLOAT;
|
||||
|
||||
thermo = false;
|
||||
thermo_warn = true;
|
||||
thermovar = nullptr;
|
||||
|
||||
framei = 0;
|
||||
@ -220,7 +221,7 @@ void DumpNetCDFMPIIO::openfile()
|
||||
|
||||
if (thermo && !singlefile_opened) {
|
||||
delete[] thermovar;
|
||||
thermovar = new int[output->thermo->nfield];
|
||||
thermovar = new int[*output->thermo->get_nfield()];
|
||||
}
|
||||
|
||||
// now the computes and fixes have been initialized, so we can query
|
||||
@ -319,8 +320,11 @@ void DumpNetCDFMPIIO::openfile()
|
||||
// perframe variables
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
for (int i = 0; i < th->nfield; i++) {
|
||||
NCERRX( ncmpi_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() );
|
||||
const auto &keywords = th->get_keywords();
|
||||
const int nfield = *th->get_nfield();
|
||||
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,17 +427,17 @@ void DumpNetCDFMPIIO::openfile()
|
||||
// perframe variables
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
for (int i = 0; i < th->nfield; i++) {
|
||||
if (th->vtype[i] == Thermo::FLOAT) {
|
||||
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::INT) {
|
||||
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::BIGINT) {
|
||||
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
|
||||
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
|
||||
#else
|
||||
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
|
||||
#endif
|
||||
const auto &fields = th->get_fields();
|
||||
const auto &keywords = th->get_keywords();
|
||||
const int nfield = *th->get_nfield();
|
||||
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
if (fields[i].type == multitype::DOUBLE) {
|
||||
NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::INT) {
|
||||
NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::BIGINT) {
|
||||
NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -595,25 +599,36 @@ void DumpNetCDFMPIIO::write()
|
||||
|
||||
if (thermo) {
|
||||
Thermo *th = output->thermo;
|
||||
for (int i = 0; i < th->nfield; i++) {
|
||||
th->call_vfunc(i);
|
||||
|
||||
// will output current thermo data only on timesteps where it was computed.
|
||||
// warn (once) about using cached copy from old timestep.
|
||||
|
||||
if (thermo_warn && (update->ntimestep != *th->get_timestep())) {
|
||||
thermo_warn = false;
|
||||
if (comm->me == 0) {
|
||||
error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n"
|
||||
" Dump netcdf/mpiio always stores thermo data from last thermo output",
|
||||
id, *th->get_timestep(), update->ntimestep);
|
||||
}
|
||||
}
|
||||
|
||||
const auto &keywords = th->get_keywords();
|
||||
const auto &fields = th->get_fields();
|
||||
int nfield = *th->get_nfield();
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
if (filewriter) {
|
||||
if (th->vtype[i] == Thermo::FLOAT) {
|
||||
NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start,
|
||||
&th->dvalue),
|
||||
th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::INT) {
|
||||
NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
|
||||
th->keyword[i].c_str() );
|
||||
} else if (th->vtype[i] == Thermo::BIGINT) {
|
||||
NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue),
|
||||
th->keyword[i].c_str() );
|
||||
if (fields[i].type == multitype::DOUBLE) {
|
||||
NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::INT) {
|
||||
NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() );
|
||||
} else if (fields[i].type == multitype::BIGINT) {
|
||||
NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write timestep header
|
||||
// write timestep header
|
||||
|
||||
write_time_and_cell();
|
||||
|
||||
|
||||
@ -62,6 +62,7 @@ class DumpNetCDFMPIIO : public DumpCustom {
|
||||
|
||||
int type_nc_real; // netcdf type to use for real variables: float or double
|
||||
bool thermo; // write thermo output to netcdf file
|
||||
bool thermo_warn; // warn (once) that thermo output is on incompatible step
|
||||
|
||||
bigint n_buffer; // size of buffer
|
||||
bigint *int_buffer; // buffer for passing data to netcdf
|
||||
|
||||
@ -48,15 +48,16 @@ using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
static const char cite_reaxff_species_delete[] =
|
||||
"fix reaxff/species, 'delete' keyword: https://doi.org/10.1016/j.carbon.2022.11.002\n\n"
|
||||
"@Article{Gissinger23,\n"
|
||||
" author = {J. R. Gissinger, S. R. Zavada, J. G. Smith, J. Kemppainen, I. Gallegos, G. M. Odegard, E. J. Siochi, K. E. Wise},\n"
|
||||
" title = {Predicting char yield of high-temperature resins},\n"
|
||||
" journal = {Carbon},\n"
|
||||
" year = 2023,\n"
|
||||
" volume = 202,\n"
|
||||
" pages = {336-347}\n"
|
||||
"}\n\n";
|
||||
"fix reaxff/species, 'delete' keyword: https://doi.org/10.1016/j.carbon.2022.11.002\n\n"
|
||||
"@Article{Gissinger23,\n"
|
||||
" author = {J. R. Gissinger, S. R. Zavada, J. G. Smith, J. Kemppainen, I. Gallegos, G. M. "
|
||||
"Odegard, E. J. Siochi, K. E. Wise},\n"
|
||||
" title = {Predicting char yield of high-temperature resins},\n"
|
||||
" journal = {Carbon},\n"
|
||||
" year = 2023,\n"
|
||||
" volume = 202,\n"
|
||||
" pages = {336-347}\n"
|
||||
"}\n\n";
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -148,13 +149,11 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) :
|
||||
setupflag = 0;
|
||||
|
||||
// set default bond order cutoff
|
||||
int itype, jtype;
|
||||
double bo_cut;
|
||||
bg_cut = 0.30;
|
||||
double bo_cut = 0.30;
|
||||
int np1 = ntypes + 1;
|
||||
memory->create(BOCut, np1, np1, "reaxff/species:BOCut");
|
||||
for (int i = 1; i < np1; i++)
|
||||
for (int j = 1; j < np1; j++) BOCut[i][j] = bg_cut;
|
||||
for (int j = 1; j < np1; j++) BOCut[i][j] = bo_cut;
|
||||
|
||||
// optional args
|
||||
eletype = nullptr;
|
||||
@ -172,16 +171,19 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) :
|
||||
// set BO cutoff
|
||||
if (strcmp(arg[iarg], "cutoff") == 0) {
|
||||
if (iarg + 4 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species cutoff", error);
|
||||
itype = utils::inumeric(FLERR, arg[iarg + 1], false, lmp);
|
||||
jtype = utils::inumeric(FLERR, arg[iarg + 2], false, lmp);
|
||||
int ilo, ihi, jlo, jhi;
|
||||
utils::bounds(FLERR, arg[iarg + 1], 1, atom->ntypes, ilo, ihi, error);
|
||||
utils::bounds(FLERR, arg[iarg + 2], 1, atom->ntypes, jlo, jhi, error);
|
||||
bo_cut = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
|
||||
if ((itype <= 0) || (jtype <= 0) || (itype > ntypes) || (jtype > ntypes))
|
||||
error->all(FLERR, "Fix reaxff/species cutoff atom type(s) out of range");
|
||||
if ((bo_cut > 1.0) || (bo_cut < 0.0))
|
||||
error->all(FLERR, "Fix reaxff/species invalid cutoff value: {}", bo_cut);
|
||||
|
||||
BOCut[itype][jtype] = bo_cut;
|
||||
BOCut[jtype][itype] = bo_cut;
|
||||
for (int i = ilo; i <= ihi; ++i) {
|
||||
for (int j = MAX(jlo, i); j <= jhi; ++j) {
|
||||
BOCut[i][j] = bo_cut;
|
||||
BOCut[j][i] = bo_cut;
|
||||
}
|
||||
}
|
||||
iarg += 4;
|
||||
|
||||
// modify element type names
|
||||
@ -240,17 +242,21 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) :
|
||||
error->all(FLERR, "Unknown fix reaxff/species delete option: {}", arg[iarg]);
|
||||
// rate limit when deleting molecules
|
||||
} else if (strcmp(arg[iarg], "delete_rate_limit") == 0) {
|
||||
if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species delete_rate_limit", error);
|
||||
if (iarg + 3 > narg)
|
||||
utils::missing_cmd_args(FLERR, "fix reaxff/species delete_rate_limit", error);
|
||||
delete_Nlimit_varid = -1;
|
||||
if (strncmp(arg[iarg+1],"v_",2) == 0) {
|
||||
delete_Nlimit_varname = &arg[iarg+1][2];
|
||||
if (strncmp(arg[iarg + 1], "v_", 2) == 0) {
|
||||
delete_Nlimit_varname = &arg[iarg + 1][2];
|
||||
delete_Nlimit_varid = input->variable->find(delete_Nlimit_varname.c_str());
|
||||
if (delete_Nlimit_varid < 0)
|
||||
error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",delete_Nlimit_varname);
|
||||
error->all(FLERR, "Fix reaxff/species: Variable name {} does not exist",
|
||||
delete_Nlimit_varname);
|
||||
if (!input->variable->equalstyle(delete_Nlimit_varid))
|
||||
error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",delete_Nlimit_varname);
|
||||
} else delete_Nlimit = utils::numeric(FLERR, arg[iarg+1], false, lmp);
|
||||
delete_Nsteps = utils::numeric(FLERR, arg[iarg+2], false, lmp);
|
||||
error->all(FLERR, "Fix reaxff/species: Variable {} is not equal-style",
|
||||
delete_Nlimit_varname);
|
||||
} else
|
||||
delete_Nlimit = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
|
||||
delete_Nsteps = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
|
||||
iarg += 3;
|
||||
// position of molecules
|
||||
} else if (strcmp(arg[iarg], "position") == 0) {
|
||||
@ -292,10 +298,9 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
if (delete_Nsteps > 0) {
|
||||
if (lmp->citeme) lmp->citeme->add(cite_reaxff_species_delete);
|
||||
memory->create(delete_Tcount,delete_Nsteps,"reaxff/species:delete_Tcount");
|
||||
memory->create(delete_Tcount, delete_Nsteps, "reaxff/species:delete_Tcount");
|
||||
|
||||
for (int i = 0; i < delete_Nsteps; i++)
|
||||
delete_Tcount[i] = -1;
|
||||
for (int i = 0; i < delete_Nsteps; i++) delete_Tcount[i] = -1;
|
||||
delete_Tcount[0] = 0;
|
||||
}
|
||||
|
||||
@ -393,9 +398,11 @@ void FixReaxFFSpecies::init()
|
||||
if (delete_Nsteps > 0) {
|
||||
delete_Nlimit_varid = input->variable->find(delete_Nlimit_varname.c_str());
|
||||
if (delete_Nlimit_varid < 0)
|
||||
error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",delete_Nlimit_varname);
|
||||
error->all(FLERR, "Fix reaxff/species: Variable name {} does not exist",
|
||||
delete_Nlimit_varname);
|
||||
if (!input->variable->equalstyle(delete_Nlimit_varid))
|
||||
error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",delete_Nlimit_varname);
|
||||
error->all(FLERR, "Fix reaxff/species: Variable {} is not equal-style",
|
||||
delete_Nlimit_varname);
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,8 +434,7 @@ void FixReaxFFSpecies::Output_ReaxFF_Bonds(bigint ntimestep, FILE * /*fp*/)
|
||||
if (ntimestep != nvalid) {
|
||||
// push back delete_Tcount on every step
|
||||
if (delete_Nsteps > 0)
|
||||
for (int i = delete_Nsteps-1; i > 0; i--)
|
||||
delete_Tcount[i] = delete_Tcount[i-1];
|
||||
for (int i = delete_Nsteps - 1; i > 0; i--) delete_Tcount[i] = delete_Tcount[i - 1];
|
||||
return;
|
||||
}
|
||||
|
||||
@ -732,31 +738,31 @@ void FixReaxFFSpecies::WriteFormulas(int Nmole, int Nspec)
|
||||
int i, j, itemp;
|
||||
bigint ntimestep = update->ntimestep;
|
||||
|
||||
fprintf(fp, "# Timestep No_Moles No_Specs ");
|
||||
fprintf(fp, "# Timestep No_Moles No_Specs");
|
||||
|
||||
Nmoltype = 0;
|
||||
|
||||
for (i = 0; i < Nspec; i++) nd[i] = CheckExistence(i, ntypes);
|
||||
|
||||
for (i = 0; i < Nmoltype; i++) {
|
||||
std::string molname;
|
||||
for (j = 0; j < ntypes; j++) {
|
||||
itemp = MolType[ntypes * i + j];
|
||||
if (itemp != 0) {
|
||||
if (eletype)
|
||||
fprintf(fp, "%s", eletype[j]);
|
||||
molname += eletype[j];
|
||||
else
|
||||
fprintf(fp, "%c", ele[j]);
|
||||
if (itemp != 1) fprintf(fp, "%d", itemp);
|
||||
molname += ele[j];
|
||||
if (itemp != 1) molname += std::to_string(itemp);
|
||||
}
|
||||
}
|
||||
fputs("\t", fp);
|
||||
fmt::print(fp, " {:>11}", molname);
|
||||
}
|
||||
fputs("\n", fp);
|
||||
|
||||
fmt::print(fp, "{} {:11} {:11}\t", ntimestep, Nmole, Nspec);
|
||||
|
||||
for (i = 0; i < Nmoltype; i++) fprintf(fp, " %d\t", NMol[i]);
|
||||
fprintf(fp, "\n");
|
||||
fmt::print(fp, "{:>11} {:>11} {:>11}", ntimestep, Nmole, Nspec);
|
||||
for (i = 0; i < Nmoltype; i++) fmt::print(fp, " {:>11}", NMol[i]);
|
||||
fputs("\n", fp);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -884,8 +890,8 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec)
|
||||
int ndeletions;
|
||||
int headroom = -1;
|
||||
if (delete_Nsteps > 0) {
|
||||
if (delete_Tcount[delete_Nsteps-1] == -1) return;
|
||||
ndeletions = delete_Tcount[0] - delete_Tcount[delete_Nsteps-1];
|
||||
if (delete_Tcount[delete_Nsteps - 1] == -1) return;
|
||||
ndeletions = delete_Tcount[0] - delete_Tcount[delete_Nsteps - 1];
|
||||
if (delete_Nlimit_varid > -1)
|
||||
delete_Nlimit = input->variable->compute_equal(delete_Nlimit_varid);
|
||||
headroom = MAX(0, delete_Nlimit - ndeletions);
|
||||
@ -925,13 +931,11 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec)
|
||||
std::random_device rnd;
|
||||
std::minstd_rand park_rng(rnd());
|
||||
int *molrange;
|
||||
memory->create(molrange,Nmole,"reaxff/species:molrange");
|
||||
for (m = 0; m < Nmole; m++)
|
||||
molrange[m] = m + 1;
|
||||
memory->create(molrange, Nmole, "reaxff/species:molrange");
|
||||
for (m = 0; m < Nmole; m++) molrange[m] = m + 1;
|
||||
if (delete_Nsteps > 0) {
|
||||
// shuffle index when using rate_limit, in case order is biased
|
||||
if (comm->me == 0)
|
||||
std::shuffle(&molrange[0],&molrange[Nmole], park_rng);
|
||||
if (comm->me == 0) std::shuffle(&molrange[0], &molrange[Nmole], park_rng);
|
||||
MPI_Bcast(&molrange[0], Nmole, MPI_INT, 0, world);
|
||||
}
|
||||
|
||||
@ -1060,11 +1064,9 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// push back delete_Tcount on every step
|
||||
if (delete_Nsteps > 0) {
|
||||
for (i = delete_Nsteps-1; i > 0; i--)
|
||||
delete_Tcount[i] = delete_Tcount[i-1];
|
||||
for (i = delete_Nsteps - 1; i > 0; i--) delete_Tcount[i] = delete_Tcount[i - 1];
|
||||
delete_Tcount[0] += this_delete_Tcount;
|
||||
}
|
||||
|
||||
|
||||
@ -51,8 +51,6 @@ class FixReaxFFSpecies : public Fix {
|
||||
int *Mol2Spec;
|
||||
double *clusterID;
|
||||
AtomCoord *x0;
|
||||
|
||||
double bg_cut;
|
||||
double **BOCut;
|
||||
|
||||
std::vector<std::string> del_species;
|
||||
|
||||
279
src/library.cpp
279
src/library.cpp
@ -247,6 +247,8 @@ void *lammps_open_no_mpi(int argc, char **argv, void **ptr)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
This function is a version of :cpp:func:`lammps_open`, that uses an
|
||||
integer for the MPI communicator as the MPI Fortran interface does. It
|
||||
is used in the :f:func:`lammps` constructor of the LAMMPS Fortran
|
||||
@ -257,8 +259,6 @@ communicator with ``MPI_Comm_f2c()`` and then calls
|
||||
If for some reason the creation or initialization of the LAMMPS instance
|
||||
fails a null pointer is returned.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_open_fortran`, :cpp:func:`lammps_open_no_mpi`
|
||||
|
||||
@ -304,13 +304,13 @@ void lammps_close(void *handle)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
The MPI standard requires that any MPI application must call
|
||||
``MPI_Init()`` exactly once before performing any other MPI function
|
||||
calls. This function checks, whether MPI is already initialized and
|
||||
calls ``MPI_Init()`` in case it is not.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
\endverbatim */
|
||||
|
||||
void lammps_mpi_init()
|
||||
@ -333,6 +333,8 @@ void lammps_mpi_init()
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
The MPI standard requires that any MPI application calls
|
||||
``MPI_Finalize()`` before exiting. Even if a calling program does not
|
||||
do any MPI calls, MPI is still initialized internally to avoid errors
|
||||
@ -341,8 +343,6 @@ before exiting the program to wait until all (parallel) tasks are
|
||||
completed and then MPI is cleanly shut down. After calling this
|
||||
function no more MPI calls may be made.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_kokkos_finalize`, :cpp:func:`lammps_python_finalize`
|
||||
\endverbatim */
|
||||
@ -366,6 +366,8 @@ void lammps_mpi_finalize()
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 2Jul2021
|
||||
|
||||
The Kokkos library may only be initialized once during the execution of
|
||||
a process. This is done automatically the first time Kokkos
|
||||
functionality is used. This requires that the Kokkos environment
|
||||
@ -373,8 +375,6 @@ must be explicitly shut down after any LAMMPS instance using it is
|
||||
closed (to release associated resources).
|
||||
After calling this function no Kokkos functionality may be used.
|
||||
|
||||
.. versionadded:: 2Jul2021
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_python_finalize`
|
||||
\endverbatim */
|
||||
@ -390,6 +390,8 @@ void lammps_kokkos_finalize()
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 20Sep2021
|
||||
|
||||
This function resets and clears an embedded Python environment
|
||||
by calling the `Py_Finalize() function
|
||||
<https://docs.python.org/3/c-api/init.html#c.Py_FinalizeEx>`_
|
||||
@ -409,8 +411,6 @@ after calling Py_Finalize().
|
||||
This function can be called to explicitly clear the Python
|
||||
environment in case it is safe to do so.
|
||||
|
||||
.. versionadded:: 20Sep2021
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_kokkos_finalize`
|
||||
\endverbatim */
|
||||
@ -427,6 +427,8 @@ void lammps_python_finalize()
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
This function is a wrapper around functions in the ``Error`` to print an
|
||||
error message and then stop LAMMPS.
|
||||
|
||||
@ -435,8 +437,6 @@ of constants from :cpp:enum:`_LMP_ERROR_CONST`. If the value does not
|
||||
match any valid combination of constants a warning is printed and the
|
||||
function returns.
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
@ -719,14 +719,16 @@ double lammps_get_natoms(void *handle)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Get current value of a thermo keyword.
|
||||
/** Evaluate a thermo keyword.
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
This function returns the current value of a :doc:`thermo keyword
|
||||
<thermo_style>`. Unlike :cpp:func:`lammps_extract_global` it does not
|
||||
give access to the storage of the desired data but returns its value as
|
||||
a ``double``, so it can also return information that is computed on-the-fly.
|
||||
This function returns the current value of a :doc:`thermo keyword <thermo_style>`.
|
||||
Unlike :cpp:func:`lammps_extract_global` it does not give access to the
|
||||
storage of the desired data but returns its value as a ``double``, so it
|
||||
can also return information that is computed on-the-fly.
|
||||
Use :cpp:func:`lammps_last_thermo` to get access to the cached data from
|
||||
the last thermo output.
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
@ -750,6 +752,117 @@ double lammps_get_thermo(void *handle, const char *keyword)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Access cached data from last thermo output
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
This function provides access to cached data from the last thermo output.
|
||||
This differs from :cpp:func:`lammps_get_thermo` in that it does not trigger
|
||||
an evaluation. Instead it provides direct access to a read-only location
|
||||
of the last thermo output data and the corresponding keyword strings.
|
||||
The how to handle the return value depends on the value of the *what*
|
||||
argument string.
|
||||
|
||||
.. note::
|
||||
|
||||
The *type* property points to a static location that is reassigned
|
||||
with every call, so the returned pointer should be recast,
|
||||
dereferenced, and assigned immediately. Otherwise, its value may be
|
||||
changed with the next invocation of the function.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
* - Value of *what*
|
||||
- Description of return value
|
||||
- Data type
|
||||
- Uses index
|
||||
* - step
|
||||
- timestep when the last thermo output was generated or -1
|
||||
- pointer to bigint
|
||||
- no
|
||||
* - num
|
||||
- number of fields in thermo output
|
||||
- pointer to int
|
||||
- no
|
||||
* - keyword
|
||||
- column keyword for thermo output
|
||||
- pointer to 0-terminated const char array
|
||||
- yes
|
||||
* - type
|
||||
- data type of thermo output column; see :cpp:enum:`_LMP_DATATYPE_CONST`
|
||||
- pointer to static int
|
||||
- yes
|
||||
* - data
|
||||
- actual field data for column
|
||||
- pointer to int, int64_t or double
|
||||
- yes
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
* \param what string with the kind of data requested
|
||||
* \param index integer with index into data arrays, ignored for scalar data
|
||||
* \return pointer to location of requested data cast to void or NULL */
|
||||
|
||||
void *lammps_last_thermo(void *handle, const char *what, int index)
|
||||
{
|
||||
auto lmp = (LAMMPS *) handle;
|
||||
void *val = nullptr;
|
||||
Thermo *th = lmp->output->thermo;
|
||||
if (!th) return nullptr;
|
||||
const int nfield = *th->get_nfield();
|
||||
static int datatype;
|
||||
|
||||
BEGIN_CAPTURE
|
||||
{
|
||||
if (strcmp(what, "step") == 0) {
|
||||
val = (void *) th->get_timestep();
|
||||
|
||||
} else if (strcmp(what, "num") == 0) {
|
||||
val = (void *) th->get_nfield();
|
||||
|
||||
} else if (strcmp(what, "keyword") == 0) {
|
||||
if ((index < 0) || (index >= nfield)) return nullptr;
|
||||
const auto &keywords = th->get_keywords();
|
||||
val = (void *) keywords[index].c_str();
|
||||
|
||||
} else if (strcmp(what, "type") == 0) {
|
||||
if ((index < 0) || (index >= nfield)) return nullptr;
|
||||
const auto &field = th->get_fields()[index];
|
||||
if (field.type == multitype::INT) {
|
||||
datatype = LAMMPS_INT;
|
||||
val = (void *) &datatype;
|
||||
} else if (field.type == multitype::BIGINT) {
|
||||
datatype = LAMMPS_INT64;
|
||||
val = (void *) &datatype;
|
||||
} else if (field.type == multitype::DOUBLE) {
|
||||
datatype = LAMMPS_DOUBLE;
|
||||
val = (void *) &datatype;
|
||||
}
|
||||
|
||||
} else if (strcmp(what, "data") == 0) {
|
||||
if ((index < 0) || (index >= nfield)) return nullptr;
|
||||
const auto &field = th->get_fields()[index];
|
||||
if (field.type == multitype::INT) {
|
||||
val = (void *) &field.data.i;
|
||||
} else if (field.type == multitype::BIGINT) {
|
||||
val = (void *) &field.data.b;
|
||||
} else if (field.type == multitype::DOUBLE) {
|
||||
val = (void *) &field.data.d;
|
||||
}
|
||||
|
||||
} else val = nullptr;
|
||||
}
|
||||
END_CAPTURE
|
||||
return val;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Extract simulation box parameters.
|
||||
*
|
||||
\verbatim embed:rst
|
||||
@ -877,6 +990,8 @@ void lammps_reset_box(void *handle, double *boxlo, double *boxhi,
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
This function will retrieve memory usage information for the current
|
||||
LAMMPS instance or process. The *meminfo* buffer will be filled with
|
||||
3 different numbers (if supported by the operating system). The first
|
||||
@ -889,8 +1004,6 @@ third number is the maximum amount of RAM (not swap) used by the process
|
||||
so far. If any of the two latter parameters is not supported by the operating
|
||||
system it will be set to zero.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
@ -910,6 +1023,8 @@ void lammps_memory_usage(void *handle, double *meminfo)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
This will take the LAMMPS "world" communicator and convert it to an
|
||||
integer using ``MPI_Comm_c2f()``, so it is equivalent to the
|
||||
corresponding MPI communicator in Fortran. This way it can be safely
|
||||
@ -918,8 +1033,6 @@ to the C language representation use ``MPI_Comm_f2c()``.
|
||||
|
||||
If LAMMPS was compiled with MPI_STUBS, this function returns -1.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_open_fortran`
|
||||
|
||||
@ -1182,13 +1295,13 @@ int lammps_extract_setting(void *handle, const char *keyword)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
This function returns an integer that encodes the data type of the global
|
||||
property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid
|
||||
values. Callers of :cpp:func:`lammps_extract_global` can use this information
|
||||
to then decide how to cast the ``void *`` pointer and access the data.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance (unused)
|
||||
@ -1671,13 +1784,13 @@ void *lammps_extract_global(void *handle, const char *name)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
This function returns an integer that encodes the data type of the per-atom
|
||||
property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid
|
||||
values. Callers of :cpp:func:`lammps_extract_atom` can use this information
|
||||
to then decide how to cast the ``void *`` pointer and access the data.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
@ -2206,13 +2319,13 @@ void *lammps_extract_variable(void *handle, const char *name, const char *group)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
This function returns an integer that encodes the data type of the variable
|
||||
with the specified name. See :cpp:enum:`_LMP_VAR_CONST` for valid values.
|
||||
Callers of :cpp:func:`lammps_extract_variable` can use this information to
|
||||
decide how to cast the ``void *`` pointer and access the data.
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance
|
||||
@ -3064,6 +3177,8 @@ void lammps_scatter_atoms_subset(void *handle, const char *name, int type,
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This function copies the list of all bonds into a buffer provided by
|
||||
the calling code. The buffer will be filled with bond type, bond atom 1,
|
||||
bond atom 2 for each bond. Thus the buffer has to be allocated to the
|
||||
@ -3078,8 +3193,6 @@ When running in parallel, the data buffer must be allocated on **all**
|
||||
MPI ranks and will be filled with the information for **all** bonds
|
||||
in the system.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
Below is a brief C code demonstrating accessing this collected bond information.
|
||||
|
||||
.. code-block:: c
|
||||
@ -3159,7 +3272,8 @@ void lammps_gather_bonds(void *handle, void *data)
|
||||
}
|
||||
|
||||
tagint **bonds;
|
||||
lmp->memory->create(bonds, localbonds, 3, "library:gather_bonds:localbonds");
|
||||
// add 1 to localbonds, so "bonds" does not become a NULL pointer
|
||||
lmp->memory->create(bonds, localbonds+1, 3, "library:gather_bonds:localbonds");
|
||||
lmp->atom->avec->pack_bond(bonds);
|
||||
MPI_Allgatherv(&bonds[0][0], 3*localbonds, MPI_LMP_TAGINT, data, bufsizes,
|
||||
bufoffsets, MPI_LMP_TAGINT, lmp->world);
|
||||
@ -3174,6 +3288,8 @@ void lammps_gather_bonds(void *handle, void *data)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This function copies the list of all angles into a buffer provided by
|
||||
the calling code. The buffer will be filled with angle type, angle atom 1,
|
||||
angle atom 2, angle atom 3 for each angle. Thus the buffer has to be allocated to the
|
||||
@ -3188,8 +3304,6 @@ When running in parallel, the data buffer must be allocated on **all**
|
||||
MPI ranks and will be filled with the information for **all** angles
|
||||
in the system.
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
Below is a brief C code demonstrating accessing this collected angle information.
|
||||
|
||||
.. code-block:: c
|
||||
@ -3269,7 +3383,8 @@ void lammps_gather_angles(void *handle, void *data)
|
||||
}
|
||||
|
||||
tagint **angles;
|
||||
lmp->memory->create(angles, localangles, 4, "library:gather_angles:localangles");
|
||||
// add 1 to localangles, so "angles" does not become a NULL pointer
|
||||
lmp->memory->create(angles, localangles+1, 4, "library:gather_angles:localangles");
|
||||
lmp->atom->avec->pack_angle(angles);
|
||||
MPI_Allgatherv(&angles[0][0], 4*localangles, MPI_LMP_TAGINT, data, bufsizes,
|
||||
bufoffsets, MPI_LMP_TAGINT, lmp->world);
|
||||
@ -3284,6 +3399,8 @@ void lammps_gather_angles(void *handle, void *data)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This function copies the list of all dihedrals into a buffer provided by
|
||||
the calling code. The buffer will be filled with dihedral type, dihedral atom 1,
|
||||
dihedral atom 2, dihedral atom 3, dihedral atom 4 for each dihedral.
|
||||
@ -3299,8 +3416,6 @@ When running in parallel, the data buffer must be allocated on **all**
|
||||
MPI ranks and will be filled with the information for **all** dihedrals
|
||||
in the system.
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
Below is a brief C code demonstrating accessing this collected dihedral information.
|
||||
|
||||
.. code-block:: c
|
||||
@ -3380,7 +3495,8 @@ void lammps_gather_dihedrals(void *handle, void *data)
|
||||
}
|
||||
|
||||
tagint **dihedrals;
|
||||
lmp->memory->create(dihedrals, localdihedrals, 5, "library:gather_dihedrals:localdihedrals");
|
||||
// add 1 to localdihedrals, so "dihedrals" does not become a NULL pointer
|
||||
lmp->memory->create(dihedrals, localdihedrals+1, 5, "library:gather_dihedrals:localdihedrals");
|
||||
lmp->atom->avec->pack_dihedral(dihedrals);
|
||||
MPI_Allgatherv(&dihedrals[0][0], 5*localdihedrals, MPI_LMP_TAGINT, data, bufsizes,
|
||||
bufoffsets, MPI_LMP_TAGINT, lmp->world);
|
||||
@ -3395,6 +3511,8 @@ void lammps_gather_dihedrals(void *handle, void *data)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
This function copies the list of all impropers into a buffer provided by
|
||||
the calling code. The buffer will be filled with improper type, improper atom 1,
|
||||
improper atom 2, improper atom 3, improper atom 4 for each improper.
|
||||
@ -3410,8 +3528,6 @@ When running in parallel, the data buffer must be allocated on **all**
|
||||
MPI ranks and will be filled with the information for **all** impropers
|
||||
in the system.
|
||||
|
||||
.. versionadded:: 8Feb2023
|
||||
|
||||
Below is a brief C code demonstrating accessing this collected improper information.
|
||||
|
||||
.. code-block:: c
|
||||
@ -3491,7 +3607,8 @@ void lammps_gather_impropers(void *handle, void *data)
|
||||
}
|
||||
|
||||
tagint **impropers;
|
||||
lmp->memory->create(impropers, localimpropers, 5, "library:gather_impropers:localimpropers");
|
||||
// add 1 to localimpropers, so "impropers" does not become a NULL pointer
|
||||
lmp->memory->create(impropers, localimpropers+1, 5, "library:gather_impropers:localimpropers");
|
||||
lmp->atom->avec->pack_improper(impropers);
|
||||
MPI_Allgatherv(&impropers[0][0], 5*localimpropers, MPI_LMP_TAGINT, data, bufsizes,
|
||||
bufoffsets, MPI_LMP_TAGINT, lmp->world);
|
||||
@ -5204,6 +5321,8 @@ int lammps_version(void *handle)
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
The :cpp:func:`lammps_get_os_info` function can be used to retrieve
|
||||
detailed information about the hosting operating system and
|
||||
compiler/runtime.
|
||||
@ -5212,8 +5331,6 @@ A suitable buffer for a C-style string has to be provided and its length.
|
||||
The assembled text will be truncated to not overflow this buffer. The
|
||||
string is typically a few hundred bytes long.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param buffer string buffer to copy the information to
|
||||
@ -5442,6 +5559,8 @@ int lammps_config_accelerator(const char *package,
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 14May2021
|
||||
|
||||
The :cpp:func:`lammps_has_gpu_device` function checks at runtime if
|
||||
an accelerator device is present that can be used with the
|
||||
:doc:`GPU package <Speed_gpu>`. If at least one suitable device is
|
||||
@ -5451,8 +5570,6 @@ More detailed information about the available device or devices can
|
||||
be obtained by calling the
|
||||
:cpp:func:`lammps_get_gpu_device_info` function.
|
||||
|
||||
.. versionadded:: 14May2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \return 1 if viable device is available, 0 if not. */
|
||||
@ -5466,6 +5583,8 @@ int lammps_has_gpu_device()
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 14May2021
|
||||
|
||||
The :cpp:func:`lammps_get_gpu_device_info` function can be used to retrieve
|
||||
detailed information about any accelerator devices that are viable for use
|
||||
with the :doc:`GPU package <Speed_gpu>`. It will produce a string that is
|
||||
@ -5477,8 +5596,6 @@ A suitable buffer for a C-style string has to be provided and its length.
|
||||
The assembled text will be truncated to not overflow this buffer. This
|
||||
string can be several kilobytes long, if multiple devices are present.
|
||||
|
||||
.. versionadded:: 14May2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param buffer string buffer to copy the information to
|
||||
@ -5575,12 +5692,13 @@ int lammps_style_name(void *handle, const char *category, int idx,
|
||||
/** Check if a specific ID exists in the current LAMMPS instance
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
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:: 9Oct2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -5614,13 +5732,14 @@ int lammps_has_id(void *handle, const char *category, const char *name) {
|
||||
/** Count the number of IDs of a category.
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
This function counts how many IDs in the provided *category*
|
||||
are defined in the current LAMMPS instance.
|
||||
Please see :cpp:func:`lammps_has_id` for a list of valid
|
||||
categories.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -5652,6 +5771,9 @@ int lammps_id_count(void *handle, const char *category) {
|
||||
/** Look up the name of an ID by index in the list of IDs of a given category.
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
This function copies the name of the *category* ID 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
|
||||
@ -5659,8 +5781,6 @@ exceeds the length of the buffer, it will be truncated accordingly.
|
||||
If the index is out of range, the function returns 0 and *buffer* is
|
||||
set to an empty string, otherwise 1.
|
||||
|
||||
.. versionadded:: 9Oct2020
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -5723,10 +5843,11 @@ int lammps_id_name(void *handle, const char *category, int idx, char *buffer, in
|
||||
/** Count the number of loaded plugins
|
||||
*
|
||||
\verbatim embed:rst
|
||||
This function counts how many plugins are currently loaded.
|
||||
|
||||
.. versionadded:: 10Mar2021
|
||||
|
||||
This function counts how many plugins are currently loaded.
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \return number of loaded plugins
|
||||
@ -5745,6 +5866,9 @@ int lammps_plugin_count()
|
||||
/** Look up the info of a loaded plugin by its index in the list of plugins
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 10Mar2021
|
||||
|
||||
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
|
||||
@ -5752,8 +5876,6 @@ exceeds the length of the buffer, it will be truncated accordingly.
|
||||
If the index is out of range, the function returns 0 and *buffer* is
|
||||
set to an empty string, otherwise 1.
|
||||
|
||||
.. versionadded:: 10Mar2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param idx index of the plugin in the list all or *style* plugins
|
||||
@ -5912,9 +6034,11 @@ void lammps_set_fix_external_callback(void *handle, const char *id, FixExternalF
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
Fix :doc:`external <fix_external>` allows programs that are running LAMMPS through
|
||||
its library interface to add or modify certain LAMMPS properties on specific
|
||||
timesteps, similar to the way other fixes do.
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
Fix :doc:`external <fix_external>` allows programs that are running
|
||||
LAMMPS through its library interface to add or modify certain LAMMPS
|
||||
properties on specific timesteps, 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
|
||||
@ -5927,12 +6051,12 @@ 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, :cpp:func:`lammps_extract_setting` to obtain the
|
||||
number of local atoms `nlocal` and then assume the dimensions of the returned
|
||||
force array as ``double force[nlocal][3]``.
|
||||
You can use, for example, :cpp:func:`lammps_extract_setting` to obtain
|
||||
the number of local atoms `nlocal` and then assume the dimensions of
|
||||
the returned force array as ``double force[nlocal][3]``.
|
||||
|
||||
This is an alternative to the callback mechanism in fix external set up by
|
||||
:cpp:func:`lammps_set_fix_external_callback`. The main difference is
|
||||
This is an alternative to the callback mechanism in fix external set up
|
||||
by :cpp:func:`lammps_set_fix_external_callback`. The main difference is
|
||||
that this mechanism can be used when forces are be pre-computed and the
|
||||
control alternates between LAMMPS and the external code, while the
|
||||
callback mechanism can call the external code to compute the force when
|
||||
@ -5942,8 +6066,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -5974,6 +6096,8 @@ double **lammps_fix_external_get_force(void *handle, const char *id)
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_get_force` to also set the contribution
|
||||
to the global energy from the external code. The value of the *eng*
|
||||
@ -5990,8 +6114,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -6020,6 +6142,8 @@ void lammps_fix_external_set_energy_global(void *handle, const char *id, double
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback`
|
||||
and :cpp:func:`lammps_fix_external_get_force` to set the contribution to
|
||||
the global virial from the external code.
|
||||
@ -6038,8 +6162,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -6068,6 +6190,8 @@ void lammps_fix_external_set_virial_global(void *handle, const char *id, double
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback`
|
||||
to set the per-atom energy contribution due to the fix from the external code
|
||||
as part of the callback function. For this to work, the handle to the
|
||||
@ -6086,8 +6210,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -6116,6 +6238,8 @@ void lammps_fix_external_set_energy_peratom(void *handle, const char *id, double
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback`
|
||||
to set the per-atom virial contribution due to the fix from the external code
|
||||
as part of the callback function. For this to work, the handle to the
|
||||
@ -6137,8 +6261,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -6167,6 +6289,8 @@ void lammps_fix_external_set_virial_peratom(void *handle, const char *id, double
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_get_force` to set the length of a global vector of
|
||||
properties that will be stored with the fix via
|
||||
@ -6181,8 +6305,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -6211,6 +6333,8 @@ void lammps_fix_external_set_vector_length(void *handle, const char *id, int len
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_get_force` to set the values of a global vector of
|
||||
properties that will be stored with the fix. And can be accessed from
|
||||
@ -6234,8 +6358,6 @@ Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
.. versionadded:: 28Jul2021
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
@ -6407,12 +6529,13 @@ int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) {
|
||||
/** Return API version of embedded Python interpreter
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
This function is used by the ML-IAP python code (mliappy) to verify
|
||||
the API version of the embedded python interpreter of the PYTHON
|
||||
package. It returns -1 if the PYTHON package is not enabled.
|
||||
|
||||
.. versionadded:: 3Nov2022
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \return PYTHON_API_VERSION constant of the python interpreter or -1 */
|
||||
|
||||
@ -148,6 +148,7 @@ void lammps_commands_string(void *handle, const char *str);
|
||||
|
||||
double lammps_get_natoms(void *handle);
|
||||
double lammps_get_thermo(void *handle, const char *keyword);
|
||||
void *lammps_last_thermo(void *handle, const char *what, int index);
|
||||
|
||||
void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz,
|
||||
double *xz, int *pflags, int *boxflag);
|
||||
|
||||
@ -95,7 +95,7 @@ typedef int64_t bigint;
|
||||
#define MAXSMALLINT INT_MAX
|
||||
#define MAXTAGINT INT_MAX
|
||||
#define MAXBIGINT INT64_MAX
|
||||
#define MAXDOUBLEINT 9007199254740992 // 2^53
|
||||
#define MAXDOUBLEINT 9007199254740992 // 2^53
|
||||
|
||||
#define MPI_LMP_TAGINT MPI_INT
|
||||
#define MPI_LMP_IMAGEINT MPI_INT
|
||||
@ -133,7 +133,7 @@ typedef int64_t bigint;
|
||||
#define MAXSMALLINT INT_MAX
|
||||
#define MAXTAGINT INT64_MAX
|
||||
#define MAXBIGINT INT64_MAX
|
||||
#define MAXDOUBLEINT 9007199254740992 // 2^53
|
||||
#define MAXDOUBLEINT 9007199254740992 // 2^53
|
||||
|
||||
#define MPI_LMP_TAGINT MPI_LL
|
||||
#define MPI_LMP_IMAGEINT MPI_LL
|
||||
@ -232,6 +232,84 @@ union ubuf {
|
||||
ubuf(const int64_t &arg) : i(arg) {}
|
||||
ubuf(const int &arg) : i(arg) {}
|
||||
};
|
||||
|
||||
/** Data structure for dynamic typing of int, bigint, and double
|
||||
*
|
||||
* Using this union allows to store any of the supported data types
|
||||
* in the same container and allows to "see" its current type.
|
||||
\verbatim embed:rst
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: To store data in multitype array:
|
||||
|
||||
multitype m[5];
|
||||
int foo = 1;
|
||||
double bar = 2.5;
|
||||
bigint baz = 1<<40 - 1;
|
||||
m[0] = foo;
|
||||
m[1] = bar;
|
||||
m[2] = -1;
|
||||
m[3] = 2.0;
|
||||
m[4] = baz;
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: To format data from multitype array into a space separated string:
|
||||
|
||||
std::string str;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
switch (m[i].type) {
|
||||
case multitype::DOUBLE:
|
||||
str += std::to_string(m[i].data.d) + ' ';
|
||||
break;
|
||||
case multitype::INT:
|
||||
str += std::to_string(m[i].data.i) + ' ';
|
||||
break;
|
||||
case multitype::BIGINT:
|
||||
str += std::to_string(m[i].data.b) + ' ';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
*/
|
||||
struct multitype {
|
||||
enum { NONE, DOUBLE, INT, BIGINT };
|
||||
|
||||
int type;
|
||||
union {
|
||||
double d;
|
||||
int i;
|
||||
int64_t b;
|
||||
} data;
|
||||
|
||||
multitype() : type(NONE) { data.d = 0.0; }
|
||||
multitype(const multitype &) = default;
|
||||
multitype(multitype &&) = default;
|
||||
~multitype() = default;
|
||||
|
||||
multitype &operator=(const double &_d)
|
||||
{
|
||||
type = DOUBLE;
|
||||
data.d = _d;
|
||||
return *this;
|
||||
}
|
||||
multitype &operator=(const int &_i)
|
||||
{
|
||||
type = INT;
|
||||
data.i = _i;
|
||||
return *this;
|
||||
}
|
||||
multitype &operator=(const int64_t &_b)
|
||||
{
|
||||
type = BIGINT;
|
||||
data.b = _b;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
// preprocessor macros for compiler specific settings
|
||||
|
||||
@ -104,6 +104,9 @@ template <class T> class MyPage {
|
||||
int errorflag; // flag > 0 if error has occurred
|
||||
// 1 = chunk size exceeded maxchunk
|
||||
// 2 = memory allocation error
|
||||
#if defined(_OPENMP)
|
||||
char pad[64]; // to avoid false sharing with multi-threading
|
||||
#endif
|
||||
void allocate();
|
||||
void deallocate();
|
||||
};
|
||||
|
||||
108
src/output.cpp
108
src/output.cpp
@ -190,6 +190,32 @@ void Output::setup(int memflag)
|
||||
{
|
||||
bigint ntimestep = update->ntimestep;
|
||||
|
||||
// print memory usage unless being called between multiple runs
|
||||
|
||||
if (memflag) memory_usage();
|
||||
|
||||
// set next_thermo to multiple of every or variable eval if var defined
|
||||
// ensure thermo output on last step of run
|
||||
// thermo may invoke computes so wrap with clear/add
|
||||
|
||||
modify->clearstep_compute();
|
||||
|
||||
thermo->header();
|
||||
thermo->compute(0);
|
||||
last_thermo = ntimestep;
|
||||
|
||||
if (var_thermo) {
|
||||
next_thermo = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_thermo));
|
||||
if (next_thermo <= ntimestep)
|
||||
error->all(FLERR,"Thermo every variable returned a bad timestep");
|
||||
} else if (thermo_every) {
|
||||
next_thermo = (ntimestep/thermo_every)*thermo_every + thermo_every;
|
||||
next_thermo = MIN(next_thermo,update->laststep);
|
||||
} else next_thermo = update->laststep;
|
||||
|
||||
modify->addstep_compute(next_thermo);
|
||||
|
||||
// consider all dumps
|
||||
// decide whether to write snapshot and/or calculate next step for dump
|
||||
|
||||
@ -257,7 +283,7 @@ void Output::setup(int memflag)
|
||||
next_dump_any = MIN(next_dump_any,next_dump[idump]);
|
||||
}
|
||||
|
||||
// if no dumps, set next_dump_any to last+1 so will not influence next
|
||||
// if no dumps, set next_dump_any to last+1 so will not influence next
|
||||
|
||||
} else next_dump_any = update->laststep + 1;
|
||||
|
||||
@ -276,7 +302,8 @@ void Output::setup(int memflag)
|
||||
auto nextrestart = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_restart_single));
|
||||
if (nextrestart <= ntimestep)
|
||||
error->all(FLERR,"Restart variable returned a bad timestep");
|
||||
error->all(FLERR,"Restart variable returned a bad next timestep: {} vs {}",
|
||||
nextrestart, ntimestep);
|
||||
next_restart_single = nextrestart;
|
||||
}
|
||||
} else next_restart_single = update->laststep + 1;
|
||||
@ -289,39 +316,14 @@ void Output::setup(int memflag)
|
||||
auto nextrestart = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_restart_double));
|
||||
if (nextrestart <= ntimestep)
|
||||
error->all(FLERR,"Restart variable returned a bad timestep");
|
||||
error->all(FLERR,"Restart variable returned a bad next timestep: {} vs {}",
|
||||
nextrestart, ntimestep);
|
||||
next_restart_double = nextrestart;
|
||||
}
|
||||
} else next_restart_double = update->laststep + 1;
|
||||
next_restart = MIN(next_restart_single,next_restart_double);
|
||||
} else next_restart = update->laststep + 1;
|
||||
|
||||
// print memory usage unless being called between multiple runs
|
||||
|
||||
if (memflag) memory_usage();
|
||||
|
||||
// set next_thermo to multiple of every or variable eval if var defined
|
||||
// ensure thermo output on last step of run
|
||||
// thermo may invoke computes so wrap with clear/add
|
||||
|
||||
modify->clearstep_compute();
|
||||
|
||||
thermo->header();
|
||||
thermo->compute(0);
|
||||
last_thermo = ntimestep;
|
||||
|
||||
if (var_thermo) {
|
||||
next_thermo = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_thermo));
|
||||
if (next_thermo <= ntimestep)
|
||||
error->all(FLERR,"Thermo every variable returned a bad timestep");
|
||||
} else if (thermo_every) {
|
||||
next_thermo = (ntimestep/thermo_every)*thermo_every + thermo_every;
|
||||
next_thermo = MIN(next_thermo,update->laststep);
|
||||
} else next_thermo = update->laststep;
|
||||
|
||||
modify->addstep_compute(next_thermo);
|
||||
|
||||
// next = next timestep any output will be done
|
||||
|
||||
next = MIN(next_dump_any,next_restart);
|
||||
@ -336,6 +338,24 @@ void Output::setup(int memflag)
|
||||
|
||||
void Output::write(bigint ntimestep)
|
||||
{
|
||||
// ensure next_thermo forces output on last step of run
|
||||
// thermo may invoke computes so wrap with clear/add
|
||||
|
||||
if (next_thermo == ntimestep) {
|
||||
modify->clearstep_compute();
|
||||
if (last_thermo != ntimestep) thermo->compute(1);
|
||||
last_thermo = ntimestep;
|
||||
if (var_thermo) {
|
||||
next_thermo = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_thermo));
|
||||
if (next_thermo <= ntimestep)
|
||||
error->all(FLERR,"Thermo every variable returned a bad timestep");
|
||||
} else if (thermo_every) next_thermo += thermo_every;
|
||||
else next_thermo = update->laststep;
|
||||
next_thermo = MIN(next_thermo,update->laststep);
|
||||
modify->addstep_compute(next_thermo);
|
||||
}
|
||||
|
||||
// perform dump if its next_dump = current ntimestep
|
||||
// but not if it was already written on this step
|
||||
// set next_dump and also next_time_dump for mode_dump = 1
|
||||
@ -401,7 +421,8 @@ void Output::write(bigint ntimestep)
|
||||
auto nextrestart = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_restart_single));
|
||||
if (nextrestart <= ntimestep)
|
||||
error->all(FLERR,"Restart variable returned a bad timestep");
|
||||
error->all(FLERR,"Restart variable returned a bad next timestep: {} vs {}",
|
||||
nextrestart, ntimestep);
|
||||
next_restart_single = nextrestart;
|
||||
modify->addstep_compute(next_restart_single);
|
||||
}
|
||||
@ -424,7 +445,8 @@ void Output::write(bigint ntimestep)
|
||||
auto nextrestart = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_restart_double));
|
||||
if (nextrestart <= ntimestep)
|
||||
error->all(FLERR,"Restart variable returned a bad timestep");
|
||||
error->all(FLERR,"Restart variable returned a bad next timestep: {} <= {}",
|
||||
nextrestart, ntimestep);
|
||||
next_restart_double = nextrestart;
|
||||
modify->addstep_compute(next_restart_double);
|
||||
}
|
||||
@ -433,24 +455,6 @@ void Output::write(bigint ntimestep)
|
||||
next_restart = MIN(next_restart_single,next_restart_double);
|
||||
}
|
||||
|
||||
// ensure next_thermo forces output on last step of run
|
||||
// thermo may invoke computes so wrap with clear/add
|
||||
|
||||
if (next_thermo == ntimestep) {
|
||||
modify->clearstep_compute();
|
||||
if (last_thermo != ntimestep) thermo->compute(1);
|
||||
last_thermo = ntimestep;
|
||||
if (var_thermo) {
|
||||
next_thermo = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_thermo));
|
||||
if (next_thermo <= ntimestep)
|
||||
error->all(FLERR,"Thermo every variable returned a bad timestep");
|
||||
} else if (thermo_every) next_thermo += thermo_every;
|
||||
else next_thermo = update->laststep;
|
||||
next_thermo = MIN(next_thermo,update->laststep);
|
||||
modify->addstep_compute(next_thermo);
|
||||
}
|
||||
|
||||
// next = next timestep any output will be done
|
||||
|
||||
next = MIN(next_dump_any,next_restart);
|
||||
@ -647,7 +651,8 @@ void Output::reset_timestep(bigint ntimestep)
|
||||
auto nextrestart = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_restart_single));
|
||||
if (nextrestart < ntimestep)
|
||||
error->all(FLERR,"Restart variable returned a bad timestep");
|
||||
error->all(FLERR,"Restart variable returned a bad next timestep: {} <= {}",
|
||||
nextrestart, ntimestep);
|
||||
update->ntimestep++;
|
||||
next_restart_single = nextrestart;
|
||||
modify->addstep_compute(next_restart_single);
|
||||
@ -666,7 +671,8 @@ void Output::reset_timestep(bigint ntimestep)
|
||||
auto nextrestart = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_restart_double));
|
||||
if (nextrestart < ntimestep)
|
||||
error->all(FLERR,"Restart variable returned a bad timestep");
|
||||
error->all(FLERR,"Restart variable returned a bad next timestep: {} <= {}",
|
||||
nextrestart, ntimestep);
|
||||
update->ntimestep++;
|
||||
next_restart_double = nextrestart;
|
||||
modify->addstep_compute(next_restart_double);
|
||||
|
||||
@ -111,6 +111,7 @@ Thermo::Thermo(LAMMPS *_lmp, int narg, char **arg) :
|
||||
lostflag = lostbond = Thermo::ERROR;
|
||||
lostbefore = warnbefore = 0;
|
||||
flushflag = 0;
|
||||
ntimestep = -1;
|
||||
|
||||
// set style and corresponding lineflag
|
||||
// custom style builds its own line of keywords, including wildcard expansion
|
||||
@ -201,6 +202,8 @@ void Thermo::init()
|
||||
ValueTokenizer *format_line = nullptr;
|
||||
if (format_line_user.size()) format_line = new ValueTokenizer(format_line_user);
|
||||
|
||||
field_data.clear();
|
||||
field_data.resize(nfield);
|
||||
std::string format_this, format_line_user_def;
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
|
||||
@ -208,6 +211,14 @@ void Thermo::init()
|
||||
format_this.clear();
|
||||
format_line_user_def.clear();
|
||||
|
||||
if (vtype[i] == FLOAT) {
|
||||
field_data[i] = (double) 0.0;
|
||||
} else if (vtype[i] == INT) {
|
||||
field_data[i] = (int) 0;
|
||||
} else if (vtype[i] == BIGINT) {
|
||||
field_data[i] = (bigint) 0;
|
||||
}
|
||||
|
||||
if ((lineflag == MULTILINE) && ((i % 3) == 0)) format[i] += "\n";
|
||||
if ((lineflag == YAMLLINE) && (i == 0)) format[i] += " - [";
|
||||
if (format_line) format_line_user_def = format_line->next_string();
|
||||
@ -361,7 +372,7 @@ void Thermo::compute(int flag)
|
||||
int i;
|
||||
|
||||
firststep = flag;
|
||||
bigint ntimestep = update->ntimestep;
|
||||
ntimestep = update->ntimestep;
|
||||
|
||||
// check for lost atoms
|
||||
// turn off normflag if natoms = 0 to avoid divide by 0
|
||||
@ -405,18 +416,23 @@ void Thermo::compute(int flag)
|
||||
}
|
||||
|
||||
// add each thermo value to line with its specific format
|
||||
field_data.clear();
|
||||
field_data.resize(nfield);
|
||||
|
||||
for (ifield = 0; ifield < nfield; ifield++) {
|
||||
(this->*vfunc[ifield])();
|
||||
if (vtype[ifield] == FLOAT) {
|
||||
snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), dvalue);
|
||||
line += fmtbuf;
|
||||
field_data[ifield] = dvalue;
|
||||
} else if (vtype[ifield] == INT) {
|
||||
snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), ivalue);
|
||||
line += fmtbuf;
|
||||
field_data[ifield] = ivalue;
|
||||
} else if (vtype[ifield] == BIGINT) {
|
||||
snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), bivalue);
|
||||
line += fmtbuf;
|
||||
field_data[ifield] = bivalue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,16 +449,6 @@ void Thermo::compute(int flag)
|
||||
firststep = 1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
call function to compute property
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Thermo::call_vfunc(int ifield_in)
|
||||
{
|
||||
ifield = ifield_in;
|
||||
(this->*vfunc[ifield])();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
check for lost atoms, return current number of atoms
|
||||
also could number of warnings across MPI ranks and update total
|
||||
@ -1062,6 +1068,8 @@ void Thermo::parse_fields(const std::string &str)
|
||||
}
|
||||
}
|
||||
}
|
||||
field_data.clear();
|
||||
field_data.resize(nfield);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
12
src/thermo.h
12
src/thermo.h
@ -21,9 +21,6 @@ namespace LAMMPS_NS {
|
||||
|
||||
class Thermo : protected Pointers {
|
||||
friend class MinCG; // accesses compute_pe
|
||||
friend class DumpNetCDF; // accesses thermo properties
|
||||
friend class DumpNetCDFMPIIO; // accesses thermo properties
|
||||
friend class DumpYAML; // accesses thermo properties
|
||||
|
||||
public:
|
||||
char *style;
|
||||
@ -45,6 +42,12 @@ class Thermo : protected Pointers {
|
||||
void compute(int);
|
||||
int evaluate_keyword(const std::string &, double *);
|
||||
|
||||
// for accessing cached thermo data
|
||||
const int *get_nfield() const { return &nfield; }
|
||||
const bigint *get_timestep() const { return &ntimestep; }
|
||||
const std::vector<multitype> &get_fields() const { return field_data; }
|
||||
const std::vector<std::string> &get_keywords() const { return keyword; }
|
||||
|
||||
private:
|
||||
int nfield, nfield_initial;
|
||||
int *vtype;
|
||||
@ -52,6 +55,7 @@ class Thermo : protected Pointers {
|
||||
std::vector<std::string> keyword, format, format_column_user, keyword_user;
|
||||
std::string format_line_user, format_float_user, format_int_user, format_bigint_user;
|
||||
std::map<std::string, int> key2col;
|
||||
std::vector<multitype> field_data;
|
||||
|
||||
int normvalue; // use this for normflag unless natoms = 0
|
||||
int normuserflag; // 0 if user has not set, 1 if has
|
||||
@ -66,6 +70,7 @@ class Thermo : protected Pointers {
|
||||
bigint last_step;
|
||||
|
||||
bigint natoms;
|
||||
bigint ntimestep;
|
||||
|
||||
// data used by routines that compute single values
|
||||
int ivalue; // integer value to print
|
||||
@ -114,7 +119,6 @@ class Thermo : protected Pointers {
|
||||
typedef void (Thermo::*FnPtr)();
|
||||
void addfield(const char *, FnPtr, int);
|
||||
FnPtr *vfunc; // list of ptrs to functions
|
||||
void call_vfunc(int ifield);
|
||||
|
||||
void compute_compute(); // functions that compute a single value
|
||||
void compute_fix(); // via calls to Compute,Fix,Variable classes
|
||||
|
||||
@ -224,7 +224,7 @@ void Variable::set(int narg, char **arg)
|
||||
if (narg == 5 && strcmp(arg[4],"pad") == 0) {
|
||||
pad[nvar] = fmt::format("{}",nlast).size();
|
||||
} else pad[nvar] = 0;
|
||||
} else error->all(FLERR,"Illegal variable loop command: too much arguments");
|
||||
} else error->all(FLERR,"Illegal variable loop command: too many arguments");
|
||||
num[nvar] = nlast;
|
||||
which[nvar] = nfirst-1;
|
||||
data[nvar] = new char*[1];
|
||||
@ -1052,7 +1052,7 @@ char *Variable::retrieve(const char *name)
|
||||
if (vecs[ivar].dynamic || vecs[ivar].currentstep != update->ntimestep) {
|
||||
eval_in_progress[ivar] = 0;
|
||||
double *result;
|
||||
int nvec = compute_vector(ivar,&result);
|
||||
compute_vector(ivar,&result);
|
||||
delete[] data[ivar][1];
|
||||
std::vector <double> vectmp(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n);
|
||||
std::string str = fmt::format("[{}]", fmt::join(vectmp,","));
|
||||
|
||||
@ -21,7 +21,7 @@ DEFAULT_CONFIG = """
|
||||
recursive: true
|
||||
include:
|
||||
- doc/src/**
|
||||
- python
|
||||
- python/**
|
||||
- src/**
|
||||
exclude:
|
||||
- src/Make.sh
|
||||
|
||||
@ -113,6 +113,7 @@ extern void lammps_commands_string(void *handle, const char *str);
|
||||
|
||||
extern double lammps_get_natoms(void *handle);
|
||||
extern double lammps_get_thermo(void *handle, const char *keyword);
|
||||
extern void *lammps_last_thermo(void *handle, const char *what, int index);
|
||||
extern void lammps_extract_box(void *handle, double *boxlo, double *boxhi,
|
||||
double *xy, double *yz, double *xz,
|
||||
int *pflags, int *boxflag);
|
||||
@ -295,6 +296,7 @@ extern void lammps_commands_string(void *handle, const char *str);
|
||||
|
||||
extern double lammps_get_natoms(void *handle);
|
||||
extern double lammps_get_thermo(void *handle, const char *keyword);
|
||||
extern void *lammps_last_thermo(void *handle, const char *what, int index);
|
||||
extern void lammps_extract_box(void *handle, double *boxlo, double *boxhi,
|
||||
double *xy, double *yz, double *xz,
|
||||
int *pflags, int *boxflag);
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#define STRINGIFY(val) XSTR(val)
|
||||
#define XSTR(val) #val
|
||||
|
||||
using ::LAMMPS_NS::bigint;
|
||||
using ::LAMMPS_NS::tagint;
|
||||
using ::LAMMPS_NS::platform::path_join;
|
||||
using ::testing::HasSubstr;
|
||||
@ -93,6 +94,9 @@ TEST_F(LibraryProperties, natoms)
|
||||
|
||||
TEST_F(LibraryProperties, thermo)
|
||||
{
|
||||
bigint bval = *(bigint *)lammps_last_thermo(lmp, "step", 0);
|
||||
EXPECT_EQ(bval, -1);
|
||||
|
||||
if (!lammps_has_style(lmp, "atom", "full")) GTEST_SKIP();
|
||||
std::string input = path_join(INPUT_DIR, "in.fourmol");
|
||||
::testing::internal::CaptureStdout();
|
||||
@ -105,6 +109,59 @@ TEST_F(LibraryProperties, thermo)
|
||||
EXPECT_DOUBLE_EQ(lammps_get_thermo(lmp, "vol"), 3375.0);
|
||||
EXPECT_DOUBLE_EQ(lammps_get_thermo(lmp, "density"), 0.12211250945013695);
|
||||
EXPECT_DOUBLE_EQ(lammps_get_thermo(lmp, "cellalpha"), 90.0);
|
||||
|
||||
bval = *(bigint *)lammps_last_thermo(lmp, "step", 0);
|
||||
EXPECT_EQ(bval, 2);
|
||||
int ival = *(int *)lammps_last_thermo(lmp, "num", 0);
|
||||
EXPECT_EQ(ival, 6);
|
||||
|
||||
const char *key = (const char *)lammps_last_thermo(lmp, "keyword", 0);
|
||||
EXPECT_THAT(key, StrEq("Step"));
|
||||
ival = *(int *)lammps_last_thermo(lmp, "type", 0);
|
||||
#if defined(LAMMPS_SMALLSMALL)
|
||||
EXPECT_EQ(ival, LAMMPS_INT);
|
||||
ival = *(int *)lammps_last_thermo(lmp, "data", 0);
|
||||
EXPECT_EQ(ival, 2);
|
||||
#else
|
||||
EXPECT_EQ(ival, LAMMPS_INT64);
|
||||
bval = *(bigint *)lammps_last_thermo(lmp, "data", 0);
|
||||
EXPECT_EQ(bval, 2);
|
||||
#endif
|
||||
|
||||
key = (const char *)lammps_last_thermo(lmp, "keyword", 1);
|
||||
EXPECT_THAT(key, StrEq("Temp"));
|
||||
ival = *(int *)lammps_last_thermo(lmp, "type", 1);
|
||||
EXPECT_EQ(ival, LAMMPS_DOUBLE);
|
||||
double dval = *(double *)lammps_last_thermo(lmp, "data", 1);
|
||||
EXPECT_DOUBLE_EQ(dval, 28.042780385852982);
|
||||
|
||||
key = (const char *)lammps_last_thermo(lmp, "keyword", 2);
|
||||
EXPECT_THAT(key, StrEq("E_pair"));
|
||||
ival = *(int *)lammps_last_thermo(lmp, "type", 2);
|
||||
EXPECT_EQ(ival, LAMMPS_DOUBLE);
|
||||
dval = *(double *)lammps_last_thermo(lmp, "data", 2);
|
||||
EXPECT_DOUBLE_EQ(dval, 0.0);
|
||||
|
||||
key = (const char *)lammps_last_thermo(lmp, "keyword", 3);
|
||||
EXPECT_THAT(key, StrEq("E_mol"));
|
||||
ival = *(int *)lammps_last_thermo(lmp, "type", 3);
|
||||
EXPECT_EQ(ival, LAMMPS_DOUBLE);
|
||||
dval = *(double *)lammps_last_thermo(lmp, "data", 3);
|
||||
EXPECT_DOUBLE_EQ(dval, 0.0);
|
||||
|
||||
key = (const char *)lammps_last_thermo(lmp, "keyword", 4);
|
||||
EXPECT_THAT(key, StrEq("TotEng"));
|
||||
ival = *(int *)lammps_last_thermo(lmp, "type", 4);
|
||||
EXPECT_EQ(ival, LAMMPS_DOUBLE);
|
||||
dval = *(double *)lammps_last_thermo(lmp, "data", 4);
|
||||
EXPECT_DOUBLE_EQ(dval, 2.3405256449146163);
|
||||
|
||||
key = (const char *)lammps_last_thermo(lmp, "keyword", 5);
|
||||
EXPECT_THAT(key, StrEq("Press"));
|
||||
ival = *(int *)lammps_last_thermo(lmp, "type", 5);
|
||||
EXPECT_EQ(ival, LAMMPS_DOUBLE);
|
||||
dval = *(double *)lammps_last_thermo(lmp, "data", 5);
|
||||
EXPECT_DOUBLE_EQ(dval, 31.700964689115658);
|
||||
};
|
||||
|
||||
TEST_F(LibraryProperties, box)
|
||||
@ -325,8 +382,8 @@ TEST_F(LibraryProperties, global)
|
||||
|
||||
EXPECT_EQ(lammps_extract_global_datatype(lmp, "special_lj"), LAMMPS_DOUBLE);
|
||||
EXPECT_EQ(lammps_extract_global_datatype(lmp, "special_coul"), LAMMPS_DOUBLE);
|
||||
double *special_lj = (double *)lammps_extract_global(lmp, "special_lj");
|
||||
double *special_coul= (double *)lammps_extract_global(lmp, "special_coul");
|
||||
double *special_lj = (double *)lammps_extract_global(lmp, "special_lj");
|
||||
double *special_coul = (double *)lammps_extract_global(lmp, "special_coul");
|
||||
EXPECT_DOUBLE_EQ(special_lj[0], 1.0);
|
||||
EXPECT_DOUBLE_EQ(special_lj[1], 0.0);
|
||||
EXPECT_DOUBLE_EQ(special_lj[2], 0.5);
|
||||
|
||||
@ -533,6 +533,33 @@ create_atoms 1 single &
|
||||
result = self.lmp.get_thermo(key)
|
||||
self.assertEqual(value, result, key)
|
||||
|
||||
|
||||
def test_last_thermo(self):
|
||||
self.lmp.command("units lj")
|
||||
self.lmp.command("atom_style atomic")
|
||||
self.lmp.command("atom_modify map array")
|
||||
self.lmp.command("boundary f f f")
|
||||
self.lmp.command("region box block 0 2 0 2 0 2")
|
||||
self.lmp.command("create_box 1 box")
|
||||
self.lmp.command("mass * 1")
|
||||
|
||||
x = [
|
||||
0.5, 0.5, 0.5,
|
||||
1.5, 1.5, 1.5
|
||||
]
|
||||
types = [1, 1]
|
||||
self.lmp.create_atoms(2, id=None, type=types, x=x)
|
||||
|
||||
self.assertEqual(self.lmp.last_thermo(), None)
|
||||
self.lmp.command("run 2 post no")
|
||||
ref = { "Step" : 2,
|
||||
"Temp" : 0.0,
|
||||
"E_pair" : 0.0,
|
||||
"E_mol" : 0.0,
|
||||
"TotEng" : 0.0,
|
||||
"Press" : 0.0}
|
||||
self.assertDictEqual(self.lmp.last_thermo(), ref)
|
||||
|
||||
def test_extract_global(self):
|
||||
self.lmp.command("region box block -1 1 -2 2 -3 3")
|
||||
self.lmp.command("create_box 1 box")
|
||||
|
||||
@ -7,6 +7,10 @@ add_executable(test_mempool test_mempool.cpp)
|
||||
target_link_libraries(test_mempool PRIVATE lammps GTest::GMockMain)
|
||||
add_test(NAME MemPool COMMAND test_mempool)
|
||||
|
||||
add_executable(test_lmptype test_lmptype.cpp)
|
||||
target_link_libraries(test_lmptype PRIVATE lammps GTest::GMockMain)
|
||||
add_test(NAME LmpType COMMAND test_lmptype)
|
||||
|
||||
add_executable(test_argutils test_argutils.cpp)
|
||||
target_link_libraries(test_argutils PRIVATE lammps GTest::GMockMain)
|
||||
add_test(NAME ArgUtils COMMAND test_argutils)
|
||||
|
||||
79
unittest/utils/test_lmptype.cpp
Normal file
79
unittest/utils/test_lmptype.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
LAMMPS Development team: developers@lammps.org
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "lmptype.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
TEST(Types, ubuf)
|
||||
{
|
||||
double buf[3];
|
||||
double d1 = 0.1;
|
||||
int i1 = -10;
|
||||
#if defined(LAMMPS_SMALLSMALL)
|
||||
bigint b1 = 2048;
|
||||
#else
|
||||
bigint b1 = (1L << 58) + (1L << 50);
|
||||
#endif
|
||||
buf[0] = d1;
|
||||
buf[1] = ubuf(i1).d;
|
||||
buf[2] = ubuf(b1).d;
|
||||
|
||||
EXPECT_EQ(d1, buf[0]);
|
||||
EXPECT_EQ(i1, (int)ubuf(buf[1]).i);
|
||||
EXPECT_EQ(b1, (bigint)ubuf(buf[2]).i);
|
||||
}
|
||||
|
||||
TEST(Types, multitype)
|
||||
{
|
||||
multitype m[7];
|
||||
int64_t b1 = (3L << 48) - 1;
|
||||
int i1 = 20;
|
||||
double d1 = 0.1;
|
||||
|
||||
m[0] = b1;
|
||||
m[1] = i1;
|
||||
m[2] = d1;
|
||||
|
||||
m[3] = (bigint) -((1L << 40) + (1L << 50));
|
||||
m[4] = -1023;
|
||||
m[5] = -2.225;
|
||||
|
||||
EXPECT_EQ(m[0].type, multitype::BIGINT);
|
||||
EXPECT_EQ(m[1].type, multitype::INT);
|
||||
EXPECT_EQ(m[2].type, multitype::DOUBLE);
|
||||
|
||||
#if defined(LAMMPS_SMALLSMALL)
|
||||
EXPECT_EQ(m[3].type, multitype::INT);
|
||||
#else
|
||||
EXPECT_EQ(m[3].type, multitype::BIGINT);
|
||||
#endif
|
||||
EXPECT_EQ(m[4].type, multitype::INT);
|
||||
EXPECT_EQ(m[5].type, multitype::DOUBLE);
|
||||
EXPECT_EQ(m[6].type, multitype::NONE);
|
||||
|
||||
EXPECT_EQ(m[0].data.b, b1);
|
||||
EXPECT_EQ(m[1].data.i, i1);
|
||||
EXPECT_EQ(m[2].data.d, d1);
|
||||
|
||||
#if !defined(LAMMPS_SMALLSMALL)
|
||||
EXPECT_EQ(m[3].data.b, -((1L << 40) + (1L << 50)));
|
||||
#endif
|
||||
EXPECT_EQ(m[4].data.i, -1023);
|
||||
EXPECT_EQ(m[5].data.d, -2.225);
|
||||
}
|
||||
Reference in New Issue
Block a user