diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp
index 7df5241a9..2d571269d 100644
--- a/src/USER-REAXC/reaxc_allocate.cpp
+++ b/src/USER-REAXC/reaxc_allocate.cpp
@@ -1,1026 +1,884 @@
 /*----------------------------------------------------------------------
   PuReMD - Purdue ReaxFF Molecular Dynamics Program
 
   Copyright (2010) Purdue University
   Hasan Metin Aktulga, hmaktulga@lbl.gov
   Joseph Fogarty, jcfogart@mail.usf.edu
   Sagar Pandit, pandit@usf.edu
   Ananth Y Grama, ayg@cs.purdue.edu
 
   Please cite the related publication:
   H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama,
   "Parallel Reactive Molecular Dynamics: Numerical Methods and
   Algorithmic Techniques", Parallel Computing, in press.
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License, or (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the GNU General Public License for more details:
   <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------*/
 
 #include "pair_reax_c.h"
-#if defined(PURE_REAX)
-#include "allocate.h"
-#include "list.h"
-#include "reset_tools.h"
-#include "tool_box.h"
-#include "vector.h"
-#elif defined(LAMMPS_REAX)
 #include "reaxc_allocate.h"
 #include "reaxc_list.h"
 #include "reaxc_reset_tools.h"
 #include "reaxc_tool_box.h"
 #include "reaxc_vector.h"
