diff --git a/doc/src/Manual.txt b/doc/src/Manual.txt
index a957470735540488c6f6de1abff3ea5c3d835645..8590e33acec4e03028a9078392b81f992122067c 100644
--- a/doc/src/Manual.txt
+++ b/doc/src/Manual.txt
@@ -1,7 +1,7 @@
 <!-- HTML_ONLY -->
 <HEAD>
 <TITLE>LAMMPS Users Manual</TITLE>
-<META NAME="docnumber" CONTENT="19 Oct 2016 version">
+<META NAME="docnumber" CONTENT="27 Oct 2016 version">
 <META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
 <META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation.  This software and manual is distributed under the GNU General Public License.">
 </HEAD>
@@ -21,7 +21,7 @@
 <H1></H1>
 
 LAMMPS Documentation :c,h3
-19 Oct 2016 version :c,h4
+27 Oct 2016 version :c,h4
 
 Version info: :h4
 
diff --git a/doc/src/Section_howto.txt b/doc/src/Section_howto.txt
index 7b8ed2d9a640b433fe8b241ddf304f1212cbd5b7..33cbfa95865b8a2222abf94f7a7f4529459cd08e 100644
--- a/doc/src/Section_howto.txt
+++ b/doc/src/Section_howto.txt
@@ -1864,8 +1864,8 @@ void lammps_close(void *)
 int lammps_version(void *)
 void lammps_file(void *, char *)
 char *lammps_command(void *, char *)
-char *lammps_commands_list(void *, int, char **)
-char *lammps_commands_concatenated(void *, char *)
+void lammps_commands_list(void *, int, char **)
+void lammps_commands_string(void *, char *)
 void lammps_free(void *) :pre
 
 The lammps_open() function is used to initialize LAMMPS, passing in a
@@ -1901,51 +1901,66 @@ changes to the LAMMPS command syntax between versions. The returned
 LAMMPS version code is an integer (e.g. 2 Sep 2015 results in
 20150902) that grows with every new LAMMPS version.
 
-The lammps_file(), lammps_command(), lammps_commands_list(),
-lammps_commands_concatenated() functions are used to pass one or more
-commands to LAMMPS to execute as if they were coming from an input
-script.
+The lammps_file(), lammps_command(), lammps_commands_list(), and
+lammps_commands_string() functions are used to pass one or more
+commands to LAMMPS to execute, the same as if they were coming from an
+input script.
+
+Via these functions, the calling code can read or generate a series of
+LAMMPS commands one or multiple at a time and pass it thru the library
+interface to setup a problem and then run it in stages.  The caller
+can interleave the command function calls with operations it performs,
+calls to extract information from or set information within LAMMPS, or
+calls to another code's library.
 
 The lammps_file() function passes the filename of an input script.
 The lammps_command() function passes a single command as a string.
-The lammps_commands_multiple() function passes multiple commands in a
-char** list.  The lammps_commands_concatentaed() function passes
-multiple commands concatenated into one long string, separated by
-newline characters.  A single command can be spread across multiple
-lines, if the last printable character of all but the last line is
-"&", the same as if the lines appeared in an input script.
-
-Via these library functions, the calling code can read or generate a
-series of LAMMPS commands one or multiple at a time and pass it thru
-the library interface to setup a problem and then run it, interleaving
-the command function calls with operations performed within the
-faller, calls to extract information from LAMMPS, or calls to another
-code's library.
-
-The lammps_free() is a clean-up function to free memory that the library
-allocated previously.
+The lammps_commands_list() function passes multiple commands in a
+char** list.  In both lammps_command() and lammps_commands_list(),
+individual commands may or may not have a trailing newline.  The
+lammps_commands_string() function passes multiple commands
+concatenated into one long string, separated by newline characters.
+In both lammps_commands_list() and lammps_commands_string(), a single
+command can be spread across multiple lines, if the last printable
+character of all but the last line is "&", the same as if the lines
+appeared in an input script.
+
+The lammps_free() function is a clean-up function to free memory that
+the library allocated previously via other function calls.  See
+comments in src/library.cpp file for which other functions need this
+clean-up.
 
 Library.cpp also contains these functions for extracting information
 from LAMMPS and setting value within LAMMPS.  Again, see the
-documentation in the src/library.cpp file for details:
+documentation in the src/library.cpp file for details, including
+which quantities can be queried by name:
 
 void *lammps_extract_global(void *, char *)
 void *lammps_extract_atom(void *, char *)
 void *lammps_extract_compute(void *, char *, int, int)
 void *lammps_extract_fix(void *, char *, int, int, int, int)
-void *lammps_extract_variable(void *, char *, char *)
+void *lammps_extract_variable(void *, char *, char *) :pre
+
 int lammps_set_variable(void *, char *, char *)
-double lammps_get_thermo(void *, char *)
+double lammps_get_thermo(void *, char *) :pre
+
 int lammps_get_natoms(void *)
 void lammps_gather_atoms(void *, double *)
 void lammps_scatter_atoms(void *, double *) :pre
+void lammps_create_atoms(void *, int, tagint *, int *, double *, double *) :pre
+
+The extract functions return a pointer to various global or per-atom
+quantities stored in LAMMPS or to values calculated by a compute, fix,
+or variable.  The pointer returned by the extract_global() function
+can be used as a permanent reference to a value which may change.  For
+the other extract functions, the underlying storage may be reallocated
+as LAMMPS runs, so you need to re-call the function to assure a
+current pointer or returned value(s).
 
-These functions can extract various global or per-atom quantities from
-LAMMPS as well as values calculated by a compute, fix, or variable.
-The lammps_set_variable() function can set an existing string-style variable
-to a new value, so that subsequent LAMMPS commands can access the
-variable.  The lammps_get_thermo() function returns the current
-value of a thermo keyword.
+The lammps_set_variable() function can set an existing string-style
+variable to a new string value, so that subsequent LAMMPS commands can
+access the variable.  The lammps_get_thermo() function returns the
+current value of a thermo keyword as a double.
 
 The lammps_get_natoms() function returns the total number of atoms in
 the system and can be used by the caller to allocate space for the
@@ -1956,15 +1971,22 @@ returns a full list to each calling processor.  The scatter function
 does the inverse.  It distributes the same kinds of values, 
 passed by the caller, to each atom owned by individual processors.
 
+The lammps_create_atoms() function takes a list of N atoms as input
+with atom types and coords (required), an optionally atom IDs and
+velocities.  It uses the coords of each atom to assign it as a new
+atom to the processor that owns it.  Additional properties for the new
+atoms can be assigned via the lammps_scatter_atoms() or
+lammps_extract_atom() functions.
+
 The examples/COUPLE and python directories have example C++ and C and
 Python codes which show how a driver code can link to LAMMPS as a
 library, run LAMMPS on a subset of processors, grab data from LAMMPS,
 change it, and put it back into LAMMPS.
 
-NOTE: You can write your own additional functions as needed to define
+NOTE: You can write code for additional functions as needed to define
 how your code talks to LAMMPS and add them to src/library.cpp and
 src/library.h, as well as to the "Python
-interface"_Section_python.html.  The routines you add can access or
+interface"_Section_python.html.  The added functions can access or
 change any LAMMPS data you wish.
 
 :line
diff --git a/doc/src/Section_python.txt b/doc/src/Section_python.txt
index 352c1fa5927b50c3a595295ce612385c174f00af..b3b5171e74ac291429c23768b63f0da2706d14d8 100644
--- a/doc/src/Section_python.txt
+++ b/doc/src/Section_python.txt
@@ -550,7 +550,8 @@ version = lmp.version()  # return the numerical version id, e.g. LAMMPS 2 Sep 20
 
 lmp.file(file)           # run an entire input script, file = "in.lj"
 lmp.command(cmd)         # invoke a single LAMMPS command, cmd = "run 100" :pre
-lmp.commands_list(cmdlist)  # invoke commands in cmdlist
+lmp.commands_list(cmdlist)     # invoke commands in cmdlist = ["run 10", "run 20"]
+lmp.commands_string(multicmd)  # invoke commands in multicmd = "run 10\nrun 20"
 
 xlo = lmp.extract_global(name,type)  # extract a global quantity
                                      # name = "boxxlo", "nlocal", etc
@@ -631,8 +632,9 @@ lmp2 = lammps()
 lmp1.file("in.file1")
 lmp2.file("in.file2") :pre
 
-The file() and command() methods allow an input script or single
-commands to be invoked.
+The file(), command(), commands_list(), commands_string() methods
+allow an input script, a single command, or multiple commands to be
+invoked.
 
 The extract_global(), extract_atom(), extract_compute(),
 extract_fix(), and extract_variable() methods return values or
diff --git a/examples/COUPLE/simple/in.lj b/examples/COUPLE/simple/in.lj
index 5f6ebdc4f2d414babe4a03a38f3180ce84e2737e..3dc80bdfea750f6b7e12cf81929d4b0304c11929 100644
--- a/examples/COUPLE/simple/in.lj
+++ b/examples/COUPLE/simple/in.lj
@@ -20,4 +20,6 @@ neigh_modify	delay 0 every 20 check no
 
 fix		1 all nve
 
+variable        fx atom fx
+
 run		10
diff --git a/examples/COUPLE/simple/simple.c b/examples/COUPLE/simple/simple.c
index c50f289b7af63c2d595cec213b7764f957be9270..cc813d78fe785cd695344e8f939c356013a7cd3a 100644
--- a/examples/COUPLE/simple/simple.c
+++ b/examples/COUPLE/simple/simple.c
@@ -71,8 +71,8 @@ int main(int narg, char **arg)
      (could just send it to proc 0 of comm_lammps and let it Bcast)
      all LAMMPS procs call lammps_command() on the line */
 
-  void *ptr;
-  if (lammps == 1) lammps_open(0,NULL,comm_lammps,&ptr);
+  void *lmp = NULL;
+  if (lammps == 1) lammps_open(0,NULL,comm_lammps,&lmp);
 
   int n;
   char line[1024];
@@ -85,7 +85,7 @@ int main(int narg, char **arg)
     MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
     if (n == 0) break;
     MPI_Bcast(line,n,MPI_CHAR,0,MPI_COMM_WORLD);
-    if (lammps == 1) lammps_command(ptr,line);
+    if (lammps == 1) lammps_command(lmp,line);
   }
 
   /* run 10 more steps
@@ -94,23 +94,72 @@ int main(int narg, char **arg)
      put coords back into LAMMPS
      run a single step with changed coords */
 
+  double *x = NULL;
+  double *v = NULL;
+
   if (lammps == 1) {
-    lammps_command(ptr,"run 10");
+    lammps_command(lmp,"run 10");
 
-    int natoms = lammps_get_natoms(ptr);
-    double *x = (double *) malloc(3*natoms*sizeof(double));
-    lammps_gather_atoms(ptr,"x",1,3,x);
+    int natoms = lammps_get_natoms(lmp);
+    x = (double *) malloc(3*natoms*sizeof(double));
+    lammps_gather_atoms(lmp,"x",1,3,x);
+    v = (double *) malloc(3*natoms*sizeof(double));
+    lammps_gather_atoms(lmp,"v",1,3,v);
     double epsilon = 0.1;
     x[0] += epsilon;
-    lammps_scatter_atoms(ptr,"x",1,3,x);
-    free(x);
+    lammps_scatter_atoms(lmp,"x",1,3,x);
+
+    lammps_command(lmp,"run 1");
+  }
+
+  // extract force on single atom two different ways
+
+  if (lammps == 1) {
+    double **f = (double **) lammps_extract_atom(lmp,"f");
+    printf("Force on 1 atom via extract_atom: %g\n",f[0][0]);
+
+    double *fx = (double *) lammps_extract_variable(lmp,"fx","all");
+    printf("Force on 1 atom via extract_variable: %g\n",fx[0]);
+  }
 
-    lammps_command(ptr,"run 1");
+  /* use commands_string() and commands_list() to invoke more commands */
+
+  char *strtwo = "run 10\nrun 20";
+  if (lammps == 1) lammps_commands_string(lmp,strtwo);
+
+  char *cmds[2];
+  cmds[0] = "run 10";
+  cmds[1] = "run 20";
+  if (lammps == 1) lammps_commands_list(lmp,2,cmds);
+
+  /* delete all atoms
+     create_atoms() to create new ones with old coords, vels
+     initial thermo should be same as step 20 */
+
+  int *type = NULL;
+
+  if (lammps == 1) {
+    int natoms = lammps_get_natoms(lmp);
+    type = (int *) malloc(natoms*sizeof(double));
+    int i;
+    for (i = 0; i < natoms; i++) type[i] = 1;
+
+    lammps_command(lmp,"delete_atoms group all");
+    lammps_create_atoms(lmp,natoms,NULL,type,x,v);
+    lammps_command(lmp,"run 10");
   }
 
