diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index 6f87b8c97a..53dc5b8897 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -323,6 +323,12 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS. :ftype set_internal_variable: subroutine :f eval: :f:func:`eval` :ftype eval: function + :f clearstep_compute: :f:subr:`clearstep_compute` + :ftype clearstep_compute: subroutine + :f addstep_compute: :f:subr:`addstep_compute` + :ftype addstep_compute: subroutine + :f addstep_compute_all: :f:subr:`addstep_compute_all` + :ftype addstep_compute_all: subroutine :f gather_atoms: :f:subr:`gather_atoms` :ftype gather_atoms: subroutine :f gather_atoms_concat: :f:subr:`gather_atoms_concat` @@ -1453,11 +1459,62 @@ Procedures Bound to the :f:type:`lammps` Derived Type an internal-style variable, an error is generated. :p character(len=*) name: name of the variable - :p read(c_double) val: new value to assign to the variable + :p real(c_double) val: new value to assign to the variable :to: :cpp:func:`lammps_set_internal_variable` -------- +.. f:function:: eval(expr) + + This function is a wrapper around :cpp:func:`lammps_eval` that takes a + LAMMPS equal style variable string, evaluates it and returns the resulting + scalar value as a floating-point number. + + .. versionadded:: TBD + + :p character(len=\*) expr: string to be evaluated + :to: :cpp:func:`lammps_eval` + :r value [real(c_double)]: result of the evaluated string + +-------- + +.. f:subroutine:: clearstep_compute() + + Clear whether a compute has been invoked + + .. versionadded:: TBD + + :to: :cpp:func:`lammps_clearstep_compute` + +-------- + +.. f:subroutine:: addstep_compute(nextstep) + + Add timestep to list of future compute invocations + if the compute has been invoked on the current timestep + + .. versionadded:: TBD + + overloaded for 32-bit and 64-bit integer arguments + + :p integer(kind=8 or kind=4) nextstep: next timestep + :to: :cpp:func:`lammps_addstep_compute` + +-------- + +.. f:subroutine:: addstep_compute_all(nextstep) + + Add timestep to list of future compute invocations + + .. versionadded:: TBD + + overloaded for 32-bit and 64-bit integer arguments + + :p integer(kind=8 or kind=4) nextstep: next timestep + :to: :cpp:func:`lammps_addstep_compute_all` + +-------- + .. f:subroutine:: gather_atoms(name, count, data) This function calls :cpp:func:`lammps_gather_atoms` to gather the named diff --git a/doc/src/Library_objects.rst b/doc/src/Library_objects.rst index 53edfce9e6..86b6d253f0 100644 --- a/doc/src/Library_objects.rst +++ b/doc/src/Library_objects.rst @@ -13,6 +13,9 @@ fixes, or variables in LAMMPS using the following functions: - :cpp:func:`lammps_set_internal_variable` - :cpp:func:`lammps_variable_info` - :cpp:func:`lammps_eval` +- :cpp:func:`lammps_clearstep_compute` +- :cpp:func:`lammps_addstep_compute_all` +- :cpp:func:`lammps_addstep_compute` ----------------------- @@ -61,6 +64,21 @@ fixes, or variables in LAMMPS using the following functions: ----------------------- +.. doxygenfunction:: lammps_clearstep_compute + :project: progguide + +----------------------- + +.. doxygenfunction:: lammps_addstep_compute_all + :project: progguide + +----------------------- + +.. doxygenfunction:: lammps_addstep_compute + :project: progguide + +----------------------- + .. doxygenenum:: _LMP_DATATYPE_CONST .. doxygenenum:: _LMP_STYLE_CONST diff --git a/doc/src/fix_python_invoke.rst b/doc/src/fix_python_invoke.rst index ad55882270..4f33f5483b 100644 --- a/doc/src/fix_python_invoke.rst +++ b/doc/src/fix_python_invoke.rst @@ -66,6 +66,15 @@ gives access to the LAMMPS state from Python. from these callbacks, trying to execute input script commands will in the best case not work or in the worst case result in undefined behavior. +Restart, fix_modify, output, run start/stop, minimize info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +No information about this fix is written to :doc:`binary restart files `. None of the :doc:`fix_modify ` options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various :doc:`output commands `. +No parameter of this fix can be used with the *start/stop* keywords of +the :doc:`run ` command. This fix is not invoked during :doc:`energy minimization `. + Restrictions """""""""""" diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 0f14ecc966..f9fb3a0f8a 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2535,6 +2535,7 @@ Nevery Nevins newfile Newns +newstep newtype nextsort Neyts @@ -3773,6 +3774,7 @@ Tigran Tij Tildesley Timan +timeflag timeI timespan timestamp diff --git a/examples/COUPLE/plugin/liblammpsplugin.c b/examples/COUPLE/plugin/liblammpsplugin.c index 99e38df32b..619b8828fc 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.c +++ b/examples/COUPLE/plugin/liblammpsplugin.c @@ -118,6 +118,9 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib) ADDSYM(set_internal_variable); ADDSYM(variable_info); ADDSYM(eval); + ADDSYM(clearstep_compute); + ADDSYM(addstep_compute); + ADDSYM(addstep_compute_all); ADDSYM(gather_atoms); ADDSYM(gather_atoms_concat); diff --git a/examples/COUPLE/plugin/liblammpsplugin.h b/examples/COUPLE/plugin/liblammpsplugin.h index dd1c9628f5..c765b0adc3 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.h +++ b/examples/COUPLE/plugin/liblammpsplugin.h @@ -164,6 +164,9 @@ struct _liblammpsplugin { int (*set_internal_variable)(void *, const char *, double); int (*variable_info)(void *, int, char *, int); double (*eval)(void *, const char *); + void (*clearstep_compute)(void *); + void (*addstep_compute)(void *, void *); + void (*addstep_compute_all)(void *, void *); void (*gather_atoms)(void *, const char *, int, int, void *); void (*gather_atoms_concat)(void *, const char *, int, int, void *); diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index 552b3dfad3..2cfd4422b0 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -127,6 +127,16 @@ MODULE LIBLAMMPS PROCEDURE :: set_string_variable => lmp_set_string_variable PROCEDURE :: set_internal_variable => lmp_set_internal_variable PROCEDURE :: eval => lmp_eval + + PROCEDURE :: clearstep_compute => lmp_clearstep_compute + PROCEDURE, PRIVATE :: lmp_addstep_compute_smallint + PROCEDURE, PRIVATE :: lmp_addstep_compute_bigint + GENERIC :: addstep_compute => lmp_addstep_compute_smallint, lmp_addstep_compute_bigint + PROCEDURE, PRIVATE :: lmp_addstep_compute_all_smallint + PROCEDURE, PRIVATE :: lmp_addstep_compute_all_bigint + GENERIC :: addstep_compute_all => lmp_addstep_compute_all_smallint, & + lmp_addstep_compute_all_bigint + PROCEDURE, PRIVATE :: lmp_gather_atoms_int PROCEDURE, PRIVATE :: lmp_gather_atoms_double GENERIC :: gather_atoms => lmp_gather_atoms_int, & @@ -626,6 +636,24 @@ MODULE LIBLAMMPS REAL(c_double) :: lammps_eval END FUNCTION lammps_eval + SUBROUTINE lammps_clearstep_compute(handle) BIND(C) + IMPORT :: c_ptr + IMPLICIT NONE + TYPE(c_ptr), VALUE :: handle + END SUBROUTINE lammps_clearstep_compute + + SUBROUTINE lammps_addstep_compute(handle, step) BIND(C) + IMPORT :: c_ptr + IMPLICIT NONE + TYPE(c_ptr), VALUE :: handle, step + END SUBROUTINE lammps_addstep_compute + + SUBROUTINE lammps_addstep_compute_all(handle, step) BIND(C) + IMPORT :: c_ptr + IMPLICIT NONE + TYPE(c_ptr), VALUE :: handle, step + END SUBROUTINE lammps_addstep_compute_all + SUBROUTINE lammps_gather_atoms(handle, name, TYPE, count, DATA) BIND(C) IMPORT :: c_int, c_ptr IMPLICIT NONE @@ -1846,6 +1874,80 @@ CONTAINS CALL lammps_free(Cexpr) END FUNCTION lmp_eval + ! equivalent subroutine to lammps_clearstep_compute + SUBROUTINE lmp_clearstep_compute(self) + CLASS(lammps), INTENT(IN) :: self + CALL lammps_clearstep_compute(self%handle) + END SUBROUTINE lmp_clearstep_compute + + ! equivalent subroutine to lammps_addstep_compute + SUBROUTINE lmp_addstep_compute_bigint(self, nextstep) + CLASS(lammps), INTENT(IN) :: self + INTEGER(kind=8), INTENT(IN) :: nextstep + INTEGER(c_int), TARGET :: smallstep + INTEGER(c_int64_t), TARGET :: bigstep + TYPE(c_ptr) :: ptrstep + IF (SIZE_BIGINT == 4_c_int) THEN + smallstep = INT(nextstep,kind=c_int) + ptrstep = C_LOC(smallstep) + ELSE + bigstep = nextstep + ptrstep = C_LOC(bigstep) + END IF + CALL lammps_addstep_compute(self%handle, ptrstep) + END SUBROUTINE lmp_addstep_compute_bigint + + ! equivalent subroutine to lammps_addstep_compute + SUBROUTINE lmp_addstep_compute_smallint(self, nextstep) + CLASS(lammps), INTENT(IN) :: self + INTEGER(kind=4), INTENT(IN) :: nextstep + INTEGER(c_int), TARGET :: smallstep + INTEGER(c_int64_t), TARGET :: bigstep + TYPE(c_ptr) :: ptrstep + IF (SIZE_BIGINT == 4_c_int) THEN + smallstep = nextstep + ptrstep = C_LOC(smallstep) + ELSE + bigstep = nextstep + ptrstep = C_LOC(bigstep) + END IF + CALL lammps_addstep_compute(self%handle, ptrstep) + END SUBROUTINE lmp_addstep_compute_smallint + + ! equivalent subroutine to lammps_addstep_compute_all + SUBROUTINE lmp_addstep_compute_all_bigint(self, nextstep) + CLASS(lammps), INTENT(IN) :: self + INTEGER(kind=8), INTENT(IN) :: nextstep + INTEGER(c_int), TARGET :: smallstep + INTEGER(c_int64_t), TARGET :: bigstep + TYPE(c_ptr) :: ptrstep + IF (SIZE_BIGINT == 4_c_int) THEN + smallstep = INT(nextstep,kind=c_int) + ptrstep = C_LOC(smallstep) + ELSE + bigstep = nextstep + ptrstep = C_LOC(bigstep) + END IF + CALL lammps_addstep_compute_all(self%handle, ptrstep) + END SUBROUTINE lmp_addstep_compute_all_bigint + + ! equivalent subroutine to lammps_addstep_compute_all + SUBROUTINE lmp_addstep_compute_all_smallint(self, nextstep) + CLASS(lammps), INTENT(IN) :: self + INTEGER(kind=4), INTENT(IN) :: nextstep + INTEGER(c_int), TARGET :: smallstep + INTEGER(c_int64_t), TARGET :: bigstep + TYPE(c_ptr) :: ptrstep + IF (SIZE_BIGINT == 4_c_int) THEN + smallstep = nextstep + ptrstep = C_LOC(smallstep) + ELSE + bigstep = nextstep + ptrstep = C_LOC(bigstep) + END IF + CALL lammps_addstep_compute_all(self%handle, ptrstep) + END SUBROUTINE lmp_addstep_compute_all_smallint + ! equivalent function to lammps_gather_atoms (for integers) SUBROUTINE lmp_gather_atoms_int(self, name, count, data) CLASS(lammps), INTENT(IN) :: self diff --git a/python/lammps/core.py b/python/lammps/core.py index 89a3dd2bf0..089517bab7 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -422,6 +422,10 @@ class lammps(object): self.lib.lammps_extract_variable_datatype.argtypes = [c_void_p, c_char_p] self.lib.lammps_extract_variable_datatype.restype = c_int + self.lib.lammps_clearstep_compute.argtype = [c_void_p] + self.lib.lammps_addstep_compute.argtype = [c_void_p, c_void_p] + self.lib.lammps_addstep_compute_all.argtype = [c_void_p, c_void_p] + self.lib.lammps_eval.argtypes = [c_void_p, c_char_p] self.lib.lammps_eval.restype = c_double @@ -1594,6 +1598,26 @@ class lammps(object): # ------------------------------------------------------------------------- + def clearstep_compute(self, nextstep): + with ExceptionCheck(self): + return self.lib.lammps_clearstep_compute(self.lmp) + + # ------------------------------------------------------------------------- + + def addstep_compute(self, nextstep): + with ExceptionCheck(self): + nextstep = self.c_bigint(nextstep) + return self.lib.lammps_addstep_compute(self.lmp, POINTER(nextstep)) + + # ------------------------------------------------------------------------- + + def addstep_compute_all(self, nextstep): + with ExceptionCheck(self): + nextstep = self.c_bigint(nextstep) + return self.lib.lammps_addstep_compute_all(self.lmp, POINTER(nextstep)) + + # ------------------------------------------------------------------------- + def flush_buffers(self): """Flush output buffers diff --git a/src/PYTHON/fix_python_invoke.cpp b/src/PYTHON/fix_python_invoke.cpp index 7fd3ad88f7..6f27831438 100644 --- a/src/PYTHON/fix_python_invoke.cpp +++ b/src/PYTHON/fix_python_invoke.cpp @@ -22,6 +22,7 @@ #include "lmppython.h" #include "python_compat.h" #include "python_utils.h" +#include "modify.h" #include "update.h" #include @@ -70,6 +71,12 @@ FixPythonInvoke::FixPythonInvoke(LAMMPS *lmp, int narg, char **arg) : } lmpPtr = PY_VOID_POINTER(lmp); + + // nvalid = next step on which end_of_step or post_force does something + // add nextvalid() to all computes that store invocation times + // since we don't know a priori which are invoked by python code + nvalid = nextvalid(); + modify->addstep_compute_all(nvalid); } /* ---------------------------------------------------------------------- */ @@ -89,8 +96,23 @@ int FixPythonInvoke::setmask() /* ---------------------------------------------------------------------- */ +void FixPythonInvoke::init() +{ + // need to reset nvalid if nvalid < ntimestep b/c minimize was performed + + if (nvalid < update->ntimestep) { + nvalid = nextvalid(); + modify->addstep_compute_all(nvalid); + } +} + +/* ---------------------------------------------------------------------- */ + void FixPythonInvoke::end_of_step() { + // python code may invoke computes so wrap with clear/add + modify->clearstep_compute(); + PyUtils::GIL lock; PyObject * result = PyObject_CallFunction((PyObject*)pFunc, (char *)"O", (PyObject*)lmpPtr); @@ -101,6 +123,9 @@ void FixPythonInvoke::end_of_step() } Py_CLEAR(result); + + nvalid = nextvalid(); + modify->addstep_compute(nvalid); } /* ---------------------------------------------------------------------- */ @@ -116,6 +141,9 @@ void FixPythonInvoke::post_force(int vflag) { if (update->ntimestep % nevery != 0) return; + // python code may invoke computes so wrap with clear/add + modify->clearstep_compute(); + PyUtils::GIL lock; char fmt[] = "Oi"; @@ -127,4 +155,14 @@ void FixPythonInvoke::post_force(int vflag) } Py_CLEAR(result); + + nvalid = nextvalid(); + modify->addstep_compute(nvalid); +} + +/* ---------------------------------------------------------------------- */ + +bigint FixPythonInvoke::nextvalid() +{ + return (update->ntimestep/nevery + 1)*nevery; } diff --git a/src/PYTHON/fix_python_invoke.h b/src/PYTHON/fix_python_invoke.h index 09382e5780..fdb931b69c 100644 --- a/src/PYTHON/fix_python_invoke.h +++ b/src/PYTHON/fix_python_invoke.h @@ -31,6 +31,7 @@ class FixPythonInvoke : public Fix { ~FixPythonInvoke() override; int setmask() override; void setup(int) override; + void init() override; void end_of_step() override; void post_force(int) override; @@ -38,6 +39,8 @@ class FixPythonInvoke : public Fix { void *lmpPtr; void *pFunc; int selected_callback; + bigint nextvalid(); + bigint nvalid; }; } // namespace LAMMPS_NS diff --git a/src/library.cpp b/src/library.cpp index 2cd9879e76..07ed9184bc 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2925,6 +2925,8 @@ int lammps_variable_info(void *handle, int idx, char *buffer, int buf_size) { return 0; } +/* ---------------------------------------------------------------------- */ + /** Evaluate an immediate variable expression * \verbatim embed:rst @@ -2958,6 +2960,86 @@ double lammps_eval(void *handle, const char *expr) return result; } +/* ---------------------------------------------------------------------- */ + +/** Clear whether a compute has been invoked. + * +\verbatim embed:rst + +.. versionadded:: TBD + + This function clears the invoked flag of all computes. + Called everywhere that computes are used, before computes are invoked. + The invoked flag is used to avoid re-invoking same compute multiple times + and to flag computes that store invocation times as having been invoked + +*See also* + :cpp:func:`lammps_addstep_compute_all` + :cpp:func:`lammps_addstep_compute` + +\endverbatim + + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + */ +void lammps_clearstep_compute(void *handle) { + auto lmp = (LAMMPS *) handle; + lmp->modify->clearstep_compute(); +} + +/* ---------------------------------------------------------------------- */ + +/** Add next timestep to all computes + * +\verbatim embed:rst + +.. versionadded:: TBD + + loop over all computes + schedule next invocation for those that store invocation times + called when not sure what computes will be needed on newstep + do not loop only over n_timeflag, since may not be set yet + +*See also* + :cpp:func:`lammps_clearstep_compute` + :cpp:func:`lammps_addstep_compute` + +\endverbatim + + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param newstep pointer to bigint of next timestep the compute will be invoked + */ +void lammps_addstep_compute_all(void *handle, void *newstep) { + auto lmp = (LAMMPS *) handle; + auto ns = (bigint *) newstep; + if (lmp && lmp->modify && ns) lmp->modify->addstep_compute_all(*ns); +} +/* ---------------------------------------------------------------------- */ + +/** Add next timestep to compute if it has been invoked in the current timestep + * +\verbatim embed:rst + +.. versionadded:: TBD + + loop over computes that store invocation times + if its invoked flag set on this timestep, schedule next invocation + called everywhere that computes are used, after computes are invoked + +*See also* + :cpp:func:`lammps_addstep_compute_all` + :cpp:func:`lammps_clearstep_compute` + +\endverbatim + + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param newstep next timestep the compute will be invoked + */ +void lammps_addstep_compute(void *handle, void *newstep) { + auto lmp = (LAMMPS *) handle; + auto ns = (bigint *) newstep; + if (lmp && lmp->modify && ns) lmp->modify->addstep_compute(*ns); +} + // ---------------------------------------------------------------------- // Library functions for scatter/gather operations of data // ---------------------------------------------------------------------- diff --git a/src/library.h b/src/library.h index f64ae9e7c2..99b251ee85 100644 --- a/src/library.h +++ b/src/library.h @@ -191,6 +191,10 @@ int lammps_set_internal_variable(void *handle, const char *name, double value); int lammps_variable_info(void *handle, int idx, char *buf, int bufsize); double lammps_eval(void *handle, const char *expr); +void lammps_clearstep_compute(void *handle); +void lammps_addstep_compute_all(void *handle, void * nextstep); +void lammps_addstep_compute(void *handle, void * nextstep); + /* ---------------------------------------------------------------------- * Library functions for scatter/gather operations of data * ---------------------------------------------------------------------- */ diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index bc9f46f407..476e6ad17d 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -143,6 +143,9 @@ extern int lammps_set_string_variable(void *, const char *, const char *); extern int lammps_set_internal_variable(void *, const char *, double); extern int lammps_variable_info(void *handle, int idx, char *buf, int bufsize); extern double lammps_eval(void *handle, const char *expr); +extern void lammps_clearstep_compute(void *handle); +extern void lammps_addstep_compute(void *handle, void *nstep); +extern void lammps_addstep_compute_all(void *handle, void *nstep); extern void lammps_gather_atoms(void *, char *, int, int, void *); extern void lammps_gather_atoms_concat(void *, char *, int, int, void *); @@ -336,6 +339,9 @@ extern int lammps_set_string_variable(void *, const char *, const char *); extern int lammps_set_internal_variable(void *, const char *, double); extern int lammps_variable_info(void *handle, int idx, char *buf, int bufsize); extern double lammps_eval(void *handle, const char *expr); +extern void lammps_clearstep_compute(void *handle); +extern void lammps_addstep_compute(void *handle, void *nstep); +extern void lammps_addstep_compute_all(void *handle, void *nstep); extern void lammps_gather_atoms(void *, char *, int, int, void *); extern void lammps_gather_atoms_concat(void *, char *, int, int, void *); diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index 737015ccdc..1feccf5cb0 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -3,9 +3,12 @@ #include "library.h" #include "atom.h" +#include "compute.h" #include "lammps.h" #include "lmptype.h" +#include "modify.h" #include "platform.h" + #include #include @@ -668,6 +671,77 @@ TEST_F(LibraryProperties, neighlist) } }; +static constexpr char lj_setup[] = "lattice fcc 0.8442\n" + "region box block 0 10 0 10 0 10\n" + "create_box 1 box\n" + "create_atoms 1 box\n" + "mass 1 1.0\n" + "pair_style lj/cut 2.5\n" + "pair_coeff 1 1 1.0 1.0\n" + "fix 1 all nve\n"; + +TEST_F(LibraryProperties, step_compute) +{ + ::testing::internal::CaptureStdout(); + lammps_commands_string(lmp, lj_setup); + lammps_command(lmp, "compute pr all pressure thermo_temp"); + lammps_command(lmp, "fix av all ave/time 2 1 2 c_pr mode scalar"); + lammps_command(lmp, "run 2 post no"); + std::string output = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << output; + if (lammps_has_error(lmp)) { + char buf[2048]; + lammps_get_last_error_message(lmp, buf, 2048); + FAIL() << buf << "\n"; + } + auto lammps = (LAMMPS_NS::LAMMPS *)lmp; + auto icomp = lammps->modify->get_compute_by_id("pr"); + EXPECT_EQ(icomp->ntime, 2); + EXPECT_EQ(icomp->tlist[0], 4); + EXPECT_EQ(icomp->tlist[1], 2); + EXPECT_EQ(icomp->invoked_flag, 0); + EXPECT_EQ(icomp->invoked_scalar, 2); + EXPECT_EQ(icomp->invoked_vector, -1); + lammps_clearstep_compute(lmp); + EXPECT_EQ(icomp->invoked_flag, 0); + EXPECT_EQ(icomp->invoked_scalar, 2); + EXPECT_EQ(icomp->invoked_vector, -1); + bigint nextstep = 6; + lammps_addstep_compute(lmp, (void *)&nextstep); + EXPECT_EQ(icomp->ntime, 3); + EXPECT_EQ(icomp->tlist[0], 6); + EXPECT_EQ(icomp->tlist[1], 4); + EXPECT_EQ(icomp->tlist[2], 2); + EXPECT_EQ(icomp->invoked_flag, 0); + EXPECT_EQ(icomp->invoked_scalar, 2); + EXPECT_EQ(icomp->invoked_vector, -1); + lammps_command(lmp, "run 4 post no"); + EXPECT_EQ(icomp->ntime, 2); + EXPECT_EQ(icomp->tlist[0], 8); + EXPECT_EQ(icomp->tlist[1], 6); + EXPECT_EQ(icomp->invoked_flag, 0); + EXPECT_EQ(icomp->invoked_scalar, 6); + EXPECT_EQ(icomp->invoked_vector, -1); + lammps_command(lmp, "run 2 post no"); + EXPECT_EQ(icomp->ntime, 2); + EXPECT_EQ(icomp->tlist[0], 10); + EXPECT_EQ(icomp->tlist[1], 8); + EXPECT_EQ(icomp->invoked_flag, 0); + EXPECT_EQ(icomp->invoked_scalar, 8); + EXPECT_EQ(icomp->invoked_vector, -1); + nextstep = 9; + lammps_addstep_compute(lmp, (void *)&nextstep); + lammps_command(lmp, "run 1 post no"); + EXPECT_EQ(icomp->ntime, 2); + EXPECT_EQ(icomp->tlist[0], 10); + EXPECT_EQ(icomp->tlist[1], 9); + EXPECT_EQ(icomp->invoked_flag, 0); + EXPECT_EQ(icomp->invoked_scalar, -1); + EXPECT_EQ(icomp->invoked_vector, -1); + icomp->compute_scalar(); + EXPECT_EQ(icomp->invoked_scalar, 9); +} + TEST_F(LibraryProperties, has_error) { EXPECT_EQ(lammps_has_error(lmp), 0);