From c4d0f07093310ac0d3e8cf6ee9c3c35b5a640099 Mon Sep 17 00:00:00 2001
From: Richard Berger <richard.berger@temple.edu>
Date: Fri, 12 May 2017 00:29:58 -0400
Subject: [PATCH] Allow fix python to only execute every N steps

---
 doc/src/fix_python.txt        | 13 +++++++------
 examples/python/in.fix_python |  4 ++--
 src/PYTHON/fix_python.cpp     | 13 +++++++++----
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/doc/src/fix_python.txt b/doc/src/fix_python.txt
index f69ff41bfa..8b921bc999 100644
--- a/doc/src/fix_python.txt
+++ b/doc/src/fix_python.txt
@@ -10,13 +10,14 @@ fix python command :h3
 
 [Syntax:]
 
-fix ID group-ID python callback function_name :pre
+fix ID group-ID python N callback function_name :pre
 
 ID, group-ID are ignored by this fix :ulb,l
 python = style name of this fix command :l
+N = execute every N steps :l
 callback = {post_force} or {end_of_step} :l
-  {post_force} = callback after force computations on atoms
-  {end_of_step} = callback after each time step :pre
+  {post_force} = callback after force computations on atoms every N time steps
+  {end_of_step} = callback after each N time steps :pre
 :ule
 
 [Examples:]
@@ -35,14 +36,14 @@ def end_of_step_callback(lammps_ptr):
     # access LAMMPS state using Python interface
 """ :pre
 
-fix pf  all python post_force post_force_callback
-fix eos all python end_of_step end_of_step_callback :pre
+fix pf  all python 50 post_force post_force_callback
+fix eos all python 50 end_of_step end_of_step_callback :pre
 
 [Description:]
 
 This fix allows you to call a Python function during a simulation run.
 The callback is either executed after forces have been applied to atoms
-or at the end of each time step.
+or at the end of every N time steps.
 
 Callback functions must be declared in the global scope of the
 active Python interpreter. This can either be done by defining it
diff --git a/examples/python/in.fix_python b/examples/python/in.fix_python
index 426b456688..c98029a63b 100644
--- a/examples/python/in.fix_python
+++ b/examples/python/in.fix_python
@@ -33,8 +33,8 @@ def post_force_callback(lmp, v):
 """
 
 fix		1 all nve
-fix     2 all python end_of_step end_of_step_callback
-fix     3 all python post_force post_force_callback
+fix     2 all python 50 end_of_step end_of_step_callback
+fix     3 all python 50 post_force post_force_callback
 
 #dump		id all atom 50 dump.melt
 
diff --git a/src/PYTHON/fix_python.cpp b/src/PYTHON/fix_python.cpp
index 08beb511cb..4f437b7488 100644
--- a/src/PYTHON/fix_python.cpp
+++ b/src/PYTHON/fix_python.cpp
@@ -36,14 +36,17 @@ using namespace FixConst;
 FixPython::FixPython(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
-  if (narg != 5) error->all(FLERR,"Illegal fix python command");
+  if (narg != 6) error->all(FLERR,"Illegal fix python command");
+
+  nevery = force->inumeric(FLERR,arg[3]);
+  if (nevery <= 0) error->all(FLERR,"Illegal fix python command");
 
   // ensure Python interpreter is initialized
   python->init();
 
-  if (strcmp(arg[3],"post_force") == 0) {
+  if (strcmp(arg[4],"post_force") == 0) {
     selected_callback = POST_FORCE;
-  } else if (strcmp(arg[3],"end_of_step") == 0) {
+  } else if (strcmp(arg[4],"end_of_step") == 0) {
     selected_callback = END_OF_STEP;
   }
 
@@ -57,7 +60,7 @@ FixPython::FixPython(LAMMPS *lmp, int narg, char **arg) :
     error->all(FLERR,"Could not initialize embedded Python");
   }
 
-  char * fname = arg[4];
+  char * fname = arg[5];
   pFunc = PyObject_GetAttrString(pyMain, fname);
 
   if (!pFunc) {
@@ -94,6 +97,8 @@ void FixPython::end_of_step()
 
 void FixPython::post_force(int vflag)
 {
+  if (update->ntimestep % nevery != 0) return;
+
   PyGILState_STATE gstate = PyGILState_Ensure();
 
   PyObject * ptr = PY_VOID_POINTER(lmp);
-- 
GitLab