-  if (lammps == 1) lammps_close(ptr);
+  if (x) free(x);
+  if (v) free(v);
+  if (type) free(type);
+
+  // close down LAMMPS
+
+  lammps_close(lmp);
 
   /* close down MPI */
 
+  if (lammps == 1) MPI_Comm_free(&comm_lammps);
+  MPI_Barrier(MPI_COMM_WORLD);
   MPI_Finalize();
 }
diff --git a/examples/COUPLE/simple/simple.cpp b/examples/COUPLE/simple/simple.cpp
index a440bcb1ae9c711dad0cf9dbe9d046071fb62b95..b279ae704cb9febd3401fe420ec0a7db292c5189 100644
--- a/examples/COUPLE/simple/simple.cpp
+++ b/examples/COUPLE/simple/simple.cpp
@@ -77,7 +77,7 @@ int main(int narg, char **arg)
   // (could just send it to proc 0 of comm_lammps and let it Bcast)
   // all LAMMPS procs call input->one() on the line
   
-  LAMMPS *lmp;
+  LAMMPS *lmp = NULL;
   if (lammps == 1) lmp = new LAMMPS(0,NULL,comm_lammps);
 
   int n;
@@ -91,7 +91,7 @@ int main(int narg, char **arg)
     MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
     if (n == 0) break;
     MPI_Bcast(line,n,MPI_CHAR,0,MPI_COMM_WORLD);
-    if (lammps == 1) lmp->input->one(line);
+    if (lammps == 1) lammps_command(lmp,line);
   }
 
   // run 10 more steps
@@ -100,23 +100,74 @@ int main(int narg, char **arg)
   // put coords back into LAMMPS
   // run a single step with changed coords
 
+  double *x = NULL;
+  double *v = NULL;
+
   if (lammps == 1) {
     lmp->input->one("run 10");
 
     int natoms = static_cast<int> (lmp->atom->natoms);
-    double *x = new double[3*natoms];
+    x = new double[3*natoms];
+    v = new double[3*natoms];
     lammps_gather_atoms(lmp,"x",1,3,x);
+    lammps_gather_atoms(lmp,"v",1,3,v);
     double epsilon = 0.1;
     x[0] += epsilon;
     lammps_scatter_atoms(lmp,"x",1,3,x);
-    delete [] x;
 
+    // these 2 lines are the same
+
+    // lammps_command(lmp,"run 1");
     lmp->input->one("run 1");
   }
 
-  if (lammps == 1) delete lmp;
+  // extract force on single atom two different ways
+
+  if (lammps == 1) {
+    double **f = (double **) lammps_extract_atom(lmp,"f");
+    printf("Force on 1 atom via extract_atom: %g\n",f[0][0]);
+
+    double *fx = (double *) lammps_extract_variable(lmp,"fx","all");
+    printf("Force on 1 atom via extract_variable: %g\n",fx[0]);
+  }
+
+  // use commands_string() and commands_list() to invoke more commands
+
+  char *strtwo = "run 10\nrun 20";
+  if (lammps == 1) lammps_commands_string(lmp,strtwo);
+
+  char *cmds[2];
+  cmds[0] = "run 10";
+  cmds[1] = "run 20";
+  if (lammps == 1) lammps_commands_list(lmp,2,cmds);
+
+  // delete all atoms
+  // create_atoms() to create new ones with old coords, vels
+  // initial thermo should be same as step 20
+
+  int *type = NULL;
+
+  if (lammps == 1) {
+    int natoms = static_cast<int> (lmp->atom->natoms);
+    type = new int[natoms];
+    for (int i = 0; i < natoms; i++) type[i] = 1;
+
+    lmp->input->one("delete_atoms group all");
+    lammps_create_atoms(lmp,natoms,NULL,type,x,v);
+    lmp->input->one("run 10");
+  }
+
+  delete [] x;
+  delete [] v;
+  delete [] type;
+
+  // close down LAMMPS
+
+  delete lmp;
 
   // close down MPI
 
+  if (lammps == 1) MPI_Comm_free(&comm_lammps);
+  MPI_Barrier(MPI_COMM_WORLD);
   MPI_Finalize();
 }
diff --git a/python/examples/simple.py b/python/examples/simple.py
index 9315a555fca0e64c368b2a8d9ecf8576a779a710..6336c89de3e6171d16ed82968a99ed2bf8d39a3d 100755
--- a/python/examples/simple.py
+++ b/python/examples/simple.py
@@ -13,6 +13,8 @@
 
 from __future__ import print_function
 import sys
+import numpy as np
+import ctypes
 
 # parse command line
 
@@ -51,17 +53,39 @@ for line in lines: lmp.command(line)
 
 lmp.command("run 10")
 x = lmp.gather_atoms("x",1,3)
+v = lmp.gather_atoms("v",1,3)
 epsilon = 0.1
 x[0] += epsilon
 lmp.scatter_atoms("x",1,3,x)
 lmp.command("run 1");
 
+# extract force on single atom two different ways
+
 f = lmp.extract_atom("f",3)
 print("Force on 1 atom via extract_atom: ",f[0][0])
 
 fx = lmp.extract_variable("fx","all",1)
 print("Force on 1 atom via extract_variable:",fx[0])
 
+# use commands_string() and commands_list() to invoke more commands
+
+strtwo = "run 10\nrun 20"
+lmp.commands_string(strtwo)
+
+cmds = ["run 10","run 20"]
+lmp.commands_list(cmds)
+
+# delete all atoms
+# create_atoms() to create new ones with old coords, vels
+# initial thermo should be same as step 20
+
+natoms = lmp.get_natoms()
+type = natoms*[1]
+
+lmp.command("delete_atoms group all");
+lmp.create_atoms(natoms,None,type,x,v);
+lmp.command("run 10");
+
 # uncomment if running in parallel via Pypar
 #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
 #pypar.finalize()
diff --git a/python/lammps.py b/python/lammps.py
index 8c5792806450e6d73119531d41ca0cd5d1a33f6e..7344a16be30fb8ab47e3ffc1f6cd939dae95b4fe 100644
--- a/python/lammps.py
+++ b/python/lammps.py
@@ -172,6 +172,8 @@ class lammps(object):
     if file: file = file.encode()
     self.lib.lammps_file(self.lmp,file)
 
+  # send a single command
+    
   def command(self,cmd):
     if cmd: cmd = cmd.encode()
     self.lib.lammps_command(self.lmp,cmd)
@@ -185,6 +187,19 @@ class lammps(object):
         raise MPIAbortException(error_msg)
       raise Exception(error_msg)
 
+  # send a list of commands
+
+  def commands_list(self,cmdlist):
+    args = (c_char_p * len(cmdlist))(*cmdlist)
+    self.lib.lammps_commands_list(self.lmp,len(cmdlist),args)
+    
+  # send a string of commands
+
+  def commands_string(self,multicmd):
+    self.lib.lammps_commands_string(self.lmp,c_char_p(multicmd))
+    
+  # extract global info
+    
   def extract_global(self,name,type):
     if name: name = name.encode()
     if type == 0:
@@ -195,6 +210,8 @@ class lammps(object):
     ptr = self.lib.lammps_extract_global(self.lmp,name)
     return ptr[0]
 
+  # extract per-atom info
+  
   def extract_atom(self,name,type):
     if name: name = name.encode()
     if type == 0:
@@ -209,6 +226,8 @@ class lammps(object):
     ptr = self.lib.lammps_extract_atom(self.lmp,name)
     return ptr
 
+  # extract compute info
+  
   def extract_compute(self,id,style,type):
     if id: id = id.encode()
     if type == 0:
@@ -226,6 +245,7 @@ class lammps(object):
       return ptr
     return None
 
+  # extract fix info
   # in case of global datum, free memory for 1 double via lammps_free()
   # double was allocated by library interface function
 
@@ -249,6 +269,7 @@ class lammps(object):
     else:
       return None
 
+  # extract variable info
   # free memory for 1 double or 1 vector of doubles via lammps_free()
   # for vector, must copy nlocal returned values to local c_double vector
   # memory was allocated by library interface function
@@ -296,7 +317,14 @@ class lammps(object):
     return self.lib.lammps_get_natoms(self.lmp)
 
   # return vector of atom properties gathered across procs, ordered by atom ID
-
+  # name = atom property recognized by LAMMPS in atom->extract()
+  # type = 0 for integer values, 1 for double values
+  # count = number of per-atom valus, 1 for type or charge, 3 for x or f
+  # returned data is a 1d vector - doc how it is ordered?
+  # NOTE: how could we insure are converting to correct Python type
+  #   e.g. for Python list or NumPy, etc
+  #   ditto for extact_atom() above
+  
   def gather_atoms(self,name,type,count):
     if name: name = name.encode()
     natoms = self.lib.lammps_get_natoms(self.lmp)
@@ -310,12 +338,38 @@ class lammps(object):
     return data
 
   # scatter vector of atom properties across procs, ordered by atom ID
-  # assume vector is of correct type and length, as created by gather_atoms()
-
+  # name = atom property recognized by LAMMPS in atom->extract()
+  # type = 0 for integer values, 1 for double values
+  # count = number of per-atom valus, 1 for type or charge, 3 for x or f
+  # assume data is of correct type and length, as created by gather_atoms()
+  # NOTE: how could we insure are passing correct type to LAMMPS
+  # e.g. for Python list or NumPy, etc
+    
   def scatter_atoms(self,name,type,count,data):
     if name: name = name.encode()
     self.lib.lammps_scatter_atoms(self.lmp,name,type,count,data)
 
+  # create N atoms on all procs
+  # N = global number of atoms
+  # id = ID of each atom (optional, can be None)
+  # type = type of each atom (1 to Ntypes) (required)
+  # x = coords of each atom as (N,3) array (required)
+  # v = velocity of each atom as (N,3) array (optional, can be None)
+  # NOTE: how could we insure are passing correct type to LAMMPS
+  #   e.g. for Python list or NumPy, etc
+  #   ditto for gather_atoms() above
+
+  def create_atoms(self,n,id,type,x,v):
+    if id:
+      id_lmp = (c_int * n)()
+      id_lmp[:] = id
+    else: id_lmp = id
+    type_lmp = (c_int * n)()
+    type_lmp[:] = type
+    self.lib.lammps_create_atoms(self.lmp,n,id_lmp,type_lmp,x,v)
+
+  # document this?
+    
   @property
   def uses_exceptions(self):
     try:
diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh
index c45be8c973502b9fa536dc6ba7665bb56748184f..41f9304f8bf6cdd6d1f76e83589334336efe9094 100644
--- a/src/KOKKOS/Install.sh
+++ b/src/KOKKOS/Install.sh
@@ -83,6 +83,10 @@ action fix_nvt_kokkos.cpp
 action fix_nvt_kokkos.h
 action fix_qeq_reax_kokkos.cpp fix_qeq_reax.cpp
 action fix_qeq_reax_kokkos.h fix_qeq_reax.h
+action fix_reaxc_bonds_kokkos.cpp fix_reaxc_bonds.cpp
+action fix_reaxc_bonds_kokkos.h fix_reaxc_bonds.h
+action fix_reaxc_species_kokkos.cpp fix_reaxc_species.cpp
+action fix_reaxc_species_kokkos.h fix_reaxc_species.h
 action fix_setforce_kokkos.cpp
 action fix_setforce_kokkos.h
 action fix_wall_reflect_kokkos.cpp
diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp
index e54be7412402736e71243395442839753c01bb95..d39d5cc84a2b8ff322fc411a3246c364bfe6c6f1 100644
--- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp
+++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp
@@ -431,8 +431,8 @@ void FixQEqReaxKokkos<DeviceType>::compute_h_item(int ii, int &m_fill, const boo
       const F_FLOAT rsq = delx*delx + dely*dely + delz*delz;
       if (rsq > cutsq) continue;
 
-      const F_FLOAT r = sqrt(rsq);
       if (final) {
+        const F_FLOAT r = sqrt(rsq);
         d_jlist(m_fill) = j;
         const F_FLOAT shldij = d_shield(itype,jtype);
         d_val(m_fill) = calculate_H_k(r,shldij);
diff --git a/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp b/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e96c491968d6d90056de3c07b8c4e56ca652b0f
--- /dev/null
+++ b/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp
@@ -0,0 +1,124 @@
+/* ----------------------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+   Contributing author: Stan Moore (Sandia)
+------------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include "fix_ave_atom.h"
+#include "fix_reaxc_bonds_kokkos.h"
+#include "atom.h"
+#include "update.h"
+#include "pair_reax_c_kokkos.h"
+#include "modify.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "comm.h"
+#include "force.h"
+#include "compute.h"
+#include "input.h"
+#include "variable.h"
+#include "memory.h"
+#include "error.h"
+#include "reaxc_list.h"
+#include "reaxc_types.h"
+#include "reaxc_defs.h"
+#include "atom_masks.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixReaxCBondsKokkos::FixReaxCBondsKokkos(LAMMPS *lmp, int narg, char **arg) :
+  FixReaxCBonds(lmp, narg, arg)
+{
+  kokkosable = 1;
+  atomKK = (AtomKokkos *) atom;
+
+  datamask_read = EMPTY_MASK;
+  datamask_modify = EMPTY_MASK;
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixReaxCBondsKokkos::~FixReaxCBondsKokkos()
+{
+
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixReaxCBondsKokkos::init()
+{
+  Pair *pair_kk = force->pair_match("reax/c/kk",1);
+  if (pair_kk == NULL) error->all(FLERR,"Cannot use fix reax/c/bonds without "
+                  "pair_style reax/c/kk");
+
+  FixReaxCBonds::init();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixReaxCBondsKokkos::Output_ReaxC_Bonds(bigint ntimestep, FILE *fp)
+
+{
+  int i, j;
+  int nbuf_local;
+  int nlocal_max, numbonds, numbonds_max;
+  double *buf;
+  DAT::tdual_ffloat_1d k_buf;
+
+  int nlocal = atom->nlocal;
+  int nlocal_tot = static_cast<int> (atom->natoms);
+
+  numbonds = 0;
+  if (reaxc->execution_space == Device)
+    ((PairReaxCKokkos<LMPDeviceType>*) reaxc)->FindBond(numbonds);
+  else
+    ((PairReaxCKokkos<LMPHostType>*) reaxc)->FindBond(numbonds);
+
+  // allocate a temporary buffer for the snapshot info
+  MPI_Allreduce(&numbonds,&numbonds_max,1,MPI_INT,MPI_MAX,world);
+  MPI_Allreduce(&nlocal,&nlocal_max,1,MPI_INT,MPI_MAX,world);
+
+  nbuf = 1+(numbonds_max*2+10)*nlocal_max;
+  memory->create_kokkos(k_buf,buf,nbuf,"reax/c/bonds:buf");
+
+  // Pass information to buffer
+  if (reaxc->execution_space == Device)
+    ((PairReaxCKokkos<LMPDeviceType>*) reaxc)->PackBondBuffer(k_buf,nbuf_local);
+  else
+    ((PairReaxCKokkos<LMPHostType>*) reaxc)->PackBondBuffer(k_buf,nbuf_local);
+
+  // Receive information from buffer for output
+  RecvBuffer(buf, nbuf, nbuf_local, nlocal_tot, numbonds_max);
+
+  memory->destroy_kokkos(k_buf,buf);
+}
+
+double FixReaxCBondsKokkos::memory_usage()
+{
+  double bytes;
+
+  bytes = nbuf*sizeof(double);
+  // These are accounted for in PairReaxCKokkos:
+  //bytes += nmax*sizeof(int);
+  //bytes += 1.0*nmax*MAXREAXBOND*sizeof(double);
+  //bytes += 1.0*nmax*MAXREAXBOND*sizeof(int);
+
+  return bytes;
+}
diff --git a/src/KOKKOS/fix_reaxc_bonds_kokkos.h b/src/KOKKOS/fix_reaxc_bonds_kokkos.h
new file mode 100644
index 0000000000000000000000000000000000000000..f27e558fddcd835efe3171a9127f462f6a9d435e
--- /dev/null
+++ b/src/KOKKOS/fix_reaxc_bonds_kokkos.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- ----------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   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.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(reax/c/bonds/kk,FixReaxCBondsKokkos)
+
+#else
+
+#ifndef LMP_FIX_REAXC_BONDS_KOKKOS_H
+#define LMP_FIX_REAXC_BONDS_KOKKOS_H
+
+#include "fix_reaxc_bonds.h"
+#include "kokkos_type.h"
+
+namespace LAMMPS_NS {
+
+class FixReaxCBondsKokkos : public FixReaxCBonds {
+ public:
+  FixReaxCBondsKokkos(class LAMMPS *, int, char **);
+  virtual ~FixReaxCBondsKokkos();
+  void init();
+
+ private:
+  double nbuf;
+  void Output_ReaxC_Bonds(bigint, FILE *);
+  double memory_usage();
+};
+}
+
+#endif
+#endif
diff --git a/src/KOKKOS/fix_reaxc_species_kokkos.cpp b/src/KOKKOS/fix_reaxc_species_kokkos.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3de0c998c31b937cdebb2c4876bcd972879feb7
--- /dev/null
+++ b/src/KOKKOS/fix_reaxc_species_kokkos.cpp
@@ -0,0 +1,157 @@
+/* ----------------------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+   Contributing authors: Stan Moore (Sandia)
+------------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <math.h>
+#include "atom.h"
+#include <string.h>
+#include "fix_ave_atom.h"
+#include "fix_reaxc_species_kokkos.h"
+#include "domain.h"
+#include "update.h"
+#include "pair_reax_c_kokkos.h"
+#include "modify.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "comm.h"
+#include "force.h"
+#include "compute.h"
+#include "input.h"
+#include "variable.h"
+#include "memory.h"
+#include "error.h"
+#include "reaxc_list.h"
+#include "atom_masks.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixReaxCSpeciesKokkos::FixReaxCSpeciesKokkos(LAMMPS *lmp, int narg, char **arg) :
+  FixReaxCSpecies(lmp, narg, arg)
+{
+  kokkosable = 1;
+  atomKK = (AtomKokkos *) atom;
+  
+  // NOTE: Could improve performance if a Kokkos version of ComputeSpecAtom is added
+
+  datamask_read = X_MASK | V_MASK | Q_MASK | MASK_MASK;
+  datamask_modify = EMPTY_MASK;
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixReaxCSpeciesKokkos::~FixReaxCSpeciesKokkos()
+{
+
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixReaxCSpeciesKokkos::init()
+{
+  Pair* pair_kk = force->pair_match("reax/c/kk",1);
+  if (pair_kk == NULL) error->all(FLERR,"Cannot use fix reax/c/species/kk without "
+                  "pair_style reax/c/kk");
+
+  FixReaxCSpecies::init();
+
+  int irequest = neighbor->request(this,instance_me);
+  neighbor->requests[irequest]->pair = 0;
+  neighbor->requests[irequest]->fix = 1;
+  neighbor->requests[irequest]->newton = 2;
+  neighbor->requests[irequest]->ghost = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixReaxCSpeciesKokkos::FindMolecule()
+{
+  int i,j,ii,jj,inum,itype,jtype,loop,looptot;
+  int change,done,anychange;
+  int *mask = atom->mask;
+  int *ilist;
+  double bo_tmp,bo_cut;
+  double **spec_atom = f_SPECBOND->array_atom;
+
+  inum = list->inum;
+  ilist = list->ilist;
+
+  for (ii = 0; ii < inum; ii++) {
+    i = ilist[ii];
+    if (mask[i] & groupbit) {
+      clusterID[i] = atom->tag[i];
+      x0[i].x = spec_atom[i][1];
+      x0[i].y = spec_atom[i][2];
+      x0[i].z = spec_atom[i][3];
+    }
+    else clusterID[i] = 0.0;
+  }
+
+  loop = 0;
+  while (1) {
+    comm->forward_comm_fix(this);
+    loop ++;
+
+    change = 0;
+    while (1) {
+      done = 1;
+
+      for (ii = 0; ii < inum; ii++) {
+      	i = ilist[ii];
+      	if (!(mask[i] & groupbit)) continue;
+
+      	itype = atom->type[i];
+
+        for (jj = 0; jj < MAXSPECBOND; jj++) {
+      	  j = reaxc->tmpid[i][jj];
+
+      	  if (j < i) continue;
+      	  if (!(mask[j] & groupbit)) continue;
+
+      	  if (clusterID[i] == clusterID[j] && PBCconnected[i] == PBCconnected[j]
+	    && x0[i].x == x0[j].x && x0[i].y == x0[j].y && x0[i].z == x0[j].z) continue;
+
+          jtype = atom->type[j];
+      	  bo_cut = BOCut[itype][jtype];
+      	  bo_tmp = spec_atom[i][jj+7];
+
+      	  if (bo_tmp > bo_cut) {
+            clusterID[i] = clusterID[j] = MIN(clusterID[i], clusterID[j]);
+            PBCconnected[i] = PBCconnected[j] = MAX(PBCconnected[i], PBCconnected[j]);
+            x0[i] = x0[j] = chAnchor(x0[i], x0[j]);
+            if ((fabs(spec_atom[i][1] - spec_atom[j][1]) > reaxc->control->bond_cut)
+             || (fabs(spec_atom[i][2] - spec_atom[j][2]) > reaxc->control->bond_cut)
+             || (fabs(spec_atom[i][3] - spec_atom[j][3]) > reaxc->control->bond_cut))
+              PBCconnected[i] = PBCconnected[j] = 1;
+      	    done = 0;
+      	  }
+      	}
+      }
+      if (!done) change = 1;
+      if (done) break;
+    }
+    MPI_Allreduce(&change,&anychange,1,MPI_INT,MPI_MAX,world);
+    if (!anychange) break;
+
+    MPI_Allreduce(&loop,&looptot,1,MPI_INT,MPI_SUM,world);
+    if (looptot >= 400*nprocs) break;
+
+  }
+}
\ No newline at end of file
diff --git a/src/KOKKOS/fix_reaxc_species_kokkos.h b/src/KOKKOS/fix_reaxc_species_kokkos.h
new file mode 100644
index 0000000000000000000000000000000000000000..64de060006caf0a9965f40c33bad609cfdd468e2
--- /dev/null
+++ b/src/KOKKOS/fix_reaxc_species_kokkos.h
@@ -0,0 +1,41 @@
+/* -*- c++ -*- ----------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   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.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(reax/c/species/kk,FixReaxCSpeciesKokkos)
+
+#else
+
+#ifndef LMP_FIX_REAXC_SPECIES_KOKKOS_H
+#define LMP_FIX_REAXC_SPECIES_KOKKOS_H
+
+#include "fix_reaxc_species.h"
+
+#define BUFLEN 1000
+
+namespace LAMMPS_NS {
+
+class FixReaxCSpeciesKokkos : public FixReaxCSpecies {
+ public:
+  FixReaxCSpeciesKokkos(class LAMMPS *, int, char **);
+  virtual ~FixReaxCSpeciesKokkos();
+  void init();
+
+ private:
+  void FindMolecule();
+};
+}
+
+#endif
+#endif
diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp
index 3bb8b0dce4a20bfea8f88b4c7d5cd8b4facb32dd..9622129e703c13f1fdea34c56bb799a2c71aeca2 100644
--- a/src/KOKKOS/neighbor_kokkos.cpp
+++ b/src/KOKKOS/neighbor_kokkos.cpp
@@ -181,6 +181,9 @@ int NeighborKokkos::init_lists_kokkos()
 
 void NeighborKokkos::init_list_flags1_kokkos(int i)
 {
+  if (style != BIN)
+    error->all(FLERR,"KOKKOS package only supports 'bin' neighbor lists");
+
   if (lists_host[i]) {
     lists_host[i]->buildflag = 1;
     if (pair_build_host[i] == NULL) lists_host[i]->buildflag = 0;
diff --git a/src/KOKKOS/neighbor_kokkos.h b/src/KOKKOS/neighbor_kokkos.h
index 3693ebd9a475df28ca450463e09fdc7eacd8eb66..8c097139a76afa1d9164ff7aaba40aa1601610ef 100644
--- a/src/KOKKOS/neighbor_kokkos.h
+++ b/src/KOKKOS/neighbor_kokkos.h
@@ -434,6 +434,10 @@ class NeighborKokkos : public Neighbor {
 
 /* ERROR/WARNING messages:
 
+E: KOKKOS package only supports 'bin' neighbor lists
+
+Self-explanatory.
+
 E: Too many local+ghost atoms for neighbor list
 
 The number of nlocal + nghost atoms on a processor
diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h
index b880654fbf64933cdf2f7d76f0f37f785c503d83..3710c460c0246e12e10571aa5a9680026597eeb7 100644
--- a/src/KOKKOS/pair_kokkos.h
+++ b/src/KOKKOS/pair_kokkos.h
@@ -611,7 +611,7 @@ struct PairComputeFunctor<PairStyle,N2,STACKPARAMS,Specialisation>  {
 // pair_compute_neighlist and pair_compute_fullcluster will match - either the dummy version
 // or the real one further below.
 template<class PairStyle, unsigned NEIGHFLAG, class Specialisation>
-EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if<!(NEIGHFLAG&PairStyle::EnabledNeighFlags), NeighListKokkos<typename PairStyle::device_type>*>::type list) {
+EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if<!((NEIGHFLAG&PairStyle::EnabledNeighFlags) != 0), NeighListKokkos<typename PairStyle::device_type>*>::type list) {
   EV_FLOAT ev;
   (void) fpair;
   (void) list;
@@ -620,7 +620,7 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable
 }
 
 template<class PairStyle, class Specialisation>
-EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enable_if<!(FULLCLUSTER&PairStyle::EnabledNeighFlags), NeighListKokkos<typename PairStyle::device_type>*>::type list) {
+EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enable_if<!((FULLCLUSTER&PairStyle::EnabledNeighFlags) != 0), NeighListKokkos<typename PairStyle::device_type>*>::type list) {
   EV_FLOAT ev;
   (void) fpair;
   (void) list;
@@ -630,7 +630,7 @@ EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enab
 
 // Submit ParallelFor for NEIGHFLAG=HALF,HALFTHREAD,FULL,N2
 template<class PairStyle, unsigned NEIGHFLAG, class Specialisation>
-EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if<NEIGHFLAG&PairStyle::EnabledNeighFlags, NeighListKokkos<typename PairStyle::device_type>*>::type list) {
+EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if<(NEIGHFLAG&PairStyle::EnabledNeighFlags) != 0, NeighListKokkos<typename PairStyle::device_type>*>::type list) {
   EV_FLOAT ev;
   if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) {
     PairComputeFunctor<PairStyle,NEIGHFLAG,false,Specialisation > ff(fpair,list);
@@ -646,7 +646,7 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable
 
 // Submit ParallelFor for NEIGHFLAG=FULLCLUSTER
 template<class PairStyle, class Specialisation>
-EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enable_if<FULLCLUSTER&PairStyle::EnabledNeighFlags, NeighListKokkos<typename PairStyle::device_type>*>::type list) {
+EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enable_if<(FULLCLUSTER&PairStyle::EnabledNeighFlags) != 0, NeighListKokkos<typename PairStyle::device_type>*>::type list) {
   EV_FLOAT ev;
   if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) {
     typedef PairComputeFunctor<PairStyle,FULLCLUSTER,false,Specialisation >
diff --git a/src/KOKKOS/pair_reax_c_kokkos.cpp b/src/KOKKOS/pair_reax_c_kokkos.cpp
index 4fcb3652e30f2c9881d2bb6e352e3bac585bd761..894c3ab53c9235a7c9d8cbf5e287f7883f536bc0 100644
--- a/src/KOKKOS/pair_reax_c_kokkos.cpp
+++ b/src/KOKKOS/pair_reax_c_kokkos.cpp
@@ -44,7 +44,7 @@
 
 /* ---------------------------------------------------------------------- */
 
-namespace LAMMPS_NS{
+namespace LAMMPS_NS {
 using namespace MathConst;
 using namespace MathSpecial;
 
@@ -69,6 +69,9 @@ PairReaxCKokkos<DeviceType>::PairReaxCKokkos(LAMMPS *lmp) : PairReaxC(lmp)
   nmax = 0;
   maxbo = 1;
   maxhb = 1;
+
+  k_error_flag = DAT::tdual_int_scalar("pair:error_flag");
+  k_nbuf_local = DAT::tdual_int_scalar("pair:nbuf_local");
 }
 
 /* ---------------------------------------------------------------------- */
@@ -76,10 +79,15 @@ PairReaxCKokkos<DeviceType>::PairReaxCKokkos(LAMMPS *lmp) : PairReaxC(lmp)
 template<class DeviceType>
 PairReaxCKokkos<DeviceType>::~PairReaxCKokkos()
 {
-  if (!copymode) {
-    memory->destroy_kokkos(k_eatom,eatom);
-    memory->destroy_kokkos(k_vatom,vatom);
-  }
+  if (copymode) return;
+
+  memory->destroy_kokkos(k_eatom,eatom);
+  memory->destroy_kokkos(k_vatom,vatom);
+
+  memory->destroy_kokkos(k_tmpid,tmpid);
+  tmpid = NULL;
+  memory->destroy_kokkos(k_tmpbo,tmpbo);
+  tmpbo = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -306,6 +314,11 @@ void PairReaxCKokkos<DeviceType>::setup()
   bo_cut = 0.01 * gp[29];
   thb_cut = control->thb_cut;
   thb_cutsq = 0.000010; //thb_cut*thb_cut;
+
+  if (atom->nmax > nmax) {
+    nmax = atom->nmax;
+    allocate_array();
+  }
 }
 
 /* ---------------------------------------------------------------------- */
@@ -980,6 +993,9 @@ void PairReaxCKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
     k_vatom.template sync<LMPHostType>();
   }
 
+  if (fixspecies_flag)
+    FindBondSpecies();
+
   copymode = 0;
 }
 
@@ -1346,6 +1362,19 @@ void PairReaxCKokkos<DeviceType>::allocate_array()
   d_Delta_lp_temp = typename AT::t_ffloat_1d("reax/c/kk:Delta_lp_temp",nmax);
   d_CdDelta = typename AT::t_ffloat_1d("reax/c/kk:CdDelta",nmax);
   d_sum_ovun = typename AT::t_ffloat_2d_dl("reax/c/kk:sum_ovun",nmax,3);
+
+  // FixReaxCSpecies
+  if (fixspecies_flag) {
+    memory->destroy_kokkos(k_tmpid,tmpid);
+    memory->destroy_kokkos(k_tmpbo,tmpbo);
+    memory->create_kokkos(k_tmpid,tmpid,nmax,MAXSPECBOND,"pair:tmpid");
+    memory->create_kokkos(k_tmpbo,tmpbo,nmax,MAXSPECBOND,"pair:tmpbo");
+  }
+
+  // FixReaxCBonds
+  d_abo = typename AT::t_ffloat_2d("reax/c/kk:abo",nmax,maxbo);
+  d_neighid = typename AT::t_tagint_2d("reax/c/kk:neighid",nmax,maxbo);
+  d_numneigh_bonds = typename AT::t_int_1d("reax/c/kk:numneigh_bonds",nmax);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -3954,11 +3983,214 @@ double PairReaxCKokkos<DeviceType>::memory_usage()
   bytes += nmax*17*sizeof(F_FLOAT);
   bytes += maxbo*nmax*34*sizeof(F_FLOAT);
 
+  // FixReaxCSpecies
+  if (fixspecies_flag) {
+    bytes += MAXSPECBOND*nmax*sizeof(tagint);
+    bytes += MAXSPECBOND*nmax*sizeof(F_FLOAT);
+  }
+
+  // FixReaxCBonds
+  bytes += maxbo*nmax*sizeof(tagint);
+  bytes += maxbo*nmax*sizeof(F_FLOAT);
+  bytes += nmax*sizeof(int);
+
   return bytes;
 }
 
 /* ---------------------------------------------------------------------- */
 
