diff --git a/environ/param.gpu.water b/environ/param.gpu.water
index bed2200680dffb9cf0cf81d7a422a8b0dbd8fd36..3c38e57dd9a357e3d293dcedc2e0becf90f15e72 100644
--- a/environ/param.gpu.water
+++ b/environ/param.gpu.water
@@ -17,10 +17,12 @@ hbond_cutoff            7.50                    ! cutoff distance for hydrogen b
 charge_method          0                        ! charge method: 0 = QEq, 1 = EEM, 2 = ACKS2
 cm_q_net               0.0                      ! net system charge
 cm_solver_type         0                        ! iterative linear solver for charge method: 0 = GMRES, 1 = GMRES_H, 2 = CG, 3 = SDM
+cm_solver_max_iters    20                       ! max solver iterations
+cm_solver_restart      100                      ! inner iterations of GMRES before restarting
 cm_solver_q_err        1e-6                     ! relative residual norm threshold used in solver
 cm_domain_sparsity     1.0                      ! scalar for scaling cut-off distance, used to sparsify charge matrix (between 0.0 and 1.0)
 cm_solver_pre_comp_type           1             ! method used to compute preconditioner, if applicable
-cm_solver_pre_comp_refactor       100           ! number of steps before recomputing preconditioner
+cm_solver_pre_comp_refactor       1000           ! number of steps before recomputing preconditioner
 cm_solver_pre_comp_droptol        0.0           ! threshold tolerance for dropping values in preconditioner computation, if applicable
 cm_solver_pre_comp_sweeps         3             ! number of sweeps used to compute preconditioner (ILU_PAR)
 cm_solver_pre_app_type            1             ! method used to apply preconditioner
diff --git a/sPuReMD/src/charges.c b/sPuReMD/src/charges.c
index ecd2827e18d42585568f723ad5371811dcbcfb3d..c2242449c0df822996beaf6d5cb7dbe34481540e 100644
--- a/sPuReMD/src/charges.c
+++ b/sPuReMD/src/charges.c
@@ -574,7 +574,7 @@ static real SuperLU_Factorize( const sparse_matrix * const A,
 
 
 /* Diagonal (Jacobi) preconditioner computation */
-static real diag_pre_comp( const reax_system * const system, real * const Hdia_inv )
+static real diag_pre_comp( const sparse_matrix * const H, real * const Hdia_inv )
 {
     unsigned int i;
     real start;
@@ -583,16 +583,9 @@ static real diag_pre_comp( const reax_system * const system, real * const Hdia_i
 
     #pragma omp parallel for schedule(static) \
         default(none) private(i)
-    for ( i = 0; i < system->N; ++i )
-    {
-        Hdia_inv[i] = 1.0 / system->reaxprm.sbp[system->atoms[i].type].eta;
-    }
-
-    #pragma omp parallel for schedule(static) \
-        default(none) private(i)
-    for ( i = system->N; i < system->N_cm; ++i )
+    for ( i = 0; i < H->n; ++i )
     {
-        Hdia_inv[i] = 1.0;
+        Hdia_inv[i] = 1.0 / H->val[H->start[i + 1] - 1];
     }
 
     return Get_Timing_Info( start );
@@ -1485,7 +1478,7 @@ static void Compute_Preconditioner_QEq( const reax_system * const system,
     {
     case DIAG_PC:
         data->timing.cm_solver_pre_comp +=
-            diag_pre_comp( system, workspace->Hdia_inv );
+            diag_pre_comp( Hptr, workspace->Hdia_inv );
         break;
 
     case ICHOLT_PC:
@@ -1578,7 +1571,7 @@ static void Compute_Preconditioner_EEM( const reax_system * const system,
     {
     case DIAG_PC:
         data->timing.cm_solver_pre_comp +=
-            diag_pre_comp( system, workspace->Hdia_inv );
+            diag_pre_comp( Hptr, workspace->Hdia_inv );
         break;
 
     case ICHOLT_PC:
@@ -1819,7 +1812,7 @@ static void Compute_Preconditioner_ACKS2( const reax_system * const system,
     {
     case DIAG_PC:
         data->timing.cm_solver_pre_comp +=
-            diag_pre_comp( system, workspace->Hdia_inv );
+            diag_pre_comp( Hptr, workspace->Hdia_inv );
         break;
 
     case ICHOLT_PC:
@@ -2468,9 +2461,9 @@ static void QEq( reax_system * const system, control_params * const control,
         break;
 
     case CG_S:
-        iters = CG( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
+        iters = CG( workspace, control, workspace->H, workspace->b_s, control->cm_solver_q_err,
                     workspace->s[0], out_control->log ) + 1;
-        iters += CG( workspace, workspace->H, workspace->b_t, control->cm_solver_q_err,
+        iters += CG( workspace, control, workspace->H, workspace->b_t, control->cm_solver_q_err,
                      workspace->t[0], out_control->log ) + 1;
 //            iters = CG( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
 //                    workspace->L, workspace->U, workspace->s[0], control->cm_solver_pre_app_type,
@@ -2481,9 +2474,9 @@ static void QEq( reax_system * const system, control_params * const control,
         break;
 
     case SDM_S:
-        iters = SDM( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
+        iters = SDM( workspace, control, workspace->H, workspace->b_s, control->cm_solver_q_err,
                      workspace->s[0], out_control->log ) + 1;
-        iters += SDM( workspace, workspace->H, workspace->b_t, control->cm_solver_q_err,
+        iters += SDM( workspace,control,  workspace->H, workspace->b_t, control->cm_solver_q_err,
                       workspace->t[0], out_control->log ) + 1;
 //            iters = SDM( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
 //                    workspace->L, workspace->U, workspace->s[0], control->cm_solver_pre_app_type,
@@ -2561,12 +2554,12 @@ static void EEM( reax_system * const system, control_params * const control,
         break;
 
     case CG_S:
-        iters = CG( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
+        iters = CG( workspace, control, workspace->H, workspace->b_s, control->cm_solver_q_err,
                 workspace->s[0], out_control->log ) + 1;
         break;
 
     case SDM_S:
-        iters = SDM( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
+        iters = SDM( workspace, control, workspace->H, workspace->b_s, control->cm_solver_q_err,
                 workspace->s[0], out_control->log ) + 1;
         break;
 
@@ -2640,12 +2633,12 @@ static void ACKS2( reax_system * const system, control_params * const control,
         break;
 
     case CG_S:
-        iters = CG( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
+        iters = CG( workspace, control, workspace->H, workspace->b_s, control->cm_solver_q_err,
                 workspace->s[0], out_control->log ) + 1;
         break;
 
     case SDM_S:
-        iters = SDM( workspace, workspace->H, workspace->b_s, control->cm_solver_q_err,
+        iters = SDM( workspace, control, workspace->H, workspace->b_s, control->cm_solver_q_err,
                 workspace->s[0], out_control->log ) + 1;
         break;
 
diff --git a/sPuReMD/src/control.c b/sPuReMD/src/control.c
index 7f0134f3c69b25f13a0f12b7845ce0afe432dad0..e906fc85db5cda6898af5400242be5c23d0415b5 100644
--- a/sPuReMD/src/control.c
+++ b/sPuReMD/src/control.c
@@ -73,6 +73,8 @@ char Read_Control_File( FILE* fp, reax_system *system, control_params* control,
     control->charge_method = QEQ_CM;
     control->cm_q_net = 0.0;
     control->cm_solver_type = GMRES_S;
+    control->cm_solver_max_iters = 100;
+    control->cm_solver_restart = 50;
     control->cm_solver_q_err = 0.000001;
     control->cm_domain_sparsify_enabled = FALSE;
     control->cm_domain_sparsity = 1.0;
@@ -257,6 +259,16 @@ char Read_Control_File( FILE* fp, reax_system *system, control_params* control,
             ival = atoi( tmp[1] );
             control->cm_solver_type = ival;
         }
+        else if ( strcmp(tmp[0], "cm_solver_max_iters") == 0 )
+        {
+            ival = atoi( tmp[1] );
+            control->cm_solver_max_iters = ival;
+        }
+        else if ( strcmp(tmp[0], "cm_solver_restart") == 0 )
+        {
+            ival = atoi( tmp[1] );
+            control->cm_solver_restart = ival;
+        }
         else if ( strcmp(tmp[0], "cm_solver_q_err") == 0 )
         {
             val = atof( tmp[1] );
diff --git a/sPuReMD/src/grid.c b/sPuReMD/src/grid.c
index c45c1a2214d7589b3e4c1a647ebde1b9d3c7e56d..c422a48ae746f336cb0c3398c3990678d93ec35e 100644
--- a/sPuReMD/src/grid.c
+++ b/sPuReMD/src/grid.c
@@ -494,13 +494,12 @@ static inline void reax_atom_Copy( reax_atom *dest, reax_atom *src )
 
 
 void Copy_Storage( reax_system *system, static_storage *workspace,
-                   int top, int old_id, int old_type,
-                   int *num_H, real **v, real **s, real **t,
-                   int *orig_id, rvec *f_old )
+        control_params *control, int top, int old_id, int old_type, int *num_H,
+        real **v, real **s, real **t, int *orig_id, rvec *f_old )
 {
     int i;
 
-    for ( i = 0; i < RESTART + 1; ++i )
+    for ( i = 0; i < control->cm_solver_restart + 1; ++i )
     {
         v[i][top] = workspace->v[i][old_id];
     }
@@ -529,11 +528,11 @@ void Copy_Storage( reax_system *system, static_storage *workspace,
 }
 
 
-void Free_Storage( static_storage *workspace )
+void Free_Storage( static_storage *workspace, control_params * control )
 {
     int i;
 
-    for ( i = 0; i < RESTART + 1; ++i )
+    for ( i = 0; i < control->cm_solver_restart + 1; ++i )
     {
         free( workspace->v[i] );
     }
@@ -566,7 +565,8 @@ void Assign_New_Storage( static_storage *workspace,
 }
 
 
-void Cluster_Atoms( reax_system *system, static_storage *workspace )
+void Cluster_Atoms( reax_system *system, static_storage *workspace,
+        control_params *control )
 {
     int         i, j, k, l, top, old_id, num_H;
     reax_atom  *old_atom;
@@ -591,8 +591,8 @@ void Cluster_Atoms( reax_system *system, static_storage *workspace )
         t[i] = (real *) calloc( system->N, sizeof( real ) );
     }
 
-    v = (real**) calloc( RESTART + 1, sizeof( real* ) );
-    for ( i = 0; i < RESTART + 1; ++i )
+    v = (real**) calloc( control->cm_solver_restart + 1, sizeof( real* ) );
+    for ( i = 0; i < control->cm_solver_restart + 1; ++i )
     {
         v[i] = (real *) calloc( system->N, sizeof( real ) );
     }
@@ -614,8 +614,8 @@ void Cluster_Atoms( reax_system *system, static_storage *workspace )
                     // fprintf( stderr, "%d <-- %d\n", top, old_id );
 
                     reax_atom_Copy( &(new_atoms[top]), old_atom );
-                    Copy_Storage( system, workspace, top, old_id, old_atom->type,
-                                  &num_H, v, s, t, orig_id, f_old );
+                    Copy_Storage( system, workspace, control, top, old_id, old_atom->type,
+                            &num_H, v, s, t, orig_id, f_old );
                     ++top;
                 }
 
@@ -626,7 +626,7 @@ void Cluster_Atoms( reax_system *system, static_storage *workspace )
 
 
     free( system->atoms );
-    Free_Storage( workspace );
+    Free_Storage( workspace, control );
 
     system->atoms = new_atoms;
     Assign_New_Storage( workspace, v, s, t, orig_id, f_old );
diff --git a/sPuReMD/src/grid.h b/sPuReMD/src/grid.h
index 41d7b57edb2ba271bd41f71c6a77d5f179370910..cab825018606dd56e9f2b057c89a7d43287ed1f7 100644
--- a/sPuReMD/src/grid.h
+++ b/sPuReMD/src/grid.h
@@ -30,7 +30,7 @@ void Update_Grid( reax_system* );
 
 int  Shift( int, int, int, grid* );
 
-void Cluster_Atoms( reax_system*, static_storage* );
+void Cluster_Atoms( reax_system *, static_storage *, control_params * );
 
 void Bin_Atoms( reax_system*, static_storage* );
 
diff --git a/sPuReMD/src/init_md.c b/sPuReMD/src/init_md.c
index 2ddcbeb6ebfe05491d718b41ee390d40a6903575..4b93ec83c4d6dcfbb8c32ba2c7736889ba6fc635 100644
--- a/sPuReMD/src/init_md.c
+++ b/sPuReMD/src/init_md.c
@@ -266,7 +266,7 @@ void Init_Taper( control_params *control )
 
 
 void Init_Workspace( reax_system *system, control_params *control,
-                     static_storage *workspace )
+        static_storage *workspace )
 {
     int i;
 
@@ -406,18 +406,18 @@ void Init_Workspace( reax_system *system, control_params *control,
         /* GMRES storage */
         case GMRES_S:
         case GMRES_H_S:
-            workspace->y  = (real *)  calloc( RESTART + 1, sizeof( real ) );
-            workspace->z  = (real *)  calloc( RESTART + 1, sizeof( real ) );
-            workspace->g  = (real *)  calloc( RESTART + 1, sizeof( real ) );
-            workspace->h  = (real **) calloc( RESTART + 1, sizeof( real*) );
-            workspace->hs = (real *)  calloc( RESTART + 1, sizeof( real ) );
-            workspace->hc = (real *)  calloc( RESTART + 1, sizeof( real ) );
-            workspace->rn = (real **) calloc( RESTART + 1, sizeof( real*) );
-            workspace->v  = (real **) calloc( RESTART + 1, sizeof( real*) );
-
-            for ( i = 0; i < RESTART + 1; ++i )
+            workspace->y  = (real *)  calloc( control->cm_solver_restart + 1, sizeof( real ) );
+            workspace->z  = (real *)  calloc( control->cm_solver_restart + 1, sizeof( real ) );
+            workspace->g  = (real *)  calloc( control->cm_solver_restart + 1, sizeof( real ) );
+            workspace->h  = (real **) calloc( control->cm_solver_restart + 1, sizeof( real*) );
+            workspace->hs = (real *)  calloc( control->cm_solver_restart + 1, sizeof( real ) );
+            workspace->hc = (real *)  calloc( control->cm_solver_restart + 1, sizeof( real ) );
+            workspace->rn = (real **) calloc( control->cm_solver_restart + 1, sizeof( real*) );
+            workspace->v  = (real **) calloc( control->cm_solver_restart + 1, sizeof( real*) );
+
+            for ( i = 0; i < control->cm_solver_restart + 1; ++i )
             {
-                workspace->h[i]  = (real *) calloc( RESTART + 1, sizeof( real ) );
+                workspace->h[i]  = (real *) calloc( control->cm_solver_restart + 1, sizeof( real ) );
                 workspace->rn[i] = (real *) calloc( system->N_cm * 2, sizeof( real ) );
                 workspace->v[i]  = (real *) calloc( system->N_cm, sizeof( real ) );
             }
diff --git a/sPuReMD/src/lin_alg.c b/sPuReMD/src/lin_alg.c
index 65cea774c8edfebba473f9a12555c7d26828604e..31bd16e1b1052cd302ffaed2b40ff465eab2dc35 100644
--- a/sPuReMD/src/lin_alg.c
+++ b/sPuReMD/src/lin_alg.c
@@ -1177,9 +1177,8 @@ static void apply_preconditioner( const static_storage * const workspace, const
 
 /* generalized minimual residual iterative solver for sparse linear systems */
 int GMRES( const static_storage * const workspace, const control_params * const control,
-           simulation_data * const data, const sparse_matrix * const H,
-           const real * const b, const real tol, real * const x,
-           const FILE * const fout, const int fresh_pre )
+        simulation_data * const data, const sparse_matrix * const H, const real * const b,
+        const real tol, real * const x, const FILE * const fout, const int fresh_pre )
 {
     int i, j, k, itr, N, g_j, g_itr;
     real cc, tmp1, tmp2, temp, ret_temp, bnorm, time_start;
@@ -1214,7 +1213,7 @@ int GMRES( const static_storage * const workspace, const control_params * const
         }
 
         /* GMRES outer-loop */
-        for ( itr = 0; itr < MAX_ITR; ++itr )
+        for ( itr = 0; itr < control->cm_solver_max_iters; ++itr )
         {
             /* calculate r0 */
             #pragma omp master
@@ -1295,7 +1294,7 @@ int GMRES( const static_storage * const workspace, const control_params * const
             }
 
             /* GMRES inner-loop */
-            for ( j = 0; j < RESTART && FABS(workspace->g[j]) / bnorm > tol; j++ )
+            for ( j = 0; j < control->cm_solver_restart && FABS(workspace->g[j]) / bnorm > tol; j++ )
             {
                 /* matvec */
                 #pragma omp master
@@ -1501,28 +1500,28 @@ int GMRES( const static_storage * const workspace, const control_params * const
 
     // fprintf(fout,"GMRES outer:%d, inner:%d iters - residual norm: %25.20f\n",
     //          itr, j, fabs( workspace->g[j] ) / bnorm );
-    // data->timing.solver_iters += itr * RESTART + j;
+    // data->timing.solver_iters += itr * control->cm_solver_restart + j;
 
-    if ( g_itr >= MAX_ITR )
+    if ( g_itr >= control->cm_solver_max_iters )
     {
         fprintf( stderr, "GMRES convergence failed\n" );
         // return -1;
-        return g_itr * (RESTART + 1) + g_j + 1;
+        return g_itr * (control->cm_solver_restart + 1) + g_j + 1;
     }
 
-    return g_itr * (RESTART + 1) + g_j + 1;
+    return g_itr * (control->cm_solver_restart + 1) + g_j + 1;
 }
 
 
-int GMRES_HouseHolder( const static_storage * const workspace, const control_params * const control,
-                       simulation_data * const data, const sparse_matrix * const H,
-                       const real * const b, real tol, real * const x,
-                       const FILE * const fout, const int fresh_pre )
+int GMRES_HouseHolder( const static_storage * const workspace,
+        const control_params * const control, simulation_data * const data,
+        const sparse_matrix * const H, const real * const b, real tol,
+        real * const x, const FILE * const fout, const int fresh_pre )
 {
     int  i, j, k, itr, N;
     real cc, tmp1, tmp2, temp, bnorm;
-    real v[10000], z[RESTART + 2][10000], w[RESTART + 2];
-    real u[RESTART + 2][10000];
+    real v[10000], z[control->cm_solver_restart + 2][10000], w[control->cm_solver_restart + 2];
+    real u[control->cm_solver_restart + 2][10000];
 
     N = H->n;
     bnorm = Norm( b, N );
@@ -1536,7 +1535,7 @@ int GMRES_HouseHolder( const static_storage * const workspace, const control_par
     // memset( x, 0, sizeof(real) * N );
 
     /* GMRES outer-loop */
-    for ( itr = 0; itr < MAX_ITR; ++itr )
+    for ( itr = 0; itr < control->cm_solver_max_iters; ++itr )
     {
         /* compute z = r0 */
         Sparse_MatVec( H, x, workspace->b_prm );
@@ -1546,7 +1545,7 @@ int GMRES_HouseHolder( const static_storage * const workspace, const control_par
         }
         Vector_Sum( z[0], 1.,  workspace->b_prc, -1., workspace->b_prm, N );
 
-        Vector_MakeZero( w, RESTART + 1 );
+        Vector_MakeZero( w, control->cm_solver_restart + 1 );
         w[0] = Norm( z[0], N );
 
         Vector_Copy( u[0], z[0], N );
@@ -1557,7 +1556,7 @@ int GMRES_HouseHolder( const static_storage * const workspace, const control_par
         // fprintf( stderr, "\n\n%12.6f\n", w[0] );
 
         /* GMRES inner-loop */
-        for ( j = 0; j < RESTART && fabs( w[j] ) / bnorm > tol; j++ )
+        for ( j = 0; j < control->cm_solver_restart && fabs( w[j] ) / bnorm > tol; j++ )
         {
             /* compute v_j */
             Vector_Scale( z[j], -2 * u[j][j], u[j], N );
@@ -1661,7 +1660,7 @@ int GMRES_HouseHolder( const static_storage * const workspace, const control_par
         }
 
         // fprintf( stderr, "y: " );
-        // for( i = 0; i < RESTART+1; ++i )
+        // for( i = 0; i < control->cm_solver_restart+1; ++i )
         //   fprintf( stderr, "%8.3f ", workspace->y[i] );
 
 
@@ -1712,20 +1711,21 @@ int GMRES_HouseHolder( const static_storage * const workspace, const control_par
     //fprintf( fout,"GMRES outer:%d, inner:%d iters - residual norm: %15.10f\n",
     //         itr, j, fabs( workspace->g[j] ) / bnorm );
 
-    if ( itr >= MAX_ITR )
+    if ( itr >= control->cm_solver_max_iters )
     {
         fprintf( stderr, "GMRES convergence failed\n" );
         // return -1;
-        return itr * (RESTART + 1) + j + 1;
+        return itr * (control->cm_solver_restart + 1) + j + 1;
     }
 
-    return itr * (RESTART + 1) + j + 1;
+    return itr * (control->cm_solver_restart + 1) + j + 1;
 }
 
 
 /* Preconditioned Conjugate Gradient */
-int PCG( static_storage *workspace, sparse_matrix *A, real *b, real tol,
-         sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout )
+int PCG( static_storage *workspace, const control_params * const control,
+        sparse_matrix *A, real *b, real tol,
+        sparse_matrix *L, sparse_matrix *U, real *x, FILE *fout )
 {
     int  i, N;
     real tmp, alpha, beta, b_norm, r_norm;
@@ -1780,8 +1780,9 @@ int PCG( static_storage *workspace, sparse_matrix *A, real *b, real tol,
 
 
 /* Conjugate Gradient */
-int CG( static_storage *workspace, sparse_matrix *H,
-        real *b, real tol, real *x, FILE *fout )
+int CG( const static_storage * const workspace, const control_params * const control,
+        const sparse_matrix * const H, const real * const b, const real tol, real * const x,
+        const FILE * const fout )
 {
     int  i, j, N;
     real tmp, alpha, beta, b_norm;
@@ -1805,7 +1806,7 @@ int CG( static_storage *workspace, sparse_matrix *H,
     // sqrt(sig_new), Norm(workspace->d,N), Norm(workspace->q,N) );
     //fprintf( stderr, "sig_new: %f\n", sig_new );
 
-    for ( i = 0; i < 300 && SQRT(sig_new) / b_norm > tol; ++i )
+    for ( i = 0; i < control->cm_solver_max_iters && SQRT(sig_new) / b_norm > tol; ++i )
     {
         //for( i = 0; i < 300 && sig_new > SQR(tol)*sig0; ++i ) {
         Sparse_MatVec( H, workspace->d, workspace->q );
@@ -1842,8 +1843,9 @@ int CG( static_storage *workspace, sparse_matrix *H,
 
 
 /* Steepest Descent */
-int SDM( static_storage *workspace, sparse_matrix *H,
-         real *b, real tol, real *x, FILE *fout )
+int SDM( const static_storage * const workspace, const control_params * const control,
+        const sparse_matrix * const H, const real * const b, const real tol, real * const x,
+        const FILE * const fout )
 {
     int  i, j, N;
     real tmp, alpha, beta, b_norm;
@@ -1863,7 +1865,7 @@ int SDM( static_storage *workspace, sparse_matrix *H,
     sig = Dot( workspace->r, workspace->d, N );
     sig0 = sig;
 
-    for ( i = 0; i < 300 && SQRT(sig) / b_norm > tol; ++i )
+    for ( i = 0; i < control->cm_solver_max_iters && SQRT(sig) / b_norm > tol; ++i )
     {
         Sparse_MatVec( H, workspace->d, workspace->q );
 
diff --git a/sPuReMD/src/lin_alg.h b/sPuReMD/src/lin_alg.h
index 6678e1b4edc48f88944833e4927d5f54c59da292..e293a96864a0458e745bbf88fade8ec90ec5e861 100644
--- a/sPuReMD/src/lin_alg.h
+++ b/sPuReMD/src/lin_alg.h
@@ -56,11 +56,13 @@ int GMRES_HouseHolder( const static_storage * const, const control_params * cons
         const real * const, const real, real * const,
         const FILE * const, const int );
 
-int CG( static_storage*, sparse_matrix*,
-        real*, real, real*, FILE* );
+int CG( const static_storage * const, const control_params * const,
+        const sparse_matrix * const, const real * const, const real, real * const,
+        const FILE * const );
 
-int SDM( static_storage*, sparse_matrix*,
-         real*, real, real*, FILE* );
+int SDM( const static_storage * const, const control_params * const,
+        const sparse_matrix * const, const real * const, const real, real * const,
+        const FILE * const );
 
 real condest( const sparse_matrix * const, const sparse_matrix * const );
 
diff --git a/sPuReMD/src/mytypes.h b/sPuReMD/src/mytypes.h
index 826dee383d23785b2fcd657b0e94f3745609042c..7487086ec260f15f8731834ca444c02638365d17 100644
--- a/sPuReMD/src/mytypes.h
+++ b/sPuReMD/src/mytypes.h
@@ -113,9 +113,6 @@
 #define MAX_dT              4.00
 #define MIN_dT              0.00
 
-#define MAX_ITR             10
-#define RESTART             50
-
 #define ZERO           0.000000000000000e+00
 #define ALMOST_ZERO    1e-10
 #define NEG_INF       -1e10
@@ -530,6 +527,8 @@ typedef struct
     unsigned int charge_method;
     unsigned int cm_solver_type;
     real cm_q_net;
+    unsigned int cm_solver_max_iters;
+    unsigned int cm_solver_restart;
     real cm_solver_q_err;
     real cm_domain_sparsity;
     unsigned int cm_domain_sparsify_enabled;
diff --git a/sPuReMD/src/neighbors.c b/sPuReMD/src/neighbors.c
index fc318ef2d7d7022fc97df29548017299cd1f5e63..1208c826606e61bf912d3623a9d4011eb95f99ee 100644
--- a/sPuReMD/src/neighbors.c
+++ b/sPuReMD/src/neighbors.c
@@ -390,7 +390,7 @@ void Generate_Neighbor_Lists( reax_system *system, control_params *control,
     // fprintf( stderr, "atoms sorted - " );
 
 #ifdef REORDER_ATOMS
-    Cluster_Atoms( system, workspace );
+    Cluster_Atoms( system, workspace, control );
     // fprintf( stderr, "atoms clustered - " );
 #endif