From 0fa1255cc33804e275f71efc68b91a69d7011f3d Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Tue, 12 Nov 2024 09:38:16 -0700 Subject: [PATCH 01/14] fix python/invoke: ensure computes have run --- src/PYTHON/fix_python_invoke.cpp | 18 ++++++++++++++++++ src/PYTHON/fix_python_invoke.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/PYTHON/fix_python_invoke.cpp b/src/PYTHON/fix_python_invoke.cpp index 7fd3ad88f7..b47a94c6c7 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,8 @@ FixPythonInvoke::FixPythonInvoke(LAMMPS *lmp, int narg, char **arg) : } lmpPtr = PY_VOID_POINTER(lmp); + + modify->addstep_compute_all(nextvalid()); } /* ---------------------------------------------------------------------- */ @@ -91,6 +94,8 @@ int FixPythonInvoke::setmask() void FixPythonInvoke::end_of_step() { + modify->clearstep_compute(); + PyUtils::GIL lock; PyObject * result = PyObject_CallFunction((PyObject*)pFunc, (char *)"O", (PyObject*)lmpPtr); @@ -101,6 +106,8 @@ void FixPythonInvoke::end_of_step() } Py_CLEAR(result); + + modify->addstep_compute(nextvalid()); } /* ---------------------------------------------------------------------- */ @@ -116,6 +123,8 @@ void FixPythonInvoke::post_force(int vflag) { if (update->ntimestep % nevery != 0) return; + modify->clearstep_compute(); + PyUtils::GIL lock; char fmt[] = "Oi"; @@ -127,4 +136,13 @@ void FixPythonInvoke::post_force(int vflag) } Py_CLEAR(result); + + modify->addstep_compute(nextvalid()); +} + +/* ---------------------------------------------------------------------- */ + +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..3d2324a939 100644 --- a/src/PYTHON/fix_python_invoke.h +++ b/src/PYTHON/fix_python_invoke.h @@ -38,6 +38,7 @@ class FixPythonInvoke : public Fix { void *lmpPtr; void *pFunc; int selected_callback; + bigint nextvalid(); }; } // namespace LAMMPS_NS From 83a73ba0b91c8a9f7bac9a1a50a7598d7a19d96e Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Tue, 12 Nov 2024 13:43:22 -0700 Subject: [PATCH 02/14] library: add API for compute clearstep and addstep --- python/lammps/core.py | 22 ++++++++++++ src/library.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++ src/library.h | 9 +++++ 3 files changed, 112 insertions(+) diff --git a/python/lammps/core.py b/python/lammps/core.py index 30df44f050..045d893448 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -339,6 +339,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_compute_clearstep.argtype = [c_void_p] + self.lib.lammps_compute_addstep.argtype = [c_void_p, self.c_bigint] + self.lib.lammps_compute_addstep_all.argtype = [c_void_p, self.c_bigint] + self.lib.lammps_fix_external_get_force.argtypes = [c_void_p, c_char_p] self.lib.lammps_fix_external_get_force.restype = POINTER(POINTER(c_double)) @@ -1453,6 +1457,24 @@ class lammps(object): # ------------------------------------------------------------------------- + def compute_clearstep(self, nextstep): + with ExceptionCheck(self): + return self.lib.lammps_compute_clearstep(self.lmp) + + # ------------------------------------------------------------------------- + + def compute_addstep(self, nextstep): + with ExceptionCheck(self): + return self.lib.lammps_compute_addstep(self.lmp, nextstep) + + # ------------------------------------------------------------------------- + + def compute_addstep_all(self, nextstep): + with ExceptionCheck(self): + return self.lib.lammps_compute_addstep_all(self.lmp, nextstep) + + # ------------------------------------------------------------------------- + def flush_buffers(self): """Flush output buffers diff --git a/src/library.cpp b/src/library.cpp index 9876d363e5..89c6e92bbd 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2904,6 +2904,87 @@ int lammps_variable_info(void *handle, int idx, char *buffer, int buf_size) { return 0; } +/* ---------------------------------------------------------------------- */ + +/** 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 + +\endverbatim + + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + */ +void lammps_compute_clearstep(void * handle) { + auto lmp = (LAMMPS *) handle; + + BEGIN_CAPTURE + { + lmp->modify->clearstep_compute(); + } + END_CAPTURE +} + +/* ---------------------------------------------------------------------- */ + +/** 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 + +\endverbatim + + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param newstep next timestep the compute will be invoked + */ +void lammps_compute_addstep_all(void * handle, bigint newstep) { + auto lmp = (LAMMPS *) handle; + + BEGIN_CAPTURE + { + lmp->modify->addstep_compute_all(newstep); + } + END_CAPTURE +} +/* ---------------------------------------------------------------------- */ + +/** 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 + +\endverbatim + + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param newstep next timestep the compute will be invoked + */ +void lammps_compute_addstep(void * handle, bigint newstep) { + auto lmp = (LAMMPS *) handle; + + BEGIN_CAPTURE + { + lmp->modify->addstep_compute(newstep); + } + END_CAPTURE +} + // ---------------------------------------------------------------------- // Library functions for scatter/gather operations of data // ---------------------------------------------------------------------- diff --git a/src/library.h b/src/library.h index 36e67470ae..b1213b67c8 100644 --- a/src/library.h +++ b/src/library.h @@ -190,6 +190,15 @@ int lammps_set_string_variable(void *handle, const char *name, const char *str); int lammps_set_internal_variable(void *handle, const char *name, double value); int lammps_variable_info(void *handle, int idx, char *buf, int bufsize); +void lammps_compute_clearstep(void * handle); +#if defined(LAMMPS_SMALLSMALL) +void lammps_compute_addstep_all(void * handle, int nextstep); +void lammps_compute_addstep(void * handle, int nextstep); +#else +void lammps_compute_addstep_all(void * handle, int64_t nextstep); +void lammps_compute_addstep(void * handle, int64_t nextstep); +#endif + /* ---------------------------------------------------------------------- * Library functions for scatter/gather operations of data * ---------------------------------------------------------------------- */ From 783d21c19b2b988c16a91dcadf294a885026c89a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 14 Jan 2025 00:55:48 -0500 Subject: [PATCH 03/14] these functions do not create errors or throw exceptions --- src/library.cpp | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index 71243611a2..17225fec40 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2979,12 +2979,7 @@ double lammps_eval(void *handle, const char *expr) */ void lammps_compute_clearstep(void * handle) { auto lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { - lmp->modify->clearstep_compute(); - } - END_CAPTURE + lmp->modify->clearstep_compute(); } /* ---------------------------------------------------------------------- */ @@ -3007,12 +3002,7 @@ void lammps_compute_clearstep(void * handle) { */ void lammps_compute_addstep_all(void * handle, bigint newstep) { auto lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { - lmp->modify->addstep_compute_all(newstep); - } - END_CAPTURE + lmp->modify->addstep_compute_all(newstep); } /* ---------------------------------------------------------------------- */ @@ -3033,12 +3023,7 @@ void lammps_compute_addstep_all(void * handle, bigint newstep) { */ void lammps_compute_addstep(void * handle, bigint newstep) { auto lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { - lmp->modify->addstep_compute(newstep); - } - END_CAPTURE + lmp->modify->addstep_compute(newstep); } // ---------------------------------------------------------------------- From e682f3d3e5a94cda53163e37022726c2624160a2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 14 Jan 2025 01:18:59 -0500 Subject: [PATCH 04/14] work on docs --- doc/src/Library_objects.rst | 18 ++++++++++++++++++ src/library.cpp | 12 ++++++++++++ src/library.h | 10 +++++----- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/doc/src/Library_objects.rst b/doc/src/Library_objects.rst index 53edfce9e6..bea5dec167 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_compute_clearstep` +- :cpp:func:`lammps_compute_addstep_all` +- :cpp:func:`lammps_compute_addstep` ----------------------- @@ -61,6 +64,21 @@ fixes, or variables in LAMMPS using the following functions: ----------------------- +.. doxygenfunction:: lammps_compute_clearstep + :project: progguide + +----------------------- + +.. doxygenfunction:: lammps_compute_addstep_all(void *handle, int nextstep) + :project: progguide + +----------------------- + +.. doxygenfunction:: lammps_compute_addstep(void *handle, int nextstep) + :project: progguide + +----------------------- + .. doxygenenum:: _LMP_DATATYPE_CONST .. doxygenenum:: _LMP_STYLE_CONST diff --git a/src/library.cpp b/src/library.cpp index 17225fec40..1bb589c2b2 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2973,6 +2973,10 @@ double lammps_eval(void *handle, const char *expr) 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_compute_addstep_all` + :cpp:func:`lammps_compute_addstep` + \endverbatim * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -2995,6 +2999,10 @@ void lammps_compute_clearstep(void * handle) { 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_compute_clearstep` + :cpp:func:`lammps_compute_addstep` + \endverbatim * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -3016,6 +3024,10 @@ void lammps_compute_addstep_all(void * handle, bigint newstep) { 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_compute_addstep_all` + :cpp:func:`lammps_compute_clearstep` + \endverbatim * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. diff --git a/src/library.h b/src/library.h index 54600ed422..a2575db20a 100644 --- a/src/library.h +++ b/src/library.h @@ -191,13 +191,13 @@ 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_compute_clearstep(void * handle); +void lammps_compute_clearstep(void *handle); #if defined(LAMMPS_SMALLSMALL) -void lammps_compute_addstep_all(void * handle, int nextstep); -void lammps_compute_addstep(void * handle, int nextstep); +void lammps_compute_addstep_all(void *handle, int nextstep); +void lammps_compute_addstep(void *handle, int nextstep); #else -void lammps_compute_addstep_all(void * handle, int64_t nextstep); -void lammps_compute_addstep(void * handle, int64_t nextstep); +void lammps_compute_addstep_all(void *handle, int64_t nextstep); +void lammps_compute_addstep(void *handle, int64_t nextstep); #endif /* ---------------------------------------------------------------------- From 2c82ce8142cc3465dfeef70ac81d7571fbb02f24 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 19 Jan 2025 16:06:33 -0700 Subject: [PATCH 05/14] library: update new function signatures to use void* instead of bigint --- doc/src/Library_objects.rst | 12 ++++++------ python/lammps/core.py | 20 +++++++++++--------- src/library.cpp | 24 ++++++++++++------------ src/library.h | 11 +++-------- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/doc/src/Library_objects.rst b/doc/src/Library_objects.rst index bea5dec167..86b6d253f0 100644 --- a/doc/src/Library_objects.rst +++ b/doc/src/Library_objects.rst @@ -13,9 +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_compute_clearstep` -- :cpp:func:`lammps_compute_addstep_all` -- :cpp:func:`lammps_compute_addstep` +- :cpp:func:`lammps_clearstep_compute` +- :cpp:func:`lammps_addstep_compute_all` +- :cpp:func:`lammps_addstep_compute` ----------------------- @@ -64,17 +64,17 @@ fixes, or variables in LAMMPS using the following functions: ----------------------- -.. doxygenfunction:: lammps_compute_clearstep +.. doxygenfunction:: lammps_clearstep_compute :project: progguide ----------------------- -.. doxygenfunction:: lammps_compute_addstep_all(void *handle, int nextstep) +.. doxygenfunction:: lammps_addstep_compute_all :project: progguide ----------------------- -.. doxygenfunction:: lammps_compute_addstep(void *handle, int nextstep) +.. doxygenfunction:: lammps_addstep_compute :project: progguide ----------------------- diff --git a/python/lammps/core.py b/python/lammps/core.py index 7e70b5392a..15968ee605 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -422,9 +422,9 @@ 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_compute_clearstep.argtype = [c_void_p] - self.lib.lammps_compute_addstep.argtype = [c_void_p, self.c_bigint] - self.lib.lammps_compute_addstep_all.argtype = [c_void_p, self.c_bigint] + 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 @@ -1598,21 +1598,23 @@ class lammps(object): # ------------------------------------------------------------------------- - def compute_clearstep(self, nextstep): + def clearstep_compute(self, nextstep): with ExceptionCheck(self): - return self.lib.lammps_compute_clearstep(self.lmp) + return self.lib.lammps_clearstep_compute(self.lmp) # ------------------------------------------------------------------------- - def compute_addstep(self, nextstep): + def addstep_compute(self, nextstep): with ExceptionCheck(self): - return self.lib.lammps_compute_addstep(self.lmp, nextstep) + nextstep = self.c_bigint(nextstep) + return self.lib.lammps_addstep_compute(self.lmp, pointer(nextstep)) # ------------------------------------------------------------------------- - def compute_addstep_all(self, nextstep): + def addstep_compute_all(self, nextstep): with ExceptionCheck(self): - return self.lib.lammps_compute_addstep_all(self.lmp, nextstep) + nextstep = self.c_bigint(nextstep) + return self.lib.lammps_addstep_compute_all(self.lmp, pointer(nextstep)) # ------------------------------------------------------------------------- diff --git a/src/library.cpp b/src/library.cpp index 1bb589c2b2..4902236e98 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2974,14 +2974,14 @@ double lammps_eval(void *handle, const char *expr) and to flag computes that store invocation times as having been invoked *See also* - :cpp:func:`lammps_compute_addstep_all` - :cpp:func:`lammps_compute_addstep` + :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_compute_clearstep(void * handle) { +void lammps_clearstep_compute(void * handle) { auto lmp = (LAMMPS *) handle; lmp->modify->clearstep_compute(); } @@ -3000,17 +3000,17 @@ void lammps_compute_clearstep(void * handle) { do not loop only over n_timeflag, since may not be set yet *See also* - :cpp:func:`lammps_compute_clearstep` - :cpp:func:`lammps_compute_addstep` + :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 next timestep the compute will be invoked + * \param newstep pointer to bigint of next timestep the compute will be invoked */ -void lammps_compute_addstep_all(void * handle, bigint newstep) { +void lammps_addstep_compute_all(void * handle, void * newstep) { auto lmp = (LAMMPS *) handle; - lmp->modify->addstep_compute_all(newstep); + lmp->modify->addstep_compute_all(*static_cast(newstep)); } /* ---------------------------------------------------------------------- */ @@ -3025,17 +3025,17 @@ void lammps_compute_addstep_all(void * handle, bigint newstep) { called everywhere that computes are used, after computes are invoked *See also* - :cpp:func:`lammps_compute_addstep_all` - :cpp:func:`lammps_compute_clearstep` + :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_compute_addstep(void * handle, bigint newstep) { +void lammps_addstep_compute(void * handle, void * newstep) { auto lmp = (LAMMPS *) handle; - lmp->modify->addstep_compute(newstep); + lmp->modify->addstep_compute(*static_cast(newstep)); } // ---------------------------------------------------------------------- diff --git a/src/library.h b/src/library.h index a2575db20a..99b251ee85 100644 --- a/src/library.h +++ b/src/library.h @@ -191,14 +191,9 @@ 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_compute_clearstep(void *handle); -#if defined(LAMMPS_SMALLSMALL) -void lammps_compute_addstep_all(void *handle, int nextstep); -void lammps_compute_addstep(void *handle, int nextstep); -#else -void lammps_compute_addstep_all(void *handle, int64_t nextstep); -void lammps_compute_addstep(void *handle, int64_t nextstep); -#endif +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 From a242511ce77712a8933314d46b7e153ea457ddc9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 11:16:27 -0500 Subject: [PATCH 06/14] avoid segfaults --- src/library.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index dd7fec1ed0..07ed9184bc 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2981,7 +2981,7 @@ double lammps_eval(void *handle, const char *expr) * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. */ -void lammps_clearstep_compute(void * handle) { +void lammps_clearstep_compute(void *handle) { auto lmp = (LAMMPS *) handle; lmp->modify->clearstep_compute(); } @@ -3008,9 +3008,10 @@ void lammps_clearstep_compute(void * handle) { * \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) { +void lammps_addstep_compute_all(void *handle, void *newstep) { auto lmp = (LAMMPS *) handle; - lmp->modify->addstep_compute_all(*static_cast(newstep)); + auto ns = (bigint *) newstep; + if (lmp && lmp->modify && ns) lmp->modify->addstep_compute_all(*ns); } /* ---------------------------------------------------------------------- */ @@ -3033,9 +3034,10 @@ void lammps_addstep_compute_all(void * handle, void * newstep) { * \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) { +void lammps_addstep_compute(void *handle, void *newstep) { auto lmp = (LAMMPS *) handle; - lmp->modify->addstep_compute(*static_cast(newstep)); + auto ns = (bigint *) newstep; + if (lmp && lmp->modify && ns) lmp->modify->addstep_compute(*ns); } // ---------------------------------------------------------------------- From 0fde98cfbc873ba154248463b8b33f1832db3fe3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 11:17:04 -0500 Subject: [PATCH 07/14] use POINTER() captitalization consistently --- python/lammps/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index 15968ee605..bbfd5ba6f4 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -1607,14 +1607,14 @@ class lammps(object): def addstep_compute(self, nextstep): with ExceptionCheck(self): nextstep = self.c_bigint(nextstep) - return self.lib.lammps_addstep_compute(self.lmp, pointer(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)) + return self.lib.lammps_addstep_compute_all(self.lmp, POINTER(nextstep)) # ------------------------------------------------------------------------- From 6398a7c7aac2b1f02d962f3c1a226f2e8f37777a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 12:25:46 -0500 Subject: [PATCH 08/14] add test for the library interface to clearstep_compute and addstep_compute --- .../c-library/test_library_properties.cpp | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) 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); From 5d47c417ed28530cc174526422c594a655a80077 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 14:18:50 -0500 Subject: [PATCH 09/14] add fortran interface for lammps_clearstep_compute() --- doc/src/Fortran.rst | 2 ++ fortran/lammps.f90 | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index bc641a237f..18d96875a8 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -323,6 +323,8 @@ 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 gather_atoms: :f:subr:`gather_atoms` :ftype gather_atoms: subroutine :f gather_atoms_concat: :f:subr:`gather_atoms_concat` diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index 552b3dfad3..fee8d41de1 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -127,6 +127,7 @@ 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_gather_atoms_int PROCEDURE, PRIVATE :: lmp_gather_atoms_double GENERIC :: gather_atoms => lmp_gather_atoms_int, & @@ -626,6 +627,12 @@ 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_gather_atoms(handle, name, TYPE, count, DATA) BIND(C) IMPORT :: c_int, c_ptr IMPLICIT NONE @@ -1846,6 +1853,12 @@ 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 function to lammps_gather_atoms (for integers) SUBROUTINE lmp_gather_atoms_int(self, name, count, data) CLASS(lammps), INTENT(IN) :: self From 23045d62c57ce16f048aff722a234054fa38db84 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 14:27:34 -0500 Subject: [PATCH 10/14] add plugin wrapper and swig interface to new LAMMPS library functions --- examples/COUPLE/plugin/liblammpsplugin.c | 3 +++ examples/COUPLE/plugin/liblammpsplugin.h | 3 +++ tools/swig/lammps.i | 6 ++++++ 3 files changed, 12 insertions(+) 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/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 *); From 8f551df46a56497d96f3e1253df7bb331662d95b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 20:38:08 -0500 Subject: [PATCH 11/14] add fortran interface for lammps_addstep_compute() and lammps_addstep_compute_all() --- fortran/lammps.f90 | 89 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index fee8d41de1..2cfd4422b0 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -127,7 +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, & @@ -633,6 +642,18 @@ MODULE LIBLAMMPS 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 @@ -1859,6 +1880,74 @@ CONTAINS 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 From 2c3f0d65acf6f0a8ff971a1f467fe5a8318c6d40 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Jan 2025 20:58:49 -0500 Subject: [PATCH 12/14] update docs --- doc/src/Fortran.rst | 57 ++++++++++++++++++++- doc/utils/sphinx-config/false_positives.txt | 2 + 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index 18d96875a8..30d0d5f4a7 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -325,6 +325,10 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS. :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` @@ -1452,11 +1456,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/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 6746d591c6..c43e0941a5 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2532,6 +2532,7 @@ Nevery Nevins newfile Newns +newstep newtype nextsort Neyts @@ -3769,6 +3770,7 @@ Tigran Tij Tildesley Timan +timeflag timeI timespan timestamp From 31720b27413f1f6351385827bf56ec6e1769f8fd Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Wed, 29 Jan 2025 23:53:23 -0700 Subject: [PATCH 13/14] add missing init function to fix python/invoke --- src/PYTHON/fix_python_invoke.cpp | 26 +++++++++++++++++++++++--- src/PYTHON/fix_python_invoke.h | 2 ++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/PYTHON/fix_python_invoke.cpp b/src/PYTHON/fix_python_invoke.cpp index b47a94c6c7..6f27831438 100644 --- a/src/PYTHON/fix_python_invoke.cpp +++ b/src/PYTHON/fix_python_invoke.cpp @@ -72,7 +72,11 @@ FixPythonInvoke::FixPythonInvoke(LAMMPS *lmp, int narg, char **arg) : lmpPtr = PY_VOID_POINTER(lmp); - modify->addstep_compute_all(nextvalid()); + // 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); } /* ---------------------------------------------------------------------- */ @@ -92,8 +96,21 @@ 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; @@ -107,7 +124,8 @@ void FixPythonInvoke::end_of_step() Py_CLEAR(result); - modify->addstep_compute(nextvalid()); + nvalid = nextvalid(); + modify->addstep_compute(nvalid); } /* ---------------------------------------------------------------------- */ @@ -123,6 +141,7 @@ 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; @@ -137,7 +156,8 @@ void FixPythonInvoke::post_force(int vflag) Py_CLEAR(result); - modify->addstep_compute(nextvalid()); + nvalid = nextvalid(); + modify->addstep_compute(nvalid); } /* ---------------------------------------------------------------------- */ diff --git a/src/PYTHON/fix_python_invoke.h b/src/PYTHON/fix_python_invoke.h index 3d2324a939..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; @@ -39,6 +40,7 @@ class FixPythonInvoke : public Fix { void *pFunc; int selected_callback; bigint nextvalid(); + bigint nvalid; }; } // namespace LAMMPS_NS From 2b0a6419b76b09fbdef33104672c36f9f3fe0498 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Wed, 29 Jan 2025 23:57:44 -0700 Subject: [PATCH 14/14] add missing doc section for fix python/invoke --- doc/src/fix_python_invoke.rst | 9 +++++++++ 1 file changed, 9 insertions(+) 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 """"""""""""