+template<class DeviceType>
+void PairReaxCKokkos<DeviceType>::FindBond(int &numbonds)
+{
+  copymode = 1;
+  Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, PairReaxFindBondZero>(0,nmax),*this);
+  DeviceType::fence();
+
+  bo_cut_bond = control->bg_cut;
+
+  atomKK->sync(execution_space,TAG_MASK);
+  tag = atomKK->k_tag.view<DeviceType>();
+
+  const int inum = list->inum;
+  NeighListKokkos<DeviceType>* k_list = static_cast<NeighListKokkos<DeviceType>*>(list);
+  d_ilist = k_list->d_ilist;
+  k_list->clean_copy();
+
+  numbonds = 0;
+  PairReaxCKokkosFindBondFunctor<DeviceType> find_bond_functor(this);
+  Kokkos::parallel_reduce(inum,find_bond_functor,numbonds);
+  DeviceType::fence();
+  copymode = 0;
+}
+
+template<class DeviceType>
+KOKKOS_INLINE_FUNCTION
+void PairReaxCKokkos<DeviceType>::operator()(PairReaxFindBondZero, const int &i) const {
+  d_numneigh_bonds[i] = 0;
+  for (int j = 0; j < maxbo; j++) {
+    d_neighid(i,j) = 0;
+    d_abo(i,j) = 0.0;
+  }
+}
+
+template<class DeviceType>
+KOKKOS_INLINE_FUNCTION
+void PairReaxCKokkos<DeviceType>::calculate_find_bond_item(int ii, int &numbonds) const
+{
+  const int i = d_ilist[ii];
+  int nj = 0;
+
+  const int j_start = d_bo_first[i];
+  const int j_end = j_start + d_bo_num[i];
+  for (int jj = j_start; jj < j_end; jj++) {
+    int j = d_bo_list[jj];
+    j &= NEIGHMASK;
+    const tagint jtag = tag[j];
+    const int j_index = jj - j_start;
+    double bo_tmp = d_BO(i,j_index);
+
+    if (bo_tmp > bo_cut_bond) {
+      d_neighid(i,nj) = jtag;
+      d_abo(i,nj) = bo_tmp;
+      nj++;
+    }
+  }
+  d_numneigh_bonds[i] = nj;
+  if (nj > numbonds) numbonds = nj;
+}
+
+/* ---------------------------------------------------------------------- */
+
+template<class DeviceType>
+void PairReaxCKokkos<DeviceType>::PackBondBuffer(DAT::tdual_ffloat_1d k_buf, int &nbuf_local)
+{
+  d_buf = k_buf.view<DeviceType>();
+  k_params_sing.template sync<DeviceType>();
+  atomKK->sync(execution_space,TAG_MASK|TYPE_MASK|Q_MASK|MOLECULE_MASK);
+
+  tag = atomKK->k_tag.view<DeviceType>();
+  type = atomKK->k_type.view<DeviceType>();
+  q = atomKK->k_q.view<DeviceType>();
+  if (atom->molecule)
+    molecule = atomKK->k_molecule.view<DeviceType>();
+
+  copymode = 1;
+  nlocal = atomKK->nlocal;
+  PairReaxCKokkosPackBondBufferFunctor<DeviceType> pack_bond_buffer_functor(this);
+  Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor);
+  DeviceType::fence();
+  copymode = 0;
+
+  k_buf.modify<DeviceType>();
+  k_nbuf_local.modify<DeviceType>();
+
+  k_buf.sync<LMPHostType>();
+  k_nbuf_local.sync<LMPHostType>();
+  nbuf_local = k_nbuf_local.h_view();
+}
+
+template<class DeviceType>
+KOKKOS_INLINE_FUNCTION
+void PairReaxCKokkos<DeviceType>::pack_bond_buffer_item(int i, int &j, const bool &final) const
+{
+  if (i == 0)
+    j += 2;
+
+  if (final) {
+    d_buf[j-1] = tag[i];
+    d_buf[j+0] = type[i];
+    d_buf[j+1] = d_total_bo[i];
+    d_buf[j+2] = paramssing(type[i]).nlp_opt - d_Delta_lp[i];
+    d_buf[j+3] = q[i];
+    d_buf[j+4] = d_numneigh_bonds[i];
+  }
+  const int numbonds = d_numneigh_bonds[i];
+
+  if (final) {
+    for (int k = 5; k < 5+numbonds; k++) {
+      d_buf[j+k] = d_neighid(i,k-5);
+    }
+  }
+  j += (5+numbonds);
+
+  if (final) {
+    if (!molecule.data()) d_buf[j] = 0.0;
+    else d_buf[j] = molecule[i];
+  }
+  j++;
+
+  if (final) {
+    for (int k = 0; k < numbonds; k++) {
+      d_buf[j+k] = d_abo(i,k);
+    }
+  }
+  j += (1+numbonds);
+
+  if (final && i == nlocal-1)
+    k_nbuf_local.view<DeviceType>()() = j - 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+template<class DeviceType>
+void PairReaxCKokkos<DeviceType>::FindBondSpecies()
+{
+  copymode = 1;
+  Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, PairReaxFindBondSpeciesZero>(0,nmax),*this);
+  DeviceType::fence();
+
+  nlocal = atomKK->nlocal;
+  Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, PairReaxFindBondSpecies>(0,nlocal),*this);
+  DeviceType::fence();
+  copymode = 0;
+
+  // NOTE: Could improve performance if a Kokkos version of ComputeSpecAtom is added
+
+  k_tmpbo.modify<DeviceType>();
+  k_tmpid.modify<DeviceType>();
+  k_error_flag.modify<DeviceType>();
+
+  k_tmpbo.sync<LMPHostType>();
+  k_tmpid.sync<LMPHostType>();
+  k_error_flag.sync<LMPHostType>();
+
+  if (k_error_flag.h_view())
+    error->all(FLERR,"Increase MAXSPECBOND in reaxc_defs.h");
+}
+
+template<class DeviceType>
+KOKKOS_INLINE_FUNCTION
+void PairReaxCKokkos<DeviceType>::operator()(PairReaxFindBondSpeciesZero, const int &i) const {
+  for (int j = 0; j < MAXSPECBOND; j++) {
+    k_tmpbo.view<DeviceType>()(i,j) = 0.0;
+    k_tmpid.view<DeviceType>()(i,j) = 0;
+  }
+}
+
+template<class DeviceType>
+KOKKOS_INLINE_FUNCTION
+void PairReaxCKokkos<DeviceType>::operator()(PairReaxFindBondSpecies, const int &i) const {
+  int nj = 0;
+
+  const int j_start = d_bo_first[i];
+  const int j_end = j_start + d_bo_num[i];
+  for (int jj = j_start; jj < j_end; jj++) {
+    int j = d_bo_list[jj];
+    j &= NEIGHMASK;
+    if (j < i) continue;
+    const int j_index = jj - j_start;
+  
+    double bo_tmp = d_BO(i,j_index);
+  
+    if (bo_tmp >= 0.10 ) { // Why is this a hardcoded value?
+      k_tmpid.view<DeviceType>()(i,nj) = j;
+      k_tmpbo.view<DeviceType>()(i,nj) = bo_tmp;
+      nj++;
+      if (nj > MAXSPECBOND) k_error_flag.view<DeviceType>()() = 1;
+    }
+  }
+}
+
 template class PairReaxCKokkos<LMPDeviceType>;
 #ifdef KOKKOS_HAVE_CUDA
 template class PairReaxCKokkos<LMPHostType>;
diff --git a/src/KOKKOS/pair_reax_c_kokkos.h b/src/KOKKOS/pair_reax_c_kokkos.h
index 8c07ee2a0355a7870c88e48aeb8522f6e4a3538d..204ad7732f9cd56d54b30b6d442f9b0f32e2c2fa 100644
--- a/src/KOKKOS/pair_reax_c_kokkos.h
+++ b/src/KOKKOS/pair_reax_c_kokkos.h
@@ -115,6 +115,13 @@ struct PairReaxComputeTorsion{};
 template<int NEIGHFLAG, int EVFLAG>
 struct PairReaxComputeHydrogen{};
 
+struct PairReaxFindBondZero{};
+
+struct PairReaxFindBondSpeciesZero{};
+
+struct PairReaxFindBondSpecies{};
+
+
 template<class DeviceType>
 class PairReaxCKokkos : public PairReaxC {
  public:
@@ -132,6 +139,9 @@ class PairReaxCKokkos : public PairReaxC {
   void *extract(const char *, int &);
   void init_style();
   double memory_usage();
+  void FindBond(int &);
+  void PackBondBuffer(DAT::tdual_ffloat_1d, int &);
+  void FindBondSpecies();
 
   template<int NEIGHFLAG, int EVFLAG>
   KOKKOS_INLINE_FUNCTION
@@ -245,6 +255,21 @@ class PairReaxCKokkos : public PairReaxC {
   KOKKOS_INLINE_FUNCTION
   void operator()(PairReaxComputeHydrogen<NEIGHFLAG,EVFLAG>, const int&) const;
 
+  KOKKOS_INLINE_FUNCTION
+  void operator()(PairReaxFindBondZero, const int&) const;
+
+  KOKKOS_INLINE_FUNCTION
+  void calculate_find_bond_item(int, int&) const;
+
+  KOKKOS_INLINE_FUNCTION
+  void pack_bond_buffer_item(int, int&, const bool&) const;
+
+  KOKKOS_INLINE_FUNCTION
+  void operator()(PairReaxFindBondSpeciesZero, const int&) const;
+
+  KOKKOS_INLINE_FUNCTION
+  void operator()(PairReaxFindBondSpecies, const int&) const;
+
   struct params_sing{
     KOKKOS_INLINE_FUNCTION
     params_sing(){mass=0;chi=0;eta=0;r_s=0;r_pi=0;r_pi2=0;valency=0;valency_val=0;valency_e=0;valency_boc=0;nlp_opt=0;
@@ -359,8 +384,9 @@ class PairReaxCKokkos : public PairReaxC {
   typename AT::t_x_array_randomread x;
   typename AT::t_f_array f;
   typename AT::t_int_1d_randomread type;
-  typename AT::t_tagint_1d tag;
+  typename AT::t_tagint_1d_randomread tag;
   typename AT::t_float_1d_randomread q;
+  typename AT::t_tagint_1d_randomread molecule;
 
   DAT::tdual_efloat_1d k_eatom;
   typename AT::t_efloat_1d v_eatom;
@@ -405,6 +431,7 @@ class PairReaxCKokkos : public PairReaxC {
   int neighflag,newton_pair, maxnumneigh, maxhb, maxbo;
   int nlocal,nall,eflag,vflag;
   F_FLOAT cut_nbsq, cut_hbsq, cut_bosq, bo_cut, thb_cut, thb_cutsq;
+  F_FLOAT bo_cut_bond;
 
   int vdwflag, lgflag;
   F_FLOAT gp[39], p_boc1, p_boc2;
@@ -418,6 +445,49 @@ class PairReaxCKokkos : public PairReaxC {
 
   tdual_LR_lookup_table_kk_2d k_LR;
   t_LR_lookup_table_kk_2d d_LR;
+
+  DAT::tdual_int_2d k_tmpid;
+  DAT::tdual_ffloat_2d k_tmpbo;
+  DAT::tdual_int_scalar k_error_flag;
+
+  typename AT::t_int_1d d_numneigh_bonds;
+  typename AT::t_tagint_2d d_neighid;
+  typename AT::t_ffloat_2d d_abo;
+
+  typename AT::t_ffloat_1d d_buf;
+  DAT::tdual_int_scalar k_nbuf_local;
+};
+
+template <class DeviceType>
+struct PairReaxCKokkosFindBondFunctor  {
+  typedef DeviceType device_type;
+  typedef int value_type;
+  PairReaxCKokkos<DeviceType> c;
+  PairReaxCKokkosFindBondFunctor(PairReaxCKokkos<DeviceType>* c_ptr):c(*c_ptr) {};
+
+  KOKKOS_INLINE_FUNCTION
+  void join(volatile int &dst,
+             const volatile int &src) const {
+    dst = MAX(dst,src);
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  void operator()(const int ii, int &numbonds) const {
+    c.calculate_find_bond_item(ii,numbonds);
+  }
+};
+
+template <class DeviceType>
+struct PairReaxCKokkosPackBondBufferFunctor  {
+  typedef DeviceType device_type;
+  typedef int value_type;
+  PairReaxCKokkos<DeviceType> c;
+  PairReaxCKokkosPackBondBufferFunctor(PairReaxCKokkos<DeviceType>* c_ptr):c(*c_ptr) {};
+
+  KOKKOS_INLINE_FUNCTION
+  void operator()(const int ii, int &j, const bool &final) const {
+    c.pack_bond_buffer_item(ii,j,final);
+  }
 };
 
 }
diff --git a/src/USER-REAXC/compute_spec_atom.cpp b/src/USER-REAXC/compute_spec_atom.cpp
index 38cf9ad6e6524f495b177f60749b66c0110b2906..4af8efcae71b324da7d5b8a872f13e5e491dae59 100644
--- a/src/USER-REAXC/compute_spec_atom.cpp
+++ b/src/USER-REAXC/compute_spec_atom.cpp
@@ -44,6 +44,8 @@ ComputeSpecAtom::ComputeSpecAtom(LAMMPS *lmp, int narg, char **arg) :
 
   // Initiate reaxc
   reaxc = (PairReaxC *) force->pair_match("reax/c",1);
+  if (reaxc == NULL)
+    reaxc = (PairReaxC *) force->pair_match("reax/c/kk",1);
 
   pack_choice = new FnPtrPack[nvalues];
 
diff --git a/src/USER-REAXC/fix_reaxc_bonds.cpp b/src/USER-REAXC/fix_reaxc_bonds.cpp
index 5f653557a5dabdd3a03f3330c0bf3533f2a8ab54..543669de766cce7c3a1466988623af1f564b2dd0 100644
--- a/src/USER-REAXC/fix_reaxc_bonds.cpp
+++ b/src/USER-REAXC/fix_reaxc_bonds.cpp
@@ -107,11 +107,10 @@ void FixReaxCBonds::setup(int vflag)
 
 void FixReaxCBonds::init()
 {
-  Pair *pair_kk = force->pair_match("reax/c/kk",1);
-  if (pair_kk != NULL) error->all(FLERR,"Cannot (yet) use fix reax/c/bonds with "
-                  "pair_style reax/c/kk");
-
   reaxc = (PairReaxC *) force->pair_match("reax/c",1);
+  if (reaxc == NULL)
+    reaxc = (PairReaxC *) force->pair_match("reax/c/kk",1);
+
   if (reaxc == NULL) error->all(FLERR,"Cannot use fix reax/c/bonds without "
                   "pair_style reax/c");
 
diff --git a/src/USER-REAXC/fix_reaxc_bonds.h b/src/USER-REAXC/fix_reaxc_bonds.h
index b91085163b51c1f0eb73811c447668e3dd52175c..e1dcd82c0e43ed96323668a918dfd9259e05939e 100644
--- a/src/USER-REAXC/fix_reaxc_bonds.h
+++ b/src/USER-REAXC/fix_reaxc_bonds.h
@@ -29,13 +29,13 @@ namespace LAMMPS_NS {
 class FixReaxCBonds : public Fix {
  public:
   FixReaxCBonds(class LAMMPS *, int, char **);
-  ~FixReaxCBonds();
+  virtual ~FixReaxCBonds();
   int setmask();
-  void init();
+  virtual void init();
   void setup(int);
   void end_of_step();
 
- private:
+ protected:
   int me, nprocs, nmax, ntypes, maxsize;
   int *numneigh;
   tagint **neighid;
@@ -44,12 +44,12 @@ class FixReaxCBonds : public Fix {
 
   void allocate();
   void destroy();
-  void Output_ReaxC_Bonds(bigint, FILE *);
+  virtual void Output_ReaxC_Bonds(bigint, FILE *);
   void FindBond(struct _reax_list*, int &);
   void PassBuffer(double *, int &);
   void RecvBuffer(double *, int, int, int, int);
   int nint(const double &);
-  double memory_usage();
+  virtual double memory_usage();
 
   bigint nvalid, nextvalid();
   struct _reax_list *lists;
diff --git a/src/USER-REAXC/fix_reaxc_species.cpp b/src/USER-REAXC/fix_reaxc_species.cpp
index c8acc5f0e0a803fbab1fc347686ba2f5ea36cd37..ead73f02a1328cef35a4af076ee8e1f0818aa490 100644
--- a/src/USER-REAXC/fix_reaxc_species.cpp
+++ b/src/USER-REAXC/fix_reaxc_species.cpp
@@ -284,11 +284,10 @@ void FixReaxCSpecies::init()
   if (atom->tag_enable == 0)
     error->all(FLERR,"Cannot use fix reax/c/species unless atoms have IDs");
 
-  Pair *pair_kk = force->pair_match("reax/c/kk",1);
-  if (pair_kk != NULL) error->all(FLERR,"Cannot (yet) use fix reax/c/species with "
-                  "pair_style reax/c/kk");
-
   reaxc = (PairReaxC *) force->pair_match("reax/c",1);
+  if (reaxc == NULL)
+    reaxc = (PairReaxC *) force->pair_match("reax/c/kk",1);
+
   if (reaxc == NULL) error->all(FLERR,"Cannot use fix reax/c/species without "
 		  "pair_style reax/c");
 
@@ -485,7 +484,7 @@ void FixReaxCSpecies::Output_ReaxC_Bonds(bigint ntimestep, FILE *fp)
 
 /* ---------------------------------------------------------------------- */
 
-AtomCoord chAnchor(AtomCoord in1, AtomCoord in2)
+AtomCoord FixReaxCSpecies::chAnchor(AtomCoord in1, AtomCoord in2)
 {
   if (in1.x < in2.x)
     return in1;
diff --git a/src/USER-REAXC/fix_reaxc_species.h b/src/USER-REAXC/fix_reaxc_species.h
index a3a47b29ddfa6b7b42d7377372eb8f1cd2db2354..872ea2528f06df00cd27ee0e76fd19fa66fdad51 100644
--- a/src/USER-REAXC/fix_reaxc_species.h
+++ b/src/USER-REAXC/fix_reaxc_species.h
@@ -38,15 +38,15 @@ typedef struct {
 class FixReaxCSpecies : public Fix {
  public:
   FixReaxCSpecies(class LAMMPS *, int, char **);
-  ~FixReaxCSpecies();
+  virtual ~FixReaxCSpecies();
   int setmask();
-  void init();
+  virtual void init();
   void init_list(int, class NeighList *);
   void setup(int);
   void post_integrate();
   double compute_vector(int);
 
- private:
+ protected:
   int me, nprocs, nmax, nlocal, ntypes, ntotal;
   int nrepeat, nfreq, posfreq;
   int Nmoltype, vector_nmole, vector_nspec;
@@ -67,7 +67,8 @@ class FixReaxCSpecies : public Fix {
   void Output_ReaxC_Bonds(bigint, FILE *);
   void create_compute();
   void create_fix();
-  void FindMolecule();
+  AtomCoord chAnchor(AtomCoord, AtomCoord);
+  virtual void FindMolecule();
   void SortMolecule(int &);
   void FindSpecies(int, int &);
   void WriteFormulas(int, int);
diff --git a/src/atom.cpp b/src/atom.cpp
index 8e48611284b92700942c4ffcb38955af2a0252fe..e1ec60fd99fc1dcc229e48f1e68a155437cb4402 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -26,11 +26,14 @@
 #include "force.h"
 #include "modify.h"
 #include "fix.h"
+#include "compute.h"
 #include "output.h"
 #include "thermo.h"
 #include "update.h"
 #include "domain.h"
 #include "group.h"
+#include "input.h"
+#include "variable.h"
 #include "molecule.h"
 #include "atom_masks.h"
 #include "math_const.h"
@@ -1388,6 +1391,33 @@ void Atom::data_bodies(int n, char *buf, AtomVecBody *avec_body,
   delete [] dvalues;
 }
 
+/* ----------------------------------------------------------------------
+   init per-atom fix/compute/variable values for newly created atoms
+   called from create_atoms, read_data, read_dump,
+     lib::lammps_create_atoms()
+   fixes, computes, variables may or may not exist when called
+------------------------------------------------------------------------- */
+
+void Atom::data_fix_compute_variable(int nprev, int nnew)
+{
+  for (int m = 0; m < modify->nfix; m++) {
+    Fix *fix = modify->fix[m];
+    if (fix->create_attribute)
+      for (int i = nprev; i < nnew; i++)
+        fix->set_arrays(i);
+  }
+
+  for (int m = 0; m < modify->ncompute; m++) {
+    Compute *compute = modify->compute[m];
+    if (compute->create_attribute)
+      for (int i = nprev; i < nnew; i++)
+        compute->set_arrays(i);
+  }
+
+  for (int i = nprev; i < nnew; i++)
+    input->variable->set_arrays(i);
+}
+
 /* ----------------------------------------------------------------------
    allocate arrays of length ntypes
    only done after ntypes is set
diff --git a/src/atom.h b/src/atom.h
index 61cd9673bfc838e730d30698250780411fe7b15a..748d43cddd1c4e685986c7c9e0c048e7d9ebff1d 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -225,15 +225,14 @@ class Atom : protected Pointers {
 
   void data_atoms(int, char *, tagint, int, int, double *);
   void data_vels(int, char *, tagint);
-
   void data_bonds(int, char *, int *, tagint, int);
   void data_angles(int, char *, int *, tagint, int);
   void data_dihedrals(int, char *, int *, tagint, int);
   void data_impropers(int, char *, int *, tagint, int);
-
   void data_bonus(int, char *, class AtomVec *, tagint);
   void data_bodies(int, char *, class AtomVecBody *, tagint);
-
+  void data_fix_compute_variable(int, int);
+  
   virtual void allocate_type_arrays();
   void set_mass(const char *, int);
   void set_mass(int, double);
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index 82315e7dc5f813374fdeace3d79c53531d60c4dc..776a94c8b933d58960cecf5ac6ba1178f780ba75 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -359,30 +359,9 @@ void CreateAtoms::command(int narg, char **arg)
   else if (style == RANDOM) add_random();
   else add_lattice();
 
-  // invoke set_arrays() for fixes/computes/variables
-  //   that need initialization of attributes of new atoms
-  // don't use modify->create_attributes() since would be inefficient
-  //   for large number of atoms
-  // note that for typical early use of create_atoms,
-  //   no fixes/computes/variables exist yet
-
-  int nlocal = atom->nlocal;
-  for (int m = 0; m < modify->nfix; m++) {
-    Fix *fix = modify->fix[m];
-    if (fix->create_attribute)
-      for (int i = nlocal_previous; i < nlocal; i++)
-        fix->set_arrays(i);
-  }
-
-  for (int m = 0; m < modify->ncompute; m++) {
-    Compute *compute = modify->compute[m];
-    if (compute->create_attribute)
-      for (int i = nlocal_previous; i < nlocal; i++)
-        compute->set_arrays(i);
-  }
-
-  for (int i = nlocal_previous; i < nlocal; i++)
-    input->variable->set_arrays(i);
+  // init per-atom fix/compute/variable values for created atoms
+  
+  atom->data_fix_compute_variable(nlocal_previous,atom->nlocal);
 
   // set new total # of atoms and error check
 
diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp
index 4ac7c0262203c89db1f7f9208a40606622d92722..116c2a2f1e057431644c82b2747d7d95eac6095c 100644
--- a/src/delete_atoms.cpp
+++ b/src/delete_atoms.cpp
@@ -59,7 +59,9 @@ void DeleteAtoms::command(int narg, char **arg)
   bigint ndihedrals_previous = atom->ndihedrals;
   bigint nimpropers_previous = atom->nimpropers;
 
-  // delete the atoms
+  // flag atoms for deletion
+
+  allflag = 0;
 
   if (strcmp(arg[0],"group") == 0) delete_group(narg,arg);
   else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg);
@@ -67,36 +69,44 @@ void DeleteAtoms::command(int narg, char **arg)
   else if (strcmp(arg[0],"porosity") == 0) delete_porosity(narg,arg);
   else error->all(FLERR,"Illegal delete_atoms command");
 
-  // optionally delete additional bonds or atoms in molecules
+  // if allflag = 1, just reset atom->nlocal
+  // else delete atoms one by one
 
-  if (bond_flag) delete_bond();
-  if (mol_flag) delete_molecule();
+  if (allflag) atom->nlocal = 0;
+  else {
 
-  // delete local atoms flagged in dlist
-  // reset nlocal
+    // optionally delete additional bonds or atoms in molecules
 
-  AtomVec *avec = atom->avec;
-  int nlocal = atom->nlocal;
+    if (bond_flag) delete_bond();
+    if (mol_flag) delete_molecule();
 
-  int i = 0;
-  while (i < nlocal) {
-    if (dlist[i]) {
-      avec->copy(nlocal-1,i,1);
-      dlist[i] = dlist[nlocal-1];
-      nlocal--;
-    } else i++;
-  }
+    // delete local atoms flagged in dlist
+    // reset nlocal
 
-  atom->nlocal = nlocal;
-  memory->destroy(dlist);
+    AtomVec *avec = atom->avec;
+    int nlocal = atom->nlocal;
 
+    int i = 0;
+    while (i < nlocal) {
+      if (dlist[i]) {
+	avec->copy(nlocal-1,i,1);
+	dlist[i] = dlist[nlocal-1];
+	nlocal--;
+      } else i++;
+    }
+    
+    atom->nlocal = nlocal;
+    memory->destroy(dlist);
+  }
+  
   // if non-molecular system and compress flag set,
   // reset atom tags to be contiguous
   // set all atom IDs to 0, call tag_extend()
 
   if (atom->molecular == 0 && compress_flag) {
     tagint *tag = atom->tag;
-    for (i = 0; i < nlocal; i++) tag[i] = 0;
+    int nlocal = atom->nlocal;
+    for (int i = 0; i < nlocal; i++) tag[i] = 0;
     atom->tag_extend();
   }
 
@@ -185,6 +195,13 @@ void DeleteAtoms::delete_group(int narg, char **arg)
   if (igroup == -1) error->all(FLERR,"Could not find delete_atoms group ID");
   options(narg-2,&arg[2]);
 
+  // check for special case of group = all
+
+  if (strcmp(arg[1],"all") == 0) {
+    allflag = 1;
+    return;
+  }
+  
   // allocate and initialize deletion list
 
   int nlocal = atom->nlocal;
diff --git a/src/delete_atoms.h b/src/delete_atoms.h
index 6fc2ea1f90b8134c1322f37e463f2aa7fa6cdf3e..62ba47d715d47efab94161362d21c5dcfa542847 100644
--- a/src/delete_atoms.h
+++ b/src/delete_atoms.h
@@ -32,7 +32,7 @@ class DeleteAtoms : protected Pointers {
 
  private:
   int *dlist;
-  int compress_flag,bond_flag,mol_flag;
+  int allflag,compress_flag,bond_flag,mol_flag;
   std::map<tagint,int> *hash;
 
   void delete_group(int, char **);
diff --git a/src/domain.cpp b/src/domain.cpp
index 2c3f61401d9112a3504afa0e504e2db9edb3fecc..c348167dfb623e4925d858db7b649ff6de491d8d 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -1496,6 +1496,28 @@ void Domain::image_flip(int m, int n, int p)
   }
 }
 
+/* ----------------------------------------------------------------------
+   return 1 if this proc owns atom with coords x, else return 0
+   x is returned remapped into periodic box
+------------------------------------------------------------------------- */
+
+int Domain::ownatom(double *x)
+{
+  double lamda[3];
+  double *coord;
+  
+  remap(x);
+  if (triclinic) {
+    x2lamda(x,lamda);
+    coord = lamda;
+  } else coord = x;
+  
+  if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
+      coord[1] >= sublo[1] && coord[1] < subhi[1] &&
+      coord[2] >= sublo[2] && coord[2] < subhi[2]) return 1;
+  return 0;
+}
+
 /* ----------------------------------------------------------------------
    create a lattice
 ------------------------------------------------------------------------- */
@@ -1929,5 +1951,3 @@ void Domain::lamda_box_corners(double *lo, double *hi)
   corners[7][0] = hi[0]; corners[7][1] = hi[1]; corners[7][2] = subhi_lamda[2];
   lamda2x(corners[7],corners[7]);
 }
-
-
diff --git a/src/domain.h b/src/domain.h
index ef3de4207177438854ba13281334442d3bf8a2d4..e2425f458576da20197b8e9675476d33aaabcdaf 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -121,6 +121,8 @@ class Domain : protected Pointers {
   void unmap(double *, imageint);
   void unmap(double *, imageint, double *);
   void image_flip(int, int, int);
+  int ownatom(double *);
+  
   void set_lattice(int, char **);
   void add_region(int, char **);
   void delete_region(int, char **);
diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp
index 01ba81e5547c09c2dfc84418f4824e90206c3b90..1799a00558c039f3484a39b3eb70ad03aca7bd0d 100644
--- a/src/fix_nh.cpp
+++ b/src/fix_nh.cpp
@@ -51,11 +51,10 @@ enum{ISO,ANISO,TRICLINIC};
  ---------------------------------------------------------------------- */
 
 FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
-tstat_flag(0), pstat_flag(0),
 rfix(NULL), id_dilate(NULL), irregular(NULL), id_temp(NULL), id_press(NULL),
-tcomputeflag(0), pcomputeflag(0), eta(NULL), eta_dot(NULL), eta_dotdot(NULL),
+eta(NULL), eta_dot(NULL), eta_dotdot(NULL),
 eta_mass(NULL), etap(NULL), etap_dot(NULL), etap_dotdot(NULL), 
-etap_mass(NULL), mpchain(0)
+etap_mass(NULL)
 {
   if (narg < 4) error->all(FLERR,"Illegal fix nvt/npt/nph command");
 
@@ -478,8 +477,10 @@ etap_mass(NULL), mpchain(0)
 
     // pre_exchange only required if flips can occur due to shape changes
 
-    if (flipflag && (p_flag[3] || p_flag[4] || p_flag[5])) pre_exchange_flag = 1;
-    if (flipflag && (domain->yz != 0.0 || domain->xz != 0.0 || domain->xy != 0.0))
+    if (flipflag && (p_flag[3] || p_flag[4] || p_flag[5])) 
+      pre_exchange_flag = 1;
+    if (flipflag && (domain->yz != 0.0 || domain->xz != 0.0 || 
+                     domain->xy != 0.0))
       pre_exchange_flag = 1;
   }
 
diff --git a/src/input.cpp b/src/input.cpp
index 905e7f0590438ad068f347b4b30cd87d5a2102b0..fdb551d3da455f987daf03813377986c699e26e3 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -278,7 +278,8 @@ void Input::file(const char *filename)
 }
 
 /* ----------------------------------------------------------------------
-   copy command in single to line, parse and execute it
+   invoke one command in single
+   first copy to line, then parse, then execute it
    return command name to caller
 ------------------------------------------------------------------------- */
 
diff --git a/src/library.cpp b/src/library.cpp
index 44e2c407825b51cc0b523173475a23eb302dcbb8..90c7cfa9d5162d120131385b3bed0cdd858fcebe 100644
--- a/src/library.cpp
+++ b/src/library.cpp
@@ -18,9 +18,11 @@
 #include <string.h>
 #include <stdlib.h>
 #include "library.h"
+#include "lmptype.h"
 #include "lammps.h"
 #include "universe.h"
 #include "input.h"
+#include "atom_vec.h"
 #include "atom.h"
 #include "domain.h"
 #include "update.h"
@@ -38,8 +40,12 @@
 
 using namespace LAMMPS_NS;
 
+// ----------------------------------------------------------------------
+// utility macros
+// ----------------------------------------------------------------------
+
 /* ----------------------------------------------------------------------
-   Utility macros for optional code path which captures all exceptions
+   macros for optional code path which captures all exceptions
    and stores the last error message. These assume there is a variable lmp
    which is a pointer to the current LAMMPS instance.
 
@@ -76,6 +82,37 @@ using namespace LAMMPS_NS;
 #define END_CAPTURE
 #endif
 
+// ----------------------------------------------------------------------
+// helper functions, not in library API
+// ----------------------------------------------------------------------
+
+/* ----------------------------------------------------------------------
+   concatenate one or more LAMMPS input lines starting at ptr
+   removes NULL terminator when last printable char of line = '&'
+     by replacing both NULL and '&' with space character
+   repeat as many times as needed
+   on return, ptr now points to longer line
+------------------------------------------------------------------------- */
+
+void concatenate_lines(char *ptr)
+{
+  int nend = strlen(ptr);
+  int n = nend-1;
+  while (n && isspace(ptr[n])) n--;
+  while (ptr[n] == '&') {
+    ptr[nend] = ' ';
+    ptr[n] = ' ';
+    strtok(ptr,"\n");
+    nend = strlen(ptr);
+    n = nend-1;
+    while (n && isspace(ptr[n])) n--;
+  }
+}
+
+// ----------------------------------------------------------------------
+// library API functions to create/destroy an instance of LAMMPS
+//   and communicate commands to it
+// ----------------------------------------------------------------------
 
 /* ----------------------------------------------------------------------
    create an instance of LAMMPS and return pointer to it
@@ -172,12 +209,14 @@ void lammps_file(void *ptr, char *str)
 
 /* ----------------------------------------------------------------------
    process a single input command in str
+   does not matter if str ends in newline
+   return command name to caller
 ------------------------------------------------------------------------- */
 
 char *lammps_command(void *ptr, char *str)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
-  char * result = NULL;
+  char *result = NULL;
 
   BEGIN_CAPTURE
   {
@@ -188,6 +227,69 @@ char *lammps_command(void *ptr, char *str)
   return result;
 }
 
+/* ----------------------------------------------------------------------
+   process multiple input commands in cmds = list of strings
+   does not matter if each string ends in newline
+   create long contatentated string for processing by commands_string()
+   insert newlines in concatenated string as needed
+------------------------------------------------------------------------- */
+
+void lammps_commands_list(void *ptr, int ncmd, char **cmds)
+{
+  LAMMPS *lmp = (LAMMPS *) ptr;
+
+  int n = ncmd+1;
+  for (int i = 0; i < ncmd; i++) n += strlen(cmds[i]);
+
+  char *str = (char *) lmp->memory->smalloc(n,"lib/commands/list:str");
+  str[0] = '\0';
+  n = 0;
+
+  for (int i = 0; i < ncmd; i++) {
+    strcpy(&str[n],cmds[i]);
+    n += strlen(cmds[i]);
+    if (str[n-1] != '\n') {
+      str[n] = '\n';
+      str[n+1] = '\0';
+      n++;
+    }
+  }
+
+  lammps_commands_string(ptr,str);
+  lmp->memory->sfree(str);
+}
+
+/* ----------------------------------------------------------------------
+   process multiple input commands in single long str, separated by newlines
+   single command can span multiple lines via continuation characters 
+   multi-line commands enabled by triple quotes will not work
+------------------------------------------------------------------------- */
+
+void lammps_commands_string(void *ptr, char *str)
+{
+  LAMMPS *lmp = (LAMMPS *) ptr;
+
+  // make copy of str so can strtok() it
+
+  int n = strlen(str) + 1;
+  char *copy = new char[n];
+  strcpy(copy,str);
+
+  BEGIN_CAPTURE
+  {
+    char *ptr = strtok(copy,"\n");
+    if (ptr) concatenate_lines(ptr);
+    while (ptr) {
+      lmp->input->one(ptr);
+      ptr = strtok(NULL,"\n");
+      if (ptr) concatenate_lines(ptr);
+    }
+  }
+  END_CAPTURE
+
+  delete [] copy;
+}
+
 /* ----------------------------------------------------------------------
    clean-up function to free memory allocated by lib and returned to caller
 ------------------------------------------------------------------------- */
@@ -197,6 +299,10 @@ void lammps_free(void *ptr)
   free(ptr);
 }
 
+// ----------------------------------------------------------------------
+// library API functions to extract info from LAMMPS or set info in LAMMPS
+// ----------------------------------------------------------------------
+
 /* ----------------------------------------------------------------------
    add LAMMPS-specific library functions
    all must receive LAMMPS pointer as argument
@@ -209,6 +315,8 @@ void lammps_free(void *ptr)
    returns a void pointer to the entity
      which the caller can cast to the proper data type
    returns a NULL if name not listed below
+   this function need only be invoked once
+     the returned pointer is a permanent valid reference to the quantity
    customize by adding names
 ------------------------------------------------------------------------- */
 
@@ -232,14 +340,16 @@ void *lammps_extract_global(void *ptr, char *name)
   if (strcmp(name,"ndihedrals") == 0) return (void *) &lmp->atom->ndihedrals;
   if (strcmp(name,"nimpropers") == 0) return (void *) &lmp->atom->nimpropers;
   if (strcmp(name,"nlocal") == 0) return (void *) &lmp->atom->nlocal;
+  if (strcmp(name,"nghost") == 0) return (void *) &lmp->atom->nghost;
+  if (strcmp(name,"nmax") == 0) return (void *) &lmp->atom->nmax;
   if (strcmp(name,"ntimestep") == 0) return (void *) &lmp->update->ntimestep;
 
-  // NOTE: we cannot give access to the thermo "time" data by reference,
-  // as that is a recomputed property.  Only "atime" can be provided as pointer.
-  // please use lammps_get_thermo() defined below to access all supported
-  // thermo keywords by value.
+  // update atime can be referenced as a pointer
+  // thermo "timer" data cannot be, since it is computed on request
+  // lammps_get_thermo() can access all thermo keywords by value
 
   if (strcmp(name,"atime") == 0) return (void *) &lmp->update->atime;
+  if (strcmp(name,"atimestep") == 0) return (void *) &lmp->update->atimestep;
 
   return NULL;
 }
@@ -250,6 +360,8 @@ void *lammps_extract_global(void *ptr, char *name)
    returns a void pointer to the entity
      which the caller can cast to the proper data type
    returns a NULL if Atom::extract() does not recognize the name
+   the returned pointer is not a permanent valid reference to the
+     per-atom quantity, since LAMMPS may reallocate per-atom data
    customize by adding names to Atom::extract()
 ------------------------------------------------------------------------- */
 
@@ -261,6 +373,7 @@ void *lammps_extract_atom(void *ptr, char *name)
 
 /* ----------------------------------------------------------------------
    extract a pointer to an internal LAMMPS compute-based entity
+   the compute is invoked if its value(s) is not current
    id = compute ID
    style = 0 for global data, 1 for per-atom data, 2 for local data
    type = 0 for scalar, 1 for vector, 2 for array
@@ -275,6 +388,8 @@ void *lammps_extract_atom(void *ptr, char *name)
    returns a void pointer to the compute's internal data structure
      for the entity which the caller can cast to the proper data type
    returns a NULL if id is not recognized or style/type not supported
+   the returned pointer is not a permanent valid reference to the
+     compute data, this function should be re-invoked
    IMPORTANT: if the compute is not current it will be invoked
      LAMMPS cannot easily check here if it is valid to invoke the compute,
      so caller must insure that it is OK
@@ -492,11 +607,11 @@ int lammps_set_variable(void *ptr, char *name, char *str)
 }
 
 /* ----------------------------------------------------------------------
-   return the current value of a thermo keyword as double.
+   return the current value of a thermo keyword as a double
    unlike lammps_extract_global() this does not give access to the
-   storage of the data in question, and thus needs to be called
-   again to retrieve an updated value. The upshot is that it allows
-   accessing information that is only computed on-the-fly.
+     storage of the data in question
+   instead it triggers the Thermo class to compute the current value
+     and returns it
 ------------------------------------------------------------------------- */
 
 double lammps_get_thermo(void *ptr, char *name)
@@ -529,12 +644,13 @@ int lammps_get_natoms(void *ptr)
 
 /* ----------------------------------------------------------------------
    gather the named atom-based entity across all processors
+   atom IDs must be consecutive from 1 to N
    name = desired quantity, e.g. x or charge
    type = 0 for integer values, 1 for double values
    count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f
    return atom-based values in data, ordered by count, then by atom ID
      e.g. x[0][0],x[0][1],x[0][2],x[1][0],x[1][1],x[1][2],x[2][0],...
-   data must be pre-allocated by caller to correct length
+     data must be pre-allocated by caller to correct length
 ------------------------------------------------------------------------- */
 
 void lammps_gather_atoms(void *ptr, char *name,
@@ -547,7 +663,8 @@ void lammps_gather_atoms(void *ptr, char *name,
     // error if tags are not defined or not consecutive
 
     int flag = 0;
-    if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) flag = 1;
+    if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) 
+      flag = 1;
     if (lmp->atom->natoms > MAXSMALLINT) flag = 1;
     if (flag) {
       if (lmp->comm->me == 0)
@@ -586,7 +703,7 @@ void lammps_gather_atoms(void *ptr, char *name,
           for (j = 0; j < count; j++)
             copy[offset++] = array[i][0];
         }
-
+      
       MPI_Allreduce(copy,data,count*natoms,MPI_INT,MPI_SUM,lmp->world);
       lmp->memory->destroy(copy);
 
@@ -623,6 +740,7 @@ void lammps_gather_atoms(void *ptr, char *name,
 
 /* ----------------------------------------------------------------------
    scatter the named atom-based entity across all processors
+   atom IDs must be consecutive from 1 to N
    name = desired quantity, e.g. x or charge
    type = 0 for integer values, 1 for double values
    count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f
@@ -640,7 +758,8 @@ void lammps_scatter_atoms(void *ptr, char *name,
     // error if tags are not defined or not consecutive or no atom map
 
     int flag = 0;
-    if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) flag = 1;
+    if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) 
+      flag = 1;
     if (lmp->atom->natoms > MAXSMALLINT) flag = 1;
     if (lmp->atom->map_style == 0) flag = 1;
     if (flag) {
@@ -702,9 +821,91 @@ void lammps_scatter_atoms(void *ptr, char *name,
   END_CAPTURE
 }
 
+/* ----------------------------------------------------------------------
+   create N atoms and assign them to procs based on coords
+   id = atom IDs (optional, NULL if just use 1 to N)
+   type = N-length vector of atom types (required)
+   x = 3N-length vector of atom coords (required)
+   v = 3N-length vector of atom velocities (optional, NULL if just 0.0)
+   x,v = ordered by xyz, then by atom
+     e.g. x[0][0],x[0][1],x[0][2],x[1][0],x[1][1],x[1][2],x[2][0],...
+------------------------------------------------------------------------- */
+
+void lammps_create_atoms(void *ptr, int n, tagint *id, int *type,
+			 double *x, double *v)
+{
+  LAMMPS *lmp = (LAMMPS *) ptr;
+
+  BEGIN_CAPTURE
+  {
+    // error if box does not exist or tags not defined
+
+    int flag = 0;
+    if (lmp->domain->box_exist == 0) flag = 1;
+    if (lmp->atom->tag_enable == 0) flag = 1;
+    if (flag) {
+      if (lmp->comm->me == 0)
+        lmp->error->warning(FLERR,"Library error in lammps_create_atoms");
+      return;
+    }
+
+    // loop over N atoms of entire system
+    // if this proc owns it based on coords, invoke create_atom()
+    // optionally set atom tags and velocities
+
+    Atom *atom = lmp->atom;
+    Domain *domain = lmp->domain;
+    int nlocal = atom->nlocal;
+
+    int nprev = nlocal;
+    double xdata[3];
+    
+    for (int i = 0; i < n; i++) {
+      xdata[0] = x[3*i];
+      xdata[1] = x[3*i+1];
+      xdata[2] = x[3*i+2];
+      if (!domain->ownatom(xdata)) continue;
+  
+      atom->avec->create_atom(type[i],xdata);
+      if (id) atom->tag[nlocal] = id[i];
+      else atom->tag[nlocal] = i+1;
+      if (v) {
+	atom->v[nlocal][0] = v[3*i];
+	atom->v[nlocal][1] = v[3*i+1];
+	atom->v[nlocal][2] = v[3*i+2];
+      }
+      nlocal++;
+    }
+
+    // need to reset atom->natoms inside LAMMPS
+
+    bigint ncurrent = nlocal;
+    MPI_Allreduce(&ncurrent,&lmp->atom->natoms,1,MPI_LMP_BIGINT,
+                  MPI_SUM,lmp->world);
+
+    // init per-atom fix/compute/variable values for created atoms
+
+    atom->data_fix_compute_variable(nprev,nlocal);
+     
+    // if global map exists, reset it
+    // invoke map_init() b/c atom count has grown
+
+    if (lmp->atom->map_style) {
+      lmp->atom->map_init();
+      lmp->atom->map_set();
+    }
+  }
+  END_CAPTURE
+}
+
+// ----------------------------------------------------------------------
+// library API functions for error handling
+// ----------------------------------------------------------------------
+
 #ifdef LAMMPS_EXCEPTIONS
+
 /* ----------------------------------------------------------------------
-   Check if a new error message
+   check if a new error message
 ------------------------------------------------------------------------- */
 
 int lammps_has_error(void *ptr) {
@@ -714,8 +915,8 @@ int lammps_has_error(void *ptr) {
 }
 
 /* ----------------------------------------------------------------------
-   Copy the last error message of LAMMPS into a character buffer
-   The return value encodes which type of error it is.
+   copy the last error message of LAMMPS into a character buffer
+   return value encodes which type of error:
    1 = normal error (recoverable)
    2 = abort error (non-recoverable)
 ------------------------------------------------------------------------- */
@@ -732,4 +933,5 @@ int lammps_get_last_error_message(void *ptr, char * buffer, int buffer_size) {
   }
   return 0;
 }
+
 #endif
diff --git a/src/library.h b/src/library.h
index e4dffc63d1ccfe2cc2d456cc0ca207ea78397af5..a05b7b4eb8a79b1dd599e76fa9807c2f84207535 100644
--- a/src/library.h
+++ b/src/library.h
@@ -30,6 +30,8 @@ void lammps_close(void *);
 int  lammps_version(void *);
 void lammps_file(void *, char *);
 char *lammps_command(void *, char *);
+void lammps_commands_list(void *, int, char **);
+void lammps_commands_string(void *, char *);
 void lammps_free(void *);
 
 void *lammps_extract_global(void *, char *);
@@ -40,10 +42,11 @@ void *lammps_extract_variable(void *, char *, char *);
 
 int lammps_set_variable(void *, char *, char *);
 double lammps_get_thermo(void *, char *);
-int lammps_get_natoms(void *);
 
+int lammps_get_natoms(void *);
 void lammps_gather_atoms(void *, char *, int, int, void *);
 void lammps_scatter_atoms(void *, char *, int, int, void *);
+void lammps_create_atoms(void *, int, int *, int *, double *, double *);
 
 #ifdef LAMMPS_EXCEPTIONS
 int lammps_has_error(void *);
diff --git a/src/read_data.cpp b/src/read_data.cpp
index e170d909cf3986b262e1f126400187954503f86f..6ce3e434851b011e0e4e133ea43617ac719966fe 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -703,7 +703,11 @@ void ReadData::command(int narg, char **arg)
     if (addflag == NONE) atom->deallocate_topology();
     atom->avec->grow(atom->nmax);
   }
+
+  // init per-atom fix/compute/variable values for created atoms
   
+  atom->data_fix_compute_variable(nlocal_previous,atom->nlocal);
+
   // assign atoms added by this data file to specified group
 
   if (groupbit) {
@@ -830,6 +834,7 @@ void ReadData::command(int narg, char **arg)
   }
 
   // restore old styles, when reading with nocoeff flag given
+  
   if (coeffflag == 0) {
     if (force->pair) delete force->pair;
     force->pair = saved_pair;
diff --git a/src/read_dump.cpp b/src/read_dump.cpp
index 0d8d91a32fc2469a46d6e9662f633ae6f46de5e6..8251a01cee02bc2a15d606b2c9e4ce20e71b1b32 100644
--- a/src/read_dump.cpp
+++ b/src/read_dump.cpp
@@ -908,27 +908,9 @@ void ReadDump::process_atoms(int n)
     }
   }
 
-  // invoke set_arrays() for fixes/computes/variables
-  //   that need initialization of attributes of new atoms
-  // same as in CreateAtoms
-  // don't use modify->create_attributes() since would be inefficient
-  //   for large number of atoms
-
-  nlocal = atom->nlocal;
-  for (int m = 0; m < modify->nfix; m++) {
-    Fix *fix = modify->fix[m];
-    if (fix->create_attribute)
-      for (i = nlocal_previous; i < nlocal; i++)
-        fix->set_arrays(i);
-  }
-  for (int m = 0; m < modify->ncompute; m++) {
-    Compute *compute = modify->compute[m];
-    if (compute->create_attribute)
-      for (i = nlocal_previous; i < nlocal; i++)
-        compute->set_arrays(i);
-  }
-  for (int i = nlocal_previous; i < nlocal; i++)
-    input->variable->set_arrays(i);
+  // init per-atom fix/compute/variable values for created atoms
+  
+  atom->data_fix_compute_variable(nlocal_previous,atom->nlocal);
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/region.cpp b/src/region.cpp
index a37b81dbd5f16cc910295ccbe1a35a33de1763a9..f42b4e6ad0d92dc0e322c6d625c68246a876b771 100644
--- a/src/region.cpp
+++ b/src/region.cpp
@@ -552,8 +552,7 @@ void Region::length_restart_string(int &n)
 }
 
 /* ----------------------------------------------------------------------
-   region writes its current style, id, number of sub-regions
-     and position/angle
+   region writes its current style, id, number of sub-regions, position/angle
    needed by fix/wall/gran/region to compute velocity by differencing scheme
 ------------------------------------------------------------------------- */
 
@@ -562,37 +561,36 @@ void Region::write_restart(FILE *fp)
   int sizeid = (strlen(id)+1);
   int sizestyle = (strlen(style)+1);
   fwrite(&sizeid, sizeof(int), 1, fp);
-  fwrite(id, 1, sizeid, fp);
-  fwrite(&sizestyle, sizeof(int), 1, fp);
-  fwrite(style, 1, sizestyle, fp);
+  fwrite(id,1,sizeid,fp);
+  fwrite(&sizestyle,sizeof(int),1,fp);
+  fwrite(style,1,sizestyle,fp);
   fwrite(&nregion,sizeof(int),1,fp);
-
-  fwrite(prev, sizeof(double), size_restart, fp);
+  fwrite(prev,sizeof(double),size_restart,fp);
 }
 
 /* ----------------------------------------------------------------------
    region reads style, id, number of sub-regions from restart file
-     if they match current region, also read previous position/angle
+   if they match current region, also read previous position/angle
    needed by fix/wall/gran/region to compute velocity by differencing scheme
 ------------------------------------------------------------------------- */
 
 int Region::restart(char *buf, int &n)
 {
-  int size = *((int *)(buf+n));
+  int size = *((int *) (&buf[n]));
   n += sizeof(int);
-  if ((size <= 0) || (strcmp(buf+n,id) != 0)) return 0;
+  if ((size <= 0) || (strcmp(&buf[n],id) != 0)) return 0;
   n += size;
 
-  size = *((int *)(buf+n));
+  size = *((int *) (&buf[n]));
   n += sizeof(int);
-  if ((size <= 0) || (strcmp(buf+n,style) != 0)) return 0;
+  if ((size <= 0) || (strcmp(&buf[n],style) != 0)) return 0;
   n += size;
 
-  int restart_nreg = *((int *)(buf+n));
+  int restart_nreg = *((int *) (&buf[n]));
   n += sizeof(int);
   if (restart_nreg != nregion) return 0;
 
-  memcpy(prev,buf+n,size_restart*sizeof(double));
+  memcpy(prev,&buf[n],size_restart*sizeof(double));
   return 1;
 }
 
diff --git a/src/region.h b/src/region.h
index ecc285d6c6a12a6ebe0669fe86e7ecf0e3aedbac..9c693bfcd5cc954ef2d5276c8b6fe9324284931d 100644
--- a/src/region.h
+++ b/src/region.h
@@ -106,11 +106,12 @@ class Region : protected Pointers {
   void options(int, char **);
   void point_on_line_segment(double *, double *, double *, double *);
   void forward_transform(double &, double &, double &);
+  double point[3],runit[3];
 
  private:
   char *xstr,*ystr,*zstr,*tstr;
   int xvar,yvar,zvar,tvar;
-  double axis[3],point[3],runit[3];
+  double axis[3];
 
   void inverse_transform(double &, double &, double &);
   void rotate(double &, double &, double &, double);
diff --git a/src/region_intersect.cpp b/src/region_intersect.cpp
index 03c9ccc360ef41b2cb0a05ec216cb59a643a4c96..468bd2867041d7c480c2546ee508c5c1d918d8a7 100644
--- a/src/region_intersect.cpp
+++ b/src/region_intersect.cpp
@@ -321,24 +321,24 @@ void RegIntersect::write_restart(FILE *fp)
    needed by fix/wall/gran/region to compute velocity by differencing scheme
 ------------------------------------------------------------------------- */
 
-int RegIntersect::restart(char *buf, int& n)
+int RegIntersect::restart(char *buf, int &n)
 {
-  int size = *((int *)(buf+n));
+  int size = *((int *) (&buf[n]));
   n += sizeof(int);
-  if ((size <= 0) || (strcmp(buf+n,id) != 0)) return 0;
+  if ((size <= 0) || (strcmp(&buf[n],id) != 0)) return 0;
   n += size;
 
-  size = *((int *)(buf+n));
+  size = *((int *) (&buf[n]));
   n += sizeof(int);
-  if ((size <= 0) || (strcmp(buf+n,style) != 0)) return 0;
+  if ((size <= 0) || (strcmp(&buf[n],style) != 0)) return 0;
   n += size;
 
-  int restart_nreg = *((int *)(buf+n));
+  int restart_nreg = *((int *) (&buf[n]));
   n += sizeof(int);
   if (restart_nreg != nregion) return 0;
 
   for (int ilist = 0; ilist < nregion; ilist++)
-    if (!domain->regions[list[ilist]]->restart(buf, n)) return 0;
+    if (!domain->regions[list[ilist]]->restart(buf,n)) return 0;
 
   return 1;
 }
diff --git a/src/region_union.cpp b/src/region_union.cpp
index e1b86e159e4204a7e4ee833c7ab882bc01b526dc..51bb1b339de541104d2f46a6b30a51f005dd1e92 100644
--- a/src/region_union.cpp
+++ b/src/region_union.cpp
@@ -315,22 +315,22 @@ void RegUnion::write_restart(FILE *fp)
 
 int RegUnion::restart(char *buf, int &n)
 {
-  int size = *((int *)(buf+n));
+  int size = *((int *) (&buf[n]));
   n += sizeof(int);
-  if ((size <= 0) || (strcmp(buf+n,id) != 0)) return 0;
+  if ((size <= 0) || (strcmp(&buf[n],id) != 0)) return 0;
   n += size;
 
-  size = *((int *)(buf+n));
+  size = *((int *) (&buf[n]));
   n += sizeof(int);
-  if ((size <= 0) || (strcmp(buf+n,style) != 0)) return 0;
+  if ((size <= 0) || (strcmp(&buf[n],style) != 0)) return 0;
   n += size;
 
-  int restart_nreg = *((int *)(buf+n));
+  int restart_nreg = *((int *) (&buf[n]));
   n += sizeof(int);
   if (restart_nreg != nregion) return 0;
 
   for (int ilist = 0; ilist < nregion; ilist++)
-    if (!domain->regions[list[ilist]]->restart(buf, n)) return 0;
+    if (!domain->regions[list[ilist]]->restart(buf,n)) return 0;
 
   return 1;
 }
diff --git a/src/verlet.cpp b/src/verlet.cpp
index ce06a1c45688c03fa6281b195065061eab0d60ba..035cab79ef6f124d5189f544ffeb17ee9c011159 100644
--- a/src/verlet.cpp
+++ b/src/verlet.cpp
@@ -95,6 +95,9 @@ void Verlet::setup()
     timer->print_timeout(screen);
   }
 
+  if (lmp->kokkos)
+    error->all(FLERR,"KOKKOS package requires run_style verlet/kk");
+
   update->setupflag = 1;
 
   // setup domain, communication and neighboring
diff --git a/src/verlet.h b/src/verlet.h
index 80e46f623668b379b095a6f4a6a1479da44f465a..0e2a333fabc76ad1b32e794db741af67e8dab566 100644
--- a/src/verlet.h
+++ b/src/verlet.h
@@ -53,4 +53,9 @@ W: No fixes defined, atoms won't move
 If you are not using a fix like nve, nvt, npt then atom velocities and
 coordinates will not be updated during timestepping.
 
+E: KOKKOS package requires run_style verlet/kk
+
+The KOKKOS package requires the Kokkos version of run_style verlet; the
+regular version cannot be used.
+
 */
diff --git a/src/version.h b/src/version.h
index 3cdddc4efdb039cccbe0fa7cad7126ac19df4c98..c6e869ccdedad1656b6dc5e20bba32742220b266 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "19 Oct 2016"
+#define LAMMPS_VERSION "27 Oct 2016"