add optmized verion of ilp_water_2dm

This commit is contained in:
oywg11
2023-05-18 21:58:40 +08:00
parent 81a497adcd
commit cc30c4478d
4 changed files with 207 additions and 16 deletions

View File

@ -1,7 +1,7 @@
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
@ -23,24 +23,27 @@
#include "atom.h" #include "atom.h"
#include "citeme.h" #include "citeme.h"
#include "comm.h"
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
#include "interlayer_taper.h" #include "interlayer_taper.h"
#include "memory.h" #include "memory.h"
#include "neigh_list.h" #include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h" #include "neighbor.h"
#include "pointers.h"
#include <cmath> #include <cmath>
#include <utility> #include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace InterLayer; using namespace InterLayer;
static const char cite_ilp_cur[] = static const char cite_ilp_cur[] =
"ilp/graphene/hbn/opt potential: doi:10.1145/3458817.3476137\n" "ilp/graphene/hbn/opt potential doi:10.1145/3458817.3476137\n"
"@inproceedings{gao2021lmff\n" "@inproceedings{gao2021lmff\n"
" author = {Gao, Ping and Duan, Xiaohui and others},\n" " author = {Gao, Ping and Duan, Xiaohui and Others},\n"
" title = {{LMFF}: Efficient and Scalable Layered Materials Force Field on Heterogeneous " " title = {LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous "
"Many-Core Processors},\n" "Many-Core Processors},\n"
" year = {2021},\n" " year = {2021},\n"
" isbn = {9781450384421},\n" " isbn = {9781450384421},\n"
@ -50,14 +53,12 @@ static const char cite_ilp_cur[] =
" doi = {10.1145/3458817.3476137},\n" " doi = {10.1145/3458817.3476137},\n"
" booktitle = {Proceedings of the International Conference for High Performance Computing, " " booktitle = {Proceedings of the International Conference for High Performance Computing, "
"Networking, Storage and Analysis},\n" "Networking, Storage and Analysis},\n"
" pages = {42},\n" " articleno = {42},\n"
" numpages = {14},\n" " numpages = {14},\n"
" location = {St.~Louis, Missouri},\n" " location = {St. Louis, Missouri},\n"
" series = {SC'21},\n" " series = {SC'21},\n"
"}\n\n"; "}\n\n";
static bool check_vdw(tagint itag, tagint jtag, double *xi, double *xj);
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
PairILPGrapheneHBNOpt::PairILPGrapheneHBNOpt(LAMMPS *lmp) : PairILPGrapheneHBNOpt::PairILPGrapheneHBNOpt(LAMMPS *lmp) :
@ -168,6 +169,36 @@ void PairILPGrapheneHBNOpt::compute(int eflag, int vflag)
} }
} }
} }
} else if (variant == ILP_WATER_2DM) {
if (eflag_global || eflag_atom) {
if (vflag_either) {
if (tap_flag) {
eval<6, 1, 1, 1, ILP_WATER_2DM>();
} else {
eval<6, 1, 1, 0, ILP_WATER_2DM>();
}
} else {
if (tap_flag) {
eval<6, 1, 0, 1, ILP_WATER_2DM>();
} else {
eval<6, 1, 0, 0, ILP_WATER_2DM>();
}
}
} else {
if (vflag_either) {
if (tap_flag) {
eval<6, 0, 1, 1, ILP_WATER_2DM>();
} else {
eval<6, 0, 1, 0, ILP_WATER_2DM>();
}
} else {
if (tap_flag) {
eval<6, 0, 0, 1, ILP_WATER_2DM>();
} else {
eval<6, 0, 0, 0, ILP_WATER_2DM>();
}
}
}
} else if (variant == SAIP_METAL) { } else if (variant == SAIP_METAL) {
if (eflag_global || eflag_atom) { if (eflag_global || eflag_atom) {
if (vflag_either) { if (vflag_either) {
@ -255,7 +286,7 @@ void PairILPGrapheneHBNOpt::eval()
rsq = delx * delx + dely * dely + delz * delz; rsq = delx * delx + dely * dely + delz * delz;
if (rsq != 0 && rsq < cutILPsq[itype_map][jtype]) { if (rsq != 0 && rsq < cutILPsq[itype_map][jtype]) {
if (VARIANT == ILP_TMD && special_type[itype] && itype != type[j]) continue; if ((VARIANT == ILP_TMD || VARIANT == ILP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue;
if (ILP_nneigh >= MAX_NNEIGH) { if (ILP_nneigh >= MAX_NNEIGH) {
error->one(FLERR, "There are too many neighbors for calculating normals"); error->one(FLERR, "There are too many neighbors for calculating normals");
} }
@ -269,7 +300,8 @@ void PairILPGrapheneHBNOpt::eval()
dproddni[2] = 0.0; dproddni[2] = 0.0;
double norm[3], dnormdxi[3][3], dnormdxk[MAX_NNEIGH][3][3]; double norm[3], dnormdxi[3][3], dnormdxk[MAX_NNEIGH][3][3];
calc_normal<MAX_NNEIGH>(i, ILP_neigh, ILP_nneigh, norm, dnormdxi, dnormdxk);
calc_normal<MAX_NNEIGH>(i, itype, ILP_neigh, ILP_nneigh, norm, dnormdxi, dnormdxk);
for (jj = 0; jj < jnum_inter; jj++) { for (jj = 0; jj < jnum_inter; jj++) {
j = jlist_inter[jj]; j = jlist_inter[jj];
@ -298,7 +330,7 @@ void PairILPGrapheneHBNOpt::eval()
Tap = 1.0; Tap = 1.0;
dTap = 0.0; dTap = 0.0;
} }
if (VARIANT != SAIP_METAL || !special_type[itype]) { if (VARIANT != SAIP_METAL || special_type[itype] != SAIP_BNCH) {
// Calculate the transverse distance // Calculate the transverse distance
prodnorm1 = norm[0] * delx + norm[1] * dely + norm[2] * delz; prodnorm1 = norm[0] * delx + norm[1] * dely + norm[2] * delz;
rhosq1 = rsq - prodnorm1 * prodnorm1; // rho_ij rhosq1 = rsq - prodnorm1 * prodnorm1; // rho_ij
@ -310,7 +342,7 @@ void PairILPGrapheneHBNOpt::eval()
frho1 = exp1 * p.C; frho1 = exp1 * p.C;
Erep = 0.5 * p.epsilon + frho1; Erep = 0.5 * p.epsilon + frho1;
if (VARIANT == SAIP_METAL && special_type[jtype]) { Erep += 0.5 * p.epsilon + p.C; } if (VARIANT == SAIP_METAL && special_type[jtype] == SAIP_BNCH) { Erep += 0.5 * p.epsilon + p.C; }
Vilp = exp0 * Erep; Vilp = exp0 * Erep;
// derivatives // derivatives
@ -428,6 +460,19 @@ inline void deriv_normal(double dndr[3][3], double *del, double *n, double rnnor
dndr[1][2] = (del[1] * n[0] * n[1] + del[0] * (n[0] * n[0] + n[2] * n[2])) * rnnorm; dndr[1][2] = (del[1] * n[0] * n[1] + del[0] * (n[0] * n[0] + n[2] * n[2])) * rnnorm;
dndr[2][2] = (del[1] * n[0] * n[2] - del[0] * n[1] * n[2]) * rnnorm; dndr[2][2] = (del[1] * n[0] * n[2] - del[0] * n[1] * n[2]) * rnnorm;
} }
inline void deriv_hat(double dnhatdn[3][3], double *n, double rnnorm, double factor){
double cfactor = rnnorm * factor;
dnhatdn[0][0] = (n[1]*n[1]+n[2]*n[2])*cfactor;
dnhatdn[1][0] = -n[1]*n[0]*cfactor;
dnhatdn[2][0] = -n[2]*n[0]*cfactor;
dnhatdn[0][1] = -n[0]*n[1]*cfactor;
dnhatdn[1][1] = (n[0]*n[0]+n[2]*n[2])*cfactor;
dnhatdn[2][1] = -n[2]*n[1]*cfactor;
dnhatdn[0][2] = -n[0]*n[2]*cfactor;
dnhatdn[1][2] = -n[1]*n[2]*cfactor;
dnhatdn[2][2] = (n[0]*n[0]+n[1]*n[1])*cfactor;
}
inline double normalize_factor(double *n) inline double normalize_factor(double *n)
{ {
double nnorm = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); double nnorm = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
@ -441,7 +486,7 @@ inline double normalize_factor(double *n)
Yet another normal calculation method for simpiler code. Yet another normal calculation method for simpiler code.
*/ */
template <int MAX_NNEIGH> template <int MAX_NNEIGH>
void PairILPGrapheneHBNOpt::calc_normal(int i, int *ILP_neigh, int nneigh, double *n, void PairILPGrapheneHBNOpt::calc_normal(int i, int itype, int *ILP_neigh, int nneigh, double *n,
double (*dnormdri)[3], double (*dnormdrk)[3][3]) double (*dnormdri)[3], double (*dnormdrk)[3][3])
{ {
double **x = atom->x; double **x = atom->x;
@ -475,6 +520,32 @@ void PairILPGrapheneHBNOpt::calc_normal(int i, int *ILP_neigh, int nneigh, doubl
vet[jj][2] = x[j][2] - x[i][2]; vet[jj][2] = x[j][2] - x[i][2];
} }
//specialize for ILP_WATER_2DM for hydrogen has special normal vector rule
if (variant == ILP_WATER_2DM && special_type[itype] == WATER) {
if (nneigh == 1){
n[0] = vet[0][0];
n[1] = vet[0][1];
n[2] = vet[0][2];
double rnnorm = normalize_factor(n);
deriv_hat(dnormdri, n, rnnorm, -1.0);
deriv_hat(dnormdrk[0], n, rnnorm, 1.0);
} else if (nneigh == 2){
n[0] = (vet[0][0] + vet[1][0])*0.5;
n[1] = (vet[0][1] + vet[1][1])*0.5;
n[2] = (vet[0][2] + vet[1][2])*0.5;
double rnnorm = normalize_factor(n);
deriv_hat(dnormdri, n, rnnorm, -1.0);
deriv_hat(dnormdrk[0], n, rnnorm, 0.5);
deriv_hat(dnormdrk[1], n, rnnorm, 0.5);
} else {
error->one(FLERR, "malformed water");
}
return;
}
if (nneigh <= 1) { if (nneigh <= 1) {
n[0] = 0.0; n[0] = 0.0;
n[1] = 0.0; n[1] = 0.0;

View File

@ -1,7 +1,7 @@
/* -*- c++ -*- ---------------------------------------------------------- /* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
@ -35,7 +35,7 @@ class PairILPGrapheneHBNOpt : virtual public PairILPGrapheneHBN {
protected: protected:
void update_internal_list(); void update_internal_list();
template <int MAX_NNEIGH> template <int MAX_NNEIGH>
void calc_normal(int i, int *ILP_neigh, int nneigh, double *normal, double (*dnormdri)[3], void calc_normal(int i, int itype, int *ILP_neigh, int nneigh, double *normal, double (*dnormdri)[3],
double (*dnormdrk)[3][3]); double (*dnormdrk)[3][3]);
template <int MAX_NNEIGH, int EFLAG, int VFLAG_EITHER, int TAP_FLAG, int VARIANT = ILP_GrhBN> template <int MAX_NNEIGH, int EFLAG, int VFLAG_EITHER, int TAP_FLAG, int VARIANT = ILP_GrhBN>
void eval(); void eval();
@ -44,6 +44,14 @@ class PairILPGrapheneHBNOpt : virtual public PairILPGrapheneHBN {
int *special_type; int *special_type;
int *num_intra, *num_inter, *num_vdw; int *num_intra, *num_inter, *num_vdw;
int inum_max, jnum_max; int inum_max, jnum_max;
enum special_type_const {
NOT_SPECIAL = 0,
TMD_METAL,
SAIP_BNCH,
WATER,
};
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -0,0 +1,73 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
This is an optimized version of ilp/water/2dm based on the contribution of:
author: Wengen Ouyang (Wuhan University)
e-mail: w.g.ouyang at gmail dot com
Optimizations are done by:
author1: Xiaohui Duan (National Supercomputing Center in Wuxi, China)
e-mail: sunrise_duan at 126 dot com
author2: Ping Gao (National Supercomputing Center in Wuxi, China)
e-mail: qdgaoping at gmail dot com
Optimizations are described in:
Gao, Ping and Duan, Xiaohui, et al:
LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors
DOI: 10.1145/3458817.3476137
Potential is described by:
[Feng and Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023).]
*/
#include "pair_ilp_water_2dm_opt.h"
#include "atom.h"
#include "citeme.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "interlayer_taper.h"
#include "memory.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace InterLayer;
PairILPWATER2DMOpt::PairILPWATER2DMOpt(LAMMPS *lmp) :
PairILPGrapheneHBN(lmp), PairILPTMD(lmp), PairILPWATER2DM(lmp), PairILPGrapheneHBNOpt(lmp)
{
}
void PairILPWATER2DMOpt::coeff(int narg, char **args)
{
PairILPTMD::coeff(narg, args);
memory->create(special_type, atom->ntypes + 1, "PairILPWATER2DMOpt:check_sublayer");
for (int i = 1; i <= atom->ntypes; i++) {
int itype = map[i];
if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 ||
strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0 ||
strcmp(elements[itype], "Te") == 0) {
special_type[i] = TMD_METAL;
} else if (strcmp(elements[itype], "Hw") == 0 || strcmp(elements[itype], "Ow") == 0) {
special_type[i] = WATER;
} else {
special_type[i] = NOT_SPECIAL;
}
}
}

View File

@ -0,0 +1,39 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, 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
// clang-format off
PairStyle(ilp/water/2dm/opt,PairILPWATER2DMOpt);
// clang-format on
#else
#ifndef LMP_PAIR_ILP_WATER_2DM_OPT_H
#define LMP_PAIR_ILP_WATER_2DM_OPT_H
#include "pair_ilp_graphene_hbn_opt.h"
#include "pair_ilp_water_2dm.h"
namespace LAMMPS_NS {
class PairILPWATER2DMOpt : public PairILPWATER2DM, public PairILPGrapheneHBNOpt {
public:
PairILPWATER2DMOpt(class LAMMPS *);
void coeff(int narg, char **args) override;
protected:
};
} // namespace LAMMPS_NS
#endif
#endif