-#endif
 
 
 /* allocate space for my_atoms
    important: we cannot know the exact number of atoms that will fall into a
    process's box throughout the whole simulation. therefore
    we need to make upper bound estimates for various data structures */
 int PreAllocate_Space( reax_system *system, control_params *control,
                        storage *workspace, MPI_Comm comm )
 {
   int mincap = system->mincap;
   double safezone = system->safezone;
 
   // determine the local and total capacity
 
   system->local_cap = MAX( (int)(system->n * safezone), mincap );
   system->total_cap = MAX( (int)(system->N * safezone), mincap );
 
 #if defined(DEBUG)
   fprintf( stderr, "p%d: local_cap=%d total_cap=%d\n",
            system->my_rank, system->local_cap, system->total_cap );
 #endif
 
   system->my_atoms = (reax_atom*)
     scalloc( system->total_cap, sizeof(reax_atom), "my_atoms", comm );
 
   /* space for keeping restriction info, if any */
   // not yet implemented in the parallel version!!!
   // if( control->restrict_bonds ) {
   //   workspace->restricted  = (int*)
   //     scalloc( system->local_cap, sizeof(int), "restricted_atoms", comm );
 
   //   workspace->restricted_list = (int**)
   //     scalloc( system->local_cap, sizeof(int*), "restricted_list", comm );
 
   //   for( i = 0; i < system->local_cap; ++i )
   //     workspace->restricted_list[i] = (int*)
   //         scalloc( MAX_RESTRICT, sizeof(int), "restricted_list[i]", comm );
   // }
 
   return SUCCESS;
 }
 
 
 /*************       system        *************/
 inline void reax_atom_Copy( reax_atom *dest, reax_atom *src )
 {
   dest->orig_id = src->orig_id;
   dest->type = src->type;
   strcpy( dest->name, src->name );
   rvec_Copy( dest->x, src->x );
   rvec_Copy( dest->v, src->v );
   rvec_Copy( dest->f_old, src->f_old );
   rvec_Copy( dest->s, src->s );
   rvec_Copy( dest->t, src->t );
   dest->Hindex = src->Hindex;
   dest->num_bonds = src->num_bonds;
   dest->num_hbonds = src->num_hbonds;
   dest->numbonds = src->numbonds;
 }
 
 
 void Copy_Atom_List( reax_atom *dest, reax_atom *src, int n )
 {
   int i;
 
   for( i = 0; i < n; ++i )
     memcpy( dest+i, src+i, sizeof(reax_atom) );
 }
 
 
 int Allocate_System( reax_system *system, int local_cap, int total_cap,
                      char *msg )
 {
   system->my_atoms = (reax_atom*)
     realloc( system->my_atoms, total_cap*sizeof(reax_atom) );
 
   return SUCCESS;
 }
 
 
 void DeAllocate_System( reax_system *system )
 {
   int i, j, k;
   int ntypes;
   reax_interaction *ff_params;
 
   // dealloocate the atom list
   sfree( system->my_atoms, "system->my_atoms" );
 
   // deallocate the ffield parameters storage
   ff_params = &(system->reax_param);
   ntypes = ff_params->num_atom_types;
 
   sfree( ff_params->gp.l, "ff:globals" );
 
   for( i = 0; i < ntypes; ++i ) {
     for( j = 0; j < ntypes; ++j ) {
       for( k = 0; k < ntypes; ++k ) {
         sfree( ff_params->fbp[i][j][k], "ff:fbp[i,j,k]" );
       }
       sfree( ff_params->fbp[i][j], "ff:fbp[i,j]" );
       sfree( ff_params->thbp[i][j], "ff:thbp[i,j]" );
       sfree( ff_params->hbp[i][j], "ff:hbp[i,j]" );
     }
     sfree( ff_params->fbp[i], "ff:fbp[i]" );
     sfree( ff_params->thbp[i], "ff:thbp[i]" );
     sfree( ff_params->hbp[i], "ff:hbp[i]" );
     sfree( ff_params->tbp[i], "ff:tbp[i]" );
   }
   sfree( ff_params->fbp, "ff:fbp" );
   sfree( ff_params->thbp, "ff:thbp" );
   sfree( ff_params->hbp, "ff:hbp" );
   sfree( ff_params->tbp, "ff:tbp" );
   sfree( ff_params->sbp, "ff:sbp" );
 }
 
 
 /*************       workspace        *************/
 void DeAllocate_Workspace( control_params *control, storage *workspace )
 {
   int i;
 
   if( !workspace->allocated )
     return;
 
   workspace->allocated = 0;
 
   /* communication storage */
   for( i = 0; i < MAX_NBRS; ++i ) {
     sfree( workspace->tmp_dbl[i], "tmp_dbl[i]" );
     sfree( workspace->tmp_rvec[i], "tmp_rvec[i]" );
     sfree( workspace->tmp_rvec2[i], "tmp_rvec2[i]" );
   }
 
   /* bond order storage */
   sfree( workspace->within_bond_box, "skin" );
   sfree( workspace->total_bond_order, "total_bo" );
   sfree( workspace->Deltap, "Deltap" );
   sfree( workspace->Deltap_boc, "Deltap_boc" );
   sfree( workspace->dDeltap_self, "dDeltap_self" );
   sfree( workspace->Delta, "Delta" );
   sfree( workspace->Delta_lp, "Delta_lp" );
   sfree( workspace->Delta_lp_temp, "Delta_lp_temp" );
   sfree( workspace->dDelta_lp, "dDelta_lp" );
   sfree( workspace->dDelta_lp_temp, "dDelta_lp_temp" );
   sfree( workspace->Delta_e, "Delta_e" );
   sfree( workspace->Delta_boc, "Delta_boc" );
   sfree( workspace->Delta_val, "Delta_val" );
   sfree( workspace->nlp, "nlp" );
   sfree( workspace->nlp_temp, "nlp_temp" );
   sfree( workspace->Clp, "Clp" );
   sfree( workspace->vlpex, "vlpex" );
   sfree( workspace->bond_mark, "bond_mark" );
   sfree( workspace->done_after, "done_after" );
 
   /* QEq storage */
   sfree( workspace->Hdia_inv, "Hdia_inv" );
   sfree( workspace->b_s, "b_s" );
   sfree( workspace->b_t, "b_t" );
   sfree( workspace->b_prc, "b_prc" );
   sfree( workspace->b_prm, "b_prm" );
   sfree( workspace->s, "s" );
   sfree( workspace->t, "t" );
   sfree( workspace->droptol, "droptol" );
   sfree( workspace->b, "b" );
   sfree( workspace->x, "x" );
 
   /* GMRES storage */
   for( i = 0; i < RESTART+1; ++i ) {
     sfree( workspace->h[i], "h[i]" );
     sfree( workspace->v[i], "v[i]" );
   }
   sfree( workspace->h, "h" );
   sfree( workspace->v, "v" );
   sfree( workspace->y, "y" );
   sfree( workspace->z, "z" );
   sfree( workspace->g, "g" );
   sfree( workspace->hs, "hs" );
   sfree( workspace->hc, "hc" );
   /* CG storage */
   sfree( workspace->r, "r" );
   sfree( workspace->d, "d" );
   sfree( workspace->q, "q" );
   sfree( workspace->p, "p" );
   sfree( workspace->r2, "r2" );
   sfree( workspace->d2, "d2" );
   sfree( workspace->q2, "q2" );
   sfree( workspace->p2, "p2" );
 
   /* integrator */
   // sfree( workspace->f_old );
   sfree( workspace->v_const, "v_const" );
 
   /*workspace->realloc.num_far = -1;
     workspace->realloc.Htop = -1;
     workspace->realloc.hbonds = -1;
     workspace->realloc.bonds = -1;
     workspace->realloc.num_3body = -1;
     workspace->realloc.gcell_atoms = -1;*/
 
   /* storage for analysis */
   // if( control->molecular_analysis || control->diffusion_coef ) {
   //   sfree( workspace->mark, "mark" );
   //   sfree( workspace->old_mark, "old_mark" );
   // }
 
   // if( control->diffusion_coef )
   //   sfree( workspace->x_old, "x_old" );
 
   /* force related storage */
   sfree( workspace->f, "f" );
   sfree( workspace->CdDelta, "CdDelta" );
 #ifdef TEST_FORCES
   sfree(workspace->dDelta, "dDelta" );
   sfree( workspace->f_ele, "f_ele" );
   sfree( workspace->f_vdw, "f_vdw" );
   sfree( workspace->f_bo, "f_bo" );
   sfree( workspace->f_be, "f_be" );
   sfree( workspace->f_lp, "f_lp" );
   sfree( workspace->f_ov, "f_ov" );
   sfree( workspace->f_un, "f_un" );
   sfree( workspace->f_ang, "f_ang" );
   sfree( workspace->f_coa, "f_coa" );
   sfree( workspace->f_pen, "f_pen" );
   sfree( workspace->f_hb, "f_hb" );
   sfree( workspace->f_tor, "f_tor" );
   sfree( workspace->f_con, "f_con" );
   sfree( workspace->f_tot, "f_tot" );
 
   sfree( workspace->rcounts, "rcounts" );
   sfree( workspace->displs, "displs" );
   sfree( workspace->id_all, "id_all" );
   sfree( workspace->f_all, "f_all" );
 #endif
 
   /* hbond storage */
   //sfree( workspace->Hindex, "Hindex" );
   //sfree( workspace->num_bonds );
   //sfree( workspace->num_hbonds );
   //sfree( workspace->hash, "hash" );
   //sfree( workspace->rev_hash, "rev_hash" );
 }
 
 
 int Allocate_Workspace( reax_system *system, control_params *control,
                         storage *workspace, int local_cap, int total_cap,
                         MPI_Comm comm, char *msg )
 {
   int i, total_real, total_rvec, local_rvec;
 
   workspace->allocated = 1;
   total_real = total_cap * sizeof(real);
   total_rvec = total_cap * sizeof(rvec);
   local_rvec = local_cap * sizeof(rvec);
 
   /* communication storage */
   for( i = 0; i < MAX_NBRS; ++i ) {
     workspace->tmp_dbl[i] = (real*)
       scalloc( total_cap, sizeof(real), "tmp_dbl", comm );
     workspace->tmp_rvec[i] = (rvec*)
       scalloc( total_cap, sizeof(rvec), "tmp_rvec", comm );
     workspace->tmp_rvec2[i] = (rvec2*)
       scalloc( total_cap, sizeof(rvec2), "tmp_rvec2", comm );
   }
 
   /* bond order related storage  */
   workspace->within_bond_box = (int*)
     scalloc( total_cap, sizeof(int), "skin", comm );
   workspace->total_bond_order = (real*) smalloc( total_real, "total_bo", comm );
   workspace->Deltap = (real*) smalloc( total_real, "Deltap", comm );
   workspace->Deltap_boc = (real*) smalloc( total_real, "Deltap_boc", comm );
   workspace->dDeltap_self = (rvec*) smalloc( total_rvec, "dDeltap_self", comm );
   workspace->Delta = (real*) smalloc( total_real, "Delta", comm );
   workspace->Delta_lp = (real*) smalloc( total_real, "Delta_lp", comm );
   workspace->Delta_lp_temp = (real*)
     smalloc( total_real, "Delta_lp_temp", comm );
   workspace->dDelta_lp = (real*) smalloc( total_real, "dDelta_lp", comm );
   workspace->dDelta_lp_temp = (real*)
     smalloc( total_real, "dDelta_lp_temp", comm );
   workspace->Delta_e = (real*) smalloc( total_real, "Delta_e", comm );
   workspace->Delta_boc = (real*) smalloc( total_real, "Delta_boc", comm );
   workspace->Delta_val = (real*) smalloc( total_real, "Delta_val", comm );
   workspace->nlp = (real*) smalloc( total_real, "nlp", comm );
   workspace->nlp_temp = (real*) smalloc( total_real, "nlp_temp", comm );
   workspace->Clp = (real*) smalloc( total_real, "Clp", comm );
   workspace->vlpex = (real*) smalloc( total_real, "vlpex", comm );
   workspace->bond_mark = (int*)
     scalloc( total_cap, sizeof(int), "bond_mark", comm );
   workspace->done_after = (int*)
     scalloc( total_cap, sizeof(int), "done_after", comm );
   // fprintf( stderr, "p%d: bond order storage\n", system->my_rank );
 
   /* QEq storage */
   workspace->Hdia_inv = (real*)
     scalloc( total_cap, sizeof(real), "Hdia_inv", comm );
   workspace->b_s = (real*) scalloc( total_cap, sizeof(real), "b_s", comm );
   workspace->b_t = (real*) scalloc( total_cap, sizeof(real), "b_t", comm );
   workspace->b_prc = (real*) scalloc( total_cap, sizeof(real), "b_prc", comm );
   workspace->b_prm = (real*) scalloc( total_cap, sizeof(real), "b_prm", comm );
   workspace->s = (real*) scalloc( total_cap, sizeof(real), "s", comm );
   workspace->t = (real*) scalloc( total_cap, sizeof(real), "t", comm );
   workspace->droptol = (real*)
     scalloc( total_cap, sizeof(real), "droptol", comm );
   workspace->b = (rvec2*) scalloc( total_cap, sizeof(rvec2), "b", comm );
   workspace->x = (rvec2*) scalloc( total_cap, sizeof(rvec2), "x", comm );
 
   /* GMRES storage */
   workspace->y = (real*) scalloc( RESTART+1, sizeof(real), "y", comm );
   workspace->z = (real*) scalloc( RESTART+1, sizeof(real), "z", comm );
   workspace->g = (real*) scalloc( RESTART+1, sizeof(real), "g", comm );
   workspace->h = (real**) scalloc( RESTART+1, sizeof(real*), "h", comm );
   workspace->hs = (real*) scalloc( RESTART+1, sizeof(real), "hs", comm );
   workspace->hc = (real*) scalloc( RESTART+1, sizeof(real), "hc", comm );
   workspace->v = (real**) scalloc( RESTART+1, sizeof(real*), "v", comm );
 
   for( i = 0; i < RESTART+1; ++i ) {
     workspace->h[i] = (real*) scalloc( RESTART+1, sizeof(real), "h[i]", comm );
     workspace->v[i] = (real*) scalloc( total_cap, sizeof(real), "v[i]", comm );
   }
 
   /* CG storage */
   workspace->r = (real*) scalloc( total_cap, sizeof(real), "r", comm );
   workspace->d = (real*) scalloc( total_cap, sizeof(real), "d", comm );
   workspace->q = (real*) scalloc( total_cap, sizeof(real), "q", comm );
   workspace->p = (real*) scalloc( total_cap, sizeof(real), "p", comm );
   workspace->r2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "r2", comm );
   workspace->d2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "d2", comm );
   workspace->q2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "q2", comm );
   workspace->p2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "p2", comm );
 
   /* integrator storage */
   workspace->v_const = (rvec*) smalloc( local_rvec, "v_const", comm );
 
   /* storage for analysis */
   // not yet implemented in the parallel version!!!
   // if( control->molecular_analysis || control->diffusion_coef ) {
   //   workspace->mark = (int*) scalloc( local_cap, sizeof(int), "mark", comm );
   //   workspace->old_mark = (int*)
   //     scalloc( local_cap, sizeof(int), "old_mark", comm );
   // }
   // else
   //   workspace->mark = workspace->old_mark = NULL;
 
   // if( control->diffusion_coef )
   //   workspace->x_old = (rvec*)
   //     scalloc( local_cap, sizeof(rvec), "x_old", comm );
   // else workspace->x_old = NULL;
 
   // /* force related storage */
   workspace->f = (rvec*) scalloc( total_cap, sizeof(rvec), "f", comm );
   workspace->CdDelta = (real*)
     scalloc( total_cap, sizeof(real), "CdDelta", comm );
 
 #ifdef TEST_FORCES
   workspace->dDelta=(rvec*) smalloc( total_rvec, "dDelta", comm );
   workspace->f_ele =(rvec*) smalloc( total_rvec, "f_ele", comm );
   workspace->f_vdw =(rvec*) smalloc( total_rvec, "f_vdw", comm );
   workspace->f_bo =(rvec*) smalloc( total_rvec, "f_bo", comm );
   workspace->f_be =(rvec*) smalloc( total_rvec, "f_be", comm );
   workspace->f_lp =(rvec*) smalloc( total_rvec, "f_lp", comm );
   workspace->f_ov =(rvec*) smalloc( total_rvec, "f_ov", comm );
   workspace->f_un =(rvec*) smalloc( total_rvec, "f_un", comm );
   workspace->f_ang =(rvec*) smalloc( total_rvec, "f_ang", comm );
   workspace->f_coa =(rvec*) smalloc( total_rvec, "f_coa", comm );
   workspace->f_pen =(rvec*) smalloc( total_rvec, "f_pen", comm );
   workspace->f_hb =(rvec*) smalloc( total_rvec, "f_hb", comm );
   workspace->f_tor =(rvec*) smalloc( total_rvec, "f_tor", comm );
   workspace->f_con =(rvec*) smalloc( total_rvec, "f_con", comm );
   workspace->f_tot =(rvec*) smalloc( total_rvec, "f_tot", comm );
 
   if( system->my_rank == MASTER_NODE ) {
     workspace->rcounts = (int*)
       smalloc( system->wsize*sizeof(int), "rcount", comm );
     workspace->displs = (int*)
       smalloc( system->wsize*sizeof(int), "displs", comm );
     workspace->id_all = (int*)
       smalloc( system->bigN*sizeof(int), "id_all", comm );
     workspace->f_all = (rvec*)
       smalloc( system->bigN*sizeof(rvec), "f_all", comm );
   }
   else{
     workspace->rcounts = NULL;
     workspace->displs = NULL;
     workspace->id_all = NULL;
     workspace->f_all = NULL;
   }
 #endif
 
   return SUCCESS;
 }
 
 
 void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, int num_intrs,
                                MPI_Comm comm )
 {
   Delete_List( far_nbrs, comm );
   if(!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs, comm )){
     fprintf(stderr, "Problem in initializing far nbrs list. Terminating!\n");
     MPI_Abort( comm, INSUFFICIENT_MEMORY );
   }
 }
 
 
 int Allocate_Matrix( sparse_matrix **pH, int cap, int m, MPI_Comm comm )
 {
   sparse_matrix *H;
 
   *pH = (sparse_matrix*)
     smalloc( sizeof(sparse_matrix), "sparse_matrix", comm );
   H = *pH;
   H->cap = cap;
   H->m = m;
   H->start = (int*) smalloc( sizeof(int) * cap, "matrix_start", comm );
   H->end = (int*) smalloc( sizeof(int) * cap, "matrix_end", comm );
   H->entries = (sparse_matrix_entry*)
     smalloc( sizeof(sparse_matrix_entry)*m, "matrix_entries", comm );
 
   return SUCCESS;
 }
 
 
 void Deallocate_Matrix( sparse_matrix *H )
 {
   sfree(H->start, "H->start");
   sfree(H->end, "H->end");
   sfree(H->entries, "H->entries");
   sfree(H, "H");
 }
 
 
 int Reallocate_Matrix( sparse_matrix **H, int n, int m, char *name,
                        MPI_Comm comm )
 {
   Deallocate_Matrix( *H );
   if( !Allocate_Matrix( H, n, m, comm ) ) {
     fprintf(stderr, "not enough space for %s matrix. terminating!\n", name);
     MPI_Abort( comm, INSUFFICIENT_MEMORY );
   }
 
 #if defined(DEBUG_FOCUS)
   fprintf( stderr, "reallocating %s matrix, n = %d, m = %d\n", name, n, m );
   fprintf( stderr, "memory allocated: %s = %dMB\n",
            name, (int)(m * sizeof(sparse_matrix_entry) / (1024*1024)) );
 #endif
   return SUCCESS;
 }
 
 
 int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds,
                             MPI_Comm comm )
 {
   int i, id, total_hbonds;
 
   int mincap = system->mincap;
   double saferzone = system->saferzone;
 
   total_hbonds = 0;
   for( i = 0; i < system->n; ++i )
     if( (id = system->my_atoms[i].Hindex) >= 0 ) {
       // commented out - already updated in validate_lists in forces.c
       // system->my_atoms[i].num_hbonds = MAX(Num_Entries(id,hbonds)*SAFER_ZONE,
       //                                   MIN_HBONDS);
       total_hbonds += system->my_atoms[i].num_hbonds;
     }
   total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS ));
 
   Delete_List( hbonds, comm );
   if( !Make_List( system->Hcap, total_hbonds, TYP_HBOND, hbonds, comm ) ) {
     fprintf( stderr, "not enough space for hbonds list. terminating!\n" );
     MPI_Abort( comm, INSUFFICIENT_MEMORY );
   }
 
   return total_hbonds;
 }
 
 
 int Reallocate_Bonds_List( reax_system *system, reax_list *bonds,
                            int *total_bonds, int *est_3body, MPI_Comm comm )
 {
   int i;
 
   int mincap = system->mincap;
   double safezone = system->safezone;
 
   *total_bonds = 0;
   *est_3body = 0;
   for( i = 0; i < system->N; ++i ){
     *est_3body += SQR(system->my_atoms[i].num_bonds);
     // commented out - already updated in validate_lists in forces.c
     // system->my_atoms[i].num_bonds = MAX( Num_Entries(i,bonds)*2, MIN_BONDS );
     *total_bonds += system->my_atoms[i].num_bonds;
   }
   *total_bonds = (int)(MAX( *total_bonds * safezone, mincap*MIN_BONDS ));
 
   Delete_List( bonds, comm );
   if(!Make_List(system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) {
     fprintf( stderr, "not enough space for bonds list. terminating!\n" );
     MPI_Abort( comm, INSUFFICIENT_MEMORY );
   }
 
   return SUCCESS;
 }
 
 
 /*************       grid        *************/
 int Estimate_GCell_Population( reax_system* system, MPI_Comm comm )
 {
   int d, i, j, k, l, max_atoms, my_max, all_max;
   ivec c;
   grid *g;
   grid_cell *gc;
   simulation_box *my_ext_box;
   reax_atom *atoms;
 
   my_ext_box = &(system->my_ext_box);
   g          = &(system->my_grid);
   atoms      = system->my_atoms;
   Reset_Grid( g );
 
   for( l = 0; l < system->n; l++ ) {
     for( d = 0; d < 3; ++d ) {
 
       c[d] = (int)((atoms[l].x[d]-my_ext_box->min[d])*g->inv_len[d]);
 
       if( c[d] >= g->native_end[d] )
         c[d] = g->native_end[d] - 1;
       else if( c[d] < g->native_str[d] )
         c[d] = g->native_str[d];
     }
 #if defined(DEBUG)
     fprintf( stderr, "p%d bin_my_atoms: l:%d - atom%d @ %.5f %.5f %.5f"        \
              "--> cell: %d %d %d\n",
              system->my_rank, l, atoms[l].orig_id,
              atoms[l].x[0], atoms[l].x[1], atoms[l].x[2],
              c[0], c[1], c[2] );
 #endif
     gc = &( g->cells[c[0]][c[1]][c[2]] );
     gc->top++;
   }
 
   max_atoms = 0;
   for( i = 0; i < g->ncells[0]; i++ )
     for( j = 0; j < g->ncells[1]; j++ )
       for( k = 0; k < g->ncells[2]; k++ ) {
         gc = &(g->cells[i][j][k]);
         if( max_atoms < gc->top )
           max_atoms = gc->top;
 #if defined(DEBUG)
         fprintf( stderr, "p%d gc[%d,%d,%d]->top=%d\n",
                  system->my_rank, i, j, k, gc->top );
 #endif
       }
 
   my_max = (int)(MAX(max_atoms*SAFE_ZONE, MIN_GCELL_POPL));
   MPI_Allreduce( &my_max, &all_max, 1, MPI_INT, MPI_MAX, comm );
 #if defined(DEBUG)
   fprintf( stderr, "p%d max_atoms=%d, my_max=%d, all_max=%d\n",
            system->my_rank, max_atoms, my_max, all_max );
 #endif
 
   return all_max;
 }
 
 
 void Allocate_Grid( reax_system *system, MPI_Comm comm )
 {
   int i, j, k, l;
   grid *g;
   grid_cell *gc;
 
   g = &( system->my_grid );
 
   /* allocate gcell reordering space */
   g->order = (ivec*) scalloc( g->total+1, sizeof(ivec), "g:order", comm );
 
   /* allocate the gcells for the new grid */
   g->max_nbrs = (2*g->vlist_span[0]+1)*(2*g->vlist_span[1]+1)*
     (2*g->vlist_span[2]+1)+3;
 
   g->cells = (grid_cell***)
     scalloc( g->ncells[0], sizeof(grid_cell**), "gcells", comm );
   for( i = 0; i < g->ncells[0]; i++ ) {
     g->cells[i] = (grid_cell**)
       scalloc( g->ncells[1], sizeof(grid_cell*),"gcells[i]", comm );
 
     for( j = 0; j < g->ncells[1]; ++j )        {
       g->cells[i][j] = (grid_cell*)
         scalloc( g->ncells[2], sizeof(grid_cell), "gcells[i][j]", comm );
 
       for( k = 0; k < g->ncells[2]; k++ ) {
         gc = &(g->cells[i][j][k]);
         gc->top = gc->mark = gc->str = gc->end = 0;
         gc->nbrs = (grid_cell**)
           scalloc( g->max_nbrs, sizeof(grid_cell*), "g:nbrs", comm );
         gc->nbrs_x = (ivec*)
           scalloc( g->max_nbrs, sizeof(ivec), "g:nbrs_x", comm );
         gc->nbrs_cp = (rvec*)
           scalloc( g->max_nbrs, sizeof(rvec), "g:nbrs_cp", comm );
         for( l = 0; l < g->max_nbrs; ++l )
           gc->nbrs[l] = NULL;
       }
     }
   }
 
   /* allocate atom id storage in gcells */
   g->max_atoms = Estimate_GCell_Population( system, comm );
   /* space for storing atom id's is required only for native cells */
   for( i = g->native_str[0]; i < g->native_end[0]; ++i )
     for( j = g->native_str[1]; j < g->native_end[1]; ++j )
       for( k = g->native_str[2]; k < g->native_end[2]; ++k )
         g->cells[i][j][k].atoms = (int*) scalloc( g->max_atoms, sizeof(int),
                                                   "g:atoms", comm );
 #if defined(DEBUG_FOCUS)
   fprintf( stderr, "p%d-allocated %dx%dx%d grid: nbrs=%d atoms=%d space=%dMB\n",
            system->my_rank, g->ncells[0], g->ncells[1], g->ncells[2],
            g->max_nbrs, g->max_atoms,
            (int)
            ((g->total*sizeof(grid_cell)+g->total*g->max_nbrs*sizeof(int*) +
              g->total*g->max_nbrs*sizeof(rvec) +
              (g->native_end[0]-g->native_str[0])*
              (g->native_end[1]-g->native_str[1])*
              (g->native_end[2]-g->native_str[2])*g->max_atoms*sizeof(int))/
             (1024*1024)) );
 #endif
 }
 
 
 void Deallocate_Grid( grid *g )
 {
   int i, j, k;
   grid_cell *gc;
 
   sfree( g->order, "g:order" );
 
   /* deallocate the grid cells */
   for( i = 0; i < g->ncells[0]; i++ ) {
     for( j = 0; j < g->ncells[1]; j++ ) {
       for( k = 0; k < g->ncells[2]; k++ ) {
         gc = &(g->cells[i][j][k]);
         sfree( gc->nbrs, "g:nbrs" );
         sfree( gc->nbrs_x, "g:nbrs_x" );
         sfree( gc->nbrs_cp, "g:nbrs_cp" );
         if(gc->atoms != NULL )
           sfree( gc->atoms, "g:atoms" );
       }
       sfree( g->cells[i][j], "g:cells[i][j]" );
     }
     sfree( g->cells[i], "g:cells[i]" );
   }
   sfree( g->cells, "g:cells" );
 }
 
 
-/************ mpi buffers ********************/
- /* make the allocations based on the largest need by the three comms:
-    1- transfer an atom who has moved into other proc's domain (mpi_atom)
-    2- exchange boundary atoms (boundary_atom)
-    3- update position info for boundary atoms (mpi_rvec)
-
-    the largest space by far is required for the 2nd comm operation above.
-    buffers are void*, type cast to the correct pointer type to access
-    the allocated buffers */
-int  Allocate_MPI_Buffers( mpi_datatypes *mpi_data, int est_recv,
-                           neighbor_proc *my_nbrs, char *msg )
-{
-  int i;
-  mpi_out_data  *mpi_buf;
-  MPI_Comm comm;
-
-  comm = mpi_data->world;
-
-  /* in buffers */
-  mpi_data->in1_buffer = (void*)
-    scalloc( est_recv, sizeof(boundary_atom), "in1_buffer", comm );
-  mpi_data->in2_buffer = (void*)
-    scalloc( est_recv, sizeof(boundary_atom), "in2_buffer", comm );
-
-  /* out buffers */
-  for( i = 0; i < MAX_NBRS; ++i ) {
-    mpi_buf = &( mpi_data->out_buffers[i] );
-    /* allocate storage for the neighbor processor i */
-    mpi_buf->index = (int*)
-      scalloc( my_nbrs[i].est_send, sizeof(int), "mpibuf:index", comm );
-    mpi_buf->out_atoms = (void*)
-      scalloc( my_nbrs[i].est_send, sizeof(boundary_atom), "mpibuf:out_atoms",
-               comm );
-  }
-
-  return SUCCESS;
-}
-
-
-void Deallocate_MPI_Buffers( mpi_datatypes *mpi_data )
-{
-  int i;
-  mpi_out_data  *mpi_buf;
-
-  sfree( mpi_data->in1_buffer, "in1_buffer" );
-  sfree( mpi_data->in2_buffer, "in2_buffer" );
-
-  for( i = 0; i < MAX_NBRS; ++i ) {
-    mpi_buf = &( mpi_data->out_buffers[i] );
-    sfree( mpi_buf->index, "mpibuf:index" );
-    sfree( mpi_buf->out_atoms, "mpibuf:out_atoms" );
-  }
-}
-
-
 void ReAllocate( reax_system *system, control_params *control,
                  simulation_data *data, storage *workspace, reax_list **lists,
                  mpi_datatypes *mpi_data )
 {
   int num_bonds, est_3body, Hflag, ret;
   int renbr, newsize;
   reallocate_data *realloc;
   reax_list *far_nbrs;
   grid *g;
   MPI_Comm comm;
   char msg[200];
 
   int mincap = system->mincap;
   double safezone = system->safezone;
   double saferzone = system->saferzone;
 
   realloc = &(workspace->realloc);
   g = &(system->my_grid);
   comm = mpi_data->world;
 
 #if defined(DEBUG)
   fprintf( stderr, "p%d@reallocate: n: %d, N: %d, numH: %d\n",
            system->my_rank, system->n, system->N, system->numH );
   fprintf( stderr, "p%d@reallocate: local_cap: %d, total_cap: %d, Hcap: %d\n",
            system->my_rank, system->local_cap, system->total_cap,
            system->Hcap);
   fprintf( stderr, "p%d: realloc.num_far: %d\n",
            system->my_rank, realloc->num_far );
   fprintf( stderr, "p%d: realloc.H: %d, realloc.Htop: %d\n",
            system->my_rank, realloc->H, realloc->Htop );
   fprintf( stderr, "p%d: realloc.Hbonds: %d, realloc.num_hbonds: %d\n",
            system->my_rank, realloc->hbonds, realloc->num_hbonds );
   fprintf( stderr, "p%d: realloc.bonds: %d, num_bonds: %d\n",
            system->my_rank, realloc->bonds, realloc->num_bonds );
   fprintf( stderr, "p%d: realloc.num_3body: %d\n",
            system->my_rank, realloc->num_3body );
 #endif
 
   // IMPORTANT: LOOSE ZONES CHECKS ARE DISABLED FOR NOW BY &&'ing with 0!!!
 
   int nflag = 0;
   if( system->n >= DANGER_ZONE * system->local_cap ||
       (0 && system->n <= LOOSE_ZONE * system->local_cap) ) {
     nflag = 1;
     system->local_cap = MAX( (int)(system->n * safezone), mincap );
   }
 
   int Nflag = 0;
   if( system->N >= DANGER_ZONE * system->total_cap ||
       (0 && system->N <= LOOSE_ZONE * system->total_cap) ) {
     Nflag = 1;
     system->total_cap = MAX( (int)(system->N * safezone), mincap );
   }
 
   if( Nflag ) {
     /* system */
 #if defined(DEBUG_FOCUS)
     fprintf( stderr, "p%d: reallocating system and workspace -"\
              "n=%d  N=%d  local_cap=%d  total_cap=%d\n",
              system->my_rank, system->n, system->N,
              system->local_cap, system->total_cap );
 #endif
     ret = Allocate_System( system, system->local_cap, system->total_cap, msg );
     if( ret != SUCCESS ) {
       fprintf( stderr, "not enough space for atom_list: total_cap=%d",
                system->total_cap );
       fprintf( stderr, "terminating...\n" );
       MPI_Abort( comm, INSUFFICIENT_MEMORY );
     }
 
     /* workspace */
     DeAllocate_Workspace( control, workspace );
     ret = Allocate_Workspace( system, control, workspace, system->local_cap,
                               system->total_cap, comm, msg );
     if( ret != SUCCESS ) {
       fprintf( stderr, "no space for workspace: local_cap=%d total_cap=%d",
                system->local_cap, system->total_cap );
       fprintf( stderr, "terminating...\n" );
       MPI_Abort( comm, INSUFFICIENT_MEMORY );
     }
   }
 
 
   renbr = (data->step - data->prev_steps) % control->reneighbor == 0;
   /* far neighbors */
   if( renbr ) {
     far_nbrs = *lists + FAR_NBRS;
 
     if( Nflag || realloc->num_far >= far_nbrs->num_intrs * DANGER_ZONE ) {
       if( realloc->num_far > far_nbrs->num_intrs ) {
         fprintf( stderr, "step%d-ran out of space on far_nbrs: top=%d, max=%d",
                  data->step, realloc->num_far, far_nbrs->num_intrs );
         MPI_Abort( comm, INSUFFICIENT_MEMORY );
       }
 
       newsize = static_cast<int>
         (MAX( realloc->num_far*safezone, mincap*MIN_NBRS ));
 #if defined(DEBUG_FOCUS)
       fprintf( stderr, "p%d: reallocating far_nbrs: num_fars=%d, space=%dMB\n",
                system->my_rank, (int)(realloc->num_far*SAFE_ZONE),
                (newsize*sizeof(far_neighbor_data)/(1024*1024)) );
 #endif
 
       Reallocate_Neighbor_List( far_nbrs, system->total_cap, newsize, comm );
       realloc->num_far = 0;
     }
   }
 
 #if defined(PURE_REAX)
   /* qeq coef matrix */
   H = workspace->H;
   if( nflag || realloc->Htop >= H->m * DANGER_ZONE ) {
     if( realloc->Htop > H->m ) {
       fprintf( stderr,
                "step%d - ran out of space on H matrix: Htop=%d, max = %d",
                data->step, realloc->Htop, H->m );
       MPI_Abort( comm, INSUFFICIENT_MEMORY );
     }
 #if defined(DEBUG_FOCUS)
     fprintf( stderr, "p%d: reallocating H matrix: Htop=%d, space=%dMB\n",
              system->my_rank, (int)(realloc->Htop*SAFE_ZONE),
              (int)(realloc->Htop * SAFE_ZONE * sizeof(sparse_matrix_entry) /
                    (1024*1024)) );
 #endif
 
     newsize = static_cast<int>
         (MAX( realloc->Htop*safezone, mincap*MIN_NBRS ));
     Reallocate_Matrix( &(workspace->H), system->local_cap,
                        newsize, "H", comm );
     //Deallocate_Matrix( workspace->L );
     //Deallocate_Matrix( workspace->U );
     workspace->L = NULL;
     workspace->U = NULL;
     realloc->Htop = 0;
   }
 #endif /*PURE_REAX*/
 
   /* hydrogen bonds list */
   if( control->hbond_cut > 0 ) {
     Hflag = 0;
     if( system->numH >= DANGER_ZONE * system->Hcap ||
         (0 && system->numH <= LOOSE_ZONE * system->Hcap) ) {
       Hflag = 1;
       system->Hcap = int(MAX( system->numH * saferzone, mincap ));
     }
 
     if( Hflag || realloc->hbonds ) {
       ret = Reallocate_HBonds_List( system, (*lists)+HBONDS, comm );
       realloc->hbonds = 0;
 #if defined(DEBUG_FOCUS)
       fprintf(stderr, "p%d: reallocating hbonds: total_hbonds=%d space=%dMB\n",
               system->my_rank, ret, (int)(ret*sizeof(hbond_data)/(1024*1024)));
 #endif
     }
   }
 
   /* bonds list */
   num_bonds = est_3body = -1;
   if( Nflag || realloc->bonds ){
     Reallocate_Bonds_List( system, (*lists)+BONDS, &num_bonds,
                            &est_3body, comm );
     realloc->bonds = 0;
     realloc->num_3body = MAX( realloc->num_3body, est_3body );
 #if defined(DEBUG_FOCUS)
     fprintf( stderr, "p%d: reallocating bonds: total_bonds=%d, space=%dMB\n",
              system->my_rank, num_bonds,
              (int)(num_bonds*sizeof(bond_data)/(1024*1024)) );
 #endif
   }
 
   /* 3-body list */
   if( realloc->num_3body > 0 ) {
 #if defined(DEBUG_FOCUS)
     fprintf( stderr, "p%d: reallocating 3body list: num_3body=%d, space=%dMB\n",
              system->my_rank, realloc->num_3body,
              (int)(realloc->num_3body * sizeof(three_body_interaction_data) /
                    (1024*1024)) );
 #endif
     Delete_List( (*lists)+THREE_BODIES, comm );
 
     if( num_bonds == -1 )
       num_bonds = ((*lists)+BONDS)->num_intrs;
 
     realloc->num_3body = (int)(MAX(realloc->num_3body*safezone, MIN_3BODIES));
 
     if( !Make_List( num_bonds, realloc->num_3body, TYP_THREE_BODY,
                     (*lists)+THREE_BODIES, comm ) ) {
       fprintf( stderr, "Problem in initializing angles list. Terminating!\n" );
       MPI_Abort( comm, CANNOT_INITIALIZE );
     }
     realloc->num_3body = -1;
   }
 
-#if defined(PURE_REAX)
-  /* grid */
-  if( renbr && realloc->gcell_atoms > -1 ) {
-#if defined(DEBUG_FOCUS)
-    fprintf(stderr, "reallocating gcell: g->max_atoms: %d\n", g->max_atoms);
-#endif
-    for( i = g->native_str[0]; i < g->native_end[0]; i++ )
-      for( j = g->native_str[1]; j < g->native_end[1]; j++ )
-        for( k = g->native_str[2]; k < g->native_end[2]; k++ ) {
-          // reallocate g->atoms
-          sfree( g->cells[i][j][k].atoms, "g:atoms" );
-          g->cells[i][j][k].atoms = (int*)
-            scalloc( realloc->gcell_atoms, sizeof(int), "g:atoms", comm);
-        }
-    realloc->gcell_atoms = -1;
-  }
-
-  /* mpi buffers */
-  // we have to be at a renbring step -
-  // to ensure correct values at mpi_buffers for update_boundary_positions
-  if( !renbr )
-    mpi_flag = 0;
-  // check whether in_buffer capacity is enough
-  else if( system->max_recved >= system->est_recv * 0.90 )
-    mpi_flag = 1;
-  else {
-    // otherwise check individual outgoing buffers
-    mpi_flag = 0;
-    for( p = 0; p < MAX_NBRS; ++p ) {
-      nbr_pr   = &( system->my_nbrs[p] );
-      nbr_data = &( mpi_data->out_buffers[p] );
-      if( nbr_data->cnt >= nbr_pr->est_send * 0.90 ) {
-        mpi_flag = 1;
-        break;
-      }
-    }
-  }
-
-  if( mpi_flag ) {
-#if defined(DEBUG_FOCUS)
-    fprintf( stderr, "p%d: reallocating mpi_buf: old_recv=%d\n",
-             system->my_rank, system->est_recv );
-    for( p = 0; p < MAX_NBRS; ++p )
-      fprintf( stderr, "p%d: nbr%d old_send=%d\n",
-               system->my_rank, p, system->my_nbrs[p].est_send );
-#endif
-    /* update mpi buffer estimates based on last comm */
-    system->est_recv = MAX( system->max_recved*SAFER_ZONE, MIN_SEND );
-    system->est_trans =
-      (system->est_recv * sizeof(boundary_atom)) / sizeof(mpi_atom);
-    total_send = 0;
-    for( p = 0; p < MAX_NBRS; ++p ) {
-      nbr_pr   = &( system->my_nbrs[p] );
-      nbr_data = &( mpi_data->out_buffers[p] );
-      nbr_pr->est_send = MAX( nbr_data->cnt*SAFER_ZONE, MIN_SEND );
-      total_send += nbr_pr->est_send;
-    }
-#if defined(DEBUG_FOCUS)
-    fprintf( stderr, "p%d: reallocating mpi_buf: recv=%d send=%d total=%dMB\n",
-             system->my_rank, system->est_recv, total_send,
-             (int)((system->est_recv+total_send)*sizeof(boundary_atom)/
-                   (1024*1024)));
-    for( p = 0; p < MAX_NBRS; ++p )
-      fprintf( stderr, "p%d: nbr%d new_send=%d\n",
-               system->my_rank, p, system->my_nbrs[p].est_send );
-#endif
-
-    /* reallocate mpi buffers */
-    Deallocate_MPI_Buffers( mpi_data );
-    ret = Allocate_MPI_Buffers( mpi_data, system->est_recv,
-                                system->my_nbrs, msg );
-    if( ret != SUCCESS ) {
-      fprintf( stderr, "%s", msg );
-      fprintf( stderr, "terminating...\n" );
-      MPI_Abort( comm, INSUFFICIENT_MEMORY );
-    }
-  }
-#endif /*PURE_REAX*/
-
 #if defined(DEBUG_FOCUS)
   fprintf( stderr, "p%d @ step%d: reallocate done\n",
            system->my_rank, data->step );
   MPI_Barrier( comm );
 #endif
 }
diff --git a/src/USER-REAXC/reaxc_types.h b/src/USER-REAXC/reaxc_types.h
index c7580bdbd..df8bb666a 100644
--- a/src/USER-REAXC/reaxc_types.h
+++ b/src/USER-REAXC/reaxc_types.h
@@ -1,1016 +1,976 @@
 /*----------------------------------------------------------------------
   PuReMD - Purdue ReaxFF Molecular Dynamics Program
 
   Copyright (2010) Purdue University
   Hasan Metin Aktulga, hmaktulga@lbl.gov
   Joseph Fogarty, jcfogart@mail.usf.edu
   Sagar Pandit, pandit@usf.edu
   Ananth Y Grama, ayg@cs.purdue.edu
 
   Please cite the related publication:
   H. M. Aktulga, J. C. Fogarty, S. A. Pandit, A. Y. Grama,
   "Parallel Reactive Molecular Dynamics: Numerical Methods and
   Algorithmic Techniques", Parallel Computing, in press.
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License, or (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the GNU General Public License for more details:
   <http://www.gnu.org/licenses/>.
   ----------------------------------------------------------------------*/
 
 #ifndef __REAX_TYPES_H_
 #define __REAX_TYPES_H_
 
 #include "ctype.h"
 #include "math.h"
 #include "mpi.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "sys/time.h"
 #include "time.h"
 
 /************* SOME DEFS - crucial for reax_types.h *********/
 
 //#define PURE_REAX
 #define LAMMPS_REAX
 
 //#define DEBUG
 //#define DEBUG_FOCUS
 //#define TEST_ENERGY
 //#define TEST_FORCES
 //#define CG_PERFORMANCE
 #define LOG_PERFORMANCE
 #define STANDARD_BOUNDARIES
 //#define OLD_BOUNDARIES
 //#define MIDPOINT_BOUNDARIES
 
 #define REAX_MAX_STR            1024
 #define REAX_MAX_NBRS           6
 #define REAX_MAX_3BODY_PARAM    5
 #define REAX_MAX_4BODY_PARAM    5
 #define REAX_MAX_ATOM_TYPES     25
 #define REAX_MAX_MOLECULE_SIZE  20
 #define MAX_BOND                    20  // same as reaxc_defs.h
 
 /********************** TYPE DEFINITIONS ********************/
 typedef int  ivec[3];
 typedef double real;
 typedef real rvec[3];
 typedef real rtensor[3][3];
 typedef real rvec2[2];
 typedef real rvec4[4];
 
 #ifdef LAMMPS_SMALLSMALL
 typedef int tagint;
 #endif
 
 #ifdef LAMMPS_SMALLBIG
 typedef int tagint;
 #endif
 
 #ifdef LAMMPS_BIGBIG
 typedef int64_t tagint;
 #endif
 
-typedef struct {
-  int step, bigN;
-  real T, xi, v_xi, v_xi_old, G_xi;
-  rtensor box;
-} restart_header;
-
-typedef struct {
-  tagint orig_id, type;
-  char name[8];
-  rvec x, v;
-} restart_atom;
-
-typedef struct
-{
-  tagint  orig_id;
-  int  imprt_id;
-  int  type;
-  int  num_bonds;
-  int  num_hbonds;
-  //int  pad;  // pad to 8-byte address boundary
-  char name[8];
-  rvec x;     // position
-  rvec v;     // velocity
-  rvec f_old; // old force
-  rvec4 s, t;  // for calculating q
-} mpi_atom;
-
-
-typedef struct
-{
-  tagint  orig_id;
-  int  imprt_id;
-  int  type;
-  int  num_bonds;
-  int  num_hbonds;
-  //int  pad;
-  rvec x;     // position
-} boundary_atom;
-
-
 typedef struct
 {
   //int  ncells;
   //int *cnt_by_gcell;
 
   int  cnt;
   //int *block;
   int *index;
   //MPI_Datatype out_dtype;
   void *out_atoms;
 } mpi_out_data;
 
 
 typedef struct
 {
   MPI_Comm     world;
   MPI_Comm     comm_mesh3D;
 
   MPI_Datatype sys_info;
   MPI_Datatype mpi_atom_type;
   MPI_Datatype boundary_atom_type;
   MPI_Datatype mpi_rvec, mpi_rvec2;
   MPI_Datatype restart_atom_type;
 
   MPI_Datatype header_line;
   MPI_Datatype header_view;
   MPI_Datatype init_desc_line;
   MPI_Datatype init_desc_view;
   MPI_Datatype atom_line;
   MPI_Datatype atom_view;
   MPI_Datatype bond_line;
   MPI_Datatype bond_view;
   MPI_Datatype angle_line;
   MPI_Datatype angle_view;
 
   //MPI_Request  send_req1[REAX_MAX_NBRS];
   //MPI_Request  send_req2[REAX_MAX_NBRS];
   //MPI_Status   send_stat1[REAX_MAX_NBRS];
   //MPI_Status   send_stat2[REAX_MAX_NBRS];
   //MPI_Status   recv_stat1[REAX_MAX_NBRS];
   //MPI_Status   recv_stat2[REAX_MAX_NBRS];
 
   mpi_out_data out_buffers[REAX_MAX_NBRS];
   void *in1_buffer;
   void *in2_buffer;
 } mpi_datatypes;
 
 
 /* Global params mapping */
 /*
 l[0]  = p_boc1
 l[1]  = p_boc2
 l[2]  = p_coa2
 l[3]  = N/A
 l[4]  = N/A
 l[5]  = N/A
 l[6]  = p_ovun6
 l[7]  = N/A
 l[8]  = p_ovun7
 l[9]  = p_ovun8
 l[10] = N/A
 l[11] = swa
 l[12] = swb
 l[13] = N/A
 l[14] = p_val6
 l[15] = p_lp1
 l[16] = p_val9
 l[17] = p_val10
 l[18] = N/A
 l[19] = p_pen2
 l[20] = p_pen3
 l[21] = p_pen4
 l[22] = N/A
 l[23] = p_tor2
 l[24] = p_tor3
 l[25] = p_tor4
 l[26] = N/A
 l[27] = p_cot2
 l[28] = p_vdW1
 l[29] = v_par30
 l[30] = p_coa4
 l[31] = p_ovun4
 l[32] = p_ovun3
 l[33] = p_val8
 l[34] = N/A
 l[35] = N/A
 l[36] = N/A
 l[37] = version number
 l[38] = p_coa3
 */
 
 typedef struct
 {
   int n_global;
   real* l;
   int vdw_type;
 } global_parameters;
 
 
 
 typedef struct
 {
   /* Line one in field file */
   char name[15]; // Two character atom name
 
   real r_s;
   real valency;  // Valency of the atom
   real mass;     // Mass of atom
   real r_vdw;
   real epsilon;
   real gamma;
   real r_pi;
   real valency_e;
   real nlp_opt;
 
   /* Line two in field file */
   real alpha;
   real gamma_w;
   real valency_boc;
   real p_ovun5;
   real chi;
   real eta;
   int  p_hbond; // 1 for H, 2 for hbonding atoms (O,S,P,N), 0 for others
 
   /* Line three in field file */
   real r_pi_pi;
   real p_lp2;
   real b_o_131;
   real b_o_132;
   real b_o_133;
 
   /* Line four in the field file */
   real p_ovun2;
   real p_val3;
   real valency_val;
   real p_val5;
   real rcore2;
   real ecore2;
   real acore2;
 
   /* Line five in the ffield file, only for lgvdw yes */
   real lgcij;
   real lgre;
 
 } single_body_parameters;
 
 
 
 /* Two Body Parameters */
 typedef struct {
   /* Bond Order parameters */
   real p_bo1,p_bo2,p_bo3,p_bo4,p_bo5,p_bo6;
   real r_s, r_p, r_pp;  // r_o distances in BO formula
   real p_boc3, p_boc4, p_boc5;
 
   /* Bond Energy parameters */
   real p_be1, p_be2;
   real De_s, De_p, De_pp;
 
   /* Over/Under coordination parameters */
   real p_ovun1;
 
   /* Van der Waal interaction parameters */
   real D;
   real alpha;
   real r_vdW;
   real gamma_w;
   real rcore, ecore, acore;
   real lgcij, lgre;
 
   /* electrostatic parameters */
   real gamma; // note: this parameter is gamma^-3 and not gamma.
 
   real v13cor, ovc;
 } two_body_parameters;
 
 
 
 /* 3-body parameters */
 typedef struct {
   /* valence angle */
   real theta_00;
   real p_val1, p_val2, p_val4, p_val7;
 
   /* penalty */
   real p_pen1;
 
   /* 3-body conjugation */
   real p_coa1;
 } three_body_parameters;
 
 
 typedef struct{
   int cnt;
   three_body_parameters prm[REAX_MAX_3BODY_PARAM];
 } three_body_header;
 
 
 
 /* hydrogen-bond parameters */
 typedef struct{
   real r0_hb, p_hb1, p_hb2, p_hb3;
 } hbond_parameters;
 
 
 
 /* 4-body parameters */
 typedef struct {
   real V1, V2, V3;
 
   /* torsion angle */
   real p_tor1;
 
   /* 4-body conjugation */
   real p_cot1;
 } four_body_parameters;
 
 
 typedef struct
 {
   int cnt;
   four_body_parameters prm[REAX_MAX_4BODY_PARAM];
 } four_body_header;
 
 
 typedef struct
 {
   int num_atom_types;
   global_parameters gp;
   single_body_parameters *sbp;
   two_body_parameters **tbp;
   three_body_header ***thbp;
   hbond_parameters ***hbp;
   four_body_header ****fbp;
 } reax_interaction;
 
 
 
 struct _reax_atom
 {
   tagint  orig_id;
   int  imprt_id;
   int  type;
   char name[8];
 
   rvec x; // position
   rvec v; // velocity
   rvec f; // force
   rvec f_old;
 
   real q; // charge
   rvec4 s; // they take part in
   rvec4 t; // computing q
 
   int Hindex;
   int num_bonds;
   int num_hbonds;
   int renumber;
 
   int numbonds;                  // true number of bonds around atoms
   int nbr_id[MAX_BOND];          // ids of neighbors around atoms
   double nbr_bo[MAX_BOND];          // BO values of bond between i and nbr
   double sum_bo, no_lp;           // sum of BO values and no. of lone pairs
 };
 typedef _reax_atom reax_atom;
 
 
 
 typedef struct
 {
   real V;
   rvec min, max, box_norms;
 
   rtensor box, box_inv;
   rtensor trans, trans_inv;
   rtensor g;
 } simulation_box;
 
 
 
 struct grid_cell
 {
   real cutoff;
   rvec min, max;
   ivec rel_box;
 
   int  mark;
   int  type;
   int  str;
   int  end;
   int  top;
   int* atoms;
   struct grid_cell** nbrs;
   ivec* nbrs_x;
   rvec* nbrs_cp;
 };
 
 typedef struct grid_cell grid_cell;
 
 
 typedef struct
 {
   int  total, max_atoms, max_nbrs;
   ivec ncells;
   rvec cell_len;
   rvec inv_len;
 
   ivec bond_span;
   ivec nonb_span;
   ivec vlist_span;
 
   ivec native_cells;
   ivec native_str;
   ivec native_end;
 
   real ghost_cut;
   ivec ghost_span;
   ivec ghost_nonb_span;
   ivec ghost_hbond_span;
   ivec ghost_bond_span;
 
   grid_cell*** cells;
   ivec *order;
 } grid;
 
 
 typedef struct
 {
   int  rank;
   int  est_send, est_recv;
   int  atoms_str, atoms_cnt;
   ivec rltv, prdc;
   rvec bndry_min, bndry_max;
 
   int  send_type;
   int  recv_type;
   ivec str_send;
   ivec end_send;
   ivec str_recv;
   ivec end_recv;
 } neighbor_proc;
 
 
 
 typedef struct
 {
   int N;
   int exc_gcells;
   int exc_atoms;
 } bound_estimate;
 
 
 
 typedef struct
 {
   real ghost_nonb;
   real ghost_hbond;
   real ghost_bond;
   real ghost_cutoff;
 } boundary_cutoff;
 
 using LAMMPS_NS::Pair;
 
 struct _reax_system
 {
   reax_interaction reax_param;
 
   int              n, N, bigN, numH;
   int              local_cap, total_cap, gcell_cap, Hcap;
   int              est_recv, est_trans, max_recved;
   int              wsize, my_rank, num_nbrs;
   ivec             my_coords;
   neighbor_proc    my_nbrs[REAX_MAX_NBRS];
   int             *global_offset;
   simulation_box   big_box, my_box, my_ext_box;
   grid             my_grid;
   boundary_cutoff  bndry_cuts;
   reax_atom       *my_atoms;
 
   class Pair *pair_ptr;
   int my_bonds;
   int mincap;
   real safezone, saferzone;
 
 };
 typedef _reax_system reax_system;
 
 
 
 /* system control parameters */
 typedef struct
 {
   char sim_name[REAX_MAX_STR];
   int  nprocs;
   ivec procs_by_dim;
   /* ensemble values:
      0 : NVE
      1 : bNVT (Berendsen)
      2 : nhNVT (Nose-Hoover)
      3 : sNPT (Parrinello-Rehman-Nose-Hoover) semiisotropic
      4 : iNPT (Parrinello-Rehman-Nose-Hoover) isotropic
      5 : NPT  (Parrinello-Rehman-Nose-Hoover) Anisotropic*/
   int  ensemble;
   int  nsteps;
   real dt;
   int  geo_format;
   int  restart;
 
   int  restrict_bonds;
   int  remove_CoM_vel;
   int  random_vel;
   int  reposition_atoms;
 
   int  reneighbor;
   real vlist_cut;
   real bond_cut;
   real nonb_cut, nonb_low;
   real hbond_cut;
   real user_ghost_cut;
 
   real bg_cut;
   real bo_cut;
   real thb_cut;
   real thb_cutsq;
 
   int tabulate;
 
   int qeq_freq;
   real q_err;
   int refactor;
   real droptol;
 
   real T_init, T_final, T;
   real Tau_T;
   int  T_mode;
   real T_rate, T_freq;
 
   int  virial;
   rvec P, Tau_P, Tau_PT;
   int  press_mode;
   real compressibility;
 
   int  molecular_analysis;
   int  num_ignored;
   int  ignore[REAX_MAX_ATOM_TYPES];
 
   int  dipole_anal;
   int  freq_dipole_anal;
   int  diffusion_coef;
   int  freq_diffusion_coef;
   int  restrict_type;
 
   int lgflag;
 
 } control_params;
 
 
 typedef struct
 {
   real T;
   real xi;
   real v_xi;
   real v_xi_old;
   real G_xi;
 
 } thermostat;
 
 
 typedef struct
 {
   real P;
   real eps;
   real v_eps;
   real v_eps_old;
   real a_eps;
 
 } isotropic_barostat;
 
 
 typedef struct
 {
   rtensor P;
   real P_scalar;
 
   real eps;
   real v_eps;
   real v_eps_old;
   real a_eps;
 
   rtensor h0;
   rtensor v_g0;
   rtensor v_g0_old;
   rtensor a_g0;
 
 } flexible_barostat;
 
 
 typedef struct
 {
   real start;
   real end;
   real elapsed;
 
   real total;
   real comm;
   real nbrs;
   real init_forces;
   real bonded;
   real nonb;
   real qEq;
   int  s_matvecs;
   int  t_matvecs;
 } reax_timing;
 
 
 typedef struct
 {
   real e_tot;
   real e_kin;                      // Total kinetic energy
   real e_pot;
 
   real e_bond;                     // Total bond energy
   real e_ov;                       // Total over coordination
   real e_un;                       // Total under coordination energy
   real e_lp;                       // Total under coordination energy
   real e_ang;                      // Total valance angle energy
   real e_pen;                      // Total penalty energy
   real e_coa;                      // Total three body conjgation energy
   real e_hb;                       // Total Hydrogen bond energy
   real e_tor;                      // Total torsional energy
   real e_con;                      // Total four body conjugation energy
   real e_vdW;                      // Total van der Waals energy
   real e_ele;                      // Total electrostatics energy
   real e_pol;                      // Polarization energy
 } energy_data;
 
 typedef struct
 {
   int  step;
   int  prev_steps;
   real time;
 
   real M;                           // Total Mass
   real inv_M;                      // 1 / Total Mass
 
   rvec xcm;                        // Center of mass
   rvec vcm;                        // Center of mass velocity
   rvec fcm;                        // Center of mass force
   rvec amcm;                       // Angular momentum of CoM
   rvec avcm;                       // Angular velocity of CoM
   real etran_cm;                   // Translational kinetic energy of CoM
   real erot_cm;                    // Rotational kinetic energy of CoM
 
   rtensor kinetic;                 // Kinetic energy tensor
   rtensor virial;                  // Hydrodynamic virial
 
   energy_data my_en;
   energy_data sys_en;
 
   real               N_f;          //Number of degrees of freedom
   rvec               t_scale;
   rtensor            p_scale;
   thermostat         therm;        // Used in Nose_Hoover method
   isotropic_barostat iso_bar;
   flexible_barostat  flex_bar;
   real               inv_W;
 
   real kin_press;
   rvec int_press;
   rvec my_ext_press;
   rvec ext_press;
   rvec tot_press;
 
   reax_timing timing;
 } simulation_data;
 
 
 typedef struct{
   int thb;
   int pthb; // pointer to the third body on the central atom's nbrlist
   real theta, cos_theta;
   rvec dcos_di, dcos_dj, dcos_dk;
 } three_body_interaction_data;
 
 
 typedef struct {
   int nbr;
   ivec rel_box;
   real d;
   rvec dvec;
 } far_neighbor_data;
 
 
 typedef struct {
   int nbr;
   int scl;
   far_neighbor_data *ptr;
 } hbond_data;
 
 
 typedef struct{
   int wrt;
   rvec dVal;
 } dDelta_data;
 
 
 typedef struct{
   int wrt;
   rvec dBO, dBOpi, dBOpi2;
 } dbond_data;
 
 typedef struct{
   real BO, BO_s, BO_pi, BO_pi2;
   real Cdbo, Cdbopi, Cdbopi2;
   real C1dbo, C2dbo, C3dbo;
   real C1dbopi, C2dbopi, C3dbopi, C4dbopi;
   real C1dbopi2, C2dbopi2, C3dbopi2, C4dbopi2;
   rvec dBOp, dln_BOp_s, dln_BOp_pi, dln_BOp_pi2;
 } bond_order_data;
 
 typedef struct {
   int nbr;
   int sym_index;
   int dbond_index;
   ivec rel_box;
   //  rvec ext_factor;
   real d;
   rvec dvec;
   bond_order_data bo_data;
 } bond_data;
 
 
 typedef struct {
   int j;
   real val;
 } sparse_matrix_entry;
 
 typedef struct {
   int cap, n, m;
   int *start, *end;
   sparse_matrix_entry *entries;
 } sparse_matrix;
 
 
 typedef struct {
   int num_far;
   int H, Htop;
   int hbonds, num_hbonds;
   int bonds, num_bonds;
   int num_3body;
   int gcell_atoms;
 } reallocate_data;
 
 
 typedef struct
 {
   int allocated;
 
   /* communication storage */
   real *tmp_dbl[REAX_MAX_NBRS];
   rvec *tmp_rvec[REAX_MAX_NBRS];
   rvec2 *tmp_rvec2[REAX_MAX_NBRS];
   int  *within_bond_box;
 
   /* bond order related storage */
   real *total_bond_order;
   real *Deltap, *Deltap_boc;
   real *Delta, *Delta_lp, *Delta_lp_temp, *Delta_e, *Delta_boc, *Delta_val;
   real *dDelta_lp, *dDelta_lp_temp;
   real *nlp, *nlp_temp, *Clp, *vlpex;
   rvec *dDeltap_self;
   int *bond_mark, *done_after;
 
   /* QEq storage */
   sparse_matrix *H, *L, *U;
   real *Hdia_inv, *b_s, *b_t, *b_prc, *b_prm, *s, *t;
   real *droptol;
   rvec2 *b, *x;
 
   /* GMRES storage */
   real *y, *z, *g;
   real *hc, *hs;
   real **h, **v;
   /* CG storage */
   real *r, *d, *q, *p;
   rvec2 *r2, *d2, *q2, *p2;
   /* Taper */
   real Tap[8]; //Tap7, Tap6, Tap5, Tap4, Tap3, Tap2, Tap1, Tap0;
 
   /* storage for analysis */
   int  *mark, *old_mark;
   rvec *x_old;
 
   /* storage space for bond restrictions */
   int  *restricted;
   int **restricted_list;
 
   /* integrator */
   rvec *v_const;
 
   /* force calculations */
   real *CdDelta;  // coefficient of dDelta
   rvec *f;
 #ifdef TEST_FORCES
   rvec *f_ele;
   rvec *f_vdw;
   rvec *f_bo;
   rvec *f_be;
   rvec *f_lp;
   rvec *f_ov;
   rvec *f_un;
   rvec *f_ang;
   rvec *f_coa;
   rvec *f_pen;
   rvec *f_hb;
   rvec *f_tor;
   rvec *f_con;
   rvec *f_tot;
   rvec *dDelta;   // calculated on the fly in bond_orders.c together with bo'
 
   int  *rcounts;
   int  *displs;
   int  *id_all;
   rvec *f_all;
 #endif
 
   reallocate_data realloc;
   //int *num_bonds;
   /* hydrogen bonds */
   //int   num_H, Hcap;
   //int  *Hindex;
   //int *num_hbonds;
   //int *hash;
   //int *rev_hash;
 } storage;
 
 
 typedef union
 {
   void *v;
   three_body_interaction_data *three_body_list;
   bond_data          *bond_list;
   dbond_data         *dbo_list;
   dDelta_data        *dDelta_list;
   far_neighbor_data  *far_nbr_list;
   hbond_data         *hbond_list;
 } list_type;
 
 
 struct _reax_list
 {
   int allocated;
 
   int n;
   int num_intrs;
 
   int *index;
   int *end_index;
 
   int type;
   list_type select;
 };
 typedef _reax_list  reax_list;
 
 
 typedef struct
 {
 #if defined(PURE_REAX)
   MPI_File trj;
 #endif
   FILE *strj;
   int   trj_offset;
   int   atom_line_len;
   int   bond_line_len;
   int   angle_line_len;
   int   write_atoms;
   int   write_bonds;
   int   write_angles;
   char *line;
   int   buffer_len;
   char *buffer;
 
   FILE *out;
   FILE *pot;
   FILE *log;
   FILE *mol, *ign;
   FILE *dpl;
   FILE *drft;
   FILE *pdb;
   FILE *prs;
 
   int   write_steps;
   int   traj_compress;
   int   traj_method;
   char  traj_title[81];
   int   atom_info;
   int   bond_info;
   int   angle_info;
 
   int   restart_format;
   int   restart_freq;
   int   debug_level;
   int   energy_update_freq;
 
 #ifdef TEST_ENERGY
   FILE *ebond;
   FILE *elp, *eov, *eun;
   FILE *eval, *epen, *ecoa;
   FILE *ehb;
   FILE *etor, *econ;
   FILE *evdw, *ecou;
 #endif
 
 #ifdef TEST_FORCES
   FILE *fbo, *fdbo;
   FILE *fbond;
   FILE *flp, *fov, *fun;
   FILE *fang, *fcoa, *fpen;
   FILE *fhb;
   FILE *ftor, *fcon;
   FILE *fvdw, *fele;
   FILE *ftot, *fcomp;
 #endif
 
 #if defined(TEST_ENERGY) || defined(TEST_FORCES)
   FILE *flist; // far neighbor list
   FILE *blist; // bond list
   FILE *nlist; // near neighbor list
 #endif
 } output_controls;
 
 
 typedef struct
 {
   int atom_count;
   int atom_list[REAX_MAX_MOLECULE_SIZE];
   int mtypes[REAX_MAX_ATOM_TYPES];
 } molecule;
 
 
 typedef struct
 {
   real H;
   real e_vdW, CEvd;
   real e_ele, CEclmb;
 } LR_data;
 
 
 typedef struct
 {
   real a, b, c, d;
 } cubic_spline_coef;
 
 
 
 typedef struct
 {
   real xmin, xmax;
   int n;
   real dx, inv_dx;
   real a;
   real m;
   real c;
 
   LR_data *y;
   cubic_spline_coef *H;
   cubic_spline_coef *vdW, *CEvd;
   cubic_spline_coef *ele, *CEclmb;
 } LR_lookup_table;
 extern LR_lookup_table **LR;
 
 /* function pointer defs */
 typedef void (*evolve_function)(reax_system*, control_params*,
                                 simulation_data*, storage*, reax_list**,
                                 output_controls*, mpi_datatypes* );
 #if defined(PURE_REAX)
 evolve_function  Evolve;
 #endif
 
 typedef void (*interaction_function) (reax_system*, control_params*,
                                       simulation_data*, storage*,
                                       reax_list**, output_controls*);
 
 typedef void (*print_interaction)(reax_system*, control_params*,
                                   simulation_data*, storage*,
                                   reax_list**, output_controls*);
 
 typedef real (*lookup_function)(real);
 
 typedef void (*message_sorter) (reax_system*, int, int, int, mpi_out_data*);
 typedef void (*unpacker) ( reax_system*, int, void*, int, neighbor_proc*, int );
 
 typedef void (*dist_packer) (void*, mpi_out_data*);
 typedef void (*coll_unpacker) (void*, void*, mpi_out_data*);
 #endif