From bab292b551ba7b65f205c52c7570e7c2948cab93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= <sebastian.huetter@ovgu.de>
Date: Fri, 9 Jun 2017 17:11:29 +0200
Subject: [PATCH] Create package USER-MEAMC

Step 1: very literal translation of lib/meam
---
 examples/meam/in.meamc             |  30 +
 examples/meam/in.meamc.shear       |  79 +++
 src/Makefile                       |   2 +-
 src/USER-MEAMC/Install.sh          |  47 ++
 src/USER-MEAMC/README              |  26 +
 src/USER-MEAMC/fm_exp.c            | 133 ++++
 src/USER-MEAMC/meam.h              | 157 +++++
 src/USER-MEAMC/meam_cleanup.c      |  14 +
 src/USER-MEAMC/meam_data.c         |   3 +
 src/USER-MEAMC/meam_dens_final.c   | 262 ++++++++
 src/USER-MEAMC/meam_dens_init.c    | 504 +++++++++++++++
 src/USER-MEAMC/meam_force.c        | 551 +++++++++++++++++
 src/USER-MEAMC/meam_setup_done.c   | 945 +++++++++++++++++++++++++++++
 src/USER-MEAMC/meam_setup_global.c |  99 +++
 src/USER-MEAMC/meam_setup_param.c  | 223 +++++++
 src/USER-MEAMC/pair_meamc.cpp      | 945 +++++++++++++++++++++++++++++
 src/USER-MEAMC/pair_meamc.h        | 155 +++++
 17 files changed, 4174 insertions(+), 1 deletion(-)
 create mode 100644 examples/meam/in.meamc
 create mode 100644 examples/meam/in.meamc.shear
 create mode 100644 src/USER-MEAMC/Install.sh
 create mode 100644 src/USER-MEAMC/README
 create mode 100644 src/USER-MEAMC/fm_exp.c
 create mode 100644 src/USER-MEAMC/meam.h
 create mode 100644 src/USER-MEAMC/meam_cleanup.c
 create mode 100644 src/USER-MEAMC/meam_data.c
 create mode 100644 src/USER-MEAMC/meam_dens_final.c
 create mode 100644 src/USER-MEAMC/meam_dens_init.c
 create mode 100644 src/USER-MEAMC/meam_force.c
 create mode 100644 src/USER-MEAMC/meam_setup_done.c
 create mode 100644 src/USER-MEAMC/meam_setup_global.c
 create mode 100644 src/USER-MEAMC/meam_setup_param.c
 create mode 100644 src/USER-MEAMC/pair_meamc.cpp
 create mode 100644 src/USER-MEAMC/pair_meamc.h

diff --git a/examples/meam/in.meamc b/examples/meam/in.meamc
new file mode 100644
index 0000000000..f6815cd7d4
--- /dev/null
+++ b/examples/meam/in.meamc
@@ -0,0 +1,30 @@
+# Test of MEAM potential for SiC system
+
+units		metal
+boundary	p p p
+
+atom_style	atomic
+
+read_data	data.meam
+
+pair_style	meam/c
+pair_coeff	* * library.meam Si C SiC.meam Si C
+
+neighbor	0.3 bin
+neigh_modify	delay 10
+
+fix		1 all nve
+thermo		10
+timestep	0.001
+
+#dump		1 all atom 50 dump.meam
+
+#dump		2 all image 10 image.*.jpg element element &
+#		axes yes 0.8 0.02 view 60 -30
+#dump_modify	2 pad 3 element Si C
+
+#dump		3 all movie 10 movie.mpg element element &
+#		axes yes 0.8 0.02 view 60 -30
+#dump_modify	3 pad 3 element Si C
+
+run		100
diff --git a/examples/meam/in.meamc.shear b/examples/meam/in.meamc.shear
new file mode 100644
index 0000000000..e4584d9744
--- /dev/null
+++ b/examples/meam/in.meamc.shear
@@ -0,0 +1,79 @@
+# 3d metal shear simulation
+
+units		metal
+boundary	s s p
+
+atom_style	atomic
+lattice		fcc 3.52
+region		box block 0 16.0 0 10.0 0 2.828427
+create_box	3 box
+
+lattice		fcc 3.52 orient	x 1 0 0 orient y 0 1 1 orient z 0 -1 1 &
+		origin 0.5 0 0 
+create_atoms	1 box
+
+pair_style	meam/c
+pair_coeff	* * library.meam Ni4 Ni.meam Ni4 Ni4 Ni4
+
+neighbor	0.3 bin
+neigh_modify	delay 5
+
+region		lower block INF INF INF 0.9 INF INF
+region		upper block INF INF 6.1 INF INF INF
+group		lower region lower
+group		upper region upper
+group		boundary union lower upper
+group		mobile subtract all boundary
+
+set		group lower type 2
+set		group upper type 3
+
+# void
+
+#region		void cylinder z 8 5 2.5 INF INF
+#delete_atoms	region void
+
+# temp controllers
+
+compute		new3d mobile temp
+compute		new2d mobile temp/partial 0 1 1
+
+# equilibrate
+
+velocity	mobile create 300.0 5812775 temp new3d
+fix		1 all nve
+fix		2 boundary setforce 0.0 0.0 0.0
+
+fix		3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
+fix_modify	3 temp new3d
+
+thermo		25
+thermo_modify	temp new3d
+
+timestep	0.001
+run		100
+
+# shear
+
+velocity	upper set 1.0 0 0
+velocity	mobile ramp vx 0.0 1.0 y 1.4 8.6 sum yes
+
+unfix		3
+fix		3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
+fix_modify	3 temp new2d
+
+#dump		1 all atom 500 dump.meam.shear
+
+#dump		2 all image 100 image.*.jpg type type &
+#		axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
+#dump_modify	2 pad 4
+
+#dump		3 all movie 100 movie.mpg type type &
+#		axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
+#dump_modify	3 pad 4
+
+thermo		100
+thermo_modify	temp new2d
+
+reset_timestep	0
+run		3000
diff --git a/src/Makefile b/src/Makefile
index 92a430a747..c7b20dcb13 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -59,7 +59,7 @@ PACKAGE = asphere body class2 colloid compress coreshell dipole gpu \
 
 PACKUSER = user-atc user-awpmd user-cgdna user-cgsdk user-colvars \
 	   user-diffraction user-dpd user-drude user-eff user-fep user-h5md \
-	   user-intel user-lb user-manifold user-mgpt user-misc user-molfile \
+	   user-intel user-lb user-manifold user-meamc user-mgpt user-misc user-molfile \
 	   user-netcdf user-omp user-phonon user-qmmm user-qtb \
 	   user-quip user-reaxc user-smd user-smtbq user-sph user-tally \
 	   user-vtk
diff --git a/src/USER-MEAMC/Install.sh b/src/USER-MEAMC/Install.sh
new file mode 100644
index 0000000000..2b4098a473
--- /dev/null
+++ b/src/USER-MEAMC/Install.sh
@@ -0,0 +1,47 @@
+# Install/unInstall package files in LAMMPS
+# mode = 0/1/2 for uninstall/install/update
+
+# this is default Install.sh for all packages
+# if package has an auxiliary library or a file with a dependency,
+# then package dir has its own customized Install.sh
+
+mode=$1
+
+# enforce using portable C locale
+LC_ALL=C
+export LC_ALL
+
+# arg1 = file, arg2 = file it depends on
+
+action () {
+  if (test $mode = 0) then
+    rm -f ../$1
+  elif (! cmp -s $1 ../$1) then
+    if (test -z "$2" || test -e ../$2) then
+      cp $1 ..
+      if (test $mode = 2) then
+        echo "  updating src/$1"
+      fi
+    fi
+  elif (test -n "$2") then
+    if (test ! -e ../$2) then
+      rm -f ../$1
+    fi
+  fi
+}
+
+# all package files with no dependencies
+
+for file in *.cpp *.h; do
+  test -f ${file} && action $file
+done
+
+
+# additional files
+
+for file in meam_*.c; do
+  test -f ${file} && action ${file}
+done
+
+action fm_exp.c
+action meam.h
diff --git a/src/USER-MEAMC/README b/src/USER-MEAMC/README
new file mode 100644
index 0000000000..8d6bd6360c
--- /dev/null
+++ b/src/USER-MEAMC/README
@@ -0,0 +1,26 @@
+This package implements the MEAM/C potential as a LAMMPS pair style.
+
++==============================================================================+
+
+This package is a translation of the MEAM package to native C. See
+that package as well as the Fortran code distributed in lib/meam for
+the original sources and information.
+
+
+Translation by
+ Sebastian Hütter, sebastian.huetter@ovgu.de
+ Institute of Materials and Joining Technology
+ Otto-von-Guericke University Magdeburg, Germany
+
+The original Fortran implementation was created by
+  Greg Wagner (while at Sandia, now at Northwestern U).
+
++==============================================================================+
+
+Use "make yes-user-meamc" to enable this package when building LAMMPS.
+
+In your LAMMPS input script, specifiy
+  pair_style meam/c
+to enable the use of this implementation. All parameters, input files and
+outputs are exactly identical to these used with pair_style meam.
+
diff --git a/src/USER-MEAMC/fm_exp.c b/src/USER-MEAMC/fm_exp.c
new file mode 100644
index 0000000000..00b957b27c
--- /dev/null
+++ b/src/USER-MEAMC/fm_exp.c
@@ -0,0 +1,133 @@
+/*
+   Copyright (c) 2012,2013   Axel Kohlmeyer <akohlmey@gmail.com>
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   * Neither the name of the <organization> nor the
+     names of its contributors may be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* faster versions of 2**x, e**x, and 10**x in single and double precision.
+ *
+ * Based on the Cephes math library 2.8
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+/* internal definitions for the fastermath library */
+
+/* IEEE 754 double precision floating point data manipulation */
+typedef union
+{
+    double   f;
+    uint64_t u;
+    struct {int32_t  i0,i1;};
+}  udi_t;
+#define FM_DOUBLE_BIAS 1023
+#define FM_DOUBLE_EMASK 2146435072
+#define FM_DOUBLE_MBITS 20
+#define FM_DOUBLE_MMASK 1048575
+#define FM_DOUBLE_EZERO 1072693248
+
+/* generate 2**num in floating point by bitshifting */
+#define FM_DOUBLE_INIT_EXP(var,num)                 \
+    var.i0 = 0;                                     \
+    var.i1 = (((int) num) + FM_DOUBLE_BIAS) << 20
+
+/* double precision constants */
+#define FM_DOUBLE_LOG2OFE  1.4426950408889634074
+#define FM_DOUBLE_LOGEOF2  6.9314718055994530942e-1
+#define FM_DOUBLE_LOG2OF10 3.32192809488736234789
+#define FM_DOUBLE_LOG10OF2 3.0102999566398119521e-1
+#define FM_DOUBLE_LOG10OFE 4.3429448190325182765e-1
+#define FM_DOUBLE_SQRT2    1.41421356237309504880
+#define FM_DOUBLE_SQRTH    0.70710678118654752440
+
+/* optimizer friendly implementation of exp2(x).
+ *
+ * strategy:
+ *
+ * split argument into an integer part and a fraction:
+ * ipart = floor(x+0.5);
+ * fpart = x - ipart;
+ *
+ * compute exp2(ipart) from setting the ieee754 exponent
+ * compute exp2(fpart) using a pade' approximation for x in [-0.5;0.5[
+ *
+ * the result becomes: exp2(x) = exp2(ipart) * exp2(fpart)
+ */
+
+static const double fm_exp2_q[] = {
+/*  1.00000000000000000000e0, */
+    2.33184211722314911771e2,
+    4.36821166879210612817e3
+};
+static const double fm_exp2_p[] = {
+    2.30933477057345225087e-2,
+    2.02020656693165307700e1,
+    1.51390680115615096133e3
+};
+
+static double fm_exp2(double x)
+{
+    double   ipart, fpart, px, qx;
+    udi_t    epart;
+
+    ipart = floor(x+0.5);
+    fpart = x - ipart;
+    FM_DOUBLE_INIT_EXP(epart,ipart);
+
+    x = fpart*fpart;
+
+    px =        fm_exp2_p[0];
+    px = px*x + fm_exp2_p[1];
+    qx =    x + fm_exp2_q[0];
+    px = px*x + fm_exp2_p[2];
+    qx = qx*x + fm_exp2_q[1];
+
+    px = px * fpart;
+
+    x = 1.0 + 2.0*(px/(qx-px));
+    return epart.f*x;
+}
+
+double fm_exp(double x)
+{
+#if defined(__BYTE_ORDER__)
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+    return fm_exp2(FM_DOUBLE_LOG2OFE * x);
+#endif
+#endif
+    return exp(x);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * compile-command: "make -C .."
+ * c-basic-offset: 4
+ * fill-column: 76
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/src/USER-MEAMC/meam.h b/src/USER-MEAMC/meam.h
new file mode 100644
index 0000000000..ab2c756dc3
--- /dev/null
+++ b/src/USER-MEAMC/meam.h
@@ -0,0 +1,157 @@
+#include <stdlib.h>
+
+      #define maxelt 5
+      double fm_exp(double);
+	  
+	  typedef enum {FCC, BCC, HCP, DIM, DIA, B1, C11, L12, B2} lattice_t;
+
+typedef struct {
+  int dim1, dim2;
+  double *ptr;
+} allocatable_double_2d;
+    
+typedef struct {
+// cutforce = force cutoff
+// cutforcesq = force cutoff squared
+
+      double cutforce,cutforcesq;
+
+// Ec_meam = cohesive energy
+// re_meam = nearest-neighbor distance
+// Omega_meam = atomic volume
+// B_meam = bulk modulus
+// Z_meam = number of first neighbors for reference structure
+// ielt_meam = atomic number of element
+// A_meam = adjustable parameter
+// alpha_meam = sqrt(9*Omega*B/Ec)
+// rho0_meam = density scaling parameter
+// delta_meam = heat of formation for alloys
+// beta[0-3]_meam = electron density constants
+// t[0-3]_meam = coefficients on densities in Gamma computation
+// rho_ref_meam = background density for reference structure
+// ibar_meam(i) = selection parameter for Gamma function for elt i,
+// lattce_meam(i,j) = lattce configuration for elt i or alloy (i,j)
+// neltypes = maximum number of element type defined
+// eltind = index number of pair (similar to Voigt notation; ij = ji)
+// phir = pair potential function array
+// phirar[1-6] = spline coeffs
+// attrac_meam = attraction parameter in Rose energy
+// repuls_meam = repulsion parameter in Rose energy
+// nn2_meam = 1 if second nearest neighbors are to be computed, else 0
+// zbl_meam = 1 if zbl potential for small r to be use, else 0
+// emb_lin_neg = 1 if linear embedding function for rhob to be used, else 0
+// bkgd_dyn = 1 if reference densities follows Dynamo, else 0
+// Cmin_meam, Cmax_meam = min and max values in screening cutoff
+// rc_meam = cutoff distance for meam
+// delr_meam = cutoff region for meam
+// ebound_meam = factor giving maximum boundary of sceen fcn ellipse
+// augt1 = flag for whether t1 coefficient should be augmented
+// ialloy = flag for newer alloy formulation (as in dynamo code)
+// mix_ref_t = flag to recover "old" way of computing t in reference config
+// erose_form = selection parameter for form of E_rose function
+// gsmooth_factor = factor determining length of G smoothing region
+// vind[23]D = Voight notation index maps for 2 and 3D
+// v2D,v3D = array of factors to apply for Voight notation
+
+// nr,dr = pair function discretization parameters
+// nrar,rdrar = spline coeff array parameters
+
+      double Ec_meam[maxelt+1][maxelt+1],re_meam[maxelt+1][maxelt+1];
+      double Omega_meam[maxelt+1],Z_meam[maxelt+1];
+      double A_meam[maxelt+1],alpha_meam[maxelt+1][maxelt+1],rho0_meam[maxelt+1];
+      double delta_meam[maxelt+1][maxelt+1];
+      double beta0_meam[maxelt+1],beta1_meam[maxelt+1];
+      double beta2_meam[maxelt+1],beta3_meam[maxelt+1];
+      double t0_meam[maxelt+1],t1_meam[maxelt+1];
+      double t2_meam[maxelt+1],t3_meam[maxelt+1];
+      double rho_ref_meam[maxelt+1];
+      int ibar_meam[maxelt+1],ielt_meam[maxelt+1];
+	  lattice_t lattce_meam[maxelt+1][maxelt+1];
+      int nn2_meam[maxelt+1][maxelt+1];
+      int zbl_meam[maxelt+1][maxelt+1];
+      int eltind[maxelt+1][maxelt+1];
+      int neltypes;
+
+      allocatable_double_2d phir; // [:,:]
+
+      allocatable_double_2d phirar,phirar1,phirar2,phirar3,phirar4,phirar5,phirar6;  // [:,:]
+
+      double attrac_meam[maxelt+1][maxelt+1],repuls_meam[maxelt+1][maxelt+1];
+
+      double Cmin_meam[maxelt+1][maxelt+1][maxelt+1];
+      double Cmax_meam[maxelt+1][maxelt+1][maxelt+1];
+      double rc_meam,delr_meam,ebound_meam[maxelt+1][maxelt+1];
+      int augt1, ialloy, mix_ref_t, erose_form;
+      int emb_lin_neg, bkgd_dyn;
+      double  gsmooth_factor;
+      int vind2D[3+1][3+1],vind3D[3+1][3+1][3+1];
+      int v2D[6+1],v3D[10+1];
+
+      int nr,nrar;
+      double dr,rdrar;
+} meam_data_t;
+
+meam_data_t meam_data;
+
+// Functions we need for compat
+#ifndef max
+#define max(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a > _b ? _a : _b; })
+#endif
+
+#ifndef min
+#define min(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a < _b ? _a : _b; })
+#endif
+
+#define iszero(f) (fabs(f)<1e-20)
+
+#define setall2d(arr, v) {for(int __i=1;__i<=maxelt;__i++) for(int __j=1;__j<=maxelt;__j++) arr[__i][__j] = v;}
+#define setall3d(arr, v) {for(int __i=1;__i<=maxelt;__i++) for(int __j=1;__j<=maxelt;__j++) for(int __k=1;__k<=maxelt;__k++) arr[__i][__j][__k] = v;}
+
+/*
+Fortran Array Semantics in C.
+ - Stack-Allocated and global arrays are 1-based, declared as foo[N+1] and simply ignoring the first element
+    - Multi-Dimensional MUST be declared in reverse, so that the order when accessing is the same as in Fortran
+ - arrays that are passed externally via the meam_* functions must use the arr*v() functions below
+   (or be used with 0-based indexing)
+ - allocatable arrays (only global phir*) are actually a struct, and must be accessed with arr2()
+*/
+
+// we receive a pointer to the first element, and F dimensions is ptr(a,b,c)
+// we know c data structure is ptr[c][b][a]
+#define arrdim2v(ptr,a,b) \
+  const int DIM1__##ptr = a; const int DIM2__##ptr = b;\
+  (void)(DIM1__##ptr); (void)(DIM2__##ptr);
+#define arrdim3v(ptr,a,b,c) \
+  const int DIM1__##ptr = a; const int DIM2__##ptr = b; const int DIM3__##ptr = c;\
+  (void)(DIM1__##ptr); (void)(DIM2__##ptr; (void)(DIM3__##ptr);
+  
+
+// access data with same index as used in fortran (1-based)
+#define arr1v(ptr,i) \
+  ptr[i-1]
+#define arr2v(ptr,i,j) \
+  ptr[(DIM1__##ptr)*(j-1) + (i-1)]
+#define arr3v(ptr,i,j,k) \
+  ptr[(i-1) + (j-1)*(DIM1__##ptr) + (k-1)*(DIM1__##ptr)*(DIM2__##ptr)]
+
+// allocatable arrays via special type
+#define allocate_2d(arr,cols,rows) \
+  arr.dim1 = cols; arr.dim2=rows; arr.ptr=(double*)calloc((size_t)(cols)*(size_t)(rows),sizeof(double));
+#define allocated(a) \
+  (a.ptr!=NULL)
+#define deallocate(a) \
+  ({free(a.ptr); a.ptr=NULL;})
+// access data with same index as used in fortran (1-based)
+#define arr2(arr,i,j) \
+  arr.ptr[(arr.dim1)*(j-1) + (i-1)]
+
+
+
+
+
diff --git a/src/USER-MEAMC/meam_cleanup.c b/src/USER-MEAMC/meam_cleanup.c
new file mode 100644
index 0000000000..5c81fc3b49
--- /dev/null
+++ b/src/USER-MEAMC/meam_cleanup.c
@@ -0,0 +1,14 @@
+#include "meam.h"
+
+void meam_cleanup_(void) {
+
+    deallocate(meam_data.phirar6);
+    deallocate(meam_data.phirar5);
+    deallocate(meam_data.phirar4);
+    deallocate(meam_data.phirar3);
+    deallocate(meam_data.phirar2);
+    deallocate(meam_data.phirar1);
+    deallocate(meam_data.phirar);
+    deallocate(meam_data.phir);
+
+}
diff --git a/src/USER-MEAMC/meam_data.c b/src/USER-MEAMC/meam_data.c
new file mode 100644
index 0000000000..54ddf81b64
--- /dev/null
+++ b/src/USER-MEAMC/meam_data.c
@@ -0,0 +1,3 @@
+#include "meam.h"
+
+meam_data_t meam_data = {};
\ No newline at end of file
diff --git a/src/USER-MEAMC/meam_dens_final.c b/src/USER-MEAMC/meam_dens_final.c
new file mode 100644
index 0000000000..1e553866e4
--- /dev/null
+++ b/src/USER-MEAMC/meam_dens_final.c
@@ -0,0 +1,262 @@
+#include "meam.h"
+#include <math.h>
+
+      void G_gam(double Gamma, int ibar, double gsmooth_factor, double *G, int *errorflag);
+      void dG_gam(double Gamma, int ibar, double gsmooth_factor,double *G, double *dG);
+
+// in meam_setup_done
+      void get_shpfcn(double *s /* s(3) */, lattice_t latt);
+
+// Extern "C" declaration has the form:
+//
+//  void meam_dens_final_(int *, int *, int *, int *, int *, double *, double *,
+//                int *, int *, int *,
+//		 double *, double *, double *, double *, double *, double *,
+//		 double *, double *, double *, double *, double *, double *,
+//		 double *, double *, double *, double *, double *, int *);
+//
+// Call from pair_meam.cpp has the form:
+//
+//  meam_dens_final_(&nlocal,&nmax,&eflag_either,&eflag_global,&eflag_atom,
+//            &eng_vdwl,eatom,ntype,type,fmap,
+//	     &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],
+//	     &arho3b[0][0],&t_ave[0][0],&tsq_ave[0][0],gamma,dgamma1,
+//	     dgamma2,dgamma3,rho,rho0,rho1,rho2,rho3,frhop,&errorflag);
+//
+
+      void meam_dens_final_(int *nlocal, int *nmax,
+           int *eflag_either, int *eflag_global, int *eflag_atom, double *eng_vdwl, double *eatom,
+           int *ntype, int *type, int *fmap,
+           double *Arho1, double *Arho2, double *Arho2b, double *Arho3, double *Arho3b, double *t_ave, double *tsq_ave,
+           double *Gamma, double *dGamma1, double *dGamma2, double *dGamma3,
+           double *rho, double *rho0, double *rho1, double *rho2, double *rho3, double *fp, int *errorflag)
+      {
+        
+      arrdim2v(Arho1,3,*nmax)
+      arrdim2v(Arho2,6,*nmax)
+      arrdim2v(Arho3,10,*nmax)
+      arrdim2v(Arho3b,3,*nmax)
+      arrdim2v(t_ave,3,*nmax)
+      arrdim2v(tsq_ave,3,*nmax)
+
+      int i, elti;
+      int m;
+      double  rhob, G, dG, Gbar, dGbar, gam, shp[3+1], Z;
+      double  B, denom, rho_bkgd;
+
+//     Complete the calculation of density
+
+      for(i=1; i<=*nlocal; i++) {
+        elti = arr1v(fmap,arr1v(type,i));
+        if (elti > 0) {
+          arr1v(rho1,i) = 0.0;
+          arr1v(rho2,i) = -1.0/3.0*arr1v(Arho2b,i)*arr1v(Arho2b,i);
+          arr1v(rho3,i) = 0.0;
+          for(m=1; m<=3; m++) {
+            arr1v(rho1,i) = arr1v(rho1,i) + arr2v(Arho1,m,i)*arr2v(Arho1,m,i);
+            arr1v(rho3,i) = arr1v(rho3,i) - 3.0/5.0*arr2v(Arho3b,m,i)*arr2v(Arho3b,m,i);
+          }
+          for(m=1; m<=6; m++) {
+            arr1v(rho2,i) = arr1v(rho2,i) + meam_data.v2D[m]*arr2v(Arho2,m,i)*arr2v(Arho2,m,i);
+          }
+          for(m=1; m<=10; m++) {
+            arr1v(rho3,i) = arr1v(rho3,i) + meam_data.v3D[m]*arr2v(Arho3,m,i)*arr2v(Arho3,m,i);
+          }
+
+          if( arr1v(rho0,i)  >  0.0 ) {
+            if (meam_data.ialloy==1) {
+              arr2v(t_ave,1,i) = arr2v(t_ave,1,i)/arr2v(tsq_ave,1,i);
+              arr2v(t_ave,2,i) = arr2v(t_ave,2,i)/arr2v(tsq_ave,2,i);
+              arr2v(t_ave,3,i) = arr2v(t_ave,3,i)/arr2v(tsq_ave,3,i);
+            } else if (meam_data.ialloy==2) {
+              arr2v(t_ave,1,i) = meam_data.t1_meam[elti];
+              arr2v(t_ave,2,i) = meam_data.t2_meam[elti];
+              arr2v(t_ave,3,i) = meam_data.t3_meam[elti];
+            } else {
+              arr2v(t_ave,1,i) = arr2v(t_ave,1,i)/arr1v(rho0,i);
+              arr2v(t_ave,2,i) = arr2v(t_ave,2,i)/arr1v(rho0,i);
+              arr2v(t_ave,3,i) = arr2v(t_ave,3,i)/arr1v(rho0,i);
+            }
+          }
+
+          arr1v(Gamma,i) = arr2v(t_ave,1,i)*arr1v(rho1,i) + arr2v(t_ave,2,i)*arr1v(rho2,i) + arr2v(t_ave,3,i)*arr1v(rho3,i);
+
+          if( arr1v(rho0,i)  >  0.0 ) {
+            arr1v(Gamma,i) = arr1v(Gamma,i)/(arr1v(rho0,i)*arr1v(rho0,i));
+          }
+
+          Z = meam_data.Z_meam[elti];
+
+          G_gam(arr1v(Gamma,i),meam_data.ibar_meam[elti], meam_data.gsmooth_factor,&G,errorflag);
+          if (*errorflag!=0) return;
+          get_shpfcn(shp,meam_data.lattce_meam[elti][elti]);
+          if (meam_data.ibar_meam[elti]<=0) {
+            Gbar = 1.0;
+            dGbar = 0.0;
+          } else {
+            if (meam_data.mix_ref_t==1) {
+              gam = (arr2v(t_ave,1,i)*shp[1]+arr2v(t_ave,2,i)*shp[2] +arr2v(t_ave,3,i)*shp[3])/(Z*Z);
+            } else {
+              gam = (meam_data.t1_meam[elti]*shp[1]+meam_data.t2_meam[elti]*shp[2] +meam_data.t3_meam[elti]*shp[3])/(Z*Z);
+            }
+            G_gam(gam,meam_data.ibar_meam[elti],meam_data.gsmooth_factor,&Gbar,errorflag);
+          }
+          arr1v(rho,i) = arr1v(rho0,i) * G;
+
+          if (meam_data.mix_ref_t==1) {
+            if (meam_data.ibar_meam[elti]<=0) {
+              Gbar = 1.0;
+              dGbar = 0.0;
+            } else {
+              gam = (arr2v(t_ave,1,i)*shp[1]+arr2v(t_ave,2,i)*shp[2] +arr2v(t_ave,3,i)*shp[3])/(Z*Z);
+              dG_gam(gam,meam_data.ibar_meam[elti],meam_data.gsmooth_factor, &Gbar,&dGbar);
+            }
+            rho_bkgd = meam_data.rho0_meam[elti]*Z*Gbar;
+          } else {
+            if (meam_data.bkgd_dyn==1) {
+              rho_bkgd = meam_data.rho0_meam[elti]*Z;
+            } else {
+              rho_bkgd = meam_data.rho_ref_meam[elti];
+            }
+          }
+          rhob = arr1v(rho,i)/rho_bkgd;
+          denom = 1.0/rho_bkgd;
+
+          dG_gam(arr1v(Gamma,i),meam_data.ibar_meam[elti],meam_data.gsmooth_factor,&G,&dG);
+
+          arr1v(dGamma1,i) = (G - 2*dG*arr1v(Gamma,i))*denom;
+
+          if( !iszero(arr1v(rho0,i)) ) {
+            arr1v(dGamma2,i) = (dG/arr1v(rho0,i))*denom;
+          } else {
+            arr1v(dGamma2,i) = 0.0;
+          }
+
+//     dGamma3 is nonzero only if we are using the "mixed" rule for
+//     computing t in the reference system (which is not correct, but
+//     included for backward compatibility
+          if (meam_data.mix_ref_t==1) {
+            arr1v(dGamma3,i) = arr1v(rho0,i)*G*dGbar/(Gbar*Z*Z)*denom;
+          } else {
+            arr1v(dGamma3,i) = 0.0;
+          }
+
+          B = meam_data.A_meam[elti]*meam_data.Ec_meam[elti][elti];
+
+          if( !iszero(rhob) ) {
+            if (meam_data.emb_lin_neg==1 && rhob<=0) {
+              arr1v(fp,i) = -B;
+            } else {
+              arr1v(fp,i) = B*(log(rhob)+1.0);
+            }
+            if (*eflag_either!=0) {
+              if (*eflag_global!=0) {
+                if (meam_data.emb_lin_neg==1 && rhob<=0) {
+                  *eng_vdwl = *eng_vdwl - B*rhob;
+                } else {
+                  *eng_vdwl = *eng_vdwl + B*rhob*log(rhob);
+                }
+              }
+              if (*eflag_atom!=0) {
+                if (meam_data.emb_lin_neg==1 && rhob<=0) {
+                  arr1v(eatom,i) = arr1v(eatom,i) - B*rhob;
+                } else {
+                  arr1v(eatom,i) = arr1v(eatom,i) + B*rhob*log(rhob);
+                }
+              }
+            }
+          } else {
+            if (meam_data.emb_lin_neg==1) {
+              arr1v(fp,i) = -B;
+            } else {
+              arr1v(fp,i) = B;
+            }
+          }
+        }
+      }
+
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void G_gam(double Gamma, int ibar, double gsmooth_factor, double *G, int *errorflag)
+      {
+//     Compute G(Gamma) based on selection flag ibar:
+//   0 => G = sqrt(1+Gamma)
+//   1 => G = exp(Gamma/2)
+//   2 => not implemented
+//   3 => G = 2/(1+exp(-Gamma))
+//   4 => G = sqrt(1+Gamma)
+//  -5 => G = +-sqrt(abs(1+Gamma))
+      
+      double gsmooth_switchpoint;
+      if (ibar==0 || ibar==4) {
+        gsmooth_switchpoint = -gsmooth_factor / (gsmooth_factor+1);
+        if (Gamma < gsmooth_switchpoint) {
+//         e.g. gsmooth_factor is 99, {:
+//         gsmooth_switchpoint = -0.99
+//         G = 0.01*(-0.99/Gamma)**99
+          *G = 1/(gsmooth_factor+1) * pow((gsmooth_switchpoint/Gamma),gsmooth_factor);
+          *G = sqrt(*G);
+        } else {
+          *G = sqrt(1.0+Gamma);
+        }
+      } else if (ibar==1) {
+        *G = fm_exp(Gamma/2.0);
+      } else if (ibar==3) {
+        *G = 2.0/(1.0+exp(-Gamma));
+      } else if (ibar==-5) {
+        if ((1.0+Gamma)>=0) {
+           *G = sqrt(1.0+Gamma);
+        } else {
+           *G = -sqrt(-1.0-Gamma);
+        }
+      } else {
+         *errorflag = 1;
+      }
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void dG_gam(double Gamma, int ibar, double gsmooth_factor,double *G, double *dG)
+      {
+// Compute G(Gamma) and dG(gamma) based on selection flag ibar:
+//   0 => G = sqrt(1+Gamma)
+//   1 => G = fm_exp(Gamma/2)
+//   2 => not implemented
+//   3 => G = 2/(1+fm_exp(-Gamma))
+//   4 => G = sqrt(1+Gamma)
+//  -5 => G = +-sqrt(abs(1+Gamma))
+      double gsmooth_switchpoint;
+      
+      if (ibar==0 || ibar==4) {
+        gsmooth_switchpoint = -gsmooth_factor / (gsmooth_factor+1);
+        if (Gamma < gsmooth_switchpoint) {
+//         e.g. gsmooth_factor is 99, {:
+//         gsmooth_switchpoint = -0.99
+//         G = 0.01*(-0.99/Gamma)**99
+          *G = 1/(gsmooth_factor+1) * pow((gsmooth_switchpoint/Gamma), gsmooth_factor);
+          *G = sqrt(*G);
+          *dG = -gsmooth_factor* *G/(2.0*Gamma);
+        } else {
+          *G = sqrt(1.0+Gamma);
+          *dG = 1.0/(2.0* *G);
+        }
+      } else if (ibar==1) {
+        *G = fm_exp(Gamma/2.0);
+        *dG = *G/2.0;
+      } else if (ibar==3) {
+        *G = 2.0/(1.0+fm_exp(-Gamma));
+        *dG = *G*(2.0-*G)/2;
+      } else if (ibar==-5) {
+        if ((1.0+Gamma)>=0) {
+           *G = sqrt(1.0+Gamma);
+           *dG = 1.0/(2.0* *G);
+        } else {
+           *G = -sqrt(-1.0-Gamma);
+           *dG = -1.0/(2.0* *G);
+        }
+      }
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
diff --git a/src/USER-MEAMC/meam_dens_init.c b/src/USER-MEAMC/meam_dens_init.c
new file mode 100644
index 0000000000..8c1d84f6d4
--- /dev/null
+++ b/src/USER-MEAMC/meam_dens_init.c
@@ -0,0 +1,504 @@
+#include "meam.h"
+#include <math.h>
+
+      void getscreen(int i, int nmax, double *scrfcn, double *dscrfcn, double *fcpair, double *x,
+          int numneigh, int *firstneigh,
+          int numneigh_full, int *firstneigh_full,
+          int ntype, int *type, int *fmap);
+      void calc_rho1(int i, int nmax, int ntype, int *type, int *fmap, double *x,
+          int numneigh, int *firstneigh,
+          double *scrfcn, double *fcpair, double *rho0, double *arho1, double *arho2, double *arho2b,
+          double *arho3, double *arho3b, double *t_ave, double *tsq_ave);
+          
+      void screen(int i, int j, int nmax, double *x, double rijsq, double *sij, int numneigh_full, int *firstneigh_full, int ntype, int *type, int *fmap);
+      void dsij(int i,int j,int k,int jn,int nmax,int numneigh,double rij2,double *dsij1,double *dsij2, int ntype, int *type, int *fmap,double *x,double *scrfcn, double*fcpair);
+      void fcut(double xi, double * fc);
+      void dfcut(double xi, double *fc, double *dfc);
+      void dCfunc(double rij2,double rik2,double rjk2,double *dCikj);
+      void dCfunc2(double rij2,double rik2,double rjk2,double *dCikj1,double *dCikj2);
+
+//     Extern "C" declaration has the form:
+//
+//  void meam_dens_init_(int *, int *, int *, double *, int *, int *, int *, double *,
+//		 int *, int *, int *, int *,
+//		 double *, double *, double *, double *, double *, double *,
+//		 double *, double *, double *, double *, double *, int *);
+//
+//
+//     Call from pair_meam.cpp has the form:
+//
+//    meam_dens_init_(&i,&nmax,ntype,type,fmap,&x[0][0],
+//	       &numneigh[i],firstneigh[i],&numneigh_full[i],firstneigh_full[i],
+//	       &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
+//	       rho0,&arho1[0][0],&arho2[0][0],arho2b,
+//	       &arho3[0][0],&arho3b[0][0],&t_ave[0][0],&tsq_ave[0][0],&errorflag);
+//
+
+      void meam_dens_init_(int *i, int *nmax,
+          int *ntype, int *type, int *fmap, double *x,
+          int *numneigh, int *firstneigh,
+          int *numneigh_full, int *firstneigh_full,
+          double *scrfcn, double *dscrfcn, double *fcpair, double *rho0, double *arho1, double *arho2, double *arho2b,
+          double *arho3, double *arho3b, double *t_ave, double *tsq_ave, int *errorflag)
+      {
+      *errorflag = 0;
+
+//     Compute screening function and derivatives
+      getscreen(*i, *nmax, scrfcn, dscrfcn, fcpair, x,
+          *numneigh, firstneigh,
+          *numneigh_full, firstneigh_full,
+          *ntype, type, fmap);
+
+//     Calculate intermediate density terms to be communicated
+      calc_rho1(*i, *nmax, *ntype, type, fmap, x,
+          *numneigh, firstneigh,
+          scrfcn, fcpair, rho0, arho1, arho2, arho2b,
+          arho3, arho3b, t_ave, tsq_ave);
+
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void getscreen(int i, int nmax, double *scrfcn, double *dscrfcn, double *fcpair, double *x,
+          int numneigh, int *firstneigh,
+          int numneigh_full, int *firstneigh_full,
+          int ntype, int *type, int *fmap)
+      {
+        
+        arrdim2v(x,3,nmax)
+
+      int jn,j,kn,k;
+      int elti,eltj,eltk;
+      double xitmp,yitmp,zitmp,delxij,delyij,delzij,rij2,rij;
+      double xjtmp,yjtmp,zjtmp,delxik,delyik,delzik,rik2/*,rik*/;
+      double xktmp,yktmp,zktmp,delxjk,delyjk,delzjk,rjk2/*,rjk*/;
+      double xik,xjk,sij,fcij,sfcij,dfcij,sikj,dfikj,cikj;
+      double Cmin,Cmax,delc,/*ebound,*/rbound,a,coef1,coef2;
+      //double coef1a,coef1b,coef2a,coef2b;
+      double dCikj;
+      /*unused:double dC1a,dC1b,dC2a,dC2b;*/
+      double rnorm,fc,dfc,drinv;
+
+      drinv = 1.0/meam_data.delr_meam;
+      elti = arr1v(fmap,arr1v(type,i));
+
+      if (elti > 0) {
+
+        xitmp = arr2v(x,1,i);
+        yitmp = arr2v(x,2,i);
+        zitmp = arr2v(x,3,i);
+
+        for(jn=1; jn<=numneigh; jn++) {
+          j = arr1v(firstneigh,jn);
+
+          eltj = arr1v(fmap,arr1v(type,j));
+          if (eltj > 0) {
+
+//     First compute screening function itself, sij
+            xjtmp = arr2v(x,1,j);
+            yjtmp = arr2v(x,2,j);
+            zjtmp = arr2v(x,3,j);
+            delxij = xjtmp - xitmp;
+            delyij = yjtmp - yitmp;
+            delzij = zjtmp - zitmp;
+            rij2 = delxij*delxij + delyij*delyij + delzij*delzij;
+            rij = sqrt(rij2);
+            if (rij > meam_data.rc_meam) {
+              fcij = 0.0;
+              dfcij = 0.0;
+              sij = 0.0;
+            } else {
+              rnorm = (meam_data.rc_meam-rij)*drinv;
+              screen(i, j, nmax, x, rij2, &sij, numneigh_full, firstneigh_full, ntype, type, fmap);
+              dfcut(rnorm,&fc,&dfc);
+              fcij = fc;
+              dfcij = dfc*drinv;
+            }
+
+//     Now compute derivatives
+            arr1v(dscrfcn,jn) = 0.0;
+            sfcij = sij*fcij;
+            if (iszero(sfcij) || iszero(sfcij-1.0)) goto LABEL_100;
+            rbound = meam_data.ebound_meam[elti][eltj] * rij2;
+            for(kn=1; kn<=numneigh_full; kn++) {
+              k = arr1v(firstneigh_full,kn);
+              if (k==j) continue;
+              eltk = arr1v(fmap,arr1v(type,k));
+              if (eltk==0) continue;
+              xktmp = arr2v(x,1,k);
+              yktmp = arr2v(x,2,k);
+              zktmp = arr2v(x,3,k);
+              delxjk = xktmp - xjtmp;
+              delyjk = yktmp - yjtmp;
+              delzjk = zktmp - zjtmp;
+              rjk2 = delxjk*delxjk + delyjk*delyjk + delzjk*delzjk;
+              if (rjk2 > rbound) continue;
+              delxik = xktmp - xitmp;
+              delyik = yktmp - yitmp;
+              delzik = zktmp - zitmp;
+              rik2 = delxik*delxik + delyik*delyik + delzik*delzik;
+              if (rik2 > rbound) continue;
+              xik = rik2/rij2;
+              xjk = rjk2/rij2;
+              a =  1 - (xik-xjk)*(xik-xjk);
+//     if a < 0, then ellipse equation doesn't describe this case and
+//     atom k can't possibly screen i-j
+              if (a<=0.0) continue;
+              cikj = (2.0*(xik+xjk) + a - 2.0)/a;
+              Cmax = meam_data.Cmax_meam[elti][eltj][eltk];
+              Cmin = meam_data.Cmin_meam[elti][eltj][eltk];
+              if (cikj>=Cmax) {
+                continue;
+//     Note that cikj may be slightly negative (within numerical
+//     tolerance) if atoms are colinear, so don't reject that case here
+//     (other negative cikj cases were handled by the test on "a" above)
+//     Note that we never have 0<cikj<Cmin here, else sij=0 (rejected above)
+              } else {
+                delc = Cmax - Cmin;
+                cikj = (cikj-Cmin)/delc;
+                dfcut(cikj,&sikj,&dfikj);
+                coef1 = dfikj/(delc*sikj);
+                dCfunc(rij2,rik2,rjk2,&dCikj);
+                arr1v(dscrfcn,jn) = arr1v(dscrfcn,jn) + coef1*dCikj;
+              }
+            }
+            coef1 = sfcij;
+            coef2 = sij*dfcij/rij;
+            arr1v(dscrfcn,jn) = arr1v(dscrfcn,jn)*coef1 - coef2;
+
+ LABEL_100:
+            arr1v(scrfcn,jn) = sij;
+            arr1v(fcpair,jn) = fcij;
+
+          }
+
+        }
+
+      }
+      }
+
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void calc_rho1(int i, int nmax, int ntype, int *type, int *fmap, double *x,
+          int numneigh, int *firstneigh,
+          double *scrfcn, double *fcpair, double *rho0, double *arho1, double *arho2, double *arho2b,
+          double *arho3, double *arho3b, double *t_ave, double *tsq_ave)
+      {
+        arrdim2v(x,3,nmax)
+        arrdim2v(arho1,3,nmax)
+        arrdim2v(arho2,6,nmax)
+        arrdim2v(arho3,10,nmax)
+        arrdim2v(arho3b,3,nmax)
+        arrdim2v(t_ave,3,nmax)
+        arrdim2v(tsq_ave,3,nmax)
+
+      int jn,j,m,n,p,elti,eltj;
+      int nv2,nv3;
+      double xtmp,ytmp,ztmp,delij[3+1],rij2,rij,sij;
+      double ai,aj,rhoa0j,rhoa1j,rhoa2j,rhoa3j,A1j,A2j,A3j;
+      //double G,Gbar,gam,shp[3+1];
+      double ro0i,ro0j;
+      double rhoa0i,rhoa1i,rhoa2i,rhoa3i,A1i,A2i,A3i;
+
+      elti = arr1v(fmap,arr1v(type,i));
+      xtmp = arr2v(x,1,i);
+      ytmp = arr2v(x,2,i);
+      ztmp = arr2v(x,3,i);
+      for(jn=1; jn<=numneigh; jn++) {
+        if (!iszero(arr1v(scrfcn,jn))) {
+          j = arr1v(firstneigh,jn);
+          sij = arr1v(scrfcn,jn)*arr1v(fcpair,jn);
+          delij[1] = arr2v(x,1,j) - xtmp;
+          delij[2] = arr2v(x,2,j) - ytmp;
+          delij[3] = arr2v(x,3,j) - ztmp;
+          rij2 = delij[1]*delij[1] + delij[2]*delij[2] + delij[3]*delij[3];
+          if (rij2 < meam_data.cutforcesq) {
+            eltj = arr1v(fmap,arr1v(type,j));
+            rij = sqrt(rij2);
+            ai = rij/meam_data.re_meam[elti][elti] - 1.0;
+            aj = rij/meam_data.re_meam[eltj][eltj] - 1.0;
+            ro0i = meam_data.rho0_meam[elti];
+            ro0j = meam_data.rho0_meam[eltj];
+            rhoa0j = ro0j*fm_exp(-meam_data.beta0_meam[eltj]*aj)*sij;
+            rhoa1j = ro0j*fm_exp(-meam_data.beta1_meam[eltj]*aj)*sij;
+            rhoa2j = ro0j*fm_exp(-meam_data.beta2_meam[eltj]*aj)*sij;
+            rhoa3j = ro0j*fm_exp(-meam_data.beta3_meam[eltj]*aj)*sij;
+            rhoa0i = ro0i*fm_exp(-meam_data.beta0_meam[elti]*ai)*sij;
+            rhoa1i = ro0i*fm_exp(-meam_data.beta1_meam[elti]*ai)*sij;
+            rhoa2i = ro0i*fm_exp(-meam_data.beta2_meam[elti]*ai)*sij;
+            rhoa3i = ro0i*fm_exp(-meam_data.beta3_meam[elti]*ai)*sij;
+            if (meam_data.ialloy==1) {
+              rhoa1j = rhoa1j * meam_data.t1_meam[eltj];
+              rhoa2j = rhoa2j * meam_data.t2_meam[eltj];
+              rhoa3j = rhoa3j * meam_data.t3_meam[eltj];
+              rhoa1i = rhoa1i * meam_data.t1_meam[elti];
+              rhoa2i = rhoa2i * meam_data.t2_meam[elti];
+              rhoa3i = rhoa3i * meam_data.t3_meam[elti];
+            }
+            arr1v(rho0,i) = arr1v(rho0,i) + rhoa0j;
+            arr1v(rho0,j) = arr1v(rho0,j) + rhoa0i;
+// For ialloy = 2, use single-element value (not average)
+            if (meam_data.ialloy!=2) {
+              arr2v(t_ave,1,i) = arr2v(t_ave,1,i) + meam_data.t1_meam[eltj]*rhoa0j;
+              arr2v(t_ave,2,i) = arr2v(t_ave,2,i) + meam_data.t2_meam[eltj]*rhoa0j;
+              arr2v(t_ave,3,i) = arr2v(t_ave,3,i) + meam_data.t3_meam[eltj]*rhoa0j;
+              arr2v(t_ave,1,j) = arr2v(t_ave,1,j) + meam_data.t1_meam[elti]*rhoa0i;
+              arr2v(t_ave,2,j) = arr2v(t_ave,2,j) + meam_data.t2_meam[elti]*rhoa0i;
+              arr2v(t_ave,3,j) = arr2v(t_ave,3,j) + meam_data.t3_meam[elti]*rhoa0i;
+            }
+            if (meam_data.ialloy==1) {
+              arr2v(tsq_ave,1,i) = arr2v(tsq_ave,1,i) + meam_data.t1_meam[eltj]*meam_data.t1_meam[eltj]*rhoa0j;
+              arr2v(tsq_ave,2,i) = arr2v(tsq_ave,2,i) + meam_data.t2_meam[eltj]*meam_data.t2_meam[eltj]*rhoa0j;
+              arr2v(tsq_ave,3,i) = arr2v(tsq_ave,3,i) + meam_data.t3_meam[eltj]*meam_data.t3_meam[eltj]*rhoa0j;
+              arr2v(tsq_ave,1,j) = arr2v(tsq_ave,1,j) + meam_data.t1_meam[elti]*meam_data.t1_meam[elti]*rhoa0i;
+              arr2v(tsq_ave,2,j) = arr2v(tsq_ave,2,j) + meam_data.t2_meam[elti]*meam_data.t2_meam[elti]*rhoa0i;
+              arr2v(tsq_ave,3,j) = arr2v(tsq_ave,3,j) + meam_data.t3_meam[elti]*meam_data.t3_meam[elti]*rhoa0i;
+            }
+            arr1v(arho2b,i) = arr1v(arho2b,i) + rhoa2j;
+            arr1v(arho2b,j) = arr1v(arho2b,j) + rhoa2i;
+
+            A1j = rhoa1j/rij;
+            A2j = rhoa2j/rij2;
+            A3j = rhoa3j/(rij2*rij);
+            A1i = rhoa1i/rij;
+            A2i = rhoa2i/rij2;
+            A3i = rhoa3i/(rij2*rij);
+            nv2 = 1;
+            nv3 = 1;
+            for(m=1; m<=3; m++) {
+              arr2v(arho1,m,i)  = arr2v(arho1,m,i) + A1j*delij[m];
+              arr2v(arho1,m,j)  = arr2v(arho1,m,j) - A1i*delij[m];
+              arr2v(arho3b,m,i) = arr2v(arho3b,m,i) + rhoa3j*delij[m]/rij;
+              arr2v(arho3b,m,j) = arr2v(arho3b,m,j) - rhoa3i*delij[m]/rij;
+              for(n=m; n<=3; n++) {
+                arr2v(arho2,nv2,i) = arr2v(arho2,nv2,i) + A2j*delij[m]*delij[n];
+                arr2v(arho2,nv2,j) = arr2v(arho2,nv2,j) + A2i*delij[m]*delij[n];
+                nv2 = nv2+1;
+                for(p=n; p<=3; p++) {
+                  arr2v(arho3,nv3,i) = arr2v(arho3,nv3,i) + A3j*delij[m]*delij[n]*delij[p];
+                  arr2v(arho3,nv3,j) = arr2v(arho3,nv3,j) - A3i*delij[m]*delij[n]*delij[p];
+                  nv3 = nv3+1;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void screen(int i, int j, int nmax, double *x, double rijsq, double *sij, int numneigh_full, int *firstneigh_full, int ntype, int *type, int *fmap)
+//     Screening function
+//     Inputs:  i = atom 1 id (integer)
+//     j = atom 2 id (integer)
+//     rijsq = squared distance between i and j
+//     Outputs: sij = screening function
+      {
+        
+        arrdim2v(x,3,nmax)
+
+      int k,nk/*,m*/;
+      int elti,eltj,eltk;
+      double delxik,delyik,delzik;
+      double delxjk,delyjk,delzjk;
+      double riksq,rjksq,xik,xjk,cikj,a,delc,sikj/*,fcij,rij*/;
+      double Cmax,Cmin,rbound;
+
+      *sij = 1.0;
+      eltj = arr1v(fmap,arr1v(type,j));
+      elti = arr1v(fmap,arr1v(type,j));
+
+//     if rjksq > ebound*rijsq, atom k is definitely outside the ellipse
+      rbound = meam_data.ebound_meam[elti][eltj]*rijsq;
+
+      for(nk=1; nk<=numneigh_full; nk++) {
+        k = arr1v(firstneigh_full,nk);
+        eltk = arr1v(fmap,arr1v(type,k));
+        if (k==j) continue;
+        delxjk = arr2v(x,1,k) - arr2v(x,1,j);
+        delyjk = arr2v(x,2,k) - arr2v(x,2,j);
+        delzjk = arr2v(x,3,k) - arr2v(x,3,j);
+        rjksq = delxjk*delxjk + delyjk*delyjk + delzjk*delzjk;
+        if (rjksq > rbound) continue;
+        delxik = arr2v(x,1,k) - arr2v(x,1,i);
+        delyik = arr2v(x,2,k) - arr2v(x,2,i);
+        delzik = arr2v(x,3,k) - arr2v(x,3,i);
+        riksq = delxik*delxik + delyik*delyik + delzik*delzik;
+        if (riksq > rbound) continue;
+        xik = riksq/rijsq;
+        xjk = rjksq/rijsq;
+        a = 1 - (xik-xjk)*(xik-xjk);
+//     if a < 0, then ellipse equation doesn't describe this case and
+//     atom k can't possibly screen i-j
+        if (a<=0.0) continue;
+        cikj = (2.0*(xik+xjk) + a - 2.0)/a;
+        Cmax = meam_data.Cmax_meam[elti][eltj][eltk];
+        Cmin = meam_data.Cmin_meam[elti][eltj][eltk];
+        if (cikj>=Cmax)
+          continue;
+//     note that cikj may be slightly negative (within numerical
+//     tolerance) if atoms are colinear, so don't reject that case here
+//     (other negative cikj cases were handled by the test on "a" above)
+        else if (cikj<=Cmin) {
+          *sij = 0.0;
+          break;
+        } else {
+          delc = Cmax - Cmin;
+          cikj = (cikj-Cmin)/delc;
+          fcut(cikj,&sikj);
+        }
+        *sij = *sij * sikj;
+      }
+
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void dsij(int i,int j,int k,int jn,int nmax,int numneigh,double rij2,double *dsij1,double *dsij2, int ntype, int *type, int *fmap,double *x,double *scrfcn, double*fcpair)
+      {
+//     Inputs: i,j,k = id's of 3 atom triplet
+//     jn = id of i-j pair
+//     rij2 = squared distance between i and j
+//     Outputs: dsij1 = deriv. of sij w.r.t. rik
+//     dsij2 = deriv. of sij w.r.t. rjk
+
+        arrdim2v(x,3,nmax)
+      int elti,eltj,eltk;
+      double rik2,rjk2;
+
+      double dxik,dyik,dzik;
+      double dxjk,dyjk,dzjk;
+      double rbound,delc,sij,xik,xjk,cikj,sikj,dfc,a;
+      double Cmax,Cmin,dCikj1,dCikj2;
+
+      sij = arr1v(scrfcn,jn)*arr1v(fcpair,jn);
+      elti = arr1v(fmap,arr1v(type,i));
+      eltj = arr1v(fmap,arr1v(type,j));
+      eltk = arr1v(fmap,arr1v(type,k));
+      Cmax = meam_data.Cmax_meam[elti][eltj][eltk];
+      Cmin = meam_data.Cmin_meam[elti][eltj][eltk];
+
+      *dsij1 = 0.0;
+      *dsij2 = 0.0;
+      if (!iszero(sij) && !iszero(sij-1.0)) {
+        rbound = rij2*meam_data.ebound_meam[elti][eltj];
+        delc = Cmax-Cmin;
+        dxjk = arr2v(x,1,k) - arr2v(x,1,j);
+        dyjk = arr2v(x,2,k) - arr2v(x,2,j);
+        dzjk = arr2v(x,3,k) - arr2v(x,3,j);
+        rjk2 = dxjk*dxjk + dyjk*dyjk + dzjk*dzjk;
+        if (rjk2<=rbound) {
+          dxik = arr2v(x,1,k) - arr2v(x,1,i);
+          dyik = arr2v(x,2,k) - arr2v(x,2,i);
+          dzik = arr2v(x,3,k) - arr2v(x,3,i);
+          rik2 = dxik*dxik + dyik*dyik + dzik*dzik;
+          if (rik2<=rbound) {
+            xik = rik2/rij2;
+            xjk = rjk2/rij2;
+            a = 1 - (xik-xjk)*(xik-xjk);
+            if (!iszero(a)) {
+              cikj = (2.0*(xik+xjk) + a - 2.0)/a;
+              if (cikj>=Cmin && cikj<=Cmax) {
+                cikj = (cikj-Cmin)/delc;
+                dfcut(cikj,&sikj,&dfc);
+                dCfunc2(rij2,rik2,rjk2,&dCikj1,&dCikj2);
+                a = sij/delc*dfc/sikj;
+                *dsij1 = a*dCikj1;
+                *dsij2 = a*dCikj2;
+              }
+            }
+          }
+        }
+      }
+      }
+
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void fcut(double xi, double * fc)
+      {
+//     cutoff function
+      double a;
+      if (xi>=1.0)
+        *fc = 1.0;
+      else if (xi<=0.0)
+        *fc = 0.0;
+      else {
+        a = 1.0-xi;
+        a = a*a;
+        a = a*a;
+        a = 1.0-a;
+        *fc = a*a;
+//     fc = xi
+      }
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void dfcut(double xi, double *fc, double *dfc)
+      {
+//     cutoff function and its derivative
+      double a,a3,a4;
+      if (xi>=1.0) {
+        *fc = 1.0;
+        *dfc = 0.0;
+      } else if (xi<=0.0) {
+        *fc = 0.0;
+        *dfc = 0.0;
+      } else {
+        a = 1.0-xi;
+        a3 = a*a*a;
+        a4 = a*a3;
+        *fc = pow((1.0-a4), 2);
+        *dfc = 8*(1.0-a4)*a3;
+//     fc = xi
+//     dfc = 1.d0
+      }
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void dCfunc(double rij2,double rik2,double rjk2,double *dCikj)
+      {
+//     Inputs: rij,rij2,rik2,rjk2
+//     Outputs: dCikj = derivative of Cikj w.r.t. rij
+      double rij4,a,b,denom;
+
+      rij4 = rij2*rij2;
+      a = rik2-rjk2;
+      b = rik2+rjk2;
+      denom = rij4 - a*a;
+      denom = denom*denom;
+      *dCikj = -4*(-2*rij2*a*a + rij4*b + a*a*b)/denom;
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      void dCfunc2(double rij2,double rik2,double rjk2,double *dCikj1,double *dCikj2)
+      {
+//     Inputs: rij,rij2,rik2,rjk2
+//     Outputs: dCikj1 = derivative of Cikj w.r.t. rik
+//     dCikj2 = derivative of Cikj w.r.t. rjk
+      double rij4,rik4,rjk4,a,b,denom;
+
+      rij4 = rij2*rij2;
+      rik4 = rik2*rik2;
+      rjk4 = rjk2*rjk2;
+      a = rik2-rjk2;
+      b = rik2+rjk2;
+      denom = rij4 - a*a;
+      denom = denom*denom;
+      *dCikj1 = 4*rij2*(rij4 + rik4 + 2*rik2*rjk2 - 3*rjk4 - 2*rij2*a)/ denom;
+      *dCikj2 = 4*rij2*(rij4 - 3*rik4 + 2*rik2*rjk2 + rjk4 + 2*rij2*a)/ denom;
+      
+      (void)(b);
+      }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+
+
+
diff --git a/src/USER-MEAMC/meam_force.c b/src/USER-MEAMC/meam_force.c
new file mode 100644
index 0000000000..d27d8ca7eb
--- /dev/null
+++ b/src/USER-MEAMC/meam_force.c
@@ -0,0 +1,551 @@
+#include "meam.h"
+#include <math.h>
+
+// in meam_setup_done
+void get_shpfcn(double *s /* s(3) */, lattice_t latt);
+
+// in meam_dens_init
+void dsij(int i,int j,int k,int jn,int nmax,int numneigh,double rij2,double *dsij1,double *dsij2, int ntype, int *type, int *fmap,double *x,double *scrfcn, double*fcpair);
+
+
+//     Extern "C" declaration has the form:
+//
+//  void meam_force_(int *, int *, int *, double *, int *, int *, int *, double *,
+//		 int *, int *, int *, int *, double *, double *,
+//		 double *, double *, double *, double *, double *, double *,
+//		 double *, double *, double *, double *, double *, double *,
+//		 double *, double *, double *, double *, double *, double *, int *);
+//
+//     Call from pair_meam.cpp has the form:
+//
+//    meam_force_(&i,&nmax,&eflag_either,&eflag_global,&eflag_atom,&vflag_atom,
+//              &eng_vdwl,eatom,&ntype,type,fmap,&x[0][0],
+//	       &numneigh[i],firstneigh[i],&numneigh_full[i],firstneigh_full[i],
+//	       &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
+//	       dgamma1,dgamma2,dgamma3,rho0,rho1,rho2,rho3,frhop,
+//	       &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],&arho3b[0][0],
+//	       &t_ave[0][0],&tsq_ave[0][0],&f[0][0],&vatom[0][0],&errorflag);
+//
+
+      void meam_force_(int *iptr, int *nmax,
+          int *eflag_either, int *eflag_global, int *eflag_atom, int *vflag_atom,
+          double *eng_vdwl, double *eatom, int *ntype, int *type, int *fmap, double *x,
+          int *numneigh, int *firstneigh, int *numneigh_full, int *firstneigh_full,
+          double *scrfcn, double *dscrfcn, double *fcpair,
+          double *dGamma1, double *dGamma2, double *dGamma3, double *rho0, double *rho1, double *rho2, double *rho3, double *fp,
+          double *Arho1, double *Arho2, double *Arho2b, double *Arho3, double *Arho3b, double *t_ave, double *tsq_ave, double *f,
+          double *vatom, int *errorflag)
+      {
+        arrdim2v(x,3,*nmax)
+        arrdim2v(Arho1,3,*nmax)
+        arrdim2v(Arho2,6,*nmax)
+        arrdim2v(Arho3,10,*nmax)
+        arrdim2v(Arho3b,3,*nmax)
+        arrdim2v(t_ave,3,*nmax)
+        arrdim2v(tsq_ave,3,*nmax)
+        arrdim2v(f,3,*nmax)
+        arrdim2v(vatom,6,*nmax)
+
+      int i,j,jn,k,kn,kk,m,n,p,q;
+      int nv2,nv3,elti,eltj,eltk,ind;
+      double xitmp,yitmp,zitmp,delij[3+1],rij2,rij,rij3;
+      double delik[3+1],deljk[3+1],v[6+1],fi[3+1],fj[3+1];
+      double third,sixth;
+      double pp,dUdrij,dUdsij,dUdrijm[3+1],force,forcem;
+      double r,recip,phi,phip;
+      double sij;
+      double a1,a1i,a1j,a2,a2i,a2j;
+      double a3i,a3j;
+      double shpi[3+1],shpj[3+1];
+      double ai,aj,ro0i,ro0j,invrei,invrej;
+      double rhoa0j,drhoa0j,rhoa0i,drhoa0i;
+      double rhoa1j,drhoa1j,rhoa1i,drhoa1i;
+      double rhoa2j,drhoa2j,rhoa2i,drhoa2i;
+      double a3,a3a,rhoa3j,drhoa3j,rhoa3i,drhoa3i;
+      double drho0dr1,drho0dr2,drho0ds1,drho0ds2;
+      double drho1dr1,drho1dr2,drho1ds1,drho1ds2;
+      double drho1drm1[3+1],drho1drm2[3+1];
+      double drho2dr1,drho2dr2,drho2ds1,drho2ds2;
+      double drho2drm1[3+1],drho2drm2[3+1];
+      double drho3dr1,drho3dr2,drho3ds1,drho3ds2;
+      double drho3drm1[3+1],drho3drm2[3+1];
+      double dt1dr1,dt1dr2,dt1ds1,dt1ds2;
+      double dt2dr1,dt2dr2,dt2ds1,dt2ds2;
+      double dt3dr1,dt3dr2,dt3ds1,dt3ds2;
+      double drhodr1,drhodr2,drhods1,drhods2,drhodrm1[3+1],drhodrm2[3+1];
+      double arg;
+      double arg1i1,arg1j1,arg1i2,arg1j2,arg1i3,arg1j3,arg3i3,arg3j3;
+      double dsij1,dsij2,force1,force2;
+      double t1i,t2i,t3i,t1j,t2j,t3j;
+
+      *errorflag = 0;
+      third = 1.0/3.0;
+      sixth = 1.0/6.0;
+      
+      //: aliased
+      i = *iptr;
+
+//     Compute forces atom i
+
+      elti = arr1v(fmap,arr1v(type,i));
+
+      if (elti > 0) {
+        xitmp = arr2v(x,1,i);
+        yitmp = arr2v(x,2,i);
+        zitmp = arr2v(x,3,i);
+
+//     Treat each pair
+        for(jn=1; jn<=*numneigh; jn++) {
+          j = arr1v(firstneigh,jn);
+          eltj = arr1v(fmap,arr1v(type,j));
+
+          if (!iszero(arr1v(scrfcn,jn)) && eltj > 0) {
+
+            sij = arr1v(scrfcn,jn)*arr1v(fcpair,jn);
+            delij[1] = arr2v(x,1,j) - xitmp;
+            delij[2] = arr2v(x,2,j) - yitmp;
+            delij[3] = arr2v(x,3,j) - zitmp;
+            rij2 = delij[1]*delij[1] + delij[2]*delij[2] + delij[3]*delij[3];
+            if (rij2 < meam_data.cutforcesq) {
+              rij = sqrt(rij2);
+              r = rij;
+
+//     Compute phi and phip
+              ind = meam_data.eltind[elti][eltj];
+              pp = rij*meam_data.rdrar + 1.0;
+              kk = (int)pp;
+              kk = min(kk,meam_data.nrar-1);
+              pp = pp - kk;
+              pp = min(pp,1.0);
+              phi = ((arr2(meam_data.phirar3,kk,ind)*pp + arr2(meam_data.phirar2,kk,ind))*pp + arr2(meam_data.phirar1,kk,ind))*pp + arr2(meam_data.phirar,kk,ind);
+              phip = (arr2(meam_data.phirar6,kk,ind)*pp + arr2(meam_data.phirar5,kk,ind))*pp + arr2(meam_data.phirar4,kk,ind);
+              recip = 1.0/r;
+
+              if (*eflag_either!=0) {
+                if (*eflag_global!=0) *eng_vdwl = *eng_vdwl + phi*sij;
+                if (*eflag_atom!=0) {
+                  arr1v(eatom,i) = arr1v(eatom,i) + 0.5*phi*sij;
+                  arr1v(eatom,j) = arr1v(eatom,j) + 0.5*phi*sij;
+                }
+              }
+
+//     write(1,*) "force_meamf: phi: ",phi
+//     write(1,*) "force_meamf: phip: ",phip
+
+//     Compute pair densities and derivatives
+              invrei = 1.0/meam_data.re_meam[elti][elti];
+              ai = rij*invrei - 1.0;
+              ro0i = meam_data.rho0_meam[elti];
+              rhoa0i = ro0i*fm_exp(-meam_data.beta0_meam[elti]*ai);
+              drhoa0i = -meam_data.beta0_meam[elti]*invrei*rhoa0i;
+              rhoa1i = ro0i*fm_exp(-meam_data.beta1_meam[elti]*ai);
+              drhoa1i = -meam_data.beta1_meam[elti]*invrei*rhoa1i;
+              rhoa2i = ro0i*fm_exp(-meam_data.beta2_meam[elti]*ai);
+              drhoa2i = -meam_data.beta2_meam[elti]*invrei*rhoa2i;
+              rhoa3i = ro0i*fm_exp(-meam_data.beta3_meam[elti]*ai);
+              drhoa3i = -meam_data.beta3_meam[elti]*invrei*rhoa3i;
+
+              if (elti!=eltj) {
+                invrej = 1.0/meam_data.re_meam[eltj][eltj];
+                aj = rij*invrej - 1.0;
+                ro0j = meam_data.rho0_meam[eltj];
+                rhoa0j = ro0j*fm_exp(-meam_data.beta0_meam[eltj]*aj);
+                drhoa0j = -meam_data.beta0_meam[eltj]*invrej*rhoa0j;
+                rhoa1j = ro0j*fm_exp(-meam_data.beta1_meam[eltj]*aj);
+                drhoa1j = -meam_data.beta1_meam[eltj]*invrej*rhoa1j;
+                rhoa2j = ro0j*fm_exp(-meam_data.beta2_meam[eltj]*aj);
+                drhoa2j = -meam_data.beta2_meam[eltj]*invrej*rhoa2j;
+                rhoa3j = ro0j*fm_exp(-meam_data.beta3_meam[eltj]*aj);
+                drhoa3j = -meam_data.beta3_meam[eltj]*invrej*rhoa3j;
+              } else {
+                rhoa0j = rhoa0i;
+                drhoa0j = drhoa0i;
+                rhoa1j = rhoa1i;
+                drhoa1j = drhoa1i;
+                rhoa2j = rhoa2i;
+                drhoa2j = drhoa2i;
+                rhoa3j = rhoa3i;
+                drhoa3j = drhoa3i;
+              }
+
+              if (meam_data.ialloy==1) {
+                rhoa1j = rhoa1j * meam_data.t1_meam[eltj];
+                rhoa2j = rhoa2j * meam_data.t2_meam[eltj];
+                rhoa3j = rhoa3j * meam_data.t3_meam[eltj];
+                rhoa1i = rhoa1i * meam_data.t1_meam[elti];
+                rhoa2i = rhoa2i * meam_data.t2_meam[elti];
+                rhoa3i = rhoa3i * meam_data.t3_meam[elti];
+                drhoa1j = drhoa1j * meam_data.t1_meam[eltj];
+                drhoa2j = drhoa2j * meam_data.t2_meam[eltj];
+                drhoa3j = drhoa3j * meam_data.t3_meam[eltj];
+                drhoa1i = drhoa1i * meam_data.t1_meam[elti];
+                drhoa2i = drhoa2i * meam_data.t2_meam[elti];
+                drhoa3i = drhoa3i * meam_data.t3_meam[elti];
+              }
+
+              nv2 = 1;
+              nv3 = 1;
+              arg1i1 = 0.0;
+              arg1j1 = 0.0;
+              arg1i2 = 0.0;
+              arg1j2 = 0.0;
+              arg1i3 = 0.0;
+              arg1j3 = 0.0;
+              arg3i3 = 0.0;
+              arg3j3 = 0.0;
+              for(n=1; n<=3; n++) {
+                for(p=n; p<=3; p++) {
+                  for(q=p; q<=3; q++) {
+                    arg = delij[n]*delij[p]*delij[q]*meam_data.v3D[nv3];
+                    arg1i3 = arg1i3 + arr2v(Arho3,nv3,i)*arg;
+                    arg1j3 = arg1j3 - arr2v(Arho3,nv3,j)*arg;
+                    nv3 = nv3+1;
+                  }
+                  arg = delij[n]*delij[p]*meam_data.v2D[nv2];
+                  arg1i2 = arg1i2 + arr2v(Arho2,nv2,i)*arg;
+                  arg1j2 = arg1j2 + arr2v(Arho2,nv2,j)*arg;
+                  nv2 = nv2+1;
+                }
+                arg1i1 = arg1i1 + arr2v(Arho1,n,i)*delij[n];
+                arg1j1 = arg1j1 - arr2v(Arho1,n,j)*delij[n];
+                arg3i3 = arg3i3 + arr2v(Arho3b,n,i)*delij[n];
+                arg3j3 = arg3j3 - arr2v(Arho3b,n,j)*delij[n];
+              }
+
+//     rho0 terms
+              drho0dr1 = drhoa0j * sij;
+              drho0dr2 = drhoa0i * sij;
+
+//     rho1 terms
+              a1 = 2*sij/rij;
+              drho1dr1 = a1*(drhoa1j-rhoa1j/rij)*arg1i1;
+              drho1dr2 = a1*(drhoa1i-rhoa1i/rij)*arg1j1;
+              a1 = 2.0*sij/rij;
+              for(m=1; m<=3; m++) {
+                drho1drm1[m] =  a1*rhoa1j*arr2v(Arho1,m,i);
+                drho1drm2[m] = -a1*rhoa1i*arr2v(Arho1,m,j);
+              }
+
+//     rho2 terms
+              a2 = 2*sij/rij2;
+              drho2dr1 = a2*(drhoa2j - 2*rhoa2j/rij)*arg1i2            - 2.0/3.0*arr1v(Arho2b,i)*drhoa2j*sij;
+              drho2dr2 = a2*(drhoa2i - 2*rhoa2i/rij)*arg1j2            - 2.0/3.0*arr1v(Arho2b,j)*drhoa2i*sij;
+              a2 = 4*sij/rij2;
+              for(m=1; m<=3; m++) {
+                drho2drm1[m] = 0.0;
+                drho2drm2[m] = 0.0;
+                for(n=1; n<=3; n++) {
+                  drho2drm1[m] = drho2drm1[m]               + arr2v(Arho2,meam_data.vind2D[m][n],i)*delij[n];
+                  drho2drm2[m] = drho2drm2[m]               - arr2v(Arho2,meam_data.vind2D[m][n],j)*delij[n];
+                }
+                drho2drm1[m] =  a2*rhoa2j*drho2drm1[m];
+                drho2drm2[m] = -a2*rhoa2i*drho2drm2[m];
+              }
+
+//     rho3 terms
+              rij3 = rij*rij2;
+              a3 = 2*sij/rij3;
+              a3a = 6.0/5.0*sij/rij;
+              drho3dr1 = a3*(drhoa3j - 3*rhoa3j/rij)*arg1i3  - a3a*(drhoa3j - rhoa3j/rij)*arg3i3;
+              drho3dr2 = a3*(drhoa3i - 3*rhoa3i/rij)*arg1j3  - a3a*(drhoa3i - rhoa3i/rij)*arg3j3;
+              a3 = 6*sij/rij3;
+              a3a = 6*sij/(5*rij);
+              for(m=1; m<=3; m++) {
+                drho3drm1[m] = 0.0;
+                drho3drm2[m] = 0.0;
+                nv2 = 1;
+                for(n=1; n<=3; n++) {
+                  for(p=n; p<=3; p++) {
+                    arg = delij[n]*delij[p]*meam_data.v2D[nv2];
+                    drho3drm1[m] = drho3drm1[m]     + arr2v(Arho3,meam_data.vind3D[m][n][p],i)*arg;
+                    drho3drm2[m] = drho3drm2[m]     + arr2v(Arho3,meam_data.vind3D[m][n][p],j)*arg;
+                    nv2 = nv2 + 1;
+                  }
+                }
+                drho3drm1[m] = ( a3*drho3drm1[m] - a3a*arr2v(Arho3b,m,i))  *rhoa3j;
+                drho3drm2[m] = (-a3*drho3drm2[m] + a3a*arr2v(Arho3b,m,j))  *rhoa3i;
+              }
+
+//     Compute derivatives of weighting functions t wrt rij
+              t1i = arr2v(t_ave,1,i);
+              t2i = arr2v(t_ave,2,i);
+              t3i = arr2v(t_ave,3,i);
+              t1j = arr2v(t_ave,1,j);
+              t2j = arr2v(t_ave,2,j);
+              t3j = arr2v(t_ave,3,j);
+
+              if (meam_data.ialloy==1) {
+
+                a1i = 0.0;
+                a1j = 0.0;
+                a2i = 0.0;
+                a2j = 0.0;
+                a3i = 0.0;
+                a3j = 0.0;
+                if ( !iszero(arr2v(tsq_ave,1,i)) )  a1i = drhoa0j*sij/arr2v(tsq_ave,1,i);
+                if ( !iszero(arr2v(tsq_ave,1,j)) )  a1j = drhoa0i*sij/arr2v(tsq_ave,1,j);
+                if ( !iszero(arr2v(tsq_ave,2,i)) )  a2i = drhoa0j*sij/arr2v(tsq_ave,2,i);
+                if ( !iszero(arr2v(tsq_ave,2,j)) )  a2j = drhoa0i*sij/arr2v(tsq_ave,2,j);
+                if ( !iszero(arr2v(tsq_ave,3,i)) )  a3i = drhoa0j*sij/arr2v(tsq_ave,3,i);
+                if ( !iszero(arr2v(tsq_ave,3,j)) )  a3j = drhoa0i*sij/arr2v(tsq_ave,3,j);
+
+                dt1dr1 = a1i*(meam_data.t1_meam[eltj]-t1i*pow(meam_data.t1_meam[eltj],2));
+                dt1dr2 = a1j*(meam_data.t1_meam[elti]-t1j*pow(meam_data.t1_meam[elti],2));
+                dt2dr1 = a2i*(meam_data.t2_meam[eltj]-t2i*pow(meam_data.t2_meam[eltj],2));
+                dt2dr2 = a2j*(meam_data.t2_meam[elti]-t2j*pow(meam_data.t2_meam[elti],2));
+                dt3dr1 = a3i*(meam_data.t3_meam[eltj]-t3i*pow(meam_data.t3_meam[eltj],2));
+                dt3dr2 = a3j*(meam_data.t3_meam[elti]-t3j*pow(meam_data.t3_meam[elti],2));
+
+              } else if (meam_data.ialloy==2) {
+
+                dt1dr1 = 0.0;
+                dt1dr2 = 0.0;
+                dt2dr1 = 0.0;
+                dt2dr2 = 0.0;
+                dt3dr1 = 0.0;
+                dt3dr2 = 0.0;
+
+              } else {
+
+                ai = 0.0;
+                if( !iszero(arr1v(rho0,i)) )
+                  ai = drhoa0j*sij/arr1v(rho0,i);
+                aj = 0.0;
+                if( !iszero(arr1v(rho0,j)) )
+                  aj = drhoa0i*sij/arr1v(rho0,j);
+
+                dt1dr1 = ai*(meam_data.t1_meam[elti]-t1i);
+                dt1dr2 = aj*(meam_data.t1_meam[elti]-t1j);
+                dt2dr1 = ai*(meam_data.t2_meam[elti]-t2i);
+                dt2dr2 = aj*(meam_data.t2_meam[elti]-t2j);
+                dt3dr1 = ai*(meam_data.t3_meam[elti]-t3i);
+                dt3dr2 = aj*(meam_data.t3_meam[elti]-t3j);
+
+              }
+
+//     Compute derivatives of total density wrt rij, sij and rij(3)
+              get_shpfcn(shpi,meam_data.lattce_meam[elti][elti]);
+              get_shpfcn(shpj,meam_data.lattce_meam[eltj][eltj]);
+              drhodr1 = arr1v(dGamma1,i)*drho0dr1
+                  + arr1v(dGamma2,i)*
+                  (dt1dr1*arr1v(rho1,i)+t1i*drho1dr1
+                  + dt2dr1*arr1v(rho2,i)+t2i*drho2dr1
+                  + dt3dr1*arr1v(rho3,i)+t3i*drho3dr1)
+                  - arr1v(dGamma3,i)*
+                  (shpi[1]*dt1dr1+shpi[2]*dt2dr1+shpi[3]*dt3dr1);
+              drhodr2 = arr1v(dGamma1,j)*drho0dr2
+                  + arr1v(dGamma2,j)*
+                  (dt1dr2*arr1v(rho1,j)+t1j*drho1dr2
+                  + dt2dr2*arr1v(rho2,j)+t2j*drho2dr2
+                  + dt3dr2*arr1v(rho3,j)+t3j*drho3dr2)
+                  - arr1v(dGamma3,j)*
+                  (shpj[1]*dt1dr2+shpj[2]*dt2dr2+shpj[3]*dt3dr2);
+              for(m=1; m<=3; m++) {
+                drhodrm1[m] = 0.0;
+                drhodrm2[m] = 0.0;
+                drhodrm1[m] = arr1v(dGamma2,i)*
+                     (t1i*drho1drm1[m]
+                    + t2i*drho2drm1[m]
+                    + t3i*drho3drm1[m]);
+                drhodrm2[m] = arr1v(dGamma2,j)*
+                     (t1j*drho1drm2[m]
+                    + t2j*drho2drm2[m]
+                    + t3j*drho3drm2[m]);
+              }
+
+//     Compute derivatives wrt sij, but only if necessary
+              if ( !iszero(arr1v(dscrfcn,jn))) {
+                drho0ds1 = rhoa0j;
+                drho0ds2 = rhoa0i;
+                a1 = 2.0/rij;
+                drho1ds1 = a1*rhoa1j*arg1i1;
+                drho1ds2 = a1*rhoa1i*arg1j1;
+                a2 = 2.0/rij2;
+                drho2ds1 = a2*rhoa2j*arg1i2  - 2.0/3.0*arr1v(Arho2b,i)*rhoa2j;
+                drho2ds2 = a2*rhoa2i*arg1j2  - 2.0/3.0*arr1v(Arho2b,j)*rhoa2i;
+                a3 = 2.0/rij3;
+                a3a = 6.0/(5.0*rij);
+                drho3ds1 = a3*rhoa3j*arg1i3 - a3a*rhoa3j*arg3i3;
+                drho3ds2 = a3*rhoa3i*arg1j3 - a3a*rhoa3i*arg3j3;
+
+                if (meam_data.ialloy==1) {
+
+                  a1i = 0.0;
+                  a1j = 0.0;
+                  a2i = 0.0;
+                  a2j = 0.0;
+                  a3i = 0.0;
+                  a3j = 0.0;
+                  if ( !iszero(arr2v(tsq_ave,1,i)) ) a1i = rhoa0j/arr2v(tsq_ave,1,i);
+                  if ( !iszero(arr2v(tsq_ave,1,j)) ) a1j = rhoa0i/arr2v(tsq_ave,1,j);
+                  if ( !iszero(arr2v(tsq_ave,2,i)) ) a2i = rhoa0j/arr2v(tsq_ave,2,i);
+                  if ( !iszero(arr2v(tsq_ave,2,j)) ) a2j = rhoa0i/arr2v(tsq_ave,2,j);
+                  if ( !iszero(arr2v(tsq_ave,3,i)) ) a3i = rhoa0j/arr2v(tsq_ave,3,i);
+                  if ( !iszero(arr2v(tsq_ave,3,j)) ) a3j = rhoa0i/arr2v(tsq_ave,3,j);
+
+                  dt1ds1 = a1i*(meam_data.t1_meam[eltj]-t1i*pow(meam_data.t1_meam[eltj],2));
+                  dt1ds2 = a1j*(meam_data.t1_meam[elti]-t1j*pow(meam_data.t1_meam[elti],2));
+                  dt2ds1 = a2i*(meam_data.t2_meam[eltj]-t2i*pow(meam_data.t2_meam[eltj],2));
+                  dt2ds2 = a2j*(meam_data.t2_meam[elti]-t2j*pow(meam_data.t2_meam[elti],2));
+                  dt3ds1 = a3i*(meam_data.t3_meam[eltj]-t3i*pow(meam_data.t3_meam[eltj],2));
+                  dt3ds2 = a3j*(meam_data.t3_meam[elti]-t3j*pow(meam_data.t3_meam[elti],2));
+
+                } else if (meam_data.ialloy==2) {
+
+                  dt1ds1 = 0.0;
+                  dt1ds2 = 0.0;
+                  dt2ds1 = 0.0;
+                  dt2ds2 = 0.0;
+                  dt3ds1 = 0.0;
+                  dt3ds2 = 0.0;
+
+                } else {
+
+                  ai = 0.0;
+                  if( !iszero(arr1v(rho0,i)) )
+                    ai = rhoa0j/arr1v(rho0,i);
+                  aj = 0.0;
+                  if( !iszero(arr1v(rho0,j)) )
+                    aj = rhoa0i/arr1v(rho0,j);
+
+                  dt1ds1 = ai*(meam_data.t1_meam[eltj]-t1i);
+                  dt1ds2 = aj*(meam_data.t1_meam[elti]-t1j);
+                  dt2ds1 = ai*(meam_data.t2_meam[eltj]-t2i);
+                  dt2ds2 = aj*(meam_data.t2_meam[elti]-t2j);
+                  dt3ds1 = ai*(meam_data.t3_meam[eltj]-t3i);
+                  dt3ds2 = aj*(meam_data.t3_meam[elti]-t3j);
+
+                }
+
+                drhods1 = arr1v(dGamma1,i)*drho0ds1
+                    + arr1v(dGamma2,i)*
+                    (dt1ds1*arr1v(rho1,i)+t1i*drho1ds1
+                    + dt2ds1*arr1v(rho2,i)+t2i*drho2ds1
+                    + dt3ds1*arr1v(rho3,i)+t3i*drho3ds1)
+                    - arr1v(dGamma3,i)*
+                    (shpi[1]*dt1ds1+shpi[2]*dt2ds1+shpi[3]*dt3ds1);
+                drhods2 = arr1v(dGamma1,j)*drho0ds2
+                    + arr1v(dGamma2,j)*
+                    (dt1ds2*arr1v(rho1,j)+t1j*drho1ds2
+                    + dt2ds2*arr1v(rho2,j)+t2j*drho2ds2
+                    + dt3ds2*arr1v(rho3,j)+t3j*drho3ds2)
+                    - arr1v(dGamma3,j)*
+                    (shpj[1]*dt1ds2+shpj[2]*dt2ds2+shpj[3]*dt3ds2);
+              }
+
+//     Compute derivatives of energy wrt rij, sij and rij[3]
+              dUdrij = phip*sij           + arr1v(fp,i)*drhodr1 + arr1v(fp,j)*drhodr2;
+              dUdsij = 0.0;
+              if ( !iszero(arr1v(dscrfcn,jn)) ) {
+                dUdsij = phi              + arr1v(fp,i)*drhods1 + arr1v(fp,j)*drhods2;
+              }
+              for(m=1; m<=3; m++) {
+                dUdrijm[m] = arr1v(fp,i)*drhodrm1[m] + arr1v(fp,j)*drhodrm2[m];
+              }
+
+//     Add the part of the force due to dUdrij and dUdsij
+
+              force = dUdrij*recip + dUdsij*arr1v(dscrfcn,jn);
+              for(m=1; m<=3; m++) {
+                forcem = delij[m]*force + dUdrijm[m];
+                arr2v(f,m,i) = arr2v(f,m,i) + forcem;
+                arr2v(f,m,j) = arr2v(f,m,j) - forcem;
+              }
+
+//     Tabulate per-atom virial as symmetrized stress tensor
+
+              if (*vflag_atom!=0) {
+                fi[1] = delij[1]*force + dUdrijm[1];
+                fi[2] = delij[2]*force + dUdrijm[2];
+                fi[3] = delij[3]*force + dUdrijm[3];
+                v[1] = -0.5 * (delij[1] * fi[1]);
+                v[2] = -0.5 * (delij[2] * fi[2]);
+                v[3] = -0.5 * (delij[3] * fi[3]);
+                v[4] = -0.25 * (delij[1]*fi[2] + delij[2]*fi[1]);
+                v[5] = -0.25 * (delij[1]*fi[3] + delij[3]*fi[1]);
+                v[6] = -0.25 * (delij[2]*fi[3] + delij[3]*fi[2]);
+
+                arr2v(vatom,1,i) = arr2v(vatom,1,i) + v[1];
+                arr2v(vatom,2,i) = arr2v(vatom,2,i) + v[2];
+                arr2v(vatom,3,i) = arr2v(vatom,3,i) + v[3];
+                arr2v(vatom,4,i) = arr2v(vatom,4,i) + v[4];
+                arr2v(vatom,5,i) = arr2v(vatom,5,i) + v[5];
+                arr2v(vatom,6,i) = arr2v(vatom,6,i) + v[6];
+                arr2v(vatom,1,j) = arr2v(vatom,1,j) + v[1];
+                arr2v(vatom,2,j) = arr2v(vatom,2,j) + v[2];
+                arr2v(vatom,3,j) = arr2v(vatom,3,j) + v[3];
+                arr2v(vatom,4,j) = arr2v(vatom,4,j) + v[4];
+                arr2v(vatom,5,j) = arr2v(vatom,5,j) + v[5];
+                arr2v(vatom,6,j) = arr2v(vatom,6,j) + v[6];
+              }
+
+//     Now compute forces on other atoms k due to change in sij
+
+              if (iszero(sij) || iszero(sij-1.0)) continue; //: cont jn loop
+              for(kn=1; kn<=*numneigh_full; kn++) {
+                k = arr1v(firstneigh_full,kn);
+                eltk = arr1v(fmap,arr1v(type,k));
+                if (k!=j && eltk > 0) {
+                  dsij(i,j,k,jn,*nmax,*numneigh,rij2,&dsij1,&dsij2,*ntype,type,fmap,x,scrfcn,fcpair);
+                  if (!iszero(dsij1) || !iszero(dsij2)) {
+                    force1 = dUdsij*dsij1;
+                    force2 = dUdsij*dsij2;
+                    for(m=1; m<=3; m++) {
+                      delik[m] = arr2v(x,m,k) - arr2v(x,m,i);
+                      deljk[m] = arr2v(x,m,k) - arr2v(x,m,j);
+                    }
+                    for(m=1; m<=3; m++) {
+                      arr2v(f,m,i) = arr2v(f,m,i) + force1*delik[m];
+                      arr2v(f,m,j) = arr2v(f,m,j) + force2*deljk[m];
+                      arr2v(f,m,k) = arr2v(f,m,k) - force1*delik[m] - force2*deljk[m];
+                    }
+
+//     Tabulate per-atom virial as symmetrized stress tensor
+
+                    if (*vflag_atom!=0) {
+                      fi[1] = force1*delik[1];
+                      fi[2] = force1*delik[2];
+                      fi[3] = force1*delik[3];
+                      fj[1] = force2*deljk[1];
+                      fj[2] = force2*deljk[2];
+                      fj[3] = force2*deljk[3];
+                      v[1] = -third * (delik[1]*fi[1] + deljk[1]*fj[1]);
+                      v[2] = -third * (delik[2]*fi[2] + deljk[2]*fj[2]);
+                      v[3] = -third * (delik[3]*fi[3] + deljk[3]*fj[3]);
+                      v[4] = -sixth * (delik[1]*fi[2] + deljk[1]*fj[2] +                    delik[2]*fi[1] + deljk[2]*fj[1]);
+                      v[5] = -sixth * (delik[1]*fi[3] + deljk[1]*fj[3] +                    delik[3]*fi[1] + deljk[3]*fj[1]);
+                      v[6] = -sixth * (delik[2]*fi[3] + deljk[2]*fj[3] +                    delik[3]*fi[2] + deljk[3]*fj[2]);
+
+                      arr2v(vatom,1,i) = arr2v(vatom,1,i) + v[1];
+                      arr2v(vatom,2,i) = arr2v(vatom,2,i) + v[2];
+                      arr2v(vatom,3,i) = arr2v(vatom,3,i) + v[3];
+                      arr2v(vatom,4,i) = arr2v(vatom,4,i) + v[4];
+                      arr2v(vatom,5,i) = arr2v(vatom,5,i) + v[5];
+                      arr2v(vatom,6,i) = arr2v(vatom,6,i) + v[6];
+                      arr2v(vatom,1,j) = arr2v(vatom,1,j) + v[1];
+                      arr2v(vatom,2,j) = arr2v(vatom,2,j) + v[2];
+                      arr2v(vatom,3,j) = arr2v(vatom,3,j) + v[3];
+                      arr2v(vatom,4,j) = arr2v(vatom,4,j) + v[4];
+                      arr2v(vatom,5,j) = arr2v(vatom,5,j) + v[5];
+                      arr2v(vatom,6,j) = arr2v(vatom,6,j) + v[6];
+                      arr2v(vatom,1,k) = arr2v(vatom,1,k) + v[1];
+                      arr2v(vatom,2,k) = arr2v(vatom,2,k) + v[2];
+                      arr2v(vatom,3,k) = arr2v(vatom,3,k) + v[3];
+                      arr2v(vatom,4,k) = arr2v(vatom,4,k) + v[4];
+                      arr2v(vatom,5,k) = arr2v(vatom,5,k) + v[5];
+                      arr2v(vatom,6,k) = arr2v(vatom,6,k) + v[6];
+                    }
+
+                  }
+                }
+//     end of k loop
+              }
+            }
+          }
+//     end of j loop
+        }
+
+//     else if elti=0, this is not a meam atom
+      }
+
+      }
diff --git a/src/USER-MEAMC/meam_setup_done.c b/src/USER-MEAMC/meam_setup_done.c
new file mode 100644
index 0000000000..e777025067
--- /dev/null
+++ b/src/USER-MEAMC/meam_setup_done.c
@@ -0,0 +1,945 @@
+#include "meam.h"
+#include <math.h>
+
+void alloyparams();
+void compute_pair_meam();
+double phi_meam(double r,int a, int b);
+void compute_reference_density();
+void get_shpfcn(double *s /* s(3) */, lattice_t latt);
+void get_tavref(double *t11av,double *t21av,double *t31av,double *t12av,double *t22av,double *t32av, double t11,double t21,double t31,double t12,double t22,double t32, double r,int a,int b,lattice_t latt);
+void get_Zij(int *Zij, lattice_t latt);
+void get_Zij2(int *Zij2, double *a, double*S, lattice_t latt,double cmin,double cmax);
+void get_sijk(double C,int i,int j,int k, double *sijk);
+void get_densref(double r,int a,int b,double *rho01,double *rho11,double *rho21,double *rho31, double *rho02,double *rho12,double *rho22,double *rho32);
+double zbl(double r, int z1, int z2);
+double erose(double r,double re,double alpha,double Ec,double repuls,double attrac,int form);
+void interpolate_meam(int ind);
+double compute_phi(double rij, int elti, int eltj);
+
+// in meam_dens_init
+void fcut(double xi, double *fc);
+// in meam_dens_final
+void G_gam(double Gamma,int ibar,double gsmooth_factor, double *G, int *errorflag);
+
+// Declaration in pair_meam.h:
+//
+// void meam_setup_done(double *)
+//
+// Call from pair_meam.cpp:
+//
+// meam_setup_done(&cutmax)
+//
+
+      void meam_setup_done_(double *cutmax)
+      {
+      int nv2, nv3, m, n, p;
+
+//     Force cutoff
+      meam_data.cutforce = meam_data.rc_meam;
+      meam_data.cutforcesq = meam_data.cutforce*meam_data.cutforce;
+
+//     Pass cutoff back to calling program
+      *cutmax = meam_data.cutforce;
+
+//     Augment t1 term
+      for (int i=1; i<=maxelt; i++)
+        meam_data.t1_meam[i] = meam_data.t1_meam[i] + meam_data.augt1 * 3.0/5.0 * meam_data.t3_meam[i];
+
+//     Compute off-diagonal alloy parameters
+      alloyparams();
+
+// indices and factors for Voight notation
+      nv2 = 1;
+      nv3 = 1;
+      for(m = 1; m<=3; m++) {
+        for(n = m; n<=3; n++) {
+          meam_data.vind2D[m][n] = nv2;
+          meam_data.vind2D[n][m] = nv2;
+          nv2 = nv2+1;
+          for (p = n; p<=3; p++) {
+            meam_data.vind3D[m][n][p] = nv3;
+            meam_data.vind3D[m][p][n] = nv3;
+            meam_data.vind3D[n][m][p] = nv3;
+            meam_data.vind3D[n][p][m] = nv3;
+            meam_data.vind3D[p][m][n] = nv3;
+            meam_data.vind3D[p][n][m] = nv3;
+            nv3 = nv3+1;
+          }
+        }
+      }
+
+      meam_data.v2D[1] = 1;
+      meam_data.v2D[2] = 2;
+      meam_data.v2D[3] = 2;
+      meam_data.v2D[4] = 1;
+      meam_data.v2D[5] = 2;
+      meam_data.v2D[6] = 1;
+
+      meam_data.v3D[1] = 1;
+      meam_data.v3D[2] = 3;
+      meam_data.v3D[3] = 3;
+      meam_data.v3D[4] = 3;
+      meam_data.v3D[5] = 6;
+      meam_data.v3D[6] = 3;
+      meam_data.v3D[7] = 1;
+      meam_data.v3D[8] = 3;
+      meam_data.v3D[9] = 3;
+      meam_data.v3D[10] = 1;
+
+      nv2 = 1;
+      for(m = 1; m<=meam_data.neltypes; m++) {
+        for(n = m; n<=meam_data.neltypes; n++) {
+          meam_data.eltind[m][n] = nv2;
+          meam_data.eltind[n][m] = nv2;
+          nv2 = nv2+1;
+        }
+      }
+
+//     Compute background densities for reference structure
+      compute_reference_density();
+
+//     Compute pair potentials and setup arrays for interpolation
+      meam_data.nr = 1000;
+      meam_data.dr = 1.1*meam_data.rc_meam/meam_data.nr;
+      compute_pair_meam();
+    }
+
+//ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+// Fill off-diagonal alloy parameters
+      void alloyparams(void)
+      {
+      
+      int i,j,k;
+      double eb;
+
+// Loop over pairs
+      for(i = 1; i<=meam_data.neltypes; i++) {
+        for(j = 1;i<=meam_data.neltypes; i++) {
+// Treat off-diagonal pairs
+// If i>j, set all equal to i<j case (which has aready been set,
+// here or in the input file)
+          if (i > j) {
+            meam_data.re_meam[i][j] = meam_data.re_meam[j][i];
+            meam_data.Ec_meam[i][j] = meam_data.Ec_meam[j][i];
+            meam_data.alpha_meam[i][j] = meam_data.alpha_meam[j][i];
+            meam_data.lattce_meam[i][j] = meam_data.lattce_meam[j][i];
+            meam_data.nn2_meam[i][j] = meam_data.nn2_meam[j][i];
+// If i<j and term is unset, use default values (e.g. mean of i-i and j-j)
+          } else if (j > i) {
+            if (iszero(meam_data.Ec_meam[i][j])) {
+              if (meam_data.lattce_meam[i][j]==L12)
+                meam_data.Ec_meam[i][j] = (3*meam_data.Ec_meam[i][i]+meam_data.Ec_meam[j][j])/4.0 - meam_data.delta_meam[i][j];
+              else if (meam_data.lattce_meam[i][j]==C11) {
+                if (meam_data.lattce_meam[i][i]==DIA)
+                  meam_data.Ec_meam[i][j] = (2*meam_data.Ec_meam[i][i]+meam_data.Ec_meam[j][j])/3.0 - meam_data.delta_meam[i][j];
+                else
+                  meam_data.Ec_meam[i][j] = (meam_data.Ec_meam[i][i]+2*meam_data.Ec_meam[j][j])/3.0 - meam_data.delta_meam[i][j];
+              } else
+                meam_data.Ec_meam[i][j] = (meam_data.Ec_meam[i][i]+meam_data.Ec_meam[j][j])/2.0 - meam_data.delta_meam[i][j];
+            }
+            if (iszero(meam_data.alpha_meam[i][j]))
+              meam_data.alpha_meam[i][j] = (meam_data.alpha_meam[i][i]+meam_data.alpha_meam[j][j])/2.0;
+            if (iszero(meam_data.re_meam[i][j]))
+              meam_data.re_meam[i][j] = (meam_data.re_meam[i][i]+meam_data.re_meam[j][j])/2.0;
+          }
+        }
+      }
+
+// Cmin[i][k][j] is symmetric in i-j, but not k.  For all triplets
+// where i>j, set equal to the i<j element.  Likewise for Cmax.
+      for(i = 2;i<=meam_data.neltypes;i++){
+        for(j = 1;j<=i-1;j++){
+          for(k = 1;k<=meam_data.neltypes;k++){
+          meam_data.Cmin_meam[i][j][k] = meam_data.Cmin_meam[j][i][k];
+          meam_data.Cmax_meam[i][j][k] = meam_data.Cmax_meam[j][i][k];
+          }
+        }
+      }
+        
+
+// ebound gives the squared distance such that, for rik2 or rjk2>ebound,
+// atom k definitely lies outside the screening function ellipse (so
+// there is no need to calculate its effects).  Here, compute it for all
+// triplets [i][j][k] so that ebound[i][j] is the maximized over k
+      for(i = 2;i<=meam_data.neltypes;i++){
+        for(j = 1;j<=meam_data.neltypes;j++){
+          for(k = 1;k<=meam_data.neltypes;k++){
+            eb = (meam_data.Cmax_meam[i][j][k]*meam_data.Cmax_meam[i][j][k]) / (4.0*(meam_data.Cmax_meam[i][j][k]-1.0));
+            meam_data.ebound_meam[i][j] = max(meam_data.ebound_meam[i][j],eb);
+          }
+        }
+      }
+    }
+
+//-----------------------------------------------------------------------
+// compute MEAM pair potential for each pair of element types
+//
+
+      void compute_pair_meam(void)
+      {
+
+      double r/*ununsed:, temp*/;
+      int j,a,b,nv2;
+      double astar,frac,phizbl;
+      int n,nmax,Z1,Z2;
+      double arat,rarat,scrn,scrn2;
+      double phiaa,phibb/*unused:,phitmp*/;
+      double C,s111,s112,s221,S11,S22;
+
+// check for previously allocated arrays and free them
+      if(allocated(meam_data.phir)) deallocate(meam_data.phir);
+      if(allocated(meam_data.phirar)) deallocate(meam_data.phirar);
+      if(allocated(meam_data.phirar1)) deallocate(meam_data.phirar1);
+      if(allocated(meam_data.phirar2)) deallocate(meam_data.phirar2);
+      if(allocated(meam_data.phirar3)) deallocate(meam_data.phirar3);
+      if(allocated(meam_data.phirar4)) deallocate(meam_data.phirar4);
+      if(allocated(meam_data.phirar5)) deallocate(meam_data.phirar5);
+      if(allocated(meam_data.phirar6)) deallocate(meam_data.phirar6);
+
+// allocate memory for array that defines the potential
+      allocate_2d(meam_data.phir,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+
+// allocate coeff memory
+
+      allocate_2d(meam_data.phirar,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+      allocate_2d(meam_data.phirar1,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+      allocate_2d(meam_data.phirar2,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+      allocate_2d(meam_data.phirar3,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+      allocate_2d(meam_data.phirar4,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+      allocate_2d(meam_data.phirar5,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+      allocate_2d(meam_data.phirar6,meam_data.nr,(meam_data.neltypes*(meam_data.neltypes+1))/2);
+
+// loop over pairs of element types
+      nv2 = 0;
+      for(a=1; a<=meam_data.neltypes; a++) {
+        for(b=a; b<=meam_data.neltypes; b++) {
+          nv2 = nv2 + 1;
+
+// loop over r values and compute
+          for(j=1; j<=meam_data.nr; j++) {
+            r = (j-1)*meam_data.dr;
+
+            arr2(meam_data.phir,j,nv2) = phi_meam(r,a,b);
+
+// if using second-nearest neighbor, solve recursive problem
+// (see Lee and Baskes, PRB 62(13):8564 eqn.(21))
+            if (meam_data.nn2_meam[a][b]==1) {
+              get_Zij(&Z1,meam_data.lattce_meam[a][b]);
+              get_Zij2(&Z2,&arat,&scrn,meam_data.lattce_meam[a][b],meam_data.Cmin_meam[a][a][b],meam_data.Cmax_meam[a][a][b]);
+
+//     The B1, B2,  and L12 cases with NN2 have a trick to them; we need to
+//     compute the contributions from second nearest neighbors, like a-a
+//     pairs, but need to include NN2 contributions to those pairs as
+//     well.
+              if (meam_data.lattce_meam[a][b]==B1 || meam_data.lattce_meam[a][b]==B2 || meam_data.lattce_meam[a][b]==L12) {
+                rarat = r*arat;
+
+//               phi_aa
+                phiaa = phi_meam(rarat,a,a);
+                get_Zij(&Z1,meam_data.lattce_meam[a][a]);
+                get_Zij2(&Z2,&arat,&scrn,meam_data.lattce_meam[a][a], meam_data.Cmin_meam[a][a][a],meam_data.Cmax_meam[a][a][a]);
+                nmax = 10;
+                if (scrn > 0.0) {
+                  for(n=1; n<=nmax; n++) {
+                    phiaa = phiaa + pow((-Z2*scrn/Z1),n) * phi_meam(rarat*pow(arat,n),a,a);
+                  }
+                }
+
+//               phi_bb
+                phibb = phi_meam(rarat,b,b);
+                get_Zij(&Z1,meam_data.lattce_meam[b][b]);
+                get_Zij2(&Z2,&arat,&scrn,meam_data.lattce_meam[b][b], meam_data.Cmin_meam[b][b][b],meam_data.Cmax_meam[b][b][b]);
+                nmax = 10;
+                if (scrn > 0.0) {
+                  for(n=1; n<=nmax; n++) {
+                    phibb = phibb + pow((-Z2*scrn/Z1),n) * phi_meam(rarat*pow(arat,n),b,b);
+                  }
+                }
+
+                if (meam_data.lattce_meam[a][b]==B1 || meam_data.lattce_meam[a][b]==B2) {
+//     Add contributions to the B1 or B2 potential
+                  get_Zij(&Z1,meam_data.lattce_meam[a][b]);
+                  get_Zij2(&Z2,&arat,&scrn,meam_data.lattce_meam[a][b], meam_data.Cmin_meam[a][a][b],meam_data.Cmax_meam[a][a][b]);
+                  arr2(meam_data.phir,j,nv2) = arr2(meam_data.phir,j,nv2) - Z2*scrn/(2*Z1) * phiaa;
+                  get_Zij2(&Z2,&arat,&scrn2,meam_data.lattce_meam[a][b], meam_data.Cmin_meam[b][b][a],meam_data.Cmax_meam[b][b][a]);
+                  arr2(meam_data.phir,j,nv2) = arr2(meam_data.phir,j,nv2) - Z2*scrn2/(2*Z1) * phibb;
+
+                } else if (meam_data.lattce_meam[a][b]==L12) {
+//     The L12 case has one last trick; we have to be careful to compute
+//     the correct screening between 2nd-neighbor pairs.  1-1
+//     second-neighbor pairs are screened by 2 type 1 atoms and two type
+//     2 atoms.  2-2 second-neighbor pairs are screened by 4 type 1
+//     atoms.
+                  C = 1.0;
+                  get_sijk(C,a,a,a,&s111);
+                  get_sijk(C,a,a,b,&s112);
+                  get_sijk(C,b,b,a,&s221);
+                  S11 = s111 * s111 * s112 * s112;
+                  S22 = pow(s221,4);
+                  arr2(meam_data.phir,j,nv2) = arr2(meam_data.phir,j,nv2) - 0.75*S11*phiaa - 0.25*S22*phibb;
+
+                }
+
+              } else {
+                nmax = 10;
+                for(n=1; n<=nmax; n++) {
+                  arr2(meam_data.phir,j,nv2) = arr2(meam_data.phir,j,nv2) + pow((-Z2*scrn/Z1),n) * phi_meam(r*pow(arat,n),a,b);
+                }
+              }
+
+            }
+
+// For Zbl potential:
+// if astar <= -3
+//   potential is zbl potential
+// else if -3 < astar < -1
+//   potential is linear combination with zbl potential
+// endif
+            if (meam_data.zbl_meam[a][b]==1) {
+              astar = meam_data.alpha_meam[a][b] * (r/meam_data.re_meam[a][b] - 1.0);
+              if (astar <= -3.0)
+                arr2(meam_data.phir,j,nv2) = zbl(r,meam_data.ielt_meam[a],meam_data.ielt_meam[b]);
+              else if (astar > -3.0 && astar < -1.0) {
+                fcut(1-(astar+1.0)/(-3.0+1.0),&frac);
+                phizbl = zbl(r,meam_data.ielt_meam[a],meam_data.ielt_meam[b]);
+                arr2(meam_data.phir,j,nv2) = frac*arr2(meam_data.phir,j,nv2) + (1-frac)*phizbl;
+              }
+            }
+
+          }
+
+// call interpolation
+          interpolate_meam(nv2);
+
+        }
+      }
+
+      }
+
+
+//----------------------------------------------------------------------c
+// Compute MEAM pair potential for distance r, element types a and b
+//
+      double phi_meam(double r,int a, int b)
+      {
+      /*unused:double a1,a2,a12;*/
+      double t11av,t21av,t31av,t12av,t22av,t32av;
+      double G1,G2,s1[3+1],s2[3+1]/*,s12[3+1]*/,rho0_1,rho0_2;
+      double Gam1,Gam2,Z1,Z2;
+      double rhobar1,rhobar2,F1,F2;
+      double rho01,rho11,rho21,rho31;
+      double rho02,rho12,rho22,rho32;
+      double scalfac,phiaa,phibb;
+      double Eu;
+      double arat,scrn/*unused:,scrn2*/;
+      int Z12, errorflag;
+      int n,nmax,Z1nn,Z2nn;
+      lattice_t latta/*unused:,lattb*/;
+      double rho_bkgd1, rho_bkgd2;
+      
+      double phi_m = 0.0;
+
+// Equation numbers below refer to:
+//   I. Huang et.al., Modelling simul. Mater. Sci. Eng. 3:615
+
+// get number of neighbors in the reference structure
+//   Nref[i][j] = # of i's neighbors of type j
+      get_Zij(&Z12,meam_data.lattce_meam[a][b]);
+
+      get_densref(r,a,b,&rho01,&rho11,&rho21,&rho31,&rho02,&rho12,&rho22,&rho32);
+
+// if densities are too small, numerical problems may result; just return zero
+      if (rho01<=1e-14 && rho02<=1e-14)
+        return 0.0;
+
+// calculate average weighting factors for the reference structure
+      if (meam_data.lattce_meam[a][b]==C11) {
+        if (meam_data.ialloy==2) {
+          t11av = meam_data.t1_meam[a];
+          t12av = meam_data.t1_meam[b];
+          t21av = meam_data.t2_meam[a];
+          t22av = meam_data.t2_meam[b];
+          t31av = meam_data.t3_meam[a];
+          t32av = meam_data.t3_meam[b];
+        } else {
+          scalfac = 1.0/(rho01+rho02);
+          t11av = scalfac*(meam_data.t1_meam[a]*rho01 + meam_data.t1_meam[b]*rho02);
+          t12av = t11av;
+          t21av = scalfac*(meam_data.t2_meam[a]*rho01 + meam_data.t2_meam[b]*rho02);
+          t22av = t21av;
+          t31av = scalfac*(meam_data.t3_meam[a]*rho01 + meam_data.t3_meam[b]*rho02);
+          t32av = t31av;
+        }
+      } else {
+// average weighting factors for the reference structure, eqn. I.8
+         get_tavref(&t11av,&t21av,&t31av,&t12av,&t22av,&t32av, meam_data.t1_meam[a],meam_data.t2_meam[a],meam_data.t3_meam[a], meam_data.t1_meam[b],meam_data.t2_meam[b],meam_data.t3_meam[b], r,a,b,meam_data.lattce_meam[a][b]);
+      }
+
+// for c11b structure, calculate background electron densities
+      if (meam_data.lattce_meam[a][b]==C11) {
+         latta = meam_data.lattce_meam[a][a];
+         if (latta==DIA) {
+            rhobar1 = pow(((Z12/2)*(rho02+rho01)),2) + t11av*pow((rho12-rho11),2) + t21av/6.0*pow(rho22+rho21,2)+ 121.0/40.0*t31av*pow((rho32-rho31),2);
+            rhobar1 = sqrt(rhobar1);
+            rhobar2 = pow(Z12*rho01,2) + 2.0/3.0*t21av*pow(rho21,2);
+            rhobar2 = sqrt(rhobar2);
+         } else {
+            rhobar2 = pow(((Z12/2)*(rho01+rho02)),2) + t12av*pow((rho11-rho12),2) + t22av/6.0*pow(rho21+rho22,2) + 121.0/40.0*t32av*pow((rho31-rho32),2);
+            rhobar2 = sqrt(rhobar2);
+            rhobar1 = pow(Z12*rho02,2) + 2.0/3.0*t22av*pow(rho22,2);
+            rhobar1 = sqrt(rhobar1);
+         }
+      } else {
+// for other structures, use formalism developed in Huang's paper
+//
+//     composition-dependent scaling, equation I.7
+//     If using mixing rule for t, apply to reference structure; else
+//     use precomputed values
+        if (meam_data.mix_ref_t==1) {
+          Z1 = meam_data.Z_meam[a];
+          Z2 = meam_data.Z_meam[b];
+          if (meam_data.ibar_meam[a]<=0)
+            G1 = 1.0;
+          else {
+            get_shpfcn(s1,meam_data.lattce_meam[a][a]);
+            Gam1 = (s1[1]*t11av+s1[2]*t21av+s1[3]*t31av)/(Z1*Z1);
+            G_gam(Gam1,meam_data.ibar_meam[a],meam_data.gsmooth_factor,&G1,&errorflag);
+          }
+          if (meam_data.ibar_meam[b]<=0)
+            G2 = 1.0;
+          else {
+            get_shpfcn(s2,meam_data.lattce_meam[b][b]);
+            Gam2 = (s2[1]*t12av+s2[2]*t22av+s2[3]*t32av)/(Z2*Z2);
+            G_gam(Gam2,meam_data.ibar_meam[b],meam_data.gsmooth_factor,&G2,&errorflag);
+          }
+          rho0_1 = meam_data.rho0_meam[a]*Z1*G1;
+          rho0_2 = meam_data.rho0_meam[b]*Z2*G2;
+        }
+        Gam1 = (t11av*rho11+t21av*rho21+t31av*rho31);
+        if (rho01 < 1.0e-14)
+          Gam1 = 0.0;
+        else
+          Gam1 = Gam1/(rho01*rho01);
+
+        Gam2 = (t12av*rho12+t22av*rho22+t32av*rho32);
+        if (rho02 < 1.0e-14)
+          Gam2 = 0.0;
+        else
+          Gam2 = Gam2/(rho02*rho02);
+
+        G_gam(Gam1,meam_data.ibar_meam[a],meam_data.gsmooth_factor,&G1,&errorflag);
+        G_gam(Gam2,meam_data.ibar_meam[b],meam_data.gsmooth_factor,&G2,&errorflag);
+        if (meam_data.mix_ref_t==1) {
+          rho_bkgd1 = rho0_1;
+          rho_bkgd2 = rho0_2;
+        } else {
+          if (meam_data.bkgd_dyn==1) {
+            rho_bkgd1 = meam_data.rho0_meam[a]*meam_data.Z_meam[a];
+            rho_bkgd2 = meam_data.rho0_meam[b]*meam_data.Z_meam[b];
+          } else {
+            rho_bkgd1 = meam_data.rho_ref_meam[a];
+            rho_bkgd2 = meam_data.rho_ref_meam[b];
+          }
+        }
+        rhobar1 = rho01/rho_bkgd1*G1;
+        rhobar2 = rho02/rho_bkgd2*G2;
+
+      }
+
+// compute embedding functions, eqn I.5
+      if (iszero(rhobar1))
+        F1 = 0.0;
+      else {
+        if (meam_data.emb_lin_neg==1 && rhobar1<=0)
+          F1 = -meam_data.A_meam[a]*meam_data.Ec_meam[a][a]*rhobar1;
+        else
+          F1 = meam_data.A_meam[a]*meam_data.Ec_meam[a][a]*rhobar1*log(rhobar1);
+      }
+      if (iszero(rhobar2))
+        F2 = 0.0;
+      else {
+        if (meam_data.emb_lin_neg==1  &&  rhobar2<=0)
+          F2 = -meam_data.A_meam[b]*meam_data.Ec_meam[b][b]*rhobar2;
+        else
+          F2 = meam_data.A_meam[b]*meam_data.Ec_meam[b][b]*rhobar2*log(rhobar2);
+      }
+
+// compute Rose function, I.16
+      Eu = erose(r,meam_data.re_meam[a][b],meam_data.alpha_meam[a][b], meam_data.Ec_meam[a][b],meam_data.repuls_meam[a][b],meam_data.attrac_meam[a][b],meam_data.erose_form);
+
+// calculate the pair energy
+      if (meam_data.lattce_meam[a][b]==C11) {
+        latta = meam_data.lattce_meam[a][a];
+        if (latta==DIA) {
+          phiaa = phi_meam(r,a,a);
+          phi_m = (3*Eu - F2 - 2*F1 - 5*phiaa)/Z12;
+        } else {
+          phibb = phi_meam(r,b,b);
+          phi_m = (3*Eu - F1 - 2*F2 - 5*phibb)/Z12;
+        }
+      } else if (meam_data.lattce_meam[a][b]==L12) {
+        phiaa = phi_meam(r,a,a);
+//       account for second neighbor a-a potential here...
+        get_Zij(&Z1nn,meam_data.lattce_meam[a][a]);
+        get_Zij2(&Z2nn,&arat,&scrn,meam_data.lattce_meam[a][a],meam_data.Cmin_meam[a][a][a],meam_data.Cmax_meam[a][a][a]);
+        nmax = 10;
+        if (scrn > 0.0) {
+          for(n=1; n<=nmax; n++) {
+            phiaa = phiaa + pow((-Z2nn*scrn/Z1nn),n) * phi_meam(r*pow(arat,n),a,a);
+          }
+        }
+        phi_m = Eu/3.0 - F1/4.0 - F2/12.0 - phiaa;
+         
+      } else {
+//
+// potential is computed from Rose function and embedding energy
+         phi_m = (2*Eu - F1 - F2)/Z12;
+//
+      }
+
+// if r = 0, just return 0
+      if (iszero(r)) {
+        phi_m = 0.0;
+      }
+      
+      return phi_m;
+    }
+
+//----------------------------------------------------------------------c
+// Compute background density for reference structure of each element
+      void compute_reference_density(void)
+      {
+      int a,Z,Z2,errorflag;
+      double gam,Gbar,shp[3+1];
+      double rho0,rho0_2nn,arat,scrn;
+
+// loop over element types
+      for(a=1; a<=meam_data.neltypes; a++) {
+        Z = (int)meam_data.Z_meam[a];
+        if (meam_data.ibar_meam[a]<=0)
+          Gbar = 1.0;
+        else {
+          get_shpfcn(shp,meam_data.lattce_meam[a][a]);
+          gam = (meam_data.t1_meam[a]*shp[1]+meam_data.t2_meam[a]*shp[2]+meam_data.t3_meam[a]*shp[3])/(Z*Z);
+          G_gam(gam,meam_data.ibar_meam[a],meam_data.gsmooth_factor,&Gbar,&errorflag);
+        }
+
+//     The zeroth order density in the reference structure, with
+//     equilibrium spacing, is just the number of first neighbors times
+//     the rho0_meam coefficient...
+        rho0 = meam_data.rho0_meam[a]*Z;
+
+//     ...unless we have unscreened second neighbors, in which case we
+//     add on the contribution from those (accounting for partial
+//     screening)
+        if (meam_data.nn2_meam[a][a]==1) {
+          get_Zij2(&Z2,&arat,&scrn,meam_data.lattce_meam[a][a],meam_data.Cmin_meam[a][a][a],meam_data.Cmax_meam[a][a][a]);
+          rho0_2nn = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta0_meam[a]*(arat-1));
+          rho0 = rho0 + Z2*rho0_2nn*scrn;
+        }
+
+        meam_data.rho_ref_meam[a] = rho0*Gbar;
+      }
+      }
+
+//----------------------------------------------------------------------c
+// Shape factors for various configurations
+      void get_shpfcn(double *s /* s(3) */, lattice_t latt)
+      {
+      if (latt==FCC || latt==BCC || latt==B1 || latt==B2) {
+        s[1] = 0.0;
+        s[2] = 0.0;
+        s[3] = 0.0;
+      } else if (latt==HCP) {
+        s[1] = 0.0;
+        s[2] = 0.0;
+        s[3] = 1.0/3.0;
+      } else if (latt==DIA) {
+        s[1] = 0.0;
+        s[2] = 0.0;
+        s[3] = 32.0/9.0;
+      } else if (latt==DIM) {
+        s[1] = 1.0;
+        s[2] = 2.0/3.0;
+//        s(3) = 1.d0
+        s[3] = 0.40;
+      } else {
+        s[1] = 0.0;
+//        call error('Lattice not defined in get_shpfcn.')
+      }
+      }
+      
+//------------------------------------------------------------------------------c
+// Average weighting factors for the reference structure
+      void get_tavref(double *t11av,double *t21av,double *t31av,double *t12av,double *t22av,double *t32av, double t11,double t21,double t31,double t12,double t22,double t32, double r,int a,int b,lattice_t latt)
+      {
+      double rhoa01,rhoa02,a1,a2,rho01/*,rho02*/;
+
+//     For ialloy = 2, no averaging is done
+      if (meam_data.ialloy==2) {
+          *t11av = t11;
+          *t21av = t21;
+          *t31av = t31;
+          *t12av = t12;
+          *t22av = t22;
+          *t32av = t32;
+      } else {
+        if (latt==FCC || latt==BCC || latt==DIA || latt==HCP || latt==B1 || latt==DIM || latt==B2) {
+//     all neighbors are of the opposite type
+          *t11av = t12;
+          *t21av = t22;
+          *t31av = t32;
+          *t12av = t11;
+          *t22av = t21;
+          *t32av = t31;
+        } else {
+          a1  = r/meam_data.re_meam[a][a] - 1.0;
+          a2  = r/meam_data.re_meam[b][b] - 1.0;
+          rhoa01 = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta0_meam[a]*a1);
+          rhoa02 = meam_data.rho0_meam[b]*fm_exp(-meam_data.beta0_meam[b]*a2);
+          if (latt==L12) {
+            rho01 = 8*rhoa01 + 4*rhoa02;
+            *t11av = (8*t11*rhoa01 + 4*t12*rhoa02)/rho01;
+            *t12av = t11;
+            *t21av = (8*t21*rhoa01 + 4*t22*rhoa02)/rho01;
+            *t22av = t21;
+            *t31av = (8*t31*rhoa01 + 4*t32*rhoa02)/rho01;
+            *t32av = t31;
+          } else {
+//      call error('Lattice not defined in get_tavref.')
+          }
+        }
+      }
+      }
+      
+//------------------------------------------------------------------------------c
+// Number of neighbors for the reference structure
+      void get_Zij(int *Zij, lattice_t latt)
+      {
+      if (latt==FCC)
+        *Zij = 12;
+      else if (latt==BCC)
+        *Zij = 8;
+      else if (latt==HCP)
+        *Zij = 12;
+      else if (latt==B1)
+        *Zij = 6;
+      else if (latt==DIA)
+        *Zij = 4;
+      else if (latt==DIM)
+        *Zij = 1;
+      else if (latt==C11)
+        *Zij = 10;
+      else if (latt==L12)
+        *Zij = 12;
+      else if (latt==B2)
+        *Zij = 8;
+      else {
+//        call error('Lattice not defined in get_Zij.')
+      }
+      }
+     
+//------------------------------------------------------------------------------c
+// Zij2 = number of second neighbors, a = distance ratio R1/R2, and S = second
+// neighbor screening function for lattice type "latt"
+
+      void get_Zij2(int *Zij2, double *a, double*S, lattice_t latt,double cmin,double cmax)
+      {
+        
+      double /*rratio,*/C,x,sijk;
+      int numscr = 0;
+
+      if (latt==BCC) {
+        *Zij2 = 6;
+        *a = 2.0/sqrt(3.0);
+        numscr = 4;
+      } else if (latt==FCC) {
+        *Zij2 = 6;
+        *a = sqrt(2.0);
+        numscr = 4;
+      } else if (latt==DIA) {
+        *Zij2 = 0;
+        *a = sqrt(8.0/3.0);
+        numscr = 4;
+        if (cmin < 0.500001) {
+//          call error('can not do 2NN MEAM for dia')
+        }
+      } else if (latt==HCP) {
+        *Zij2 = 6;
+        *a = sqrt(2.0);
+        numscr = 4;
+      } else if (latt==B1) {
+        *Zij2 = 12;
+        *a = sqrt(2.0);
+        numscr = 2;
+      } else if (latt==L12) {
+        *Zij2 = 6;
+        *a = sqrt(2.0);
+        numscr = 4;
+      } else if (latt==B2) {
+        *Zij2 = 6;
+        *a = 2.0/sqrt(3.0);
+        numscr = 4;
+      } else if (latt==DIM) {
+//        this really shouldn't be allowed; make sure screening is zero
+         *Zij2 = 0;
+         *a = 1;
+         *S = 0;
+         return;
+      } else {
+//        call error('Lattice not defined in get_Zij2.')
+      }
+
+// Compute screening for each first neighbor
+      C = 4.0/(*a * *a) - 1.0;
+      x = (C-cmin)/(cmax-cmin);
+      fcut(x,&sijk);
+// There are numscr first neighbors screening the second neighbors
+      *S = pow(sijk,numscr);
+      
+      }
+      
+
+
+//------------------------------------------------------------------------------c
+      void get_sijk(double C,int i,int j,int k, double *sijk)
+      {
+      double x;
+      x = (C-meam_data.Cmin_meam[i][j][k])/(meam_data.Cmax_meam[i][j][k]-meam_data.Cmin_meam[i][j][k]);
+      fcut(x,sijk);
+      }
+
+//------------------------------------------------------------------------------c
+// Calculate density functions, assuming reference configuration
+      void get_densref(double r,int a,int b,double *rho01,double *rho11,double *rho21,double *rho31, double *rho02,double *rho12,double *rho22,double *rho32)
+      {
+      double a1,a2;
+      double s[3+1];
+      lattice_t lat;
+      int  Zij1nn,Zij2nn;
+      double rhoa01nn,rhoa02nn;
+      double rhoa01,rhoa11,rhoa21,rhoa31;
+      double rhoa02,rhoa12,rhoa22,rhoa32;
+      double arat,scrn,denom;
+      double C,s111,s112,s221,S11,S22;
+
+      a1  = r/meam_data.re_meam[a][a] - 1.0;
+      a2  = r/meam_data.re_meam[b][b] - 1.0;
+
+      rhoa01 = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta0_meam[a]*a1);
+      rhoa11 = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta1_meam[a]*a1);
+      rhoa21 = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta2_meam[a]*a1);
+      rhoa31 = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta3_meam[a]*a1);
+      rhoa02 = meam_data.rho0_meam[b]*fm_exp(-meam_data.beta0_meam[b]*a2);
+      rhoa12 = meam_data.rho0_meam[b]*fm_exp(-meam_data.beta1_meam[b]*a2);
+      rhoa22 = meam_data.rho0_meam[b]*fm_exp(-meam_data.beta2_meam[b]*a2);
+      rhoa32 = meam_data.rho0_meam[b]*fm_exp(-meam_data.beta3_meam[b]*a2);
+
+      lat = meam_data.lattce_meam[a][b];
+
+      *rho11 = 0.0;
+      *rho21 = 0.0;
+      *rho31 = 0.0;
+      *rho12 = 0.0;
+      *rho22 = 0.0;
+      *rho32 = 0.0;
+
+      get_Zij(&Zij1nn,lat);
+
+      if (lat==FCC) {
+        *rho01 = 12.0*rhoa02;
+        *rho02 = 12.0*rhoa01;
+      } else if (lat==BCC) {
+        *rho01 = 8.0*rhoa02;
+        *rho02 = 8.0*rhoa01;
+      } else if (lat==B1) {
+        *rho01 = 6.0*rhoa02;
+        *rho02 = 6.0*rhoa01;
+      } else if (lat==DIA) {
+        *rho01 = 4.0*rhoa02;
+        *rho02 = 4.0*rhoa01;
+        *rho31 = 32.0/9.0*rhoa32*rhoa32;
+        *rho32 = 32.0/9.0*rhoa31*rhoa31;
+      } else if (lat==HCP) {
+        *rho01 = 12*rhoa02;
+        *rho02 = 12*rhoa01;
+        *rho31 = 1.0/3.0*rhoa32*rhoa32;
+        *rho32 = 1.0/3.0*rhoa31*rhoa31;
+      } else if (lat==DIM) {
+        get_shpfcn(s,DIM);
+        *rho01 = rhoa02;
+        *rho02 = rhoa01;
+        *rho11 = s[1]*rhoa12*rhoa12;
+        *rho12 = s[1]*rhoa11*rhoa11;
+        *rho21 = s[2]*rhoa22*rhoa22;
+        *rho22 = s[2]*rhoa21*rhoa21;
+        *rho31 = s[3]*rhoa32*rhoa32;
+        *rho32 = s[3]*rhoa31*rhoa31;
+      } else if (lat==C11) {
+        *rho01 = rhoa01;
+        *rho02 = rhoa02;
+        *rho11 = rhoa11;
+        *rho12 = rhoa12;
+        *rho21 = rhoa21;
+        *rho22 = rhoa22;
+        *rho31 = rhoa31;
+        *rho32 = rhoa32;
+      } else if (lat==L12) {
+        *rho01 = 8*rhoa01 + 4*rhoa02;
+        *rho02 = 12*rhoa01;
+        if (meam_data.ialloy==1) {
+          *rho21 = 8./3.*pow(rhoa21*meam_data.t2_meam[a]-rhoa22*meam_data.t2_meam[b],2);
+          denom = 8*rhoa01*pow(meam_data.t2_meam[a],2) + 4*rhoa02*pow(meam_data.t2_meam[b],2);
+          if (denom > 0.)
+            *rho21 = *rho21/denom * *rho01;
+        } else
+          *rho21 = 8./3.*(rhoa21-rhoa22)*(rhoa21-rhoa22);
+      } else if (lat==B2) {
+        *rho01 = 8.0*rhoa02;
+        *rho02 = 8.0*rhoa01;
+      } else {
+//        call error('Lattice not defined in get_densref.')
+      }
+
+      if (meam_data.nn2_meam[a][b]==1) {
+
+        get_Zij2(&Zij2nn,&arat,&scrn,lat,meam_data.Cmin_meam[a][a][b],meam_data.Cmax_meam[a][a][b]);
+
+        a1 = arat*r/meam_data.re_meam[a][a] - 1.0;
+        a2 = arat*r/meam_data.re_meam[b][b] - 1.0;
+
+        rhoa01nn = meam_data.rho0_meam[a]*fm_exp(-meam_data.beta0_meam[a]*a1);
+        rhoa02nn = meam_data.rho0_meam[b]*fm_exp(-meam_data.beta0_meam[b]*a2);
+
+        if (lat==L12) {
+//     As usual, L12 thinks it's special; we need to be careful computing
+//     the screening functions
+          C = 1.0;
+          get_sijk(C,a,a,a,&s111);
+          get_sijk(C,a,a,b,&s112);
+          get_sijk(C,b,b,a,&s221);
+          S11 = s111 * s111 * s112 * s112;
+          S22 = pow(s221,4);
+          *rho01 = *rho01 + 6*S11*rhoa01nn;
+          *rho02 = *rho02 + 6*S22*rhoa02nn;
+
+        } else {
+//     For other cases, assume that second neighbor is of same type,
+//     first neighbor may be of different type
+
+          *rho01 = *rho01 + Zij2nn*scrn*rhoa01nn;
+
+//     Assume Zij2nn and arat don't depend on order, but scrn might
+          get_Zij2(&Zij2nn,&arat,&scrn,lat,meam_data.Cmin_meam[b][b][a],meam_data.Cmax_meam[b][b][a]);
+          *rho02 = *rho02 + Zij2nn*scrn*rhoa02nn;
+        }
+      }
+      }
+
+//---------------------------------------------------------------------
+// Compute ZBL potential
+//
+      double zbl(double r, int z1, int z2)
+      {
+      int i;
+      const double c[]={0.028171,0.28022,0.50986,0.18175};
+      const double d[]={0.20162,0.40290,0.94229,3.1998};
+      const double azero=0.4685;
+      const double cc=14.3997;
+      double a,x;
+// azero = (9pi^2/128)^1/3 (0.529) Angstroms
+      a = azero/(pow(z1,0.23)+pow(z2,0.23));
+      double result = 0.0;
+      x = r/a;
+      for(i=0; i<=3; i++) {
+        result = result + c[i]*fm_exp(-d[i]*x);
+      }
+      if (r > 0.0) result = result*z1*z2/r*cc;
+      return result;
+      }
+
+//---------------------------------------------------------------------
+// Compute Rose energy function, I.16
+//
+      double erose(double r,double re,double alpha,double Ec,double repuls,double attrac,int form)
+      {
+      double astar,a3;
+      double result = 0.0;
+
+      if (r > 0.0) {
+        astar = alpha * (r/re - 1.0);
+        a3 = 0.0;
+        if (astar>=0)
+          a3 = attrac;
+        else if (astar < 0)
+          a3 = repuls;
+
+        if (form==1)
+          result = -Ec*(1+astar+(-attrac+repuls/r)* pow(astar,3))*fm_exp(-astar);
+        else if (form==2)
+          result = -Ec * (1 +astar + a3*pow(astar,3))*fm_exp(-astar);
+        else
+          result = -Ec * (1+ astar + a3*pow(astar,3)/(r/re))*fm_exp(-astar);
+       
+      }
+      return result;
+      }
+
+// -----------------------------------------------------------------------
+
+      void interpolate_meam(int ind)
+      {
+      int j;
+      double drar;
+
+// map to coefficient space
+
+      meam_data.nrar = meam_data.nr;
+      drar = meam_data.dr;
+      meam_data.rdrar = 1.0/drar;
+
+// phir interp
+      for(j=1; j<=meam_data.nrar; j++) {
+        arr2(meam_data.phirar,j,ind) = arr2(meam_data.phir,j,ind);
+      }
+      arr2(meam_data.phirar1,1,ind) = arr2(meam_data.phirar,2,ind)-arr2(meam_data.phirar,1,ind);
+      arr2(meam_data.phirar1,2,ind) = 0.5*(arr2(meam_data.phirar,3,ind)-arr2(meam_data.phirar,1,ind));
+      arr2(meam_data.phirar1,meam_data.nrar-1,ind) = 0.5*(arr2(meam_data.phirar,meam_data.nrar,ind)      -arr2(meam_data.phirar,meam_data.nrar-2,ind));
+      arr2(meam_data.phirar1,meam_data.nrar,ind) = 0.0;
+      for(j=3; j<=meam_data.nrar-2; j++) {
+        arr2(meam_data.phirar1,j,ind) = ((arr2(meam_data.phirar,j-2,ind)-arr2(meam_data.phirar,j+2,ind)) +        8.0*(arr2(meam_data.phirar,j+1,ind)-arr2(meam_data.phirar,j-1,ind)))/12.;
+      }
+
+      for(j=1; j<=meam_data.nrar-1; j++) {
+        arr2(meam_data.phirar2,j,ind) = 3.0*(arr2(meam_data.phirar,j+1,ind)-arr2(meam_data.phirar,j,ind)) -        2.0*arr2(meam_data.phirar1,j,ind) - arr2(meam_data.phirar1,j+1,ind);
+        arr2(meam_data.phirar3,j,ind) = arr2(meam_data.phirar1,j,ind) + arr2(meam_data.phirar1,j+1,ind) -        2.0*(arr2(meam_data.phirar,j+1,ind)-arr2(meam_data.phirar,j,ind));
+      }
+      arr2(meam_data.phirar2,meam_data.nrar,ind) = 0.0;
+      arr2(meam_data.phirar3,meam_data.nrar,ind) = 0.0;
+
+      for(j=1; j<=meam_data.nrar; j++) {
+        arr2(meam_data.phirar4,j,ind) = arr2(meam_data.phirar1,j,ind)/drar;
+        arr2(meam_data.phirar5,j,ind) = 2.0*arr2(meam_data.phirar2,j,ind)/drar;
+        arr2(meam_data.phirar6,j,ind) = 3.0*arr2(meam_data.phirar3,j,ind)/drar;
+      }  
+           
+      }
+
+//---------------------------------------------------------------------
+// Compute Rose energy function, I.16
+//
+      double compute_phi(double rij, int elti, int eltj)
+      {
+      double pp;
+      int ind, kk;
+
+      ind = meam_data.eltind[elti][eltj];
+      pp = rij*meam_data.rdrar + 1.0;
+      kk = (int)pp;
+      kk = min(kk,meam_data.nrar-1);
+      pp = pp - kk;
+      pp = min(pp,1.0);
+      double result = ((arr2(meam_data.phirar3,kk,ind)*pp + arr2(meam_data.phirar2,kk,ind))*pp + arr2(meam_data.phirar1,kk,ind))*pp + arr2(meam_data.phirar,kk,ind);
+
+      return result;
+      }
diff --git a/src/USER-MEAMC/meam_setup_global.c b/src/USER-MEAMC/meam_setup_global.c
new file mode 100644
index 0000000000..c8c4ef8468
--- /dev/null
+++ b/src/USER-MEAMC/meam_setup_global.c
@@ -0,0 +1,99 @@
+#include "meam.h"
+#include <math.h>
+
+//
+// declaration in pair_meam.h:
+//
+//  void meam_setup_global(int *, int *, double *, int *, double *, double *,
+//			 double *, double *, double *, double *, double *,
+//			 double *, double *, double *, double *, double *,
+//			 double *, double *, int *);
+//
+// call in pair_meam.cpp:
+//
+//  meam_setup_global(&nelements,lat,z,ielement,atwt,alpha,b0,b1,b2,b3,
+//		    alat,esub,asub,t0,t1,t2,t3,rozero,ibar);
+//
+//
+
+      void meam_setup_global_(int *nelt, int *lat, double *z, int *ielement, double *atwt, double *alpha,
+          double *b0, double *b1, double *b2, double *b3, double *alat, double *esub, double *asub,
+          double *t0, double *t1, double *t2, double *t3, double *rozero, int *ibar)
+      {
+      
+      int i;
+      double tmplat[maxelt];
+
+      meam_data.neltypes = *nelt;
+
+      for(i=1; i<=*nelt; i++) {
+         if (arr1v(lat,i)==0)
+            meam_data.lattce_meam[i][i] = FCC;
+         else if (arr1v(lat,i)==1)
+            meam_data.lattce_meam[i][i] = BCC;
+         else if (arr1v(lat,i)==2)
+            meam_data.lattce_meam[i][i] = HCP;
+         else if (arr1v(lat,i)==3)
+            meam_data.lattce_meam[i][i] = DIM;
+         else if (arr1v(lat,i)==4)
+            meam_data.lattce_meam[i][i] = DIA;
+         else {
+//           unknown
+         }
+
+         meam_data.Z_meam[i] = arr1v(z,i);
+         meam_data.ielt_meam[i] = arr1v(ielement,i);
+         meam_data.alpha_meam[i][i] = arr1v(alpha,i);
+         meam_data.beta0_meam[i] = arr1v(b0,i);
+         meam_data.beta1_meam[i] = arr1v(b1,i);
+         meam_data.beta2_meam[i] = arr1v(b2,i);
+         meam_data.beta3_meam[i] = arr1v(b3,i);
+         tmplat[i] = arr1v(alat,i);
+         meam_data.Ec_meam[i][i] = arr1v(esub,i);
+         meam_data.A_meam[i] = arr1v(asub,i);
+         meam_data.t0_meam[i] = arr1v(t0,i);
+         meam_data.t1_meam[i] = arr1v(t1,i);
+         meam_data.t2_meam[i] = arr1v(t2,i);
+         meam_data.t3_meam[i] = arr1v(t3,i);
+         meam_data.rho0_meam[i] = arr1v(rozero,i);
+         meam_data.ibar_meam[i] = arr1v(ibar,i);
+
+         if (meam_data.lattce_meam[i][i]==FCC)
+            meam_data.re_meam[i][i] = tmplat[i]/sqrt(2.0);
+         else if (meam_data.lattce_meam[i][i]==BCC)
+            meam_data.re_meam[i][i] = tmplat[i]*sqrt(3.0)/2.0;
+         else if (meam_data.lattce_meam[i][i]==HCP)
+            meam_data.re_meam[i][i] = tmplat[i];
+         else if (meam_data.lattce_meam[i][i]==DIM)
+            meam_data.re_meam[i][i] = tmplat[i];
+         else if (meam_data.lattce_meam[i][i]==DIA)
+            meam_data.re_meam[i][i] = tmplat[i]*sqrt(3.0)/4.0;
+         else {
+//           error
+         }
+
+      }
+
+
+// Set some defaults
+      meam_data.rc_meam = 4.0;
+      meam_data.delr_meam = 0.1;
+      setall2d(meam_data.attrac_meam, 0.0);
+      setall2d(meam_data.repuls_meam, 0.0);
+      setall3d(meam_data.Cmax_meam, 2.8);
+      setall3d(meam_data.Cmin_meam, 2.0);
+      setall2d(meam_data.ebound_meam, pow(2.8,2)/(4.0*(2.8-1.0)));
+      setall2d(meam_data.delta_meam, 0.0);
+      setall2d(meam_data.nn2_meam, 0);
+      setall2d(meam_data.zbl_meam, 1);
+      meam_data.gsmooth_factor = 99.0;
+      meam_data.augt1 = 1;
+      meam_data.ialloy = 0;
+      meam_data.mix_ref_t = 0;
+      meam_data.emb_lin_neg = 0;
+      meam_data.bkgd_dyn = 0;
+      meam_data.erose_form = 0;
+
+      }
+
+
diff --git a/src/USER-MEAMC/meam_setup_param.c b/src/USER-MEAMC/meam_setup_param.c
new file mode 100644
index 0000000000..2c49481a28
--- /dev/null
+++ b/src/USER-MEAMC/meam_setup_param.c
@@ -0,0 +1,223 @@
+#include "meam.h"
+
+//
+//     do a sanity check on index parameters
+      void meam_checkindex(int num, int lim, int nidx, int *idx /*idx(3)*/, int *ierr)
+      {
+        //: idx[0..2]
+        *ierr = 0;
+        if (nidx < num) {
+           *ierr = 2;
+           return;
+        }
+
+        for (int i=0; i<num; i++) {
+          if ((idx[i] < 1) || (idx[i] > lim)) {
+              *ierr = 3;
+              return;
+          }
+        }
+      }
+
+//
+//     Declaration in pair_meam.h:
+//
+//     void meam_setup_param(int *, double *, int *, int *, int *);
+//
+//     in pair_meam.cpp
+//
+//     meam_setup_param(&which,&value,&nindex,index,&errorflag);
+//
+//
+//
+//     The "which" argument corresponds to the index of the "keyword" array
+//     in pair_meam.cpp:
+//
+//     0 = Ec_meam
+//     1 = alpha_meam
+//     2 = rho0_meam
+//     3 = delta_meam
+//     4 = lattce_meam
+//     5 = attrac_meam
+//     6 = repuls_meam
+//     7 = nn2_meam
+//     8 = Cmin_meam
+//     9 = Cmax_meam
+//     10 = rc_meam
+//     11 = delr_meam
+//     12 = augt1
+//     13 = gsmooth_factor
+//     14 = re_meam
+//     15 = ialloy
+//     16 = mixture_ref_t
+//     17 = erose_form
+//     18 = zbl_meam
+//     19 = emb_lin_neg
+//     20 = bkgd_dyn
+
+      void meam_setup_param_(int *which_p, double *value_p, int *nindex_p, int *index /*index(3)*/, int *errorflag)
+      {
+        //: index[0..2]
+        int i1, i2;
+        *errorflag = 0;
+        int which = *which_p;
+        double value = *value_p;
+        int nindex = *nindex_p;
+
+      switch(which) {
+  //     0 = Ec_meam
+        case 0:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.Ec_meam[index[0]][index[1]] = value;
+          break;
+
+  //     1 = alpha_meam
+        case 1:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.alpha_meam[index[0]][index[1]] = value;
+          break;
+
+  //     2 = rho0_meam
+        case 2:
+          meam_checkindex(1,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.rho0_meam[index[0]] = value;
+          break;
+
+  //     3 = delta_meam
+        case 3:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.delta_meam[index[0]][index[1]] = value;
+          break;
+
+  //     4 = lattce_meam
+        case 4:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          int val = (int)value;
+
+          if (val==0)
+            meam_data.lattce_meam[index[0]][index[1]] = FCC;
+          else if (val==1)
+            meam_data.lattce_meam[index[0]][index[1]] = BCC;
+          else if (val==2)
+            meam_data.lattce_meam[index[0]][index[1]] = HCP;
+          else if (val==3)
+            meam_data.lattce_meam[index[0]][index[1]] = DIM;
+          else if (val==4)
+            meam_data.lattce_meam[index[0]][index[1]] = DIA;
+          else if (val==5)
+            meam_data.lattce_meam[index[0]][index[1]] = B1;
+          else if (val==6)
+            meam_data.lattce_meam[index[0]][index[1]] = C11;
+          else if (val==7)
+            meam_data.lattce_meam[index[0]][index[1]] = L12;
+          else if (val==8)
+            meam_data.lattce_meam[index[0]][index[1]] = B2;
+          break;
+
+  //     5 = attrac_meam
+        case 5:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.attrac_meam[index[0]][index[1]] = value;
+          break;
+
+  //     6 = repuls_meam
+        case 6:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.repuls_meam[index[0]][index[1]] = value;
+          break;
+
+  //     7 = nn2_meam
+        case 7:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          i1 = min(index[0],index[1]);
+          i2 = max(index[0],index[1]);
+          meam_data.nn2_meam[i1][i2] = (int)value;
+          break;
+
+  //     8 = Cmin_meam
+        case 8:
+          meam_checkindex(3,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.Cmin_meam[index[0]][index[1]][index[2]] = value;
+          break;
+
+  //     9 = Cmax_meam
+        case 9:
+          meam_checkindex(3,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.Cmax_meam[index[0]][index[1]][index[2]] = value;
+          break;
+
+  //     10 = rc_meam
+        case 10:
+          meam_data.rc_meam = value;
+          break;
+
+  //     11 = delr_meam
+        case 11:
+          meam_data.delr_meam = value;
+          break;
+
+  //     12 = augt1
+        case 12:
+          meam_data.augt1 = (int)value;
+          break;
+
+  //     13 = gsmooth
+        case 13:
+          meam_data.gsmooth_factor = value;
+          break;
+
+  //     14 = re_meam
+        case 14:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          meam_data.re_meam[index[0]][index[1]] = value;
+          break;
+
+  //     15 = ialloy
+        case 15:
+          meam_data.ialloy = (int)value;
+          break;
+
+  //     16 = mixture_ref_t
+        case 16:
+          meam_data.mix_ref_t = (int)value;
+          break;
+
+  //     17 = erose_form
+        case 17:
+          meam_data.erose_form = (int)value;
+          break;
+
+  //     18 = zbl_meam
+        case 18:
+          meam_checkindex(2,maxelt,nindex,index,errorflag);
+          if (*errorflag!=0) return;
+          i1 = min(index[0],index[1]);
+          i2 = max(index[0],index[1]);
+          meam_data.zbl_meam[i1][i2] = (int)value;
+          break;
+
+  //     19 = emb_lin_neg
+        case 19:
+          meam_data.emb_lin_neg = (int)value;
+          break;
+
+  //     20 = bkgd_dyn
+        case 20:
+          meam_data.bkgd_dyn = (int)value;
+          break;
+
+        default:
+          *errorflag = 1;
+      }
+    }
diff --git a/src/USER-MEAMC/pair_meamc.cpp b/src/USER-MEAMC/pair_meamc.cpp
new file mode 100644
index 0000000000..f2c7da9239
--- /dev/null
+++ b/src/USER-MEAMC/pair_meamc.cpp
@@ -0,0 +1,945 @@
+/* ----------------------------------------------------------------------
+   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: Greg Wagner (SNL)
+------------------------------------------------------------------------- */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pair_meamc.h"
+#include "atom.h"
+#include "force.h"
+#include "comm.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 1024
+
+enum{FCC,BCC,HCP,DIM,DIAMOND,B1,C11,L12,B2};
+static const int nkeywords = 21;
+static const char *keywords[] = {
+  "Ec","alpha","rho0","delta","lattce",
+  "attrac","repuls","nn2","Cmin","Cmax","rc","delr",
+  "augt1","gsmooth_factor","re","ialloy",
+  "mixture_ref_t","erose_form","zbl",
+  "emb_lin_neg","bkgd_dyn"};
+
+/* ---------------------------------------------------------------------- */
+
+PairMEAMC::PairMEAMC(LAMMPS *lmp) : Pair(lmp)
+{
+  single_enable = 0;
+  restartinfo = 0;
+  one_coeff = 1;
+  manybody_flag = 1;
+
+  nmax = 0;
+  rho = rho0 = rho1 = rho2 = rho3 = frhop = NULL;
+  gamma = dgamma1 = dgamma2 = dgamma3 = arho2b = NULL;
+  arho1 = arho2 = arho3 = arho3b = t_ave = tsq_ave = NULL;
+
+  maxneigh = 0;
+  allocated = 0;
+  scrfcn = dscrfcn = fcpair = NULL;
+
+  nelements = 0;
+  elements = NULL;
+  mass = NULL;
+
+  // set comm size needed by this Pair
+
+  comm_forward = 38;
+  comm_reverse = 30;
+}
+
+/* ----------------------------------------------------------------------
+   free all arrays
+   check if allocated, since class can be destructed when incomplete
+------------------------------------------------------------------------- */
+
+PairMEAMC::~PairMEAMC()
+{
+  meam_cleanup_();
+
+  memory->destroy(rho);
+  memory->destroy(rho0);
+  memory->destroy(rho1);
+  memory->destroy(rho2);
+  memory->destroy(rho3);
+  memory->destroy(frhop);
+  memory->destroy(gamma);
+  memory->destroy(dgamma1);
+  memory->destroy(dgamma2);
+  memory->destroy(dgamma3);
+  memory->destroy(arho2b);
+
+  memory->destroy(arho1);
+  memory->destroy(arho2);
+  memory->destroy(arho3);
+  memory->destroy(arho3b);
+  memory->destroy(t_ave);
+  memory->destroy(tsq_ave);
+
+  memory->destroy(scrfcn);
+  memory->destroy(dscrfcn);
+  memory->destroy(fcpair);
+
+  for (int i = 0; i < nelements; i++) delete [] elements[i];
+  delete [] elements;
+  delete [] mass;
+
+  if (allocated) {
+    memory->destroy(setflag);
+    memory->destroy(cutsq);
+    delete [] map;
+    delete [] fmap;
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMEAMC::compute(int eflag, int vflag)
+{
+  int i,j,ii,n,inum_half,errorflag;
+  int *ilist_half,*numneigh_half,**firstneigh_half;
+  int *numneigh_full,**firstneigh_full;
+
+  if (eflag || vflag) ev_setup(eflag,vflag);
+  else evflag = vflag_fdotr = eflag_global = vflag_global =
+         eflag_atom = vflag_atom = 0;
+
+  // grow local arrays if necessary
+
+  if (atom->nmax > nmax) {
+    memory->destroy(rho);
+    memory->destroy(rho0);
+    memory->destroy(rho1);
+    memory->destroy(rho2);
+    memory->destroy(rho3);
+    memory->destroy(frhop);
+    memory->destroy(gamma);
+    memory->destroy(dgamma1);
+    memory->destroy(dgamma2);
+    memory->destroy(dgamma3);
+    memory->destroy(arho2b);
+    memory->destroy(arho1);
+    memory->destroy(arho2);
+    memory->destroy(arho3);
+    memory->destroy(arho3b);
+    memory->destroy(t_ave);
+    memory->destroy(tsq_ave);
+
+    nmax = atom->nmax;
+
+    memory->create(rho,nmax,"pair:rho");
+    memory->create(rho0,nmax,"pair:rho0");
+    memory->create(rho1,nmax,"pair:rho1");
+    memory->create(rho2,nmax,"pair:rho2");
+    memory->create(rho3,nmax,"pair:rho3");
+    memory->create(frhop,nmax,"pair:frhop");
+    memory->create(gamma,nmax,"pair:gamma");
+    memory->create(dgamma1,nmax,"pair:dgamma1");
+    memory->create(dgamma2,nmax,"pair:dgamma2");
+    memory->create(dgamma3,nmax,"pair:dgamma3");
+    memory->create(arho2b,nmax,"pair:arho2b");
+    memory->create(arho1,nmax,3,"pair:arho1");
+    memory->create(arho2,nmax,6,"pair:arho2");
+    memory->create(arho3,nmax,10,"pair:arho3");
+    memory->create(arho3b,nmax,3,"pair:arho3b");
+    memory->create(t_ave,nmax,3,"pair:t_ave");
+    memory->create(tsq_ave,nmax,3,"pair:tsq_ave");
+  }
+
+  // neighbor list info
+
+  inum_half = listhalf->inum;
+  ilist_half = listhalf->ilist;
+  numneigh_half = listhalf->numneigh;
+  firstneigh_half = listhalf->firstneigh;
+  numneigh_full = listfull->numneigh;
+  firstneigh_full = listfull->firstneigh;
+
+  // strip neighbor lists of any special bond flags before using with MEAM
+  // necessary before doing neigh_f2c and neigh_c2f conversions each step
+
+  if (neighbor->ago == 0) {
+    neigh_strip(inum_half,ilist_half,numneigh_half,firstneigh_half);
+    neigh_strip(inum_half,ilist_half,numneigh_full,firstneigh_full);
+  }
+
+  // check size of scrfcn based on half neighbor list
+
+  int nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
+
+  n = 0;
+  for (ii = 0; ii < inum_half; ii++) n += numneigh_half[ilist_half[ii]];
+
+  if (n > maxneigh) {
+    memory->destroy(scrfcn);
+    memory->destroy(dscrfcn);
+    memory->destroy(fcpair);
+    maxneigh = n;
+    memory->create(scrfcn,maxneigh,"pair:scrfcn");
+    memory->create(dscrfcn,maxneigh,"pair:dscrfcn");
+    memory->create(fcpair,maxneigh,"pair:fcpair");
+  }
+
+  // zero out local arrays
+
+  for (i = 0; i < nall; i++) {
+    rho0[i] = 0.0;
+    arho2b[i] = 0.0;
+    arho1[i][0] = arho1[i][1] = arho1[i][2] = 0.0;
+    for (j = 0; j < 6; j++) arho2[i][j] = 0.0;
+    for (j = 0; j < 10; j++) arho3[i][j] = 0.0;
+    arho3b[i][0] = arho3b[i][1] = arho3b[i][2] = 0.0;
+    t_ave[i][0] = t_ave[i][1] = t_ave[i][2] = 0.0;
+    tsq_ave[i][0] = tsq_ave[i][1] = tsq_ave[i][2] = 0.0;
+  }
+
+  double **x = atom->x;
+  double **f = atom->f;
+  int *type = atom->type;
+  int ntype = atom->ntypes;
+
+  // change neighbor list indices to Fortran indexing
+
+  neigh_c2f(inum_half,ilist_half,numneigh_half,firstneigh_half);
+  neigh_c2f(inum_half,ilist_half,numneigh_full,firstneigh_full);
+
+  // 3 stages of MEAM calculation
+  // loop over my atoms followed by communication
+
+  int ifort;
+  int offset = 0;
+  errorflag = 0;
+
+  for (ii = 0; ii < inum_half; ii++) {
+    i = ilist_half[ii];
+    ifort = i+1;
+    meam_dens_init_(&ifort,&nmax,&ntype,type,fmap,&x[0][0],
+                    &numneigh_half[i],firstneigh_half[i],
+                    &numneigh_full[i],firstneigh_full[i],
+                    &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
+                    rho0,&arho1[0][0],&arho2[0][0],arho2b,
+                    &arho3[0][0],&arho3b[0][0],&t_ave[0][0],&tsq_ave[0][0],
+                    &errorflag);
+    if (errorflag) {
+      char str[128];
+      sprintf(str,"MEAM library error %d",errorflag);
+      error->one(FLERR,str);
+    }
+    offset += numneigh_half[i];
+  }
+
+  comm->reverse_comm_pair(this);
+
+  meam_dens_final_(&nlocal,&nmax,&eflag_either,&eflag_global,&eflag_atom,
+                   &eng_vdwl,eatom,&ntype,type,fmap,
+                   &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],
+                   &arho3b[0][0],&t_ave[0][0],&tsq_ave[0][0],gamma,dgamma1,
+                   dgamma2,dgamma3,rho,rho0,rho1,rho2,rho3,frhop,&errorflag);
+  if (errorflag) {
+    char str[128];
+    sprintf(str,"MEAM library error %d",errorflag);
+    error->one(FLERR,str);
+  }
+
+  comm->forward_comm_pair(this);
+
+  offset = 0;
+
+  // vptr is first value in vatom if it will be used by meam_force()
+  // else vatom may not exist, so pass dummy ptr
+
+  double *vptr;
+  if (vflag_atom) vptr = &vatom[0][0];
+  else vptr = &cutmax;
+
+  for (ii = 0; ii < inum_half; ii++) {
+    i = ilist_half[ii];
+    ifort = i+1;
+    meam_force_(&ifort,&nmax,&eflag_either,&eflag_global,&eflag_atom,
+                &vflag_atom,&eng_vdwl,eatom,&ntype,type,fmap,&x[0][0],
+                &numneigh_half[i],firstneigh_half[i],
+                &numneigh_full[i],firstneigh_full[i],
+                &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
+                dgamma1,dgamma2,dgamma3,rho0,rho1,rho2,rho3,frhop,
+                &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],&arho3b[0][0],
+                &t_ave[0][0],&tsq_ave[0][0],&f[0][0],vptr,&errorflag);
+    if (errorflag) {
+      char str[128];
+      sprintf(str,"MEAM library error %d",errorflag);
+      error->one(FLERR,str);
+    }
+    offset += numneigh_half[i];
+  }
+
+  // change neighbor list indices back to C indexing
+
+  neigh_f2c(inum_half,ilist_half,numneigh_half,firstneigh_half);
+  neigh_f2c(inum_half,ilist_half,numneigh_full,firstneigh_full);
+
+  if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMEAMC::allocate()
+{
+  allocated = 1;
+  int n = atom->ntypes;
+
+  memory->create(setflag,n+1,n+1,"pair:setflag");
+  memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+  map = new int[n+1];
+  fmap = new int[n];
+}
+
+/* ----------------------------------------------------------------------
+   global settings
+------------------------------------------------------------------------- */
+
+void PairMEAMC::settings(int narg, char **arg)
+{
+  if (narg != 0) error->all(FLERR,"Illegal pair_style command");
+}
+
+/* ----------------------------------------------------------------------
+   set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairMEAMC::coeff(int narg, char **arg)
+{
+  int i,j,m,n;
+
+  if (!allocated) allocate();
+
+  if (narg < 6) error->all(FLERR,"Incorrect args for pair coefficients");
+
+  // insure I,J args are * *
+
+  if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
+    error->all(FLERR,"Incorrect args for pair coefficients");
+
+  // read MEAM element names between 2 filenames
+  // nelements = # of MEAM elements
+  // elements = list of unique element names
+
+  if (nelements) {
+    for (i = 0; i < nelements; i++) delete [] elements[i];
+    delete [] elements;
+    delete [] mass;
+  }
+  nelements = narg - 4 - atom->ntypes;
+  if (nelements < 1) error->all(FLERR,"Incorrect args for pair coefficients");
+  elements = new char*[nelements];
+  mass = new double[nelements];
+
+  for (i = 0; i < nelements; i++) {
+    n = strlen(arg[i+3]) + 1;
+    elements[i] = new char[n];
+    strcpy(elements[i],arg[i+3]);
+  }
+
+  // read MEAM library and parameter files
+  // pass all parameters to MEAM package
+  // tell MEAM package that setup is done
+
+  read_files(arg[2],arg[2+nelements+1]);
+  meam_setup_done_(&cutmax);
+
+  // read args that map atom types to MEAM elements
+  // map[i] = which element the Ith atom type is, -1 if not mapped
+
+  for (i = 4 + nelements; i < narg; i++) {
+    m = i - (4+nelements) + 1;
+    for (j = 0; j < nelements; j++)
+      if (strcmp(arg[i],elements[j]) == 0) break;
+    if (j < nelements) map[m] = j;
+    else if (strcmp(arg[i],"NULL") == 0) map[m] = -1;
+    else error->all(FLERR,"Incorrect args for pair coefficients");
+  }
+
+  // clear setflag since coeff() called once with I,J = * *
+
+  n = atom->ntypes;
+  for (int i = 1; i <= n; i++)
+    for (int j = i; j <= n; j++)
+      setflag[i][j] = 0;
+
+  // set setflag i,j for type pairs where both are mapped to elements
+  // set mass for i,i in atom class
+
+  int count = 0;
+  for (int i = 1; i <= n; i++)
+    for (int j = i; j <= n; j++)
+      if (map[i] >= 0 && map[j] >= 0) {
+        setflag[i][j] = 1;
+        if (i == j) atom->set_mass(FLERR,i,mass[map[i]]);
+        count++;
+      }
+
+  if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+   init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairMEAMC::init_style()
+{
+  if (force->newton_pair == 0)
+    error->all(FLERR,"Pair style MEAM requires newton pair on");
+
+  // need full and half neighbor list
+
+  int irequest_full = neighbor->request(this,instance_me);
+  neighbor->requests[irequest_full]->id = 1;
+  neighbor->requests[irequest_full]->half = 0;
+  neighbor->requests[irequest_full]->full = 1;
+  int irequest_half = neighbor->request(this,instance_me);
+  neighbor->requests[irequest_half]->id = 2;
+
+  // setup Fortran-style mapping array needed by MEAM package
+  // fmap is indexed from 1:ntypes by Fortran and stores a Fortran index
+  // if type I is not a MEAM atom, fmap stores a 0
+
+  for (int i = 1; i <= atom->ntypes; i++) fmap[i-1] = map[i] + 1;
+}
+
+/* ----------------------------------------------------------------------
+   neighbor callback to inform pair style of neighbor list to use
+   half or full
+------------------------------------------------------------------------- */
+
+void PairMEAMC::init_list(int id, NeighList *ptr)
+{
+  if (id == 1) listfull = ptr;
+  else if (id == 2) listhalf = ptr;
+}
+
+/* ----------------------------------------------------------------------
+   init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairMEAMC::init_one(int i, int j)
+{
+  return cutmax;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMEAMC::read_files(char *globalfile, char *userfile)
+{
+  // open global meamf file on proc 0
+
+  FILE *fp;
+  if (comm->me == 0) {
+    fp = force->open_potential(globalfile);
+    if (fp == NULL) {
+      char str[128];
+      sprintf(str,"Cannot open MEAM potential file %s",globalfile);
+      error->one(FLERR,str);
+    }
+  }
+
+  // allocate parameter arrays
+
+  int params_per_line = 19;
+
+  int *lat = new int[nelements];
+  int *ielement = new int[nelements];
+  int *ibar = new int[nelements];
+  double *z = new double[nelements];
+  double *atwt = new double[nelements];
+  double *alpha = new double[nelements];
+  double *b0 = new double[nelements];
+  double *b1 = new double[nelements];
+  double *b2 = new double[nelements];
+  double *b3 = new double[nelements];
+  double *alat = new double[nelements];
+  double *esub = new double[nelements];
+  double *asub = new double[nelements];
+  double *t0 = new double[nelements];
+  double *t1 = new double[nelements];
+  double *t2 = new double[nelements];
+  double *t3 = new double[nelements];
+  double *rozero = new double[nelements];
+
+  bool *found = new bool[nelements];
+  for (int i = 0; i < nelements; i++) found[i] = false;
+
+  // read each set of params from global MEAM file
+  // one set of params can span multiple lines
+  // store params if element name is in element list
+  // if element name appears multiple times, only store 1st entry
+
+  int i,n,nwords;
+  char **words = new char*[params_per_line+1];
+  char line[MAXLINE],*ptr;
+  int eof = 0;
+
+  int nset = 0;
+  while (1) {
+    if (comm->me == 0) {
+      ptr = fgets(line,MAXLINE,fp);
+      if (ptr == NULL) {
+        eof = 1;
+        fclose(fp);
+      } else n = strlen(line) + 1;
+    }
+    MPI_Bcast(&eof,1,MPI_INT,0,world);
+    if (eof) break;
+    MPI_Bcast(&n,1,MPI_INT,0,world);
+    MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+    // strip comment, skip line if blank
+
+    if ((ptr = strchr(line,'#'))) *ptr = '\0';
+    nwords = atom->count_words(line);
+    if (nwords == 0) continue;
+
+    // concatenate additional lines until have params_per_line words
+
+    while (nwords < params_per_line) {
+      n = strlen(line);
+      if (comm->me == 0) {
+        ptr = fgets(&line[n],MAXLINE-n,fp);
+        if (ptr == NULL) {
+          eof = 1;
+          fclose(fp);
+        } else n = strlen(line) + 1;
+      }
+      MPI_Bcast(&eof,1,MPI_INT,0,world);
+      if (eof) break;
+      MPI_Bcast(&n,1,MPI_INT,0,world);
+      MPI_Bcast(line,n,MPI_CHAR,0,world);
+      if ((ptr = strchr(line,'#'))) *ptr = '\0';
+      nwords = atom->count_words(line);
+    }
+
+    if (nwords != params_per_line)
+      error->all(FLERR,"Incorrect format in MEAM potential file");
+
+    // words = ptrs to all words in line
+    // strip single and double quotes from words
+
+    nwords = 0;
+    words[nwords++] = strtok(line,"' \t\n\r\f");
+    while ((words[nwords++] = strtok(NULL,"' \t\n\r\f"))) continue;
+
+    // skip if element name isn't in element list
+
+    for (i = 0; i < nelements; i++)
+      if (strcmp(words[0],elements[i]) == 0) break;
+    if (i >= nelements) continue;
+
+    // skip if element already appeared
+
+    if (found[i] == true) continue;
+    found[i] = true;
+
+    // map lat string to an integer
+
+    if (strcmp(words[1],"fcc") == 0) lat[i] = FCC;
+    else if (strcmp(words[1],"bcc") == 0) lat[i] = BCC;
+    else if (strcmp(words[1],"hcp") == 0) lat[i] = HCP;
+    else if (strcmp(words[1],"dim") == 0) lat[i] = DIM;
+    else if (strcmp(words[1],"dia") == 0) lat[i] = DIAMOND;
+    else error->all(FLERR,"Unrecognized lattice type in MEAM file 1");
+
+    // store parameters
+
+    z[i] = atof(words[2]);
+    ielement[i] = atoi(words[3]);
+    atwt[i] = atof(words[4]);
+    alpha[i] = atof(words[5]);
+    b0[i] = atof(words[6]);
+    b1[i] = atof(words[7]);
+    b2[i] = atof(words[8]);
+    b3[i] = atof(words[9]);
+    alat[i] = atof(words[10]);
+    esub[i] = atof(words[11]);
+    asub[i] = atof(words[12]);
+    t0[i] = atof(words[13]);
+    t1[i] = atof(words[14]);
+    t2[i] = atof(words[15]);
+    t3[i] = atof(words[16]);
+    rozero[i] = atof(words[17]);
+    ibar[i] = atoi(words[18]);
+
+    nset++;
+  }
+
+  // error if didn't find all elements in file
+
+  if (nset != nelements)
+    error->all(FLERR,"Did not find all elements in MEAM library file");
+
+  // pass element parameters to MEAM package
+
+  meam_setup_global_(&nelements,lat,z,ielement,atwt,alpha,b0,b1,b2,b3,
+                       alat,esub,asub,t0,t1,t2,t3,rozero,ibar);
+
+  // set element masses
+
+  for (i = 0; i < nelements; i++) mass[i] = atwt[i];
+
+  // clean-up memory
+
+  delete [] words;
+
+  delete [] lat;
+  delete [] ielement;
+  delete [] ibar;
+  delete [] z;
+  delete [] atwt;
+  delete [] alpha;
+  delete [] b0;
+  delete [] b1;
+  delete [] b2;
+  delete [] b3;
+  delete [] alat;
+  delete [] esub;
+  delete [] asub;
+  delete [] t0;
+  delete [] t1;
+  delete [] t2;
+  delete [] t3;
+  delete [] rozero;
+  delete [] found;
+
+  // done if user param file is NULL
+
+  if (strcmp(userfile,"NULL") == 0) return;
+
+  // open user param file on proc 0
+
+  if (comm->me == 0) {
+    fp = force->open_potential(userfile);
+    if (fp == NULL) {
+      char str[128];
+      sprintf(str,"Cannot open MEAM potential file %s",userfile);
+      error->one(FLERR,str);
+    }
+  }
+
+  // read settings
+  // pass them one at a time to MEAM package
+  // match strings to list of corresponding ints
+
+  int which;
+  double value;
+  int nindex,index[3];
+  int maxparams = 6;
+  char **params = new char*[maxparams];
+  int nparams;
+
+  eof = 0;
+  while (1) {
+    if (comm->me == 0) {
+      ptr = fgets(line,MAXLINE,fp);
+      if (ptr == NULL) {
+        eof = 1;
+        fclose(fp);
+      } else n = strlen(line) + 1;
+    }
+    MPI_Bcast(&eof,1,MPI_INT,0,world);
+    if (eof) break;
+    MPI_Bcast(&n,1,MPI_INT,0,world);
+    MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+    // strip comment, skip line if blank
+
+    if ((ptr = strchr(line,'#'))) *ptr = '\0';
+    nparams = atom->count_words(line);
+    if (nparams == 0) continue;
+
+    // words = ptrs to all words in line
+
+    nparams = 0;
+    params[nparams++] = strtok(line,"=(), '\t\n\r\f");
+    while (nparams < maxparams &&
+           (params[nparams++] = strtok(NULL,"=(), '\t\n\r\f")))
+      continue;
+    nparams--;
+
+    for (which = 0; which < nkeywords; which++)
+      if (strcmp(params[0],keywords[which]) == 0) break;
+    if (which == nkeywords) {
+      char str[128];
+      sprintf(str,"Keyword %s in MEAM parameter file not recognized",
+              params[0]);
+      error->all(FLERR,str);
+    }
+    nindex = nparams - 2;
+    for (i = 0; i < nindex; i++) index[i] = atoi(params[i+1]);
+
+    // map lattce_meam value to an integer
+
+    if (which == 4) {
+      if (strcmp(params[nparams-1],"fcc") == 0) value = FCC;
+      else if (strcmp(params[nparams-1],"bcc") == 0) value = BCC;
+      else if (strcmp(params[nparams-1],"hcp") == 0) value = HCP;
+      else if (strcmp(params[nparams-1],"dim") == 0) value = DIM;
+      else if (strcmp(params[nparams-1],"dia") == 0) value = DIAMOND;
+      else if (strcmp(params[nparams-1],"b1")  == 0) value = B1;
+      else if (strcmp(params[nparams-1],"c11") == 0) value = C11;
+      else if (strcmp(params[nparams-1],"l12") == 0) value = L12;
+      else if (strcmp(params[nparams-1],"b2")  == 0) value = B2;
+      else error->all(FLERR,"Unrecognized lattice type in MEAM file 2");
+    }
+    else value = atof(params[nparams-1]);
+
+    // pass single setting to MEAM package
+
+    int errorflag = 0;
+    meam_setup_param_(&which,&value,&nindex,index,&errorflag);
+    if (errorflag) {
+      char str[128];
+      sprintf(str,"MEAM library error %d",errorflag);
+      error->all(FLERR,str);
+    }
+  }
+
+  delete [] params;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int PairMEAMC::pack_forward_comm(int n, int *list, double *buf,
+                                int pbc_flag, int *pbc)
+{
+  int i,j,k,m;
+
+  m = 0;
+  for (i = 0; i < n; i++) {
+    j = list[i];
+    buf[m++] = rho0[j];
+    buf[m++] = rho1[j];
+    buf[m++] = rho2[j];
+    buf[m++] = rho3[j];
+    buf[m++] = frhop[j];
+    buf[m++] = gamma[j];
+    buf[m++] = dgamma1[j];
+    buf[m++] = dgamma2[j];
+    buf[m++] = dgamma3[j];
+    buf[m++] = arho2b[j];
+    buf[m++] = arho1[j][0];
+    buf[m++] = arho1[j][1];
+    buf[m++] = arho1[j][2];
+    buf[m++] = arho2[j][0];
+    buf[m++] = arho2[j][1];
+    buf[m++] = arho2[j][2];
+    buf[m++] = arho2[j][3];
+    buf[m++] = arho2[j][4];
+    buf[m++] = arho2[j][5];
+    for (k = 0; k < 10; k++) buf[m++] = arho3[j][k];
+    buf[m++] = arho3b[j][0];
+    buf[m++] = arho3b[j][1];
+    buf[m++] = arho3b[j][2];
+    buf[m++] = t_ave[j][0];
+    buf[m++] = t_ave[j][1];
+    buf[m++] = t_ave[j][2];
+    buf[m++] = tsq_ave[j][0];
+    buf[m++] = tsq_ave[j][1];
+    buf[m++] = tsq_ave[j][2];
+  }
+
+  return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMEAMC::unpack_forward_comm(int n, int first, double *buf)
+{
+  int i,k,m,last;
+
+  m = 0;
+  last = first + n;
+  for (i = first; i < last; i++) {
+    rho0[i] = buf[m++];
+    rho1[i] = buf[m++];
+    rho2[i] = buf[m++];
+    rho3[i] = buf[m++];
+    frhop[i] = buf[m++];
+    gamma[i] = buf[m++];
+    dgamma1[i] = buf[m++];
+    dgamma2[i] = buf[m++];
+    dgamma3[i] = buf[m++];
+    arho2b[i] = buf[m++];
+    arho1[i][0] = buf[m++];
+    arho1[i][1] = buf[m++];
+    arho1[i][2] = buf[m++];
+    arho2[i][0] = buf[m++];
+    arho2[i][1] = buf[m++];
+    arho2[i][2] = buf[m++];
+    arho2[i][3] = buf[m++];
+    arho2[i][4] = buf[m++];
+    arho2[i][5] = buf[m++];
+    for (k = 0; k < 10; k++) arho3[i][k] = buf[m++];
+    arho3b[i][0] = buf[m++];
+    arho3b[i][1] = buf[m++];
+    arho3b[i][2] = buf[m++];
+    t_ave[i][0] = buf[m++];
+    t_ave[i][1] = buf[m++];
+    t_ave[i][2] = buf[m++];
+    tsq_ave[i][0] = buf[m++];
+    tsq_ave[i][1] = buf[m++];
+    tsq_ave[i][2] = buf[m++];
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int PairMEAMC::pack_reverse_comm(int n, int first, double *buf)
+{
+  int i,k,m,last;
+
+  m = 0;
+  last = first + n;
+  for (i = first; i < last; i++) {
+    buf[m++] = rho0[i];
+    buf[m++] = arho2b[i];
+    buf[m++] = arho1[i][0];
+    buf[m++] = arho1[i][1];
+    buf[m++] = arho1[i][2];
+    buf[m++] = arho2[i][0];
+    buf[m++] = arho2[i][1];
+    buf[m++] = arho2[i][2];
+    buf[m++] = arho2[i][3];
+    buf[m++] = arho2[i][4];
+    buf[m++] = arho2[i][5];
+    for (k = 0; k < 10; k++) buf[m++] = arho3[i][k];
+    buf[m++] = arho3b[i][0];
+    buf[m++] = arho3b[i][1];
+    buf[m++] = arho3b[i][2];
+    buf[m++] = t_ave[i][0];
+    buf[m++] = t_ave[i][1];
+    buf[m++] = t_ave[i][2];
+    buf[m++] = tsq_ave[i][0];
+    buf[m++] = tsq_ave[i][1];
+    buf[m++] = tsq_ave[i][2];
+  }
+
+  return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMEAMC::unpack_reverse_comm(int n, int *list, double *buf)
+{
+  int i,j,k,m;
+
+  m = 0;
+  for (i = 0; i < n; i++) {
+    j = list[i];
+    rho0[j] += buf[m++];
+    arho2b[j] += buf[m++];
+    arho1[j][0] += buf[m++];
+    arho1[j][1] += buf[m++];
+    arho1[j][2] += buf[m++];
+    arho2[j][0] += buf[m++];
+    arho2[j][1] += buf[m++];
+    arho2[j][2] += buf[m++];
+    arho2[j][3] += buf[m++];
+    arho2[j][4] += buf[m++];
+    arho2[j][5] += buf[m++];
+    for (k = 0; k < 10; k++) arho3[j][k] += buf[m++];
+    arho3b[j][0] += buf[m++];
+    arho3b[j][1] += buf[m++];
+    arho3b[j][2] += buf[m++];
+    t_ave[j][0] += buf[m++];
+    t_ave[j][1] += buf[m++];
+    t_ave[j][2] += buf[m++];
+    tsq_ave[j][0] += buf[m++];
+    tsq_ave[j][1] += buf[m++];
+    tsq_ave[j][2] += buf[m++];
+  }
+}
+
+/* ----------------------------------------------------------------------
+   memory usage of local atom-based arrays
+------------------------------------------------------------------------- */
+
+double PairMEAMC::memory_usage()
+{
+  double bytes = 11 * nmax * sizeof(double);
+  bytes += (3 + 6 + 10 + 3 + 3 + 3) * nmax * sizeof(double);
+  bytes += 3 * maxneigh * sizeof(double);
+  return bytes;
+}
+
+/* ----------------------------------------------------------------------
+   strip special bond flags from neighbor list entries
+   are not used with MEAM
+   need to do here so Fortran lib doesn't see them
+   done once per reneighbor so that neigh_f2c and neigh_c2f don't see them
+------------------------------------------------------------------------- */
+
+void PairMEAMC::neigh_strip(int inum, int *ilist,
+                           int *numneigh, int **firstneigh)
+{
+  int i,j,ii,jnum;
+  int *jlist;
+
+  for (ii = 0; ii < inum; ii++) {
+    i = ilist[ii];
+    jlist = firstneigh[i];
+    jnum = numneigh[i];
+    for (j = 0; j < jnum; j++) jlist[j] &= NEIGHMASK;
+  }
+}
+
+/* ----------------------------------------------------------------------
+   toggle neighbor list indices between zero- and one-based values
+   needed for access by MEAM Fortran library
+------------------------------------------------------------------------- */
+
+void PairMEAMC::neigh_f2c(int inum, int *ilist, int *numneigh, int **firstneigh)
+{
+  int i,j,ii,jnum;
+  int *jlist;
+
+  for (ii = 0; ii < inum; ii++) {
+    i = ilist[ii];
+    jlist = firstneigh[i];
+    jnum = numneigh[i];
+    for (j = 0; j < jnum; j++) jlist[j]--;
+  }
+}
+
+void PairMEAMC::neigh_c2f(int inum, int *ilist, int *numneigh, int **firstneigh)
+{
+  int i,j,ii,jnum;
+  int *jlist;
+
+  for (ii = 0; ii < inum; ii++) {
+    i = ilist[ii];
+    jlist = firstneigh[i];
+    jnum = numneigh[i];
+    for (j = 0; j < jnum; j++) jlist[j]++;
+  }
+}
diff --git a/src/USER-MEAMC/pair_meamc.h b/src/USER-MEAMC/pair_meamc.h
new file mode 100644
index 0000000000..c4e03aef55
--- /dev/null
+++ b/src/USER-MEAMC/pair_meamc.h
@@ -0,0 +1,155 @@
+/* -*- 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 PAIR_CLASS
+
+PairStyle(meam/c,PairMEAMC)
+
+#else
+
+#ifndef LMP_PAIR_MEAMC_H
+#define LMP_PAIR_MEAMC_H
+
+extern "C" {
+  void meam_setup_global_(int *, int *, double *, int *, double *, double *,
+                         double *, double *, double *, double *, double *,
+                         double *, double *, double *, double *, double *,
+                         double *, double *, int *);
+  void meam_setup_param_(int *, double *, int *, int *, int *);
+  void meam_setup_done_(double *);
+
+  void meam_dens_init_(int *, int *, int *, int *, int *,
+                       double *, int *, int *, int *, int *,
+                       double *, double *, double *, double *,
+                       double *, double *,
+                       double *, double *, double *, double *, double *,
+                       int *);
+
+  void meam_dens_final_(int *, int *, int *, int *, int *, double *, double *,
+                        int *, int *, int *,
+                        double *, double *, double *, double *,
+                        double *, double *, double *,
+                        double *, double *, double *, double *,
+                        double *, double *,
+                        double *, double *, double *, double *, int *);
+
+  void meam_force_(int *, int *, int *, int *, int *, int *,
+                   double *, double *, int *, int *, int *,
+                   double *, int *, int *, int *, int *, double *, double *,
+                   double *, double *, double *, double *, double *, double *,
+                   double *, double *, double *, double *, double *, double *,
+                   double *, double *, double *, double *, double *, double *, int *);
+
+  void meam_cleanup_();
+}
+
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairMEAMC : public Pair {
+ public:
+  PairMEAMC(class LAMMPS *);
+  ~PairMEAMC();
+  void compute(int, int);
+  void settings(int, char **);
+  void coeff(int, char **);
+  void init_style();
+  void init_list(int, class NeighList *);
+  double init_one(int, int);
+
+  int pack_forward_comm(int, int *, double *, int, int *);
+  void unpack_forward_comm(int, int, double *);
+  int pack_reverse_comm(int, int, double *);
+  void unpack_reverse_comm(int, int *, double *);
+  double memory_usage();
+
+ private:
+  double cutmax;                // max cutoff for all elements
+  int nelements;                // # of unique elements
+  char **elements;              // names of unique elements
+  double *mass;                 // mass of each element
+
+  int *map;                     // mapping from atom types to elements
+  int *fmap;                    // Fortran version of map array for MEAM lib
+
+  int maxneigh;
+  double *scrfcn,*dscrfcn,*fcpair;
+
+  int nmax;
+  double *rho,*rho0,*rho1,*rho2,*rho3,*frhop;
+  double *gamma,*dgamma1,*dgamma2,*dgamma3,*arho2b;
+  double **arho1,**arho2,**arho3,**arho3b,**t_ave,**tsq_ave;
+
+  void allocate();
+  void read_files(char *, char *);
+  void neigh_strip(int, int *, int *, int **);
+  void neigh_f2c(int, int *, int *, int **);
+  void neigh_c2f(int, int *, int *, int **);
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+E: MEAM library error %d
+
+A call to the MEAM Fortran library returned an error.
+
+E: Illegal ... command
+
+Self-explanatory.  Check the input script syntax and compare to the
+documentation for the command.  You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Incorrect args for pair coefficients
+
+Self-explanatory.  Check the input script or data file.
+
+E: Pair style MEAM requires newton pair on
+
+See the newton command.  This is a restriction to use the MEAM
+potential.
+
+E: Cannot open MEAM potential file %s
+
+The specified MEAM potential file cannot be opened.  Check that the
+path and name are correct.
+
+E: Incorrect format in MEAM potential file
+
+Incorrect number of words per line in the potential file.
+
+E: Unrecognized lattice type in MEAM file 1
+
+The lattice type in an entry of the MEAM library file is not
+valid.
+
+E: Did not find all elements in MEAM library file
+
+The requested elements were not found in the MEAM file.
+
+E: Keyword %s in MEAM parameter file not recognized
+
+Self-explanatory.
+
+E: Unrecognized lattice type in MEAM file 2
+
+The lattice type in an entry of the MEAM parameter file is not
+valid.
+
+*/
-- 
GitLab