Files
lammps/src/USER-MEAMC/meam.h
Sebastian Hütter bab292b551 Create package USER-MEAMC
Step 1: very literal translation of lib/meam
2017-06-11 11:29:23 +02:00

158 lines
5.8 KiB
C

#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)]