Unverified Commit 1be81096 authored by Axel Kohlmeyer's avatar Axel Kohlmeyer Committed by GitHub
Browse files

Merge pull request #1798 from martok/meamc-dec19

Collected MEAM/C additions
parents 402f5585 cb20cb9f
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -233,15 +233,20 @@ where
   Cmin(I,J,K) = Cmin screening parameter when I-J pair is screened
                 by K (I<=J); default = 2.0
   lattce(I,J) = lattice structure of I-J reference structure:
                   dia = diamond (interlaced fcc for alloy)
                   fcc = face centered cubic
                   bcc = body centered cubic
                   hcp = hexagonal close-packed
                   dim = dimer
                   dia = diamond (interlaced fcc for alloy)
                   dia3= diamond structure with primary 1NN and secondary 3NN interation
                   b1  = rock salt (NaCl structure)
                   hcp = hexagonal close-packed
                   c11 = MoSi2 structure
                   l12 = Cu3Au structure (lower case L, followed by 12)
                   b2  = CsCl structure (interpenetrating simple cubic)
                   ch4 = methane-like structure, only for binary system
                   lin = linear structure (180 degree angle)
                   zig = zigzag structure with a uniform angle
                   tri = H2O-like structure that has an angle
   nn2(I,J)    = turn on second-nearest neighbor MEAM formulation for
                 I-J pair (see for example :ref:`(Lee) <Lee>`).
                   0 = second-nearest neighbor formulation off
@@ -254,6 +259,8 @@ where
   zbl(I,J)    = blend the MEAM I-J pair potential with the ZBL potential for small
                 atom separations :ref:`(ZBL) <ZBL>`
                   default = 1
   theta(I,J)  = angle between three atoms in line, zigzag, and trimer reference structures in degrees
                   default = 180
   gsmooth_factor  = factor determining the length of the G-function smoothing
                     region; only significant for ibar=0 or ibar=4.
                         99.0 = short smoothing region, sharp step
+2 −0
Original line number Diff line number Diff line
@@ -139,6 +139,8 @@ potential parameters:

lat      = lattice structure of reference configuration
z        = number of nearest neighbors in the reference structure
             This field is only read for compatibility, the correct
             value is inferred from the lattice structure
ielement = atomic number
atwt     = atomic weight
alat     = lattice constant of reference structure
+59 −10
Original line number Diff line number Diff line
@@ -2,13 +2,15 @@
#define LMP_MEAM_H

#include <cmath>
#include <cstring>
#include "math_const.h"

#define maxelt 5

namespace LAMMPS_NS {
class Memory;

typedef enum { FCC, BCC, HCP, DIM, DIA, B1, C11, L12, B2 } lattice_t;
typedef enum { FCC, BCC, HCP, DIM, DIA, DIA3, B1, C11, L12, B2, CH4, LIN, ZIG, TRI } lattice_t;

class MEAM
{
@@ -26,9 +28,7 @@ private:

  // 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)
@@ -64,8 +64,11 @@ private:
  // nr,dr = pair function discretization parameters
  // nrar,rdrar = spline coeff array parameters

  // theta = angle between three atoms in line, zigzag, and trimer reference structures
  // stheta_meam = sin(theta/2) in radian used in line, zigzag, and trimer reference structures
  // ctheta_meam = cos(theta/2) in radian used in line, zigzag, and trimer reference structures

  double Ec_meam[maxelt][maxelt], re_meam[maxelt][maxelt];
  double Omega_meam[maxelt], Z_meam[maxelt];
  double A_meam[maxelt], alpha_meam[maxelt][maxelt], rho0_meam[maxelt];
  double delta_meam[maxelt][maxelt];
  double beta0_meam[maxelt], beta1_meam[maxelt];
@@ -108,6 +111,10 @@ public:
  int maxneigh;
  double *scrfcn, *dscrfcn, *fcpair;

  //angle for trimer, zigzag, line reference structures
  double stheta_meam[maxelt][maxelt];
  double ctheta_meam[maxelt][maxelt];

protected:
  // meam_funcs.cpp

@@ -191,9 +198,12 @@ protected:
  double embedding(const double A, const double Ec, const double rhobar, double& dF) const;
  static double erose(const double r, const double re, const double alpha, const double Ec, const double repuls, const double attrac, const int form);

  static void get_shpfcn(const lattice_t latt, double (&s)[3]);
  static int get_Zij(const lattice_t latt);
  static int get_Zij2(const lattice_t latt, const double cmin, const double cmax, double &a, double &S);
  static void get_shpfcn(const lattice_t latt, const double sthe, const double cthe, double (&s)[3]);

  static int get_Zij2(const lattice_t latt, const double cmin, const double cmax,
                      const double sthe, double &a, double &S);
  static int get_Zij2_b2nn(const lattice_t latt, const double cmin, const double cmax, double &S);

protected:
  void meam_checkindex(int, int, int, int*, int*);
  void getscreen(int i, double* scrfcn, double* dscrfcn, double* fcpair, double** x, int numneigh,
@@ -204,6 +214,7 @@ protected:
  void alloyparams();
  void compute_pair_meam();
  double phi_meam(double, int, int);
  const double phi_meam_series(const double scrn, const int Z1, const int Z2, const int a, const int b, const double r, const double arat);
  void compute_reference_density();
  void get_tavref(double*, double*, double*, double*, double*, double*, double, double, double, double,
                  double, double, double, int, int, lattice_t);
@@ -212,7 +223,41 @@ protected:
  void interpolate_meam(int);

public:
  void meam_setup_global(int nelt, lattice_t* lat, double* z, int* ielement, double* atwt, double* alpha,
  //-----------------------------------------------------------------------------
  // convert lattice spec to lattice_t
  // only use single-element lattices if single=true
  // return false on failure
  // return true and set lat on success
  static bool str_to_lat(const char* str, bool single, lattice_t& lat)
  {
    if (strcmp(str,"fcc") == 0) lat = FCC;
    else if (strcmp(str,"bcc") == 0) lat = BCC;
    else if (strcmp(str,"hcp") == 0) lat = HCP;
    else if (strcmp(str,"dim") == 0) lat = DIM;
    else if (strcmp(str,"dia") == 0) lat = DIA;
    else if (strcmp(str,"dia3") == 0) lat = DIA3;
    else if (strcmp(str,"lin") == 0) lat = LIN;
    else if (strcmp(str,"zig") == 0) lat = ZIG;
    else if (strcmp(str,"tri") == 0) lat = TRI;
    else {
      if (single)
        return false;

      if (strcmp(str,"b1")  == 0) lat = B1;
      else if (strcmp(str,"c11") == 0) lat = C11;
      else if (strcmp(str,"l12") == 0) lat = L12;
      else if (strcmp(str,"b2")  == 0) lat = B2;
      else if (strcmp(str,"ch4")  == 0) lat = CH4;
      else if (strcmp(str,"lin")  == 0) lat =LIN;
      else if (strcmp(str,"zig")  == 0) lat = ZIG;
      else if (strcmp(str,"tri")  == 0) lat = TRI;
      else return false;
    }
    return true;
  }

  static int get_Zij(const lattice_t latt);
  void meam_setup_global(int nelt, lattice_t* lat, 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);
@@ -222,9 +267,9 @@ public:
  void meam_dens_init(int i, int ntype, int* type, int* fmap, double** x, int numneigh, int* firstneigh,
                      int numneigh_full, int* firstneigh_full, int fnoffset);
  void meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_atom, double* eng_vdwl,
                       double* eatom, int ntype, int* type, int* fmap, int& errorflag);
                       double* eatom, int ntype, int* type, int* fmap, double** scale, int& errorflag);
  void meam_force(int i, 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,
                  double* eatom, int ntype, int* type, int* fmap, double** scale, double** x, int numneigh, int* firstneigh,
                  int numneigh_full, int* firstneigh_full, int fnoffset, double** f, double** vatom);
};

@@ -234,6 +279,10 @@ static inline bool iszero(const double f) {
  return fabs(f) < 1e-20;
}

static inline bool isone(const double f) {
  return fabs(f-1.0) < 1e-20;
}

// Helper functions

static inline double fdiv_zero(const double n, const double d) {
+8 −3
Original line number Diff line number Diff line
@@ -4,18 +4,20 @@ using namespace LAMMPS_NS;

void
MEAM::meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_atom, double* eng_vdwl,
                      double* eatom, int /*ntype*/, int* type, int* fmap, int& errorflag)
                      double* eatom, int /*ntype*/, int* type, int* fmap, double** scale, int& errorflag)
{
  int i, elti;
  int m;
  double rhob, G, dG, Gbar, dGbar, gam, shp[3], Z;
  double denom, rho_bkgd, Fl;
  double scaleii;

  //     Complete the calculation of density

  for (i = 0; i < nlocal; i++) {
    elti = fmap[type[i]];
    if (elti >= 0) {
      scaleii = scale[type[i]][type[i]];
      rho1[i] = 0.0;
      rho2[i] = -1.0 / 3.0 * arho2b[i] * arho2b[i];
      rho3[i] = 0.0;
@@ -52,12 +54,14 @@ MEAM::meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_
        gamma[i] = gamma[i] / (rho0[i] * rho0[i]);
      }

      Z = this->Z_meam[elti];
      Z = get_Zij(this->lattce_meam[elti][elti]);

      G = G_gam(gamma[i], this->ibar_meam[elti], errorflag);
      if (errorflag != 0)
        return;
      get_shpfcn(this->lattce_meam[elti][elti], shp);

      get_shpfcn(this->lattce_meam[elti][elti], this->stheta_meam[elti][elti], this->ctheta_meam[elti][elti], shp);

      if (this->ibar_meam[elti] <= 0) {
        Gbar = 1.0;
        dGbar = 0.0;
@@ -113,6 +117,7 @@ MEAM::meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_
      Fl = embedding(this->A_meam[elti], this->Ec_meam[elti][elti], rhob, frhop[i]);

      if (eflag_either != 0) {
        Fl *= scaleii;
        if (eflag_global != 0) {
          *eng_vdwl = *eng_vdwl + Fl;
        }
+1 −1
Original line number Diff line number Diff line
@@ -197,7 +197,7 @@ MEAM::getscreen(int i, double* scrfcn, double* dscrfcn, double* fcpair, double**
    //     Now compute derivatives
    dscrfcn[jn] = 0.0;
    sfcij = sij * fcij;
    if (!iszero(sfcij) && !iszero(sfcij - 1.0)) {
    if (!iszero(sfcij) && !isone(sfcij)) {
      for (kn = 0; kn < numneigh_full; kn++) {
        k = firstneigh_full[kn];
        if (k == j) continue;
Loading