From 0679ad8b00ba35e2216ab1d63da9c0ce71765ac9 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Thu, 9 May 2019 16:18:29 +0100 Subject: [PATCH 001/443] Implemented file reading, no debug --- src/MESOCNT/pair_mesocnt.cpp | 256 +++++++++++++++++++++++++++++++++++ src/MESOCNT/pair_mesocnt.h | 69 ++++++++++ 2 files changed, 325 insertions(+) create mode 100644 src/MESOCNT/pair_mesocnt.cpp create mode 100644 src/MESOCNT/pair_mesocnt.h diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp new file mode 100644 index 0000000000..6736ae2f81 --- /dev/null +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -0,0 +1,256 @@ +#include +#include +#include +#include +#include "pair_mesocnt.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "update.h" +#include "integrate.h" +#include "respa.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define MAXLINE 1024 + +/* ---------------------------------------------------------------------- */ + +PairMesoCNT::PairMesoCNT(LAMMPS *lmp) : Pair(lmp) +{ + respa_enable = 0; + writedata = 1; + + +} + +/* ---------------------------------------------------------------------- */ + +PairMesoCNT::~PairMesoCNT() +{ + if (allocated) { + memory->destroy(gamma_data); + memory->destroy(u_inf_data); + memory->destroy(delh_u_semi); + memory->destroy(delzeta_phi); + + memory->destroy(u_semi_data); + memory->destroy(phi_data); + memory->destroy(gamma_coeff); + memory->destroy(u_inf_coeff); + + memory->destroy(u_semi_coeff); + memory->destroy(phi_coeff); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::compute(int eflag, int vflag) +{ + +} + +/* ---------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairMesoCNT::allocate() +{ + allocated = 1; + + memory->create(gamma_data,gamma_points,"pair:gamma_data"); + memory->create(u_inf_data,pot_points,"pair:u_inf_data"); + memory->create(delh_u_semi,pot_points,"pair:delh_u_semi"); + memory->create(delzeta_phi,pot_points,"pair:delzeta_phi"); + + memory->create(u_semi_data,pot_points,pot_points,"pair:u_semi_data"); + memory->create(phi_data,pot_points,pot_points,"pair:phi_data"); + memory->create(gamma_coeff,gamma_points-1,4,"pair:gamma_coeff"); + memory->create(u_inf_coeff,pot_points-1,4,"pair:u_inf_coeff"); + + memory->create(u_semi_coeff,pot_points,pot_points-1,4,"pair:u_semi_coeff"); + memory->create(phi_coeff,pot_points,pot_points-1,4,"pair:phi_coeff"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairMesoCNT::settings(int narg, char **arg) +{ + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); + + gamma_points = force->inumeric(FLERR,arg[0]); + pot_points = force->inumeric(FLERR,arg[1]); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairMesoCNT::coeff(int narg, char **arg) +{ + if (narg != 9) error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + sigma = force->numeric(FLERR,arg[2]); + epsilon = force->numeric(FLERR,arg[3]); + n_sigma = force->numeric(FLERR,arg[4]); + + gamma_file = arg[5]; + u_inf_file = arg[6]; + u_semi_file = arg[7]; + phi_file = arg[8]; + + //Parse and bcast data + int me; + MPI_Comm_rank(world,&me); + if (me == 0) { + read_file(gamma_file,gamma_data,&del_gamma,gamma_points); + read_file(u_inf_file,u_inf_data,&del_u_inf,pot_points); + read_file(u_semi_file,u_semi_data,delh_u_semi,&delxi_u_semi,pot_points); + read_file(phi_file,phi_data,delzeta_phi,delh_phi,pot_points); + } + + MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); + MPI_Bcast(u_inf_data,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(delh_u_semi,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(delzeta_phi,pot_points,MPI_DOUBLE,0,world); + for(int i = 0; i < pot_points; i++){ + MPI_Bcast(u_semi_data[i],pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(phi_data[i],pot_points,MPI_DOUBLE,0,world); + } + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::read_file(char *file, double *data, double *dx, int ninput) +{ + char line[MAXLINE]; + + // open file + + FILE *fp = force->open_potential(file); + if (fp == NULL) { + std::string str("Cannot open file "); + str += file; + error->one(FLERR,str.c_str()); + } + + // read values from file + + int cerror = 0; + int serror = 0; + double x,xtemp; + + utils::sfgets(FLERR,line,MAXLINE,fp,file,error); + for(int i = 0; i < ninput; i++){ + if(i > 0) xtemp = x; + if(NULL == fgets(line,MAXLINE,fp)) + error->one(FLERR,"Premature end of file in pair table"); + if(2 != sscanf(line,"%lg %lg",&x, &data[i])) ++cerror; + if(i > 0){ + if(i == 1) *dx = x - xtemp; + if(*dx != x - xtemp) ++serror; + } + } + + // warn if data was read incompletely, e.g. columns were missing + + if (cerror) { + char str[128]; + sprintf(str,"%d of %d lines in table were incomplete\n" + " or could not be parsed completely",cerror,ninput); + error->warning(FLERR,str); + } + + // warn if spacing between data points is not constant + + if (serror) { + char str[128]; + sprintf(str, "%d spacings were different\n" + " from first entry",serror); + error->warning(FLERR,str); + } + +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::read_file(char *file, double **data, + double *dx, double *dy, int ninput) +{ + char line[MAXLINE]; + + // open file + + FILE *fp = force->open_potential(file); + if (fp == NULL) { + std::string str("Cannot open file "); + str += file; + error->one(FLERR,str.c_str()); + } + + // read values from file + + int cerror = 0; + int sxerror = 0; + int syerror = 0; + double x,y,xtemp,ytemp; + + utils::sfgets(FLERR,line,MAXLINE,fp,file,error); + for(int i = 0; i < ninput; i++){ + if(i > 0) ytemp = y; + for(int j = 0; j < ninput; j++){ + if(j > 0) xtemp = x; + if(NULL == fgets(line,MAXLINE,fp)) + error->one(FLERR,"Premature end of file in pair table"); + if(3 != sscanf(line,"%lg %lg %lg",&x,&y,&data[j][i])) ++cerror; + if(j > 0){ + if(j == 1) dx[i] = x - xtemp; + if(dx[i] != x - xtemp) ++sxerror; + } + } + if(i > 0){ + if(i == 1) *dy = y - ytemp; + if(*dy != y - ytemp) ++syerror; + } + } + + // warn if data was read incompletely, e.g. columns were missing + + if (cerror) { + char str[128]; + sprintf(str,"%d of %d lines in table were incomplete\n" + " or could not be parsed completely",cerror,ninput); + error->warning(FLERR,str); + } + + // warn if spacing between data points is not constant + + if (sxerror) { + char str[128]; + sprintf(str, "%d spacings in first column were different\n" + " from first block entries",sxerror); + error->warning(FLERR,str); + } + + if (syerror) { + char str[128]; + sprintf(str, "%d spacings in second column were different\n" + " from first entry",syerror); + error->warning(FLERR,str); + } + +} diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h new file mode 100644 index 0000000000..39de5b8142 --- /dev/null +++ b/src/MESOCNT/pair_mesocnt.h @@ -0,0 +1,69 @@ +#ifdef PAIR_CLASS + +PairStyle(mesocnt, PairMesoCNT) + +#else + +#ifndef LMP_PAIR_MESOCNT_H +#define LMP_PAIR_MESOCNT_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairMesoCNT : public Pair { + public: + PairMesoCNT(class LAMMPS *); + ~PairMesoCNT(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + void write_data(FILE *); + void write_data_all(FILE *); + double single(int, int, int, int, double, double, double, double &); + void *extract(const char *, int &); + + protected: + int n, gamma_points, pot_points; + double sigma, epsilon, n_sigma, radius; + double del_gamma, del_u_inf, delxi_u_semi, delh_phi; + double *delh_u_semi, *delzeta_phi; + double *gamma_data, *u_inf_data; + double **u_semi_data, **phi_data; + double **gamma_coeff, **u_inf_coeff; + double ***u_semi_coeff, ***phi_coeff; + char *gamma_file, *u_inf_file, *u_semi_file, *phi_file; + + void allocate(); + + double eval_gamma(double); + double eval_u_inf(double); + double eval_u_semi(double, double); + double eval_u_semi(double, double); + double d_gamma(double); + double d_u_inf(double); + double dh_u_semi(double, double); + double dxi_u_semi(double, double); + double dh_u_semi(double, double); + double dzeta_u_semi(double, double); + + int heaviside(double); + int sgn(double); + + double distance(double, double, double, double, double, double, double); + double cutoff(double, double, double); + + void read_file(char *, double *); + void read_file(char *, double **); +} + +} +#endif +#endif From c4777054df205374bc7d5459aef893d471f7e4da Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Thu, 9 May 2019 20:03:09 +0100 Subject: [PATCH 002/443] Code compiles, 1d spline + derivative implemented --- src/MESOCNT/pair_mesocnt.cpp | 158 +++++++++++++++++++++++++++++++---- src/MESOCNT/pair_mesocnt.h | 45 +++++----- 2 files changed, 159 insertions(+), 44 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 6736ae2f81..c6c7e6634a 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -15,6 +15,7 @@ #include "math_const.h" #include "memory.h" #include "error.h" +#include "utils.h" using namespace LAMMPS_NS; using namespace MathConst; @@ -37,16 +38,16 @@ PairMesoCNT::~PairMesoCNT() { if (allocated) { memory->destroy(gamma_data); - memory->destroy(u_inf_data); - memory->destroy(delh_u_semi); + memory->destroy(uinf_data); + memory->destroy(delh_usemi); memory->destroy(delzeta_phi); - memory->destroy(u_semi_data); + memory->destroy(usemi_data); memory->destroy(phi_data); memory->destroy(gamma_coeff); - memory->destroy(u_inf_coeff); + memory->destroy(uinf_coeff); - memory->destroy(u_semi_coeff); + memory->destroy(usemi_coeff); memory->destroy(phi_coeff); } } @@ -71,16 +72,16 @@ void PairMesoCNT::allocate() allocated = 1; memory->create(gamma_data,gamma_points,"pair:gamma_data"); - memory->create(u_inf_data,pot_points,"pair:u_inf_data"); - memory->create(delh_u_semi,pot_points,"pair:delh_u_semi"); + memory->create(uinf_data,pot_points,"pair:uinf_data"); + memory->create(delh_usemi,pot_points,"pair:delh_usemi"); memory->create(delzeta_phi,pot_points,"pair:delzeta_phi"); - memory->create(u_semi_data,pot_points,pot_points,"pair:u_semi_data"); + memory->create(usemi_data,pot_points,pot_points,"pair:usemi_data"); memory->create(phi_data,pot_points,pot_points,"pair:phi_data"); memory->create(gamma_coeff,gamma_points-1,4,"pair:gamma_coeff"); - memory->create(u_inf_coeff,pot_points-1,4,"pair:u_inf_coeff"); + memory->create(uinf_coeff,pot_points-1,4,"pair:uinf_coeff"); - memory->create(u_semi_coeff,pot_points,pot_points-1,4,"pair:u_semi_coeff"); + memory->create(usemi_coeff,pot_points,pot_points-1,4,"pair:usemi_coeff"); memory->create(phi_coeff,pot_points,pot_points-1,4,"pair:phi_coeff"); } @@ -110,8 +111,8 @@ void PairMesoCNT::coeff(int narg, char **arg) n_sigma = force->numeric(FLERR,arg[4]); gamma_file = arg[5]; - u_inf_file = arg[6]; - u_semi_file = arg[7]; + uinf_file = arg[6]; + usemi_file = arg[7]; phi_file = arg[8]; //Parse and bcast data @@ -119,20 +120,137 @@ void PairMesoCNT::coeff(int narg, char **arg) MPI_Comm_rank(world,&me); if (me == 0) { read_file(gamma_file,gamma_data,&del_gamma,gamma_points); - read_file(u_inf_file,u_inf_data,&del_u_inf,pot_points); - read_file(u_semi_file,u_semi_data,delh_u_semi,&delxi_u_semi,pot_points); - read_file(phi_file,phi_data,delzeta_phi,delh_phi,pot_points); + read_file(uinf_file,uinf_data,&del_uinf,pot_points); + read_file(usemi_file,usemi_data,delh_usemi,&delxi_usemi,pot_points); + read_file(phi_file,phi_data,delzeta_phi,&delh_phi,pot_points); } MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); - MPI_Bcast(u_inf_data,pot_points,MPI_DOUBLE,0,world); - MPI_Bcast(delh_u_semi,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(uinf_data,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(delh_usemi,pot_points,MPI_DOUBLE,0,world); MPI_Bcast(delzeta_phi,pot_points,MPI_DOUBLE,0,world); for(int i = 0; i < pot_points; i++){ - MPI_Bcast(u_semi_data[i],pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(usemi_data[i],pot_points,MPI_DOUBLE,0,world); MPI_Bcast(phi_data[i],pot_points,MPI_DOUBLE,0,world); } + spline_coeff(gamma_data,gamma_coeff,gamma_points); + spline_coeff(uinf_data,uinf_coeff,pot_points); + spline_coeff(usemi_data,usemi_coeff,pot_points); + spline_coeff(phi_data,phi_coeff,pot_points); +} + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::spline(double x, double xstart, double dx, + double **coeff, int coeff_size) +{ + int i = floor((x - xstart)/dx); + if(i < 0){ + i = 0; + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval",cerror,ninput); + error->warning(FLERR,str); + } + else if(i > coeff_size-1){ + i = coeff_size-1; + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval",cerror,ninput); + error->warning(FLERR,str); + } + + double xlo = xstart + i*dx; + double xbar = (x - xlo)/dx; + + return coeff[i][0] + xbar*(coeff[i][1] + + xbar*(coeff[i][2] + xbar*coeff[i][3])); +} + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::dspline(double x, double xstart, double dx, + double **coeff, int coeff_size) +{ + int i = floor((x - xstart)/dx); + if(i < 0){ + i = 0; + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval",cerror,ninput); + error->warning(FLERR,str); + } + else if(i > coeff_size-1){ + i = coeff_size-1; + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval",cerror,ninput); + error->warning(FLERR,str); + } + + double xlo = xstart + i*dx; + double xbar = (x - xlo)/dx; + + return coeff[i][1] + xbar*(2*coeff[i][2] + 3*xbar*coeff[i][3]); +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::spline_coeff(double *data, double **coeff, int data_size) +{ + for(int i = 0; i < data_size-1; i++){ + if(i == 0){ + coeff[i][0] = data[i]; + coeff[i][1] = data[i+1] - data[i]; + coeff[i][3] = 0.5*(data[i+2] - 2*data[i+1] + data[i]); + coeff[i][2] = -coeff[i][3]; + } + else if(i == data_size-2){ + coeff[i][0] = data[i]; + coeff[i][1] = 0.5*(data[i+1] - data[i-1]); + coeff[i][3] = 0.5*(-data[i+1] + 2*data[i] - data[i-1]); + coeff[i][2] = -2*coeff[i][3]; + } + else{ + coeff[i][0] = data[i]; + coeff[i][1] = 0.5*(data[i+1] - data[i-1]); + coeff[i][2] = 0.5*(-data[i+2] + 4*data[i+1] - 5*data[i] + 2*data[i-1]); + coeff[i][3] = 0.5*(data[i+2] - 3*data[i+1] + 3*data[i] - data[i-1]); + } + } +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::spline_coeff(double **data, double ***coeff, int data_size) +{ + for(int i = 0; i < data_size; i++){ + for(int j = 0; j < data_size-1; j++){ + if(i == 0){ + coeff[i][j][0] = data[j][i]; + coeff[i][j][1] = data[j+1][i] - data[j][i]; + coeff[i][j][3] = 0.5*(data[j+2][i] - 2*data[j+1][i] + data[j][i]); + coeff[i][j][2] = -coeff[i][j][3]; + } + else if(i == data_size-2){ + coeff[i][j][0] = data[j][i]; + coeff[i][j][1] = 0.5*(data[j+1][i] - data[j-1][i]); + coeff[i][j][3] = 0.5*(-data[j+1][i] + 2*data[j][i] - data[j-1][i]); + coeff[i][j][2] = -2*coeff[i][j][3]; + } + else{ + coeff[i][j][0] = data[j][i]; + coeff[i][j][1] = 0.5*(data[j+1][i] - data[j-1][i]); + coeff[i][j][2] = 0.5*(-data[j+2][i] + 4*data[j+1][i] + - 5*data[j][i] + 2*data[j-1][i]); + coeff[i][j][3] = 0.5*(data[j+2][i] - 3*data[j+1][i] + + 3*data[j][i] - data[j-1][i]); + } + } + } +} + /* ---------------------------------------------------------------------- */ void PairMesoCNT::read_file(char *file, double *data, double *dx, int ninput) @@ -254,3 +372,7 @@ void PairMesoCNT::read_file(char *file, double **data, } } + +/* ---------------------------------------------------------------------- */ + + diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index 39de5b8142..13147c3e12 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -33,36 +33,29 @@ class PairMesoCNT : public Pair { protected: int n, gamma_points, pot_points; double sigma, epsilon, n_sigma, radius; - double del_gamma, del_u_inf, delxi_u_semi, delh_phi; - double *delh_u_semi, *delzeta_phi; - double *gamma_data, *u_inf_data; - double **u_semi_data, **phi_data; - double **gamma_coeff, **u_inf_coeff; - double ***u_semi_coeff, ***phi_coeff; - char *gamma_file, *u_inf_file, *u_semi_file, *phi_file; + double start_gamma, start_uinf, startxi_usemi, starth_phi; + double del_gamma, del_uinf, delxi_usemi, delh_phi; + double *delh_usemi, *delzeta_phi; + double *gamma_data, *uinf_data; + double **usemi_data, **phi_data; + double **gamma_coeff, **uinf_coeff; + double ***usemi_coeff, ***phi_coeff; + char *gamma_file, *uinf_file, *usemi_file, *phi_file; void allocate(); - double eval_gamma(double); - double eval_u_inf(double); - double eval_u_semi(double, double); - double eval_u_semi(double, double); - double d_gamma(double); - double d_u_inf(double); - double dh_u_semi(double, double); - double dxi_u_semi(double, double); - double dh_u_semi(double, double); - double dzeta_u_semi(double, double); + double spline(double, double, double, double **, int); + double spline(double, double, double *, double, double *, double ***, int); + double dspline(double, double, double, double **, int); + double dxspline(double, double, double *, double, double *, double ***, int); + double dyspline(double, double, double *, double, double *, double ***, int); - int heaviside(double); - int sgn(double); - - double distance(double, double, double, double, double, double, double); - double cutoff(double, double, double); - - void read_file(char *, double *); - void read_file(char *, double **); -} + void spline_coeff(double *, double **, int); + void spline_coeff(double **, double ***, int); + + void read_file(char *, double *, double *, int); + void read_file(char *, double **, double *, double *, int); +}; } #endif From b22ae0263feb77d9e9f4c7cc6b02ce7ab9e94e7a Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Fri, 10 May 2019 17:11:56 +0100 Subject: [PATCH 003/443] Geometry parameter calculation implemented --- src/MESOCNT/pair_mesocnt.cpp | 358 +++++++++++++++++++++++++++++++++-- src/MESOCNT/pair_mesocnt.h | 33 ++-- 2 files changed, 362 insertions(+), 29 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index c6c7e6634a..f406166fde 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -13,6 +13,7 @@ #include "integrate.h" #include "respa.h" #include "math_const.h" +#include "math_extra.h" #include "memory.h" #include "error.h" #include "utils.h" @@ -103,17 +104,22 @@ void PairMesoCNT::settings(int narg, char **arg) void PairMesoCNT::coeff(int narg, char **arg) { - if (narg != 9) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg != 10) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); - sigma = force->numeric(FLERR,arg[2]); - epsilon = force->numeric(FLERR,arg[3]); - n_sigma = force->numeric(FLERR,arg[4]); + n = force->inumeric(FLERR,arg[2]); + sigma = force->numeric(FLERR,arg[3]); + epsilon = force->numeric(FLERR,arg[4]); + n_sigma = force->numeric(FLERR,arg[5]); - gamma_file = arg[5]; - uinf_file = arg[6]; - usemi_file = arg[7]; - phi_file = arg[8]; + gamma_file = arg[6]; + uinf_file = arg[7]; + usemi_file = arg[8]; + phi_file = arg[9]; + + radius = 1.421*3*n / MY_2PI; + comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius)); + ctheta = 0.35 + 0.0226*(radius - 6.785); //Parse and bcast data int me; @@ -150,14 +156,14 @@ double PairMesoCNT::spline(double x, double xstart, double dx, i = 0; // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval",cerror,ninput); + sprintf(str,"Argument below spline interval"); error->warning(FLERR,str); } else if(i > coeff_size-1){ i = coeff_size-1; // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval",cerror,ninput); + sprintf(str,"Argument above spline interval"); error->warning(FLERR,str); } @@ -170,6 +176,66 @@ double PairMesoCNT::spline(double x, double xstart, double dx, /* ---------------------------------------------------------------------- */ +double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, + double *dx, double dy, double ***coeff, int coeff_size) +{ + int i = floor((y - ystart)/dy); + if(i < 0){ + i = 0; + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } + else if(i > coeff_size-1){ + i = coeff_size-1; + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + + double ylo = ystart + i*dy; + double ybar = (y - ylo)/dy; + + // compute coefficients in y + + double a0, a1, a2, a3; + double p0, p1, p2, p3; + + p1 = spline(x,xstart[0],dx[0],coeff[0],coeff_size); + p2 = spline(x,xstart[1],dx[1],coeff[1],coeff_size); + + a0 = p1; + + if(i == 0){ + p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + + a1 = p2 - p1; + a3 = 0.5*(p3 - 2*p2 + p1); + a2 = -a3; + } + else if(i == coeff_size-2){ + p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); + + a1 = 0.5*(p2 - p0); + a3 = 0.5*(p2 - 2*p1 + p0); + a2 = -2*a3; + } + else{ + p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); + p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + + a1 = 0.5*(p2 - p0); + a2 = 0.5*(-p3 + 4*p2 - 5*p1 + 2*p0); + a3 = 0.5*(p3 - 3*p2 + 3*p1 - p0); + } + + return a0 + ybar*(a1 + ybar*(a2 + a3*ybar)); +} + +/* ---------------------------------------------------------------------- */ + double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, int coeff_size) { @@ -178,21 +244,141 @@ double PairMesoCNT::dspline(double x, double xstart, double dx, i = 0; // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval",cerror,ninput); + sprintf(str,"Argument below spline interval"); error->warning(FLERR,str); } else if(i > coeff_size-1){ i = coeff_size-1; // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval",cerror,ninput); + sprintf(str,"Argument above spline interval"); error->warning(FLERR,str); } double xlo = xstart + i*dx; double xbar = (x - xlo)/dx; - return coeff[i][1] + xbar*(2*coeff[i][2] + 3*xbar*coeff[i][3]); + return (coeff[i][1] + xbar*(2*coeff[i][2] + 3*xbar*coeff[i][3])) / dx; +} + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::dxspline(double x, double y, double *xstart, double ystart, + double *dx, double dy, double ***coeff, int coeff_size) +{ + int i = floor((y - ystart)/dy); + if(i < 0){ + i = 0; + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } + else if(i > coeff_size-1){ + i = coeff_size-1; + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + + double ylo = ystart + i*dy; + double ybar = (y - ylo)/dy; + + // compute coefficients in y + + double a0, a1, a2, a3; + double p0, p1, p2, p3; + + p1 = dspline(x,xstart[0],dx[0],coeff[0],coeff_size); + p2 = dspline(x,xstart[1],dx[1],coeff[1],coeff_size); + + a0 = p1; + + if(i == 0){ + p3 = dspline(x,xstart[2],dx[2],coeff[2],coeff_size); + + a1 = p2 - p1; + a3 = 0.5*(p3 - 2*p2 + p1); + a2 = -a3; + } + else if(i == coeff_size-2){ + p0 = dspline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); + + a1 = 0.5*(p2 - p0); + a3 = 0.5*(p2 - 2*p1 + p0); + a2 = -2*a3; + } + else{ + p0 = dspline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); + p3 = dspline(x,xstart[2],dx[2],coeff[2],coeff_size); + + a1 = 0.5*(p2 - p0); + a2 = 0.5*(-p3 + 4*p2 - 5*p1 + 2*p0); + a3 = 0.5*(p3 - 3*p2 + 3*p1 - p0); + } + + return a0 + ybar*(a1 + ybar*(a2 + a3*ybar)); +} + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::dyspline(double x, double y, double *xstart, double ystart, + double *dx, double dy, double ***coeff, int coeff_size) +{ + int i = floor((y - ystart)/dy); + if(i < 0){ + i = 0; + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } + else if(i > coeff_size-1){ + i = coeff_size-1; + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + + double ylo = ystart + i*dy; + double ybar = (y - ylo)/dy; + + // compute coefficients in y + + double a0, a1, a2, a3; + double p0, p1, p2, p3; + + p1 = spline(x,xstart[0],dx[0],coeff[0],coeff_size); + p2 = spline(x,xstart[1],dx[1],coeff[1],coeff_size); + + a0 = p1; + + if(i == 0){ + p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + + a1 = p2 - p1; + a3 = 0.5*(p3 - 2*p2 + p1); + a2 = -a3; + } + else if(i == coeff_size-2){ + p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); + + a1 = 0.5*(p2 - p0); + a3 = 0.5*(p2 - 2*p1 + p0); + a2 = -2*a3; + } + else{ + p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); + p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + + a1 = 0.5*(p2 - p0); + a2 = 0.5*(-p3 + 4*p2 - 5*p1 + 2*p0); + a3 = 0.5*(p3 - 3*p2 + 3*p1 - p0); + } + + return (a1 + ybar*(2*a2 + 3*a3*ybar)) / dy; } /* ---------------------------------------------------------------------- */ @@ -375,4 +561,150 @@ void PairMesoCNT::read_file(char *file, double **data, /* ---------------------------------------------------------------------- */ +double PairMesoCNT::uinf(double h, double alpha, double xi1, double xi2) +{ + double salpha = sin(alpha); + double salphasq = salpha*salpha; + if(salphasq < 1.0e-6){ + return (xi2 - xi1) * spline(h,start_uinf,del_uinf,uinf_coeff,pot_points); + } + else{ + double omega = 1.0 / (1.0 - comega*salphasq); + double a = omega * salpha; + double zeta1 = xi1 * a; + double zeta2 = xi2 * a; + double phi1, phi2; + if(zeta1 < 0) phi1 = -spline(-zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + else phi1 = spline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + + if(zeta2 < 0) phi2 = -spline(-zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + else phi2 = spline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + + double gamma_orth = spline(h,start_gamma,del_gamma, + gamma_coeff,gamma_points); + double gamma = 1.0 + (gamma_orth - 1.0)*salphasq; + + return gamma * (phi2 - phi1) / a; + } +} + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::usemi(double h, double alpha, + double xi1, double xi2, double etaend) +{ + double salpha = sin(alpha); + double salphasq = salpha*salpha; + double calpha = cos(alpha); + double omega = 1.0 / (1.0 - comega*salphasq); + double theta = 1.0 - ctheta*salphasq; + + int points = 100; + double delxi = (xi2 - xi1) / (points -1); + + double g, hbar, etabar; + double sum = 0; + + // first and last term in sum + + g = xi1 * omega * salpha; + hbar = sqrt(h*h + g*g); + etabar = xi1 * calpha - theta*etaend; + sum += spline(hbar,etabar,starth_usemi,startxi_usemi, + delh_usemi,delxi_usemi,usemi_coeff,pot_points); + g = xi2 * omega * salpha; + hbar = sqrt(h*h + g*g); + etabar = xi2 * calpha - theta*etaend; + sum += spline(hbar,etabar,starth_usemi,startxi_usemi, + delh_usemi,delxi_usemi,usemi_coeff,pot_points); + sum *= 0.5; + + for(int i = 1; i < points-1; i++){ + double xibar = xi1 + i*delxi; + g * xibar * omega * salpha; + hbar = sqrt(h*h + g*g); + etabar = xibar*calpha - theta*etaend; + sum += spline(hbar,etabar,starth_usemi,startxi_usemi, + delh_usemi,delxi_usemi,usemi_coeff,pot_points); + } + + double gamma_orth = spline(h,start_gamma,del_gamma, + gamma_coeff,gamma_points); + double gamma = 1.0 + (gamma_orth - 1.0)*salphasq; + + return delxi * gamma * sum; +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::geom(const double *r1, const double *r2, + const double *p1, const double *p2, double *param) +{ + using namespace MathExtra; + double r[3], p[3], delr[3], l[3], m[3], rbar[3], pbar[3], delrbar[3]; + double psil[3], psim[3], dell_psim[3], delpsil_m[3]; + double delr1[3], delr2[3], delp1[3], delp2[3]; + double ex[3], ey[3]; + double psi, frac, taur, taup; + double h, alpha, xi1, xi2, eta1, eta2; + + add3(r1,r2,r); + scale3(0.5,r); + add3(p1,p2,p); + scale3(0.5,p); + + sub3(p,r,delr); + + sub3(r2,r1,l); + normalize3(l,l); + sub3(p2,p1,m); + normalize3(m,m); + + psi = dot3(l,m); + frac = 1.0 / (1.0 - psi*psi); + + copy3(l,psil); + scale3(psi,psil); + copy3(m,psim); + scale3(psi,psim); + + sub3(l,psim,dell_psim); + sub3(psil,m,delpsil_m); + taur = dot3(delr,dell_psim) * frac; + taup = dot3(delr,delpsil_m) * frac; + + scaleadd3(taur,l,r,rbar); + scaleadd3(taup,m,p,pbar); + sub3(pbar,rbar,delrbar); + + h = len3(delrbar); + + copy3(delrbar,ex); + scale3(1/h,ex); + cross3(l,ex,ey); + + if(dot3(m,ey) < 0) alpha = acos(psi); + else alpha = MY_2PI - acos(psi); + + sub3(r1,rbar,delr1); + sub3(r2,rbar,delr2); + xi1 = dot3(delr1,l); + xi2 = dot3(delr2,l); + + sub3(p1,pbar,delp1); + sub3(p2,pbar,delp2); + eta1 = dot3(delp1,m); + eta2 = dot3(delp2,m); + + param[0] = h; + param[1] = alpha; + param[2] = xi1; + param[3] = xi2; + param[4] = eta1; + param[5] = eta2; +} diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index 13147c3e12..72ce454bbc 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -18,23 +18,15 @@ class PairMesoCNT : public Pair { void compute(int, int); void settings(int, char **); void coeff(int, char **); - void init_style(); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); - void write_data(FILE *); - void write_data_all(FILE *); - double single(int, int, int, int, double, double, double, double &); - void *extract(const char *, int &); - + //void init_style(); + //double init_one(int, int); + protected: int n, gamma_points, pot_points; - double sigma, epsilon, n_sigma, radius; + double sigma, epsilon, n_sigma, radius, comega, ctheta; double start_gamma, start_uinf, startxi_usemi, starth_phi; double del_gamma, del_uinf, delxi_usemi, delh_phi; + double *starth_usemi, *startzeta_phi; double *delh_usemi, *delzeta_phi; double *gamma_data, *uinf_data; double **usemi_data, **phi_data; @@ -45,16 +37,25 @@ class PairMesoCNT : public Pair { void allocate(); double spline(double, double, double, double **, int); - double spline(double, double, double *, double, double *, double ***, int); + double spline(double, double, double *, double, double *, + double, double ***, int); double dspline(double, double, double, double **, int); - double dxspline(double, double, double *, double, double *, double ***, int); - double dyspline(double, double, double *, double, double *, double ***, int); + double dxspline(double, double, double *, double, double *, + double, double ***, int); + double dyspline(double, double, double *, double, double *, + double, double ***, int); void spline_coeff(double *, double **, int); void spline_coeff(double **, double ***, int); void read_file(char *, double *, double *, int); void read_file(char *, double **, double *, double *, int); + + double uinf(double, double, double, double); + double usemi(double, double, double, double, double); + + void geom(const double *, const double *, const double *, const double *, + double *); }; } From 9aa17ec81fff1dd82f481f63dcfc20db2ae2680c Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Fri, 10 May 2019 21:50:39 +0100 Subject: [PATCH 004/443] Added first part of forces --- src/MESOCNT/pair_mesocnt.cpp | 133 ++++++++++++++++++++++++++++------- src/MESOCNT/pair_mesocnt.h | 12 ++-- 2 files changed, 116 insertions(+), 29 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index f406166fde..144c3406c6 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -561,16 +561,21 @@ void PairMesoCNT::read_file(char *file, double **data, /* ---------------------------------------------------------------------- */ -double PairMesoCNT::uinf(double h, double alpha, double xi1, double xi2) +double PairMesoCNT::uinf(double *param) { - double salpha = sin(alpha); - double salphasq = salpha*salpha; - if(salphasq < 1.0e-6){ + double h = param[0]; + double alpha = param[1]; + double xi1 = param[2]; + double xi2 = param[3]; + + double sin_alpha = sin(alpha); + double sin_alphasq = sin_alpha*sin_alpha; + if(sin_alphasq < 1.0e-6){ return (xi2 - xi1) * spline(h,start_uinf,del_uinf,uinf_coeff,pot_points); } else{ - double omega = 1.0 / (1.0 - comega*salphasq); - double a = omega * salpha; + double omega = 1.0 / (1.0 - comega*sin_alphasq); + double a = omega * sin_alpha; double zeta1 = xi1 * a; double zeta2 = xi2 * a; @@ -587,7 +592,7 @@ double PairMesoCNT::uinf(double h, double alpha, double xi1, double xi2) double gamma_orth = spline(h,start_gamma,del_gamma, gamma_coeff,gamma_points); - double gamma = 1.0 + (gamma_orth - 1.0)*salphasq; + double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; return gamma * (phi2 - phi1) / a; } @@ -595,14 +600,19 @@ double PairMesoCNT::uinf(double h, double alpha, double xi1, double xi2) /* ---------------------------------------------------------------------- */ -double PairMesoCNT::usemi(double h, double alpha, - double xi1, double xi2, double etaend) +double PairMesoCNT::usemi(double *param) { - double salpha = sin(alpha); - double salphasq = salpha*salpha; - double calpha = cos(alpha); - double omega = 1.0 / (1.0 - comega*salphasq); - double theta = 1.0 - ctheta*salphasq; + double h = param[0]; + double alpha = param[1]; + double xi1 = param[2]; + double xi2 = param[3]; + double etaend = param[4]; + + double sin_alpha = sin(alpha); + double sin_alphasq = sin_alpha*sin_alpha; + double cos_alpha = cos(alpha); + double omega = 1.0 / (1.0 - comega*sin_alphasq); + double theta = 1.0 - ctheta*sin_alphasq; int points = 100; double delxi = (xi2 - xi1) / (points -1); @@ -612,47 +622,121 @@ double PairMesoCNT::usemi(double h, double alpha, // first and last term in sum - g = xi1 * omega * salpha; + g = xi1 * omega * sin_alpha; hbar = sqrt(h*h + g*g); - etabar = xi1 * calpha - theta*etaend; + etabar = xi1 * cos_alpha - theta*etaend; sum += spline(hbar,etabar,starth_usemi,startxi_usemi, delh_usemi,delxi_usemi,usemi_coeff,pot_points); - g = xi2 * omega * salpha; + g = xi2 * omega * sin_alpha; hbar = sqrt(h*h + g*g); - etabar = xi2 * calpha - theta*etaend; + etabar = xi2 * cos_alpha - theta*etaend; sum += spline(hbar,etabar,starth_usemi,startxi_usemi, delh_usemi,delxi_usemi,usemi_coeff,pot_points); sum *= 0.5; + // remaining sum + for(int i = 1; i < points-1; i++){ double xibar = xi1 + i*delxi; - g * xibar * omega * salpha; + g * xibar * omega * sin_alpha; hbar = sqrt(h*h + g*g); - etabar = xibar*calpha - theta*etaend; + etabar = xibar*cos_alpha - theta*etaend; sum += spline(hbar,etabar,starth_usemi,startxi_usemi, delh_usemi,delxi_usemi,usemi_coeff,pot_points); } double gamma_orth = spline(h,start_gamma,del_gamma, gamma_coeff,gamma_points); - double gamma = 1.0 + (gamma_orth - 1.0)*salphasq; + double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; return delxi * gamma * sum; } /* ---------------------------------------------------------------------- */ +void PairMesoCNT::finf(double *param, double **f) +{ + double h = param[0]; + double alpha = param[1]; + double xi1 = param[2]; + double xi2 = param[3]; + + double sin_alpha = sin(alpha); + double sin_alphasq = sin_alpha*sin_alpha; + double sin_alpharec = 1.0 / sin_alpha; + double sin_alpharecsq = sin_alpharec * sin_alpharec; + double cos_alpha = cos(alpha); + double cot_alpha = cos_alpha * sin_alpharec; + + double omega = 1.0 / (1.0 - comega*sin_alphasq); + double domega = 2 * comega * sin_alpha * cos_alpha * omega * omega; + double a1 = omega * sin_alpha; + double a1rec = 1.0 / a1; + + double gamma_orth = spline(h,start_gamma,del_gamma, + gamma_coeff,gamma_points); + double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; + double gammarec = 1.0 / gamma; + double dalpha_gamma = 2 * (gamma_orth - 1) * sin_alpha * cos_alpha; + double dh_gamma = dspline(h,start_gamma,del_gamma, + gamma_coeff,gamma_points) * sin_alphasq; + + + double zeta1 = xi1 * a1; + double zeta2 = xi2 * a1; + double phi1 = spline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double phi2 = spline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double dzeta_phi1 = dxspline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double dzeta_phi2 = dxspline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double diff_dzeta_phi = dzeta_phi2 - dzeta_phi1; + double dh_phi1 = dyspline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double dh_phi2 = dyspline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + + double a2 = gamma * a1rec; + double u = a2 * (phi2 - phi1); + double a3 = u * gammarec; + + double dh_u = dh_gamma * a3 + a2 * (dh_phi2 - dh_phi1); + double dalpha_u = dalpha_gamma * a3 + + a2 * (domega*sin_alpha + omega*cos_alpha) + * (gamma*(xi2*dzeta_phi2 - xi1*dzeta_phi1) - u); + + double lrec = 1.0 / (xi2 - xi1); + double cx = h * gamma * sin_alpharecsq * diff_dzeta_phi; + double cy = gamma * cot_alpha * diff_dzeta_phi; + + f[0][0] = lrec * (xi2*dh_u - cx); + f[1][0] = lrec * (-xi1*dh_u + cx); + f[0][1] = lrec * (dalpha_u - xi2*cy); + f[1][1] = lrec * (-dalpha_u + xi2*cy); + f[0][2] = gamma * dzeta_phi1; + f[1][2] = -gamma * dzeta_phi2; +} + +/* ---------------------------------------------------------------------- */ + void PairMesoCNT::geom(const double *r1, const double *r2, - const double *p1, const double *p2, double *param) + const double *p1, const double *p2, + double *param, double **basis) { using namespace MathExtra; double r[3], p[3], delr[3], l[3], m[3], rbar[3], pbar[3], delrbar[3]; double psil[3], psim[3], dell_psim[3], delpsil_m[3]; double delr1[3], delr2[3], delp1[3], delp2[3]; - double ex[3], ey[3]; + double *ex, *ey, *ez; double psi, frac, taur, taup; double h, alpha, xi1, xi2, eta1, eta2; + ex = basis[0]; + ey = basis[1]; + ez = basis[2]; + add3(r1,r2,r); scale3(0.5,r); add3(p1,p2,p); @@ -685,8 +769,9 @@ void PairMesoCNT::geom(const double *r1, const double *r2, h = len3(delrbar); copy3(delrbar,ex); + copy3(l,ez); scale3(1/h,ex); - cross3(l,ex,ey); + cross3(ez,ex,ey); if(dot3(m,ey) < 0) alpha = acos(psi); else alpha = MY_2PI - acos(psi); diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index 72ce454bbc..a10beb329d 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -18,8 +18,8 @@ class PairMesoCNT : public Pair { void compute(int, int); void settings(int, char **); void coeff(int, char **); - //void init_style(); - //double init_one(int, int); + void init_style(); + double init_one(int, int); protected: int n, gamma_points, pot_points; @@ -51,11 +51,13 @@ class PairMesoCNT : public Pair { void read_file(char *, double *, double *, int); void read_file(char *, double **, double *, double *, int); - double uinf(double, double, double, double); - double usemi(double, double, double, double, double); + double uinf(double *); + double usemi(double *); + void finf(double *, double **); + void fsemi(double *, double **); void geom(const double *, const double *, const double *, const double *, - double *); + double *, double **); }; } From 6538629584870cadfc4b67a8e49789c98565abfd Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Sat, 11 May 2019 13:08:17 +0100 Subject: [PATCH 005/443] Added forces, spline ranges for file reading --- src/MESOCNT/pair_mesocnt.cpp | 239 +++++++++++++++++++++++++---------- src/MESOCNT/pair_mesocnt.h | 9 +- 2 files changed, 179 insertions(+), 69 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 144c3406c6..4af1ca7784 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -22,6 +22,7 @@ using namespace LAMMPS_NS; using namespace MathConst; #define MAXLINE 1024 +#define SMALL 1.0e-6 /* ---------------------------------------------------------------------- */ @@ -125,10 +126,12 @@ void PairMesoCNT::coeff(int narg, char **arg) int me; MPI_Comm_rank(world,&me); if (me == 0) { - read_file(gamma_file,gamma_data,&del_gamma,gamma_points); - read_file(uinf_file,uinf_data,&del_uinf,pot_points); - read_file(usemi_file,usemi_data,delh_usemi,&delxi_usemi,pot_points); - read_file(phi_file,phi_data,delzeta_phi,&delh_phi,pot_points); + read_file(gamma_file,gamma_data,&start_gamma,&del_gamma,gamma_points); + read_file(uinf_file,uinf_data,&start_uinf,&del_uinf,pot_points); + read_file(usemi_file,usemi_data,starth_usemi,&startxi_usemi, + delh_usemi,&delxi_usemi,pot_points); + read_file(phi_file,phi_data,startzeta_phi,&starth_phi, + delzeta_phi,&delh_phi,pot_points); } MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); @@ -439,7 +442,8 @@ void PairMesoCNT::spline_coeff(double **data, double ***coeff, int data_size) /* ---------------------------------------------------------------------- */ -void PairMesoCNT::read_file(char *file, double *data, double *dx, int ninput) +void PairMesoCNT::read_file(char *file, double *data, + double *startx, double *dx, int ninput) { char line[MAXLINE]; @@ -464,6 +468,7 @@ void PairMesoCNT::read_file(char *file, double *data, double *dx, int ninput) if(NULL == fgets(line,MAXLINE,fp)) error->one(FLERR,"Premature end of file in pair table"); if(2 != sscanf(line,"%lg %lg",&x, &data[i])) ++cerror; + if(i == 0) *startx = x; if(i > 0){ if(i == 1) *dx = x - xtemp; if(*dx != x - xtemp) ++serror; @@ -493,7 +498,8 @@ void PairMesoCNT::read_file(char *file, double *data, double *dx, int ninput) /* ---------------------------------------------------------------------- */ void PairMesoCNT::read_file(char *file, double **data, - double *dx, double *dy, int ninput) + double *startx, double *starty, double *dx, double *dy, + int ninput) { char line[MAXLINE]; @@ -514,18 +520,20 @@ void PairMesoCNT::read_file(char *file, double **data, double x,y,xtemp,ytemp; utils::sfgets(FLERR,line,MAXLINE,fp,file,error); - for(int i = 0; i < ninput; i++){ + for(int i = 0; i < ninput; i++){ if(i > 0) ytemp = y; for(int j = 0; j < ninput; j++){ if(j > 0) xtemp = x; if(NULL == fgets(line,MAXLINE,fp)) error->one(FLERR,"Premature end of file in pair table"); if(3 != sscanf(line,"%lg %lg %lg",&x,&y,&data[j][i])) ++cerror; + if(j == 0) startx[i] = x; if(j > 0){ if(j == 1) dx[i] = x - xtemp; if(dx[i] != x - xtemp) ++sxerror; } } + if(i == 0) *starty = y; if(i > 0){ if(i == 1) *dy = y - ytemp; if(*dy != y - ytemp) ++syerror; @@ -570,7 +578,7 @@ double PairMesoCNT::uinf(double *param) double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; - if(sin_alphasq < 1.0e-6){ + if(sin_alphasq < SMALL){ return (xi2 - xi1) * spline(h,start_uinf,del_uinf,uinf_coeff,pot_points); } else{ @@ -614,34 +622,24 @@ double PairMesoCNT::usemi(double *param) double omega = 1.0 / (1.0 - comega*sin_alphasq); double theta = 1.0 - ctheta*sin_alphasq; + double a1 = omega * sin_alpha; + double a2 = theta * etaend; + int points = 100; double delxi = (xi2 - xi1) / (points -1); - double g, hbar, etabar; double sum = 0; - // first and last term in sum - - g = xi1 * omega * sin_alpha; - hbar = sqrt(h*h + g*g); - etabar = xi1 * cos_alpha - theta*etaend; - sum += spline(hbar,etabar,starth_usemi,startxi_usemi, - delh_usemi,delxi_usemi,usemi_coeff,pot_points); - g = xi2 * omega * sin_alpha; - hbar = sqrt(h*h + g*g); - etabar = xi2 * cos_alpha - theta*etaend; - sum += spline(hbar,etabar,starth_usemi,startxi_usemi, - delh_usemi,delxi_usemi,usemi_coeff,pot_points); - sum *= 0.5; - - // remaining sum - - for(int i = 1; i < points-1; i++){ + for(int i = 0; i < points; i++){ double xibar = xi1 + i*delxi; - g * xibar * omega * sin_alpha; - hbar = sqrt(h*h + g*g); - etabar = xibar*cos_alpha - theta*etaend; - sum += spline(hbar,etabar,starth_usemi,startxi_usemi, + double g = xibar * a1; + double hbar = sqrt(h*h + g*g); + double zetabar = xibar*cos_alpha - a2; + + double c = 1.0; + if(i == 0 || i == points-1) c = 0.5; + + sum += c * spline(hbar,zetabar,starth_usemi,startxi_usemi, delh_usemi,delxi_usemi,usemi_coeff,pot_points); } @@ -661,17 +659,103 @@ void PairMesoCNT::finf(double *param, double **f) double xi1 = param[2]; double xi2 = param[3]; + double sin_alpha = sin(alpha); + double sin_alphasq = sin_alpha*sin_alpha; + + if(sin_alphasq < SMALL){ + f[0][0] = -0.5*(xi2 - xi1)*dspline(h,start_uinf,del_uinf, + uinf_coeff,pot_points); + f[1][0] = f[0][0]; + f[0][1] = 0; + f[1][1] = 0; + f[0][2] = spline(h,start_uinf,del_uinf,uinf_coeff,pot_points); + f[1][2] = -f[0][2]; + } + else{ + double sin_alpharec = 1.0 / sin_alpha; + double sin_alpharecsq = sin_alpharec * sin_alpharec; + double cos_alpha = cos(alpha); + double cot_alpha = cos_alpha * sin_alpharec; + + double omega = 1.0 / (1.0 - comega*sin_alphasq); + double domega = 2 * comega * sin_alpha * cos_alpha * omega * omega; + double a1 = omega * sin_alpha; + double a1rec = 1.0 / a1; + + double gamma_orth = spline(h,start_gamma,del_gamma, + gamma_coeff,gamma_points); + double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; + double gammarec = 1.0 / gamma; + double dalpha_gamma = 2 * (gamma_orth - 1) * sin_alpha * cos_alpha; + double dh_gamma = dspline(h,start_gamma,del_gamma, + gamma_coeff,gamma_points) * sin_alphasq; + + + double zeta1 = xi1 * a1; + double zeta2 = xi2 * a1; + double phi1 = spline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double phi2 = spline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double dzeta_phi1 = dxspline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double dzeta_phi2 = dxspline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double diff_dzeta_phi = dzeta_phi2 - dzeta_phi1; + double dh_phi1 = dyspline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + double dh_phi2 = dyspline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + + double a2 = gamma * a1rec; + double u = a2 * (phi2 - phi1); + double a3 = u * gammarec; + + double dh_u = dh_gamma * a3 + a2 * (dh_phi2 - dh_phi1); + double dalpha_u = dalpha_gamma * a3 + + a2 * (domega*sin_alpha + omega*cos_alpha) + * (gamma*(xi2*dzeta_phi2 - xi1*dzeta_phi1) - u); + + double lrec = 1.0 / (xi2 - xi1); + double cx = h * gamma * sin_alpharecsq * diff_dzeta_phi; + double cy = gamma * cot_alpha * diff_dzeta_phi; + + f[0][0] = lrec * (xi2*dh_u - cx); + f[1][0] = lrec * (-xi1*dh_u + cx); + f[0][1] = lrec * (dalpha_u - xi2*cy); + f[1][1] = lrec * (-dalpha_u + xi2*cy); + f[0][2] = gamma * dzeta_phi1; + f[1][2] = -gamma * dzeta_phi2; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::fsemi(double *param, double **f) +{ + double h = param[0]; + double alpha = param[1]; + double xi1 = param[2]; + double xi2 = param[3]; + double etaend = param[4]; + double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; double sin_alpharec = 1.0 / sin_alpha; double sin_alpharecsq = sin_alpharec * sin_alpharec; double cos_alpha = cos(alpha); - double cot_alpha = cos_alpha * sin_alpharec; double omega = 1.0 / (1.0 - comega*sin_alphasq); + double omegasq = omega * omega; double domega = 2 * comega * sin_alpha * cos_alpha * omega * omega; + + double theta = 1.0 - ctheta*sin_alphasq; + double dtheta = -2 * ctheta * sin_alpha * cos_alpha; + double a1 = omega * sin_alpha; + double a1sq = a1 * a1; double a1rec = 1.0 / a1; + double a2 = theta * etaend; double gamma_orth = spline(h,start_gamma,del_gamma, gamma_coeff,gamma_points); @@ -680,43 +764,68 @@ void PairMesoCNT::finf(double *param, double **f) double dalpha_gamma = 2 * (gamma_orth - 1) * sin_alpha * cos_alpha; double dh_gamma = dspline(h,start_gamma,del_gamma, gamma_coeff,gamma_points) * sin_alphasq; - - - double zeta1 = xi1 * a1; - double zeta2 = xi2 * a1; - double phi1 = spline(zeta1,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double phi2 = spline(zeta2,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double dzeta_phi1 = dxspline(zeta1,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double dzeta_phi2 = dxspline(zeta2,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double diff_dzeta_phi = dzeta_phi2 - dzeta_phi1; - double dh_phi1 = dyspline(zeta1,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double dh_phi2 = dyspline(zeta2,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - - double a2 = gamma * a1rec; - double u = a2 * (phi2 - phi1); - double a3 = u * gammarec; + + int points = 100; + double delxi = (xi2 - xi1) / (points -1); + double a3 = delxi * gamma; - double dh_u = dh_gamma * a3 + a2 * (dh_phi2 - dh_phi1); - double dalpha_u = dalpha_gamma * a3 - + a2 * (domega*sin_alpha + omega*cos_alpha) - * (gamma*(xi2*dzeta_phi2 - xi1*dzeta_phi1) - u); + double jh = 0; + double jh1 = 0; + double jh2 = 0; + double jxi = 0; + double jxi1 = 0; + double ubar = 0; + + for(int i = 0; i < points; i++){ + double xibar = xi1 + i*delxi; + double g = xibar * a1; + double hbar = sqrt(h*h + g*g); + double zetabar = xibar*cos_alpha - a2; + + double c = 1.0; + if(i == 0 || i == points-1) c = 0.5; + + double u = c * spline(hbar,zetabar,starth_usemi,startxi_usemi, + delh_usemi,delxi_usemi,usemi_coeff,pot_points); + double uh = c / hbar * dxspline(hbar,zetabar,starth_usemi,startxi_usemi, + delh_usemi,delxi_usemi,usemi_coeff,pot_points); + double uxi = c * dyspline(hbar,zetabar,starth_usemi,startxi_usemi, + delh_usemi,delxi_usemi,usemi_coeff,pot_points); + + double uh1 = xibar * uh; + jh += uh; + jh1 += uh1; + jh2 += xibar * uh1; + jxi += uxi; + jxi1 += xibar * uxi; + ubar += u; + } + + jh *= a3; + jh1 *= a3; + jh2 *= a3; + jxi *= a3; + jxi1 *= a3; + ubar *= a3; + + double a4 = gammarec * ubar; + double dh_ubar = dh_gamma*a4 + h*jh; + double dalpha_ubar = dalpha_gamma*a4 + + a1*(domega*sin_alpha + omega*cos_alpha)*jh2 + - sin_alpha * jxi1 - dtheta*etaend*jxi; + + double cx = h * (omegasq*jh1 + cos_alpha*ctheta*jxi); + double cy = sin_alpha * (cos_alpha*omegasq*jh1 + (ctheta-1)*jxi); + double cz1 = a1sq*jh1 + cos_alpha*jxi; + double cz2 = a1sq*jh2 + cos_alpha*jxi1; double lrec = 1.0 / (xi2 - xi1); - double cx = h * gamma * sin_alpharecsq * diff_dzeta_phi; - double cy = gamma * cot_alpha * diff_dzeta_phi; - - f[0][0] = lrec * (xi2*dh_u - cx); - f[1][0] = lrec * (-xi1*dh_u + cx); - f[0][1] = lrec * (dalpha_u - xi2*cy); - f[1][1] = lrec * (-dalpha_u + xi2*cy); - f[0][2] = gamma * dzeta_phi1; - f[1][2] = -gamma * dzeta_phi2; + f[0][0] = lrec * (xi2*dh_ubar - cx); + f[1][0] = lrec * (cx - xi1*dh_ubar); + f[0][1] = lrec * (dalpha_ubar - xi2*cy); + f[1][1] = lrec * (xi1*cy - dalpha_ubar); + f[0][2] = lrec * (cz2 + ubar - xi2*cz1); + f[1][2] = lrec * (xi1*cz1 - cz2 - ubar); } /* ---------------------------------------------------------------------- */ diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index a10beb329d..e35f107f0e 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -48,16 +48,17 @@ class PairMesoCNT : public Pair { void spline_coeff(double *, double **, int); void spline_coeff(double **, double ***, int); - void read_file(char *, double *, double *, int); - void read_file(char *, double **, double *, double *, int); + void read_file(char *, double *, double *, double *, int); + void read_file(char *, double **, double *, double *, + double *, double *, int); double uinf(double *); double usemi(double *); void finf(double *, double **); void fsemi(double *, double **); - void geom(const double *, const double *, const double *, const double *, - double *, double **); + void geom(const double *, const double *, const double *, + const double *, double *, double **); }; } From 565be0baed640dd4f0b958626400956b9087fe0b Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Mon, 13 May 2019 17:24:36 +0100 Subject: [PATCH 006/443] Compute complete, compiles with LAMMPS, pre-debug --- src/MESOCNT/pair_mesocnt.cpp | 240 ++++++++++++++++++++++++++++++++++- src/MESOCNT/pair_mesocnt.h | 6 +- 2 files changed, 244 insertions(+), 2 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 4af1ca7784..edc62cefe0 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -58,12 +58,210 @@ PairMesoCNT::~PairMesoCNT() void PairMesoCNT::compute(int eflag, int vflag) { + int inum,i1,i2,jj,jj1,jj2,j1num,j2num,numred,inflag,n; + double evdwl; + double *r1,*r2,*p1,*p2,*q1,*q2,*param,**flocal,**basis; + int *ilist,*j1list,*j2list,*numneigh,**firstneigh; + int *redlist,*nchain,*end; + int **chain; + + evdwl = 0.0; + ev_init(eflag,vflag); + + double **x = atom->x; + double **f = atom->f; + int **bondlist = neighbor->bondlist; + int *tag = atom->tag; + int *mol = atom->molecule; + int nbondlist = neighbor->nbondlist; + int nlocal = atom->nlocal; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + memory->create(p1,3,"pair:p1"); + memory->create(p2,3,"pair:p2"); + memory->create(q1,3,"pair:q1"); + memory->create(q2,3,"pair:q2"); + memory->create(param,6,"pair:param"); + memory->create(flocal,2,3,"pair:flocal"); + memory->create(basis,3,3,"pair:basis"); + + for(n = 0; n < nbondlist; n++){ + i1 = bondlist[n][0]; + i2 = bondlist[n][1]; + + r1 = x[i1]; + r2 = x[i2]; + + // reduce neighbors to common list + + j1list = firstneigh[i1]; + j2list = firstneigh[i2]; + j1num = numneigh[i1]; + j2num = numneigh[i2]; + + memory->create(redlist,j1num+j2num,"pair:redlist"); + numred = 0; + for(jj1 = 0; jj1 < j1num; jj1++) redlist[numred++] = j1list[jj1]; + for(jj2 = 0; jj2 < j2num; jj2++){ + for(jj1 = 0; jj1 < j1num; jj1++){ + if(j1list[jj1] == j2list[jj2]){ + inflag = 1; + break; + } + } + if(inflag){ + inflag = 0; + continue; + } + redlist[numred++] = j2list[jj2]; + } + + // insertion sort according to atom-id + + for(int mm = 1; mm < numred; mm++){ + int m = mm; + int loc1 = redlist[m-1]; + int loc2 = redlist[m]; + while(m > 0 && tag[loc1] > tag[loc2]){ + loc1 = redlist[m-1]; + loc2 = redlist[m]; + m--; + redlist[m] = loc1; + redlist[m-1]; + } + } + + // split into connected chains + + int cid = 0; + int cnum = 0; + memory->create(chain,numred,numred,"pair:chain"); + memory->create(nchain,numred,"pair:numred"); + for(jj = 0; jj < numred-1; jj++){ + int j = redlist[jj]; + chain[cid][cnum++] = j; + if(abs(tag[j] - tag[j+1]) != 1 || mol[j] != mol[j+1]){ + nchain[cid++] = cnum; + cnum = 0; + } + } + chain[cid][cnum++] = redlist[numred-1]; + nchain[cid++] = cnum; + + // check for ends + + memory->create(end,cid,"pair:end"); + for(int i = 0; i < cid; i++){ + int cn = nchain[i]; + int tag1 = tag[chain[i][0]]; + int tag2 = tag[chain[i][cn-1]]; + if(tag1 == 1) end[i] = 1; + else{ + int idprev = atom->map(tag1-1); + if(idprev == -1 || mol[chain[i][0]] != mol[idprev]) end[i] = 1; + } + if(tag2 == atom->natoms) end[i] = 2; + else{ + int idnext = atom->map(tag2+1); + if(idnext == -1 || mol[chain[i][0]] != mol[idnext]) end[i] = 2; + } + } + + // compute subsitute chains, forces and energies + + using namespace MathExtra; + double w,sumwreq,sumw; + + for(int i = 0; i < cid; i++){ + zero3(p1); + zero3(p2); + sumw = 0; + for(int j = 0; j < nchain[i]-1; j++){ + q1 = x[chain[i][j]]; + q2 = x[chain[i][j+1]]; + w = weight(r1,r2,q1,q2); + sumw += w; + for(int ax = 0; ax < 3; ax++){ + p1[ax] += w * q1[ax]; + p2[ax] += w * q2[ax]; + } + } + sumwreq = 1 / sumw; + scale3(sumwreq,p1); + scale3(sumwreq,p2); + + if(end[i] == 1){ + geom(r1,r2,p1,p2,param,basis); + fsemi(param,flocal); + } + else if(end[i] == 2){ + geom(r1,r2,p2,p1,param,basis); + fsemi(param,flocal); + } + else{ + geom(r1,r2,p2,p1,param,basis); + finf(param,flocal); + } + + if(eflag){ + if(end[i] == 0) evdwl = uinf(param); + else evdwl = usemi(param); + } + + f[i1][0] += flocal[0][0]*basis[0][0] + + flocal[0][1]*basis[0][1] + + flocal[0][2]*basis[0][2]; + f[i1][1] += flocal[0][0]*basis[1][0] + + flocal[0][1]*basis[1][1] + + flocal[0][2]*basis[1][2]; + f[i1][2] += flocal[0][0]*basis[2][0] + + flocal[0][1]*basis[2][1] + + flocal[0][2]*basis[2][2]; + f[i2][0] += flocal[1][0]*basis[0][0] + + flocal[1][1]*basis[0][1] + + flocal[1][2]*basis[0][2]; + f[i2][1] += flocal[1][0]*basis[1][0] + + flocal[1][1]*basis[1][1] + + flocal[1][2]*basis[1][2]; + f[i2][2] += flocal[1][0]*basis[2][0] + + flocal[1][1]*basis[2][1] + + flocal[1][2]*basis[2][2]; + } + + memory->destroy(redlist); + memory->destroy(chain); + memory->destroy(nchain); + memory->destroy(end); + } + + memory->destroy(p1); + memory->destroy(p2); + memory->destroy(q1); + memory->destroy(q2); + memory->destroy(param); + memory->destroy(flocal); + memory->destroy(basis); } /* ---------------------------------------------------------------------- */ +void PairMesoCNT::init_style() +{ + int irequest; + irequest = neighbor->request(this,instance_me); +} +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::init_one(int i, int j) +{ + return 0; +} /* ---------------------------------------------------------------------- allocate all arrays @@ -119,6 +317,8 @@ void PairMesoCNT::coeff(int narg, char **arg) phi_file = arg[9]; radius = 1.421*3*n / MY_2PI; + radiussq = radius * radius; + rc = 3 * sigma; comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius)); ctheta = 0.35 + 0.0226*(radius - 6.785); @@ -135,7 +335,9 @@ void PairMesoCNT::coeff(int narg, char **arg) } MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); - MPI_Bcast(uinf_data,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(uinf_data,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(starth_usemi,pot_points,MPI_DOUBLE,0,world); + MPI_Bcast(startzeta_phi,pot_points,MPI_DOUBLE,0,world); MPI_Bcast(delh_usemi,pot_points,MPI_DOUBLE,0,world); MPI_Bcast(delzeta_phi,pot_points,MPI_DOUBLE,0,world); for(int i = 0; i < pot_points; i++){ @@ -902,3 +1104,39 @@ void PairMesoCNT::geom(const double *r1, const double *r2, param[4] = eta1; param[5] = eta2; } + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::weight(const double *r1, const double *r2, + const double *p1, const double *p2) +{ + using namespace MathExtra; + double r[3], p[3], delr[3], delp[3], delrp[3]; + double rho, rhoc, rhomin; + + add3(r1,r2,r); + add3(p1,p2,p); + + rhoc = sqrt(0.25*distsq3(r1,r2) + radiussq) + + sqrt(0.25*distsq3(p1,p2) + radiussq) + rc; + rhomin = 1.39 * rhoc; + rho = 0.5 * sqrt(distsq3(r,p)); + + return s((rho - rhomin)/(rhoc - rhomin)); +} + +/* ---------------------------------------------------------------------- */ + +int PairMesoCNT::heaviside(double x) +{ + if(x < 0) return 0; + else return 1; +} + +/* ---------------------------------------------------------------------- */ + +double PairMesoCNT::s(double x) +{ + return heaviside(-x) + heaviside(x)*heaviside(1-x)*(1 - x*x*(3 - 2*x)); +} + diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index e35f107f0e..474506c00f 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -23,7 +23,7 @@ class PairMesoCNT : public Pair { protected: int n, gamma_points, pot_points; - double sigma, epsilon, n_sigma, radius, comega, ctheta; + double sigma, epsilon, n_sigma, radius, radiussq, rc, rc0, comega, ctheta; double start_gamma, start_uinf, startxi_usemi, starth_phi; double del_gamma, del_uinf, delxi_usemi, delh_phi; double *starth_usemi, *startzeta_phi; @@ -59,6 +59,10 @@ class PairMesoCNT : public Pair { void geom(const double *, const double *, const double *, const double *, double *, double **); + double weight(const double *, const double *, + const double *, const double *); + int heaviside(double); + double s(double x); }; } From c8897acf71dc110b8326aa53259bc0b5a3ddcfe8 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Mon, 13 May 2019 21:24:44 +0100 Subject: [PATCH 007/443] Fixed file reading issue --- src/MESOCNT/pair_mesocnt.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index edc62cefe0..9ba68cb30b 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -316,7 +316,7 @@ void PairMesoCNT::coeff(int narg, char **arg) usemi_file = arg[8]; phi_file = arg[9]; - radius = 1.421*3*n / MY_2PI; + radius = 1.421*3*n / MY_2PI / force->angstrom; radiussq = radius * radius; rc = 3 * sigma; comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius)); @@ -328,6 +328,7 @@ void PairMesoCNT::coeff(int narg, char **arg) if (me == 0) { read_file(gamma_file,gamma_data,&start_gamma,&del_gamma,gamma_points); read_file(uinf_file,uinf_data,&start_uinf,&del_uinf,pot_points); + printf("1D files read\n"); read_file(usemi_file,usemi_data,starth_usemi,&startxi_usemi, delh_usemi,&delxi_usemi,pot_points); read_file(phi_file,phi_data,startzeta_phi,&starth_phi, @@ -664,11 +665,13 @@ void PairMesoCNT::read_file(char *file, double *data, int serror = 0; double x,xtemp; - utils::sfgets(FLERR,line,MAXLINE,fp,file,error); for(int i = 0; i < ninput; i++){ if(i > 0) xtemp = x; - if(NULL == fgets(line,MAXLINE,fp)) - error->one(FLERR,"Premature end of file in pair table"); + if(NULL == fgets(line,MAXLINE,fp)){ + std::string str("Premature end of file in pair table "); + str += file; + error->one(FLERR,str.c_str()); + } if(2 != sscanf(line,"%lg %lg",&x, &data[i])) ++cerror; if(i == 0) *startx = x; if(i > 0){ @@ -721,13 +724,15 @@ void PairMesoCNT::read_file(char *file, double **data, int syerror = 0; double x,y,xtemp,ytemp; - utils::sfgets(FLERR,line,MAXLINE,fp,file,error); for(int i = 0; i < ninput; i++){ if(i > 0) ytemp = y; for(int j = 0; j < ninput; j++){ if(j > 0) xtemp = x; - if(NULL == fgets(line,MAXLINE,fp)) - error->one(FLERR,"Premature end of file in pair table"); + if(NULL == fgets(line,MAXLINE,fp)){ + std::string str("Premature end of file in pair table "); + str += file; + error->one(FLERR,str.c_str()); + } if(3 != sscanf(line,"%lg %lg %lg",&x,&y,&data[j][i])) ++cerror; if(j == 0) startx[i] = x; if(j > 0){ From 19e54c23ddd3b6f300c901e35da0b49b851d9db1 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Tue, 14 May 2019 12:01:28 +0100 Subject: [PATCH 008/443] Added correct units for lengths and energies --- src/MESOCNT/pair_mesocnt.cpp | 111 ++++++++++++++++++++++------------- src/MESOCNT/pair_mesocnt.h | 1 + 2 files changed, 72 insertions(+), 40 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 9ba68cb30b..9ba5b6bc77 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "pair_mesocnt.h" #include "atom.h" #include "comm.h" @@ -41,6 +42,8 @@ PairMesoCNT::~PairMesoCNT() if (allocated) { memory->destroy(gamma_data); memory->destroy(uinf_data); + memory->destroy(starth_usemi); + memory->destroy(startzeta_phi); memory->destroy(delh_usemi); memory->destroy(delzeta_phi); @@ -273,16 +276,18 @@ void PairMesoCNT::allocate() memory->create(gamma_data,gamma_points,"pair:gamma_data"); memory->create(uinf_data,pot_points,"pair:uinf_data"); + memory->create(starth_usemi,pot_points,"pair:starth_usemi"); + memory->create(startzeta_phi,pot_points,"pair:startzeta_phi"); memory->create(delh_usemi,pot_points,"pair:delh_usemi"); memory->create(delzeta_phi,pot_points,"pair:delzeta_phi"); memory->create(usemi_data,pot_points,pot_points,"pair:usemi_data"); memory->create(phi_data,pot_points,pot_points,"pair:phi_data"); - memory->create(gamma_coeff,gamma_points-1,4,"pair:gamma_coeff"); - memory->create(uinf_coeff,pot_points-1,4,"pair:uinf_coeff"); + memory->create(gamma_coeff,gamma_points,4,"pair:gamma_coeff"); + memory->create(uinf_coeff,pot_points,4,"pair:uinf_coeff"); - memory->create(usemi_coeff,pot_points,pot_points-1,4,"pair:usemi_coeff"); - memory->create(phi_coeff,pot_points,pot_points-1,4,"pair:phi_coeff"); + memory->create(usemi_coeff,pot_points,pot_points,4,"pair:usemi_coeff"); + memory->create(phi_coeff,pot_points,pot_points,4,"pair:phi_coeff"); } /* ---------------------------------------------------------------------- @@ -316,11 +321,17 @@ void PairMesoCNT::coeff(int narg, char **arg) usemi_file = arg[8]; phi_file = arg[9]; - radius = 1.421*3*n / MY_2PI / force->angstrom; + angstrom = force->angstrom; + angstromrec = 1 / angstrom; + qelectron = force->qelectron; + qelectronrec = 1 / qelectron; + forceunit = qelectron * angstromrec; + + radius = 1.421*3*n / MY_2PI * angstrom; radiussq = radius * radius; rc = 3 * sigma; - comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius)); - ctheta = 0.35 + 0.0226*(radius - 6.785); + comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius/angstrom)); + ctheta = 0.35 + 0.0226*(radius/angstrom - 6.785); //Parse and bcast data int me; @@ -333,6 +344,7 @@ void PairMesoCNT::coeff(int narg, char **arg) delh_usemi,&delxi_usemi,pot_points); read_file(phi_file,phi_data,startzeta_phi,&starth_phi, delzeta_phi,&delh_phi,pot_points); + printf("2D files read\n"); } MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); @@ -346,10 +358,29 @@ void PairMesoCNT::coeff(int narg, char **arg) MPI_Bcast(phi_data[i],pot_points,MPI_DOUBLE,0,world); } + if(me == 0) printf("Arrays broadcast\n"); + spline_coeff(gamma_data,gamma_coeff,gamma_points); spline_coeff(uinf_data,uinf_coeff,pot_points); + if(me == 0) printf("1D splines generated\n"); spline_coeff(usemi_data,usemi_coeff,pot_points); spline_coeff(phi_data,phi_coeff,pot_points); + if(me == 0) printf("2D splines generated\n"); + + if(me == 0){ + std::ofstream outFile; + outFile.open("test.dat"); + for(int i = 0; i < 2001; i++){ + for(int j = 0; j < 2001; j++){ + double x = startzeta_phi[i] + j*delzeta_phi[i]; + double y = starth_phi + i*delh_phi; + double test = spline(x,y,startzeta_phi,starth_phi,delzeta_phi,delh_phi,phi_coeff,pot_points); + outFile << x << " " << y << " " << test << std::endl; + } + } + outFile.close(); + } + } /* ---------------------------------------------------------------------- */ @@ -619,13 +650,13 @@ void PairMesoCNT::spline_coeff(double **data, double ***coeff, int data_size) { for(int i = 0; i < data_size; i++){ for(int j = 0; j < data_size-1; j++){ - if(i == 0){ + if(j == 0){ coeff[i][j][0] = data[j][i]; coeff[i][j][1] = data[j+1][i] - data[j][i]; coeff[i][j][3] = 0.5*(data[j+2][i] - 2*data[j+1][i] + data[j][i]); coeff[i][j][2] = -coeff[i][j][3]; } - else if(i == data_size-2){ + else if(j == data_size-2){ coeff[i][j][0] = data[j][i]; coeff[i][j][1] = 0.5*(data[j+1][i] - data[j-1][i]); coeff[i][j][3] = 0.5*(-data[j+1][i] + 2*data[j][i] - data[j-1][i]); @@ -676,7 +707,7 @@ void PairMesoCNT::read_file(char *file, double *data, if(i == 0) *startx = x; if(i > 0){ if(i == 1) *dx = x - xtemp; - if(*dx != x - xtemp) ++serror; + if((*dx - x + xtemp) / *dx > SMALL) ++serror; } } @@ -737,13 +768,13 @@ void PairMesoCNT::read_file(char *file, double **data, if(j == 0) startx[i] = x; if(j > 0){ if(j == 1) dx[i] = x - xtemp; - if(dx[i] != x - xtemp) ++sxerror; + if((dx[i] - x + xtemp)/dx[i] > SMALL) ++sxerror; } } if(i == 0) *starty = y; if(i > 0){ if(i == 1) *dy = y - ytemp; - if(*dy != y - ytemp) ++syerror; + if((*dy - y + ytemp)/ *dy > SMALL) ++syerror; } } @@ -778,10 +809,10 @@ void PairMesoCNT::read_file(char *file, double **data, double PairMesoCNT::uinf(double *param) { - double h = param[0]; + double h = param[0] * angstromrec; double alpha = param[1]; - double xi1 = param[2]; - double xi2 = param[3]; + double xi1 = param[2] * angstromrec; + double xi2 = param[3] * angstromrec; double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; @@ -809,7 +840,7 @@ double PairMesoCNT::uinf(double *param) gamma_coeff,gamma_points); double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; - return gamma * (phi2 - phi1) / a; + return gamma * (phi2 - phi1) * qelectron / a; } } @@ -817,11 +848,11 @@ double PairMesoCNT::uinf(double *param) double PairMesoCNT::usemi(double *param) { - double h = param[0]; + double h = param[0] * angstromrec; double alpha = param[1]; - double xi1 = param[2]; - double xi2 = param[3]; - double etaend = param[4]; + double xi1 = param[2] * angstromrec; + double xi2 = param[3] * angstromrec; + double etaend = param[4] * angstromrec; double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; @@ -854,17 +885,17 @@ double PairMesoCNT::usemi(double *param) gamma_coeff,gamma_points); double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; - return delxi * gamma * sum; + return delxi * gamma * sum * qelectron; } /* ---------------------------------------------------------------------- */ void PairMesoCNT::finf(double *param, double **f) { - double h = param[0]; + double h = param[0] * angstromrec; double alpha = param[1]; - double xi1 = param[2]; - double xi2 = param[3]; + double xi1 = param[2] * angstromrec; + double xi2 = param[3] * angstromrec; double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; @@ -927,12 +958,12 @@ void PairMesoCNT::finf(double *param, double **f) double cx = h * gamma * sin_alpharecsq * diff_dzeta_phi; double cy = gamma * cot_alpha * diff_dzeta_phi; - f[0][0] = lrec * (xi2*dh_u - cx); - f[1][0] = lrec * (-xi1*dh_u + cx); - f[0][1] = lrec * (dalpha_u - xi2*cy); - f[1][1] = lrec * (-dalpha_u + xi2*cy); - f[0][2] = gamma * dzeta_phi1; - f[1][2] = -gamma * dzeta_phi2; + f[0][0] = lrec * (xi2*dh_u - cx) * forceunit; + f[1][0] = lrec * (-xi1*dh_u + cx) * forceunit; + f[0][1] = lrec * (dalpha_u - xi2*cy) * forceunit; + f[1][1] = lrec * (-dalpha_u + xi2*cy) * forceunit; + f[0][2] = gamma * dzeta_phi1 * forceunit; + f[1][2] = -gamma * dzeta_phi2 * forceunit; } } @@ -940,11 +971,11 @@ void PairMesoCNT::finf(double *param, double **f) void PairMesoCNT::fsemi(double *param, double **f) { - double h = param[0]; + double h = param[0] * angstrom; double alpha = param[1]; - double xi1 = param[2]; - double xi2 = param[3]; - double etaend = param[4]; + double xi1 = param[2] * angstrom; + double xi2 = param[3] * angstrom; + double etaend = param[4] * angstrom; double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; @@ -1027,12 +1058,12 @@ void PairMesoCNT::fsemi(double *param, double **f) double cz2 = a1sq*jh2 + cos_alpha*jxi1; double lrec = 1.0 / (xi2 - xi1); - f[0][0] = lrec * (xi2*dh_ubar - cx); - f[1][0] = lrec * (cx - xi1*dh_ubar); - f[0][1] = lrec * (dalpha_ubar - xi2*cy); - f[1][1] = lrec * (xi1*cy - dalpha_ubar); - f[0][2] = lrec * (cz2 + ubar - xi2*cz1); - f[1][2] = lrec * (xi1*cz1 - cz2 - ubar); + f[0][0] = lrec * (xi2*dh_ubar - cx) * forceunit; + f[1][0] = lrec * (cx - xi1*dh_ubar) * forceunit; + f[0][1] = lrec * (dalpha_ubar - xi2*cy) * forceunit; + f[1][1] = lrec * (xi1*cy - dalpha_ubar) * forceunit; + f[0][2] = lrec * (cz2 + ubar - xi2*cz1) * forceunit; + f[1][2] = lrec * (xi1*cz1 - cz2 - ubar) * forceunit; } /* ---------------------------------------------------------------------- */ diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index 474506c00f..7aeb660efd 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -23,6 +23,7 @@ class PairMesoCNT : public Pair { protected: int n, gamma_points, pot_points; + double angstrom, angstromrec, qelectron, qelectronrec, forceunit; double sigma, epsilon, n_sigma, radius, radiussq, rc, rc0, comega, ctheta; double start_gamma, start_uinf, startxi_usemi, starth_phi; double del_gamma, del_uinf, delxi_usemi, delh_phi; From cd55697dfe0e23ef57f21cd8db5bc4d5d266a594 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Wed, 15 May 2019 12:21:44 +0100 Subject: [PATCH 009/443] splines should work now --- src/MESOCNT/pair_mesocnt.cpp | 162 ++++++++++++++++++++--------------- 1 file changed, 92 insertions(+), 70 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 9ba5b6bc77..610fdc5f22 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -370,11 +370,11 @@ void PairMesoCNT::coeff(int narg, char **arg) if(me == 0){ std::ofstream outFile; outFile.open("test.dat"); - for(int i = 0; i < 2001; i++){ - for(int j = 0; j < 2001; j++){ - double x = startzeta_phi[i] + j*delzeta_phi[i]; - double y = starth_phi + i*delh_phi; - double test = spline(x,y,startzeta_phi,starth_phi,delzeta_phi,delh_phi,phi_coeff,pot_points); + for(int i = 0; i < 1001; i++){ + for(int j = 0; j < 1001; j++){ + double x = starth_usemi[i] + j*delh_usemi[i]; + double y = startxi_usemi + i*delxi_usemi; + double test = spline(x,y,starth_usemi,startxi_usemi,delh_usemi,delxi_usemi,usemi_coeff,pot_points); outFile << x << " " << y << " " << test << std::endl; } } @@ -390,18 +390,22 @@ double PairMesoCNT::spline(double x, double xstart, double dx, { int i = floor((x - xstart)/dx); if(i < 0){ + if(i < -1){ + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval; x: %f; x0: %f", x, xstart); + error->warning(FLERR,str); + } i = 0; - // warn if argument below spline range - char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); } else if(i > coeff_size-1){ - i = coeff_size-1; - // warn if argument above spline range - char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); + if(i > coeff_size){ + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + i = coeff_size - 1; } double xlo = xstart + i*dx; @@ -418,19 +422,23 @@ double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, { int i = floor((y - ystart)/dy); if(i < 0){ + if(i < -1){ + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } i = 0; - // warn if argument below spline range - char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); - } - else if(i > coeff_size-1){ - i = coeff_size-1; - // warn if argument above spline range - char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); } + else if(i > coeff_size-2){ + if(i > coeff_size-1){ + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + i = coeff_size - 2; + } double ylo = ystart + i*dy; double ybar = (y - ylo)/dy; @@ -440,13 +448,13 @@ double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, double a0, a1, a2, a3; double p0, p1, p2, p3; - p1 = spline(x,xstart[0],dx[0],coeff[0],coeff_size); - p2 = spline(x,xstart[1],dx[1],coeff[1],coeff_size); + p1 = spline(x,xstart[i],dx[i],coeff[i],coeff_size); + p2 = spline(x,xstart[i+1],dx[i+1],coeff[i+1],coeff_size); a0 = p1; if(i == 0){ - p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + p3 = spline(x,xstart[i+2],dx[i+2],coeff[i+2],coeff_size); a1 = p2 - p1; a3 = 0.5*(p3 - 2*p2 + p1); @@ -458,10 +466,12 @@ double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, a1 = 0.5*(p2 - p0); a3 = 0.5*(p2 - 2*p1 + p0); a2 = -2*a3; + printf("p: %f %f %f \n",p0,p1,p2); + printf("x0: %f dx: %f \n",xstart[i+1],dx[i+1]); } else{ p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); - p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + p3 = spline(x,xstart[i+2],dx[i+2],coeff[i+2],coeff_size); a1 = 0.5*(p2 - p0); a2 = 0.5*(-p3 + 4*p2 - 5*p1 + 2*p0); @@ -478,19 +488,23 @@ double PairMesoCNT::dspline(double x, double xstart, double dx, { int i = floor((x - xstart)/dx); if(i < 0){ + if(i < -1){ + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } i = 0; - // warn if argument below spline range - char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); } else if(i > coeff_size-1){ - i = coeff_size-1; - // warn if argument above spline range - char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); - } + if(i > coeff_size){ + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + i = coeff_size - 1; + } double xlo = xstart + i*dx; double xbar = (x - xlo)/dx; @@ -505,19 +519,23 @@ double PairMesoCNT::dxspline(double x, double y, double *xstart, double ystart, { int i = floor((y - ystart)/dy); if(i < 0){ + if(i < -1){ + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } i = 0; - // warn if argument below spline range - char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); - } - else if(i > coeff_size-1){ - i = coeff_size-1; - // warn if argument above spline range - char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); } + else if(i > coeff_size-2){ + if(i > coeff_size-1){ + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + i = coeff_size - 2; + } double ylo = ystart + i*dy; double ybar = (y - ylo)/dy; @@ -527,13 +545,13 @@ double PairMesoCNT::dxspline(double x, double y, double *xstart, double ystart, double a0, a1, a2, a3; double p0, p1, p2, p3; - p1 = dspline(x,xstart[0],dx[0],coeff[0],coeff_size); - p2 = dspline(x,xstart[1],dx[1],coeff[1],coeff_size); + p1 = dspline(x,xstart[i],dx[i],coeff[i],coeff_size); + p2 = dspline(x,xstart[i+1],dx[i+1],coeff[i+1],coeff_size); a0 = p1; if(i == 0){ - p3 = dspline(x,xstart[2],dx[2],coeff[2],coeff_size); + p3 = dspline(x,xstart[i+2],dx[i+2],coeff[i+2],coeff_size); a1 = p2 - p1; a3 = 0.5*(p3 - 2*p2 + p1); @@ -548,7 +566,7 @@ double PairMesoCNT::dxspline(double x, double y, double *xstart, double ystart, } else{ p0 = dspline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); - p3 = dspline(x,xstart[2],dx[2],coeff[2],coeff_size); + p3 = dspline(x,xstart[i+2],dx[i+2],coeff[i+2],coeff_size); a1 = 0.5*(p2 - p0); a2 = 0.5*(-p3 + 4*p2 - 5*p1 + 2*p0); @@ -565,20 +583,24 @@ double PairMesoCNT::dyspline(double x, double y, double *xstart, double ystart, { int i = floor((y - ystart)/dy); if(i < 0){ + if(i < -1){ + // warn if argument below spline range + char str[128]; + sprintf(str,"Argument below spline interval"); + error->warning(FLERR,str); + } i = 0; - // warn if argument below spline range - char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); } - else if(i > coeff_size-1){ - i = coeff_size-1; - // warn if argument above spline range - char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); - } - + else if(i > coeff_size-2){ + if(i > coeff_size-1){ + // warn if argument above spline range + char str[128]; + sprintf(str,"Argument above spline interval"); + error->warning(FLERR,str); + } + i = coeff_size - 2; + } + double ylo = ystart + i*dy; double ybar = (y - ylo)/dy; @@ -587,13 +609,13 @@ double PairMesoCNT::dyspline(double x, double y, double *xstart, double ystart, double a0, a1, a2, a3; double p0, p1, p2, p3; - p1 = spline(x,xstart[0],dx[0],coeff[0],coeff_size); - p2 = spline(x,xstart[1],dx[1],coeff[1],coeff_size); + p1 = spline(x,xstart[i],dx[i],coeff[i],coeff_size); + p2 = spline(x,xstart[i+1],dx[i+1],coeff[i+1],coeff_size); a0 = p1; if(i == 0){ - p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + p3 = spline(x,xstart[i+2],dx[i+2],coeff[i+2],coeff_size); a1 = p2 - p1; a3 = 0.5*(p3 - 2*p2 + p1); @@ -608,7 +630,7 @@ double PairMesoCNT::dyspline(double x, double y, double *xstart, double ystart, } else{ p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); - p3 = spline(x,xstart[2],dx[2],coeff[2],coeff_size); + p3 = spline(x,xstart[i+2],dx[i+2],coeff[i+2],coeff_size); a1 = 0.5*(p2 - p0); a2 = 0.5*(-p3 + 4*p2 - 5*p1 + 2*p0); From ea43f7d451e6f9aaad92b7f829dfc2c842e879af Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Wed, 15 May 2019 19:52:32 +0100 Subject: [PATCH 010/443] compute runs without crash, produces nans --- src/MESOCNT/pair_mesocnt.cpp | 97 ++++++++++++++++++------------------ src/MESOCNT/pair_mesocnt.h | 1 + 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 610fdc5f22..80450ac851 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -40,6 +40,9 @@ PairMesoCNT::PairMesoCNT(LAMMPS *lmp) : Pair(lmp) PairMesoCNT::~PairMesoCNT() { if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(gamma_data); memory->destroy(uinf_data); memory->destroy(starth_usemi); @@ -79,7 +82,7 @@ void PairMesoCNT::compute(int eflag, int vflag) int *mol = atom->molecule; int nbondlist = neighbor->nbondlist; int nlocal = atom->nlocal; - + inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -87,8 +90,6 @@ void PairMesoCNT::compute(int eflag, int vflag) memory->create(p1,3,"pair:p1"); memory->create(p2,3,"pair:p2"); - memory->create(q1,3,"pair:q1"); - memory->create(q2,3,"pair:q2"); memory->create(param,6,"pair:param"); memory->create(flocal,2,3,"pair:flocal"); memory->create(basis,3,3,"pair:basis"); @@ -106,6 +107,8 @@ void PairMesoCNT::compute(int eflag, int vflag) j2list = firstneigh[i2]; j1num = numneigh[i1]; j2num = numneigh[i2]; + + if(j1num + j2num == 0) continue; memory->create(redlist,j1num+j2num,"pair:redlist"); numred = 0; @@ -123,7 +126,7 @@ void PairMesoCNT::compute(int eflag, int vflag) } redlist[numred++] = j2list[jj2]; } - + // insertion sort according to atom-id for(int mm = 1; mm < numred; mm++){ @@ -144,7 +147,7 @@ void PairMesoCNT::compute(int eflag, int vflag) int cid = 0; int cnum = 0; memory->create(chain,numred,numred,"pair:chain"); - memory->create(nchain,numred,"pair:numred"); + memory->create(nchain,numred,"pair:nchain"); for(jj = 0; jj < numred-1; jj++){ int j = redlist[jj]; chain[cid][cnum++] = j; @@ -244,11 +247,10 @@ void PairMesoCNT::compute(int eflag, int vflag) memory->destroy(p1); memory->destroy(p2); - memory->destroy(q1); - memory->destroy(q2); memory->destroy(param); memory->destroy(flocal); memory->destroy(basis); + } /* ---------------------------------------------------------------------- */ @@ -263,7 +265,7 @@ void PairMesoCNT::init_style() double PairMesoCNT::init_one(int i, int j) { - return 0; + return cutoff; } /* ---------------------------------------------------------------------- @@ -273,7 +275,15 @@ double PairMesoCNT::init_one(int i, int j) void PairMesoCNT::allocate() { allocated = 1; - + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + memory->create(gamma_data,gamma_points,"pair:gamma_data"); memory->create(uinf_data,pot_points,"pair:uinf_data"); memory->create(starth_usemi,pot_points,"pair:starth_usemi"); @@ -339,12 +349,10 @@ void PairMesoCNT::coeff(int narg, char **arg) if (me == 0) { read_file(gamma_file,gamma_data,&start_gamma,&del_gamma,gamma_points); read_file(uinf_file,uinf_data,&start_uinf,&del_uinf,pot_points); - printf("1D files read\n"); read_file(usemi_file,usemi_data,starth_usemi,&startxi_usemi, delh_usemi,&delxi_usemi,pot_points); read_file(phi_file,phi_data,startzeta_phi,&starth_phi, delzeta_phi,&delh_phi,pot_points); - printf("2D files read\n"); } MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); @@ -358,29 +366,22 @@ void PairMesoCNT::coeff(int narg, char **arg) MPI_Bcast(phi_data[i],pot_points,MPI_DOUBLE,0,world); } - if(me == 0) printf("Arrays broadcast\n"); - spline_coeff(gamma_data,gamma_coeff,gamma_points); spline_coeff(uinf_data,uinf_coeff,pot_points); - if(me == 0) printf("1D splines generated\n"); spline_coeff(usemi_data,usemi_coeff,pot_points); spline_coeff(phi_data,phi_coeff,pot_points); - if(me == 0) printf("2D splines generated\n"); - if(me == 0){ - std::ofstream outFile; - outFile.open("test.dat"); - for(int i = 0; i < 1001; i++){ - for(int j = 0; j < 1001; j++){ - double x = starth_usemi[i] + j*delh_usemi[i]; - double y = startxi_usemi + i*delxi_usemi; - double test = spline(x,y,starth_usemi,startxi_usemi,delh_usemi,delxi_usemi,usemi_coeff,pot_points); - outFile << x << " " << y << " " << test << std::endl; + int n = atom->ntypes; + + cutoff = rc + 2*radius; + double cutoffsq = cutoff * cutoff; + + for (int i = 1; i <= n; i++){ + for (int j = i; j <= n; j++){ + setflag[i][j] = 1; + cutsq[i][j] = cutoffsq; } } - outFile.close(); - } - } /* ---------------------------------------------------------------------- */ @@ -393,8 +394,8 @@ double PairMesoCNT::spline(double x, double xstart, double dx, if(i < -1){ // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval; x: %f; x0: %f", x, xstart); - error->warning(FLERR,str); + //sprintf(str,"Argument below spline interval; x: %f; x0: %f", x, xstart); + //error->warning(FLERR,str); } i = 0; } @@ -402,8 +403,8 @@ double PairMesoCNT::spline(double x, double xstart, double dx, if(i > coeff_size){ // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument above spline interval"); + //error->warning(FLERR,str); } i = coeff_size - 1; } @@ -425,8 +426,8 @@ double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, if(i < -1){ // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument below spline interval"); + //error->warning(FLERR,str); } i = 0; } @@ -434,8 +435,8 @@ double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, if(i > coeff_size-1){ // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument above spline interval"); + //error->warning(FLERR,str); } i = coeff_size - 2; } @@ -466,8 +467,6 @@ double PairMesoCNT::spline(double x, double y, double *xstart, double ystart, a1 = 0.5*(p2 - p0); a3 = 0.5*(p2 - 2*p1 + p0); a2 = -2*a3; - printf("p: %f %f %f \n",p0,p1,p2); - printf("x0: %f dx: %f \n",xstart[i+1],dx[i+1]); } else{ p0 = spline(x,xstart[i-1],dx[i-1],coeff[i-1],coeff_size); @@ -491,8 +490,8 @@ double PairMesoCNT::dspline(double x, double xstart, double dx, if(i < -1){ // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument below spline interval"); + //error->warning(FLERR,str); } i = 0; } @@ -500,8 +499,8 @@ double PairMesoCNT::dspline(double x, double xstart, double dx, if(i > coeff_size){ // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument above spline interval"); + //error->warning(FLERR,str); } i = coeff_size - 1; } @@ -522,8 +521,8 @@ double PairMesoCNT::dxspline(double x, double y, double *xstart, double ystart, if(i < -1){ // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument below spline interval"); + //error->warning(FLERR,str); } i = 0; } @@ -531,8 +530,8 @@ double PairMesoCNT::dxspline(double x, double y, double *xstart, double ystart, if(i > coeff_size-1){ // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument above spline interval"); + //error->warning(FLERR,str); } i = coeff_size - 2; } @@ -586,8 +585,8 @@ double PairMesoCNT::dyspline(double x, double y, double *xstart, double ystart, if(i < -1){ // warn if argument below spline range char str[128]; - sprintf(str,"Argument below spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument below spline interval"); + //error->warning(FLERR,str); } i = 0; } @@ -595,8 +594,8 @@ double PairMesoCNT::dyspline(double x, double y, double *xstart, double ystart, if(i > coeff_size-1){ // warn if argument above spline range char str[128]; - sprintf(str,"Argument above spline interval"); - error->warning(FLERR,str); + //sprintf(str,"Argument above spline interval"); + //error->warning(FLERR,str); } i = coeff_size - 2; } diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index 7aeb660efd..f8d2cf9264 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -23,6 +23,7 @@ class PairMesoCNT : public Pair { protected: int n, gamma_points, pot_points; + double cutoff; double angstrom, angstromrec, qelectron, qelectronrec, forceunit; double sigma, epsilon, n_sigma, radius, radiussq, rc, rc0, comega, ctheta; double start_gamma, start_uinf, startxi_usemi, starth_phi; From 474c92e59adf8383f8f715b8dc92dc6d0da7d6d3 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Wed, 15 May 2019 20:43:32 +0100 Subject: [PATCH 011/443] Fixed nan issues in compute --- src/MESOCNT/pair_mesocnt.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 80450ac851..91c6771432 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -184,12 +184,19 @@ void PairMesoCNT::compute(int eflag, int vflag) double w,sumwreq,sumw; for(int i = 0; i < cid; i++){ + if(nchain[i] < 2) continue; + zero3(p1); zero3(p2); sumw = 0; for(int j = 0; j < nchain[i]-1; j++){ q1 = x[chain[i][j]]; q2 = x[chain[i][j+1]]; + printf("Vectors q:\n"); + printf("%e %e %e\n",q1[0],q1[1],q1[2]); + printf("%e %e %e\n",q2[0],q2[1],q2[2]); + fflush(stdout); + w = weight(r1,r2,q1,q2); sumw += w; for(int ax = 0; ax < 3; ax++){ @@ -197,10 +204,17 @@ void PairMesoCNT::compute(int eflag, int vflag) p2[ax] += w * q2[ax]; } } + + if(sumw == 0) continue; sumwreq = 1 / sumw; scale3(sumwreq,p1); scale3(sumwreq,p2); + printf("Vectors p:\n"); + printf("%e %e %e\n",p1[0],p1[1],p1[2]); + printf("%e %e %e\n",p2[0],p2[1],p2[2]); + fflush(stdout); + if(end[i] == 1){ geom(r1,r2,p1,p2,param,basis); fsemi(param,flocal); @@ -237,6 +251,11 @@ void PairMesoCNT::compute(int eflag, int vflag) f[i2][2] += flocal[1][0]*basis[2][0] + flocal[1][1]*basis[2][1] + flocal[1][2]*basis[2][2]; + + printf("Forces:\n"); + printf("%e %e %e\n",f[i1][0],f[i1][1],f[i1][2]); + printf("%e %e %e\n",f[i2][0],f[i2][1],f[i2][2]); + fflush(stdout); } memory->destroy(redlist); @@ -394,7 +413,7 @@ double PairMesoCNT::spline(double x, double xstart, double dx, if(i < -1){ // warn if argument below spline range char str[128]; - //sprintf(str,"Argument below spline interval; x: %f; x0: %f", x, xstart); + //sprintf(str,"Argument below spline interval; x: %e; x0: %e", x, xstart); //error->warning(FLERR,str); } i = 0; From 651b3d788a72a8078a44559e76d0152b0c1c58a5 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Fri, 24 May 2019 20:21:10 +0100 Subject: [PATCH 012/443] Fixed unit errors and most major bugs --- src/MESOCNT/pair_mesocnt.cpp | 193 ++++++++++++++++++++++++----------- src/MESOCNT/pair_mesocnt.h | 2 + 2 files changed, 138 insertions(+), 57 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index 91c6771432..ec5d2d7f75 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -57,6 +57,12 @@ PairMesoCNT::~PairMesoCNT() memory->destroy(usemi_coeff); memory->destroy(phi_coeff); + + memory->destroy(p1); + memory->destroy(p2); + memory->destroy(param); + memory->destroy(flocal); + memory->destroy(basis); } } @@ -64,9 +70,14 @@ PairMesoCNT::~PairMesoCNT() void PairMesoCNT::compute(int eflag, int vflag) { + /* + int rank; + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + */ + int inum,i1,i2,jj,jj1,jj2,j1num,j2num,numred,inflag,n; double evdwl; - double *r1,*r2,*p1,*p2,*q1,*q2,*param,**flocal,**basis; + double *r1,*r2,*q1,*q2; int *ilist,*j1list,*j2list,*numneigh,**firstneigh; int *redlist,*nchain,*end; @@ -88,19 +99,13 @@ void PairMesoCNT::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; - memory->create(p1,3,"pair:p1"); - memory->create(p2,3,"pair:p2"); - memory->create(param,6,"pair:param"); - memory->create(flocal,2,3,"pair:flocal"); - memory->create(basis,3,3,"pair:basis"); - for(n = 0; n < nbondlist; n++){ i1 = bondlist[n][0]; i2 = bondlist[n][1]; r1 = x[i1]; r2 = x[i2]; - + // reduce neighbors to common list j1list = firstneigh[i1]; @@ -192,10 +197,18 @@ void PairMesoCNT::compute(int eflag, int vflag) for(int j = 0; j < nchain[i]-1; j++){ q1 = x[chain[i][j]]; q2 = x[chain[i][j+1]]; - printf("Vectors q:\n"); + + /* + if(rank == 1){ + printf("Vectors r:\n"); + printf("%e %e %e\n",r1[0],r1[1],r1[2]); + printf("%e %e %e\n",r2[0],r2[1],r2[2]); + printf("Vectors q:\n"); printf("%e %e %e\n",q1[0],q1[1],q1[2]); printf("%e %e %e\n",q2[0],q2[1],q2[2]); fflush(stdout); + } + */ w = weight(r1,r2,q1,q2); sumw += w; @@ -210,21 +223,30 @@ void PairMesoCNT::compute(int eflag, int vflag) scale3(sumwreq,p1); scale3(sumwreq,p2); + /* + if(rank == 1){ + printf("Weight sum:\n"); + printf("%e\n",sumw); printf("Vectors p:\n"); printf("%e %e %e\n",p1[0],p1[1],p1[2]); printf("%e %e %e\n",p2[0],p2[1],p2[2]); fflush(stdout); + } + */ if(end[i] == 1){ geom(r1,r2,p1,p2,param,basis); + if(param[0] > cutoff) continue; fsemi(param,flocal); } else if(end[i] == 2){ geom(r1,r2,p2,p1,param,basis); + if(param[0] > cutoff) continue; fsemi(param,flocal); } else{ geom(r1,r2,p2,p1,param,basis); + if(param[0] > cutoff) continue; finf(param,flocal); } @@ -233,43 +255,61 @@ void PairMesoCNT::compute(int eflag, int vflag) else evdwl = usemi(param); } - f[i1][0] += flocal[0][0]*basis[0][0] - + flocal[0][1]*basis[0][1] - + flocal[0][2]*basis[0][2]; - f[i1][1] += flocal[0][0]*basis[1][0] + double f1x,f1y,f1z,f2x,f2y,f2z; + + f1x = flocal[0][0]*basis[0][0] + + flocal[0][1]*basis[1][0] + + flocal[0][2]*basis[2][0]; + f1y = flocal[0][0]*basis[0][1] + flocal[0][1]*basis[1][1] - + flocal[0][2]*basis[1][2]; - f[i1][2] += flocal[0][0]*basis[2][0] - + flocal[0][1]*basis[2][1] + + flocal[0][2]*basis[2][1]; + f1z = flocal[0][0]*basis[0][2] + + flocal[0][1]*basis[1][2] + flocal[0][2]*basis[2][2]; - f[i2][0] += flocal[1][0]*basis[0][0] - + flocal[1][1]*basis[0][1] - + flocal[1][2]*basis[0][2]; - f[i2][1] += flocal[1][0]*basis[1][0] + f2x = flocal[1][0]*basis[0][0] + + flocal[1][1]*basis[1][0] + + flocal[1][2]*basis[2][0]; + f2y = flocal[1][0]*basis[0][1] + flocal[1][1]*basis[1][1] - + flocal[1][2]*basis[1][2]; - f[i2][2] += flocal[1][0]*basis[2][0] - + flocal[1][1]*basis[2][1] + + flocal[1][2]*basis[2][1]; + f2z = flocal[1][0]*basis[0][2] + + flocal[1][1]*basis[1][2] + flocal[1][2]*basis[2][2]; + f[i1][0] = flocal[0][0]*basis[0][0] + + flocal[0][1]*basis[1][0] + + flocal[0][2]*basis[2][0]; + f[i1][1] = flocal[0][0]*basis[0][1] + + flocal[0][1]*basis[1][1] + + flocal[0][2]*basis[2][1]; + f[i1][2] = flocal[0][0]*basis[0][2] + + flocal[0][1]*basis[1][2] + + flocal[0][2]*basis[2][2]; + f[i2][0] = flocal[1][0]*basis[0][0] + + flocal[1][1]*basis[1][0] + + flocal[1][2]*basis[2][0]; + f[i2][1] = flocal[1][0]*basis[0][1] + + flocal[1][1]*basis[1][1] + + flocal[1][2]*basis[2][1]; + f[i2][2] = flocal[1][0]*basis[0][2] + + flocal[1][1]*basis[1][2] + + flocal[1][2]*basis[2][2]; + + /* printf("Forces:\n"); - printf("%e %e %e\n",f[i1][0],f[i1][1],f[i1][2]); - printf("%e %e %e\n",f[i2][0],f[i2][1],f[i2][2]); + printf("%e %e %e\n",f1x,f1y,f1z); + printf("%e %e %e\n",f2x,f2y,f2z); + printf("Parameters:\n"); + printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); fflush(stdout); + */ } memory->destroy(redlist); memory->destroy(chain); memory->destroy(nchain); memory->destroy(end); - } - - memory->destroy(p1); - memory->destroy(p2); - memory->destroy(param); - memory->destroy(flocal); - memory->destroy(basis); - + } } /* ---------------------------------------------------------------------- */ @@ -317,6 +357,12 @@ void PairMesoCNT::allocate() memory->create(usemi_coeff,pot_points,pot_points,4,"pair:usemi_coeff"); memory->create(phi_coeff,pot_points,pot_points,4,"pair:phi_coeff"); + + memory->create(p1,3,"pair:p1"); + memory->create(p2,3,"pair:p2"); + memory->create(param,6,"pair:param"); + memory->create(flocal,2,3,"pair:flocal"); + memory->create(basis,3,3,"pair:basis"); } /* ---------------------------------------------------------------------- @@ -374,6 +420,15 @@ void PairMesoCNT::coeff(int narg, char **arg) delzeta_phi,&delh_phi,pot_points); } + MPI_Bcast(&start_gamma,1,MPI_DOUBLE,0,world); + MPI_Bcast(&del_gamma,1,MPI_DOUBLE,0,world); + MPI_Bcast(&start_uinf,1,MPI_DOUBLE,0,world); + MPI_Bcast(&del_uinf,1,MPI_DOUBLE,0,world); + MPI_Bcast(&startxi_usemi,1,MPI_DOUBLE,0,world); + MPI_Bcast(&delxi_usemi,1,MPI_DOUBLE,0,world); + MPI_Bcast(&starth_phi,1,MPI_DOUBLE,0,world); + MPI_Bcast(&delh_phi,1,MPI_DOUBLE,0,world); + MPI_Bcast(gamma_data,gamma_points,MPI_DOUBLE,0,world); MPI_Bcast(uinf_data,pot_points,MPI_DOUBLE,0,world); MPI_Bcast(starth_usemi,pot_points,MPI_DOUBLE,0,world); @@ -401,6 +456,7 @@ void PairMesoCNT::coeff(int narg, char **arg) cutsq[i][j] = cutoffsq; } } + } /* ---------------------------------------------------------------------- */ @@ -942,11 +998,12 @@ void PairMesoCNT::finf(double *param, double **f) if(sin_alphasq < SMALL){ f[0][0] = -0.5*(xi2 - xi1)*dspline(h,start_uinf,del_uinf, - uinf_coeff,pot_points); + uinf_coeff,pot_points) * forceunit; f[1][0] = f[0][0]; f[0][1] = 0; f[1][1] = 0; - f[0][2] = spline(h,start_uinf,del_uinf,uinf_coeff,pot_points); + f[0][2] = spline(h,start_uinf,del_uinf,uinf_coeff,pot_points) + * forceunit; f[1][2] = -f[0][2]; } else{ @@ -956,10 +1013,10 @@ void PairMesoCNT::finf(double *param, double **f) double cot_alpha = cos_alpha * sin_alpharec; double omega = 1.0 / (1.0 - comega*sin_alphasq); - double domega = 2 * comega * sin_alpha * cos_alpha * omega * omega; double a1 = omega * sin_alpha; double a1rec = 1.0 / a1; - + double domega = 2 * comega * cos_alpha * a1 * omega; + double gamma_orth = spline(h,start_gamma,del_gamma, gamma_coeff,gamma_points); double gamma = 1.0 + (gamma_orth - 1.0)*sin_alphasq; @@ -971,27 +1028,49 @@ void PairMesoCNT::finf(double *param, double **f) double zeta1 = xi1 * a1; double zeta2 = xi2 * a1; - double phi1 = spline(zeta1,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double phi2 = spline(zeta2,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double dzeta_phi1 = dxspline(zeta1,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double dzeta_phi2 = dxspline(zeta2,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double diff_dzeta_phi = dzeta_phi2 - dzeta_phi1; - double dh_phi1 = dyspline(zeta1,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); - double dh_phi2 = dyspline(zeta2,h,startzeta_phi,starth_phi, - delzeta_phi,delh_phi,phi_coeff,pot_points); + double phi1,phi2,dzeta_phi1,dzeta_phi2,dh_phi1,dh_phi2; + if(zeta1 < 0){ + phi1 = -spline(-zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dzeta_phi1 = -dxspline(-zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dh_phi1 = -dyspline(-zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + } + else{ + phi1 = spline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dzeta_phi1 = dxspline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dh_phi1 = dyspline(zeta1,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + } + if(zeta2 < 0){ + phi2 = -spline(-zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dzeta_phi2 = -dxspline(-zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dh_phi2 = -dyspline(-zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + } + else{ + phi2 = spline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dzeta_phi2 = dxspline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + dh_phi2 = dyspline(zeta2,h,startzeta_phi,starth_phi, + delzeta_phi,delh_phi,phi_coeff,pot_points); + } + double diff_dzeta_phi = dzeta_phi2 - dzeta_phi1; + double a2 = gamma * a1rec; double u = a2 * (phi2 - phi1); double a3 = u * gammarec; double dh_u = dh_gamma * a3 + a2 * (dh_phi2 - dh_phi1); double dalpha_u = dalpha_gamma * a3 - + a2 * (domega*sin_alpha + omega*cos_alpha) + + a1rec * (domega*sin_alpha + omega*cos_alpha) * (gamma*(xi2*dzeta_phi2 - xi1*dzeta_phi1) - u); double lrec = 1.0 / (xi2 - xi1); @@ -1001,7 +1080,7 @@ void PairMesoCNT::finf(double *param, double **f) f[0][0] = lrec * (xi2*dh_u - cx) * forceunit; f[1][0] = lrec * (-xi1*dh_u + cx) * forceunit; f[0][1] = lrec * (dalpha_u - xi2*cy) * forceunit; - f[1][1] = lrec * (-dalpha_u + xi2*cy) * forceunit; + f[1][1] = lrec * (-dalpha_u + xi1*cy) * forceunit; f[0][2] = gamma * dzeta_phi1 * forceunit; f[1][2] = -gamma * dzeta_phi2 * forceunit; } @@ -1011,11 +1090,11 @@ void PairMesoCNT::finf(double *param, double **f) void PairMesoCNT::fsemi(double *param, double **f) { - double h = param[0] * angstrom; + double h = param[0] * angstromrec; double alpha = param[1]; - double xi1 = param[2] * angstrom; - double xi2 = param[3] * angstrom; - double etaend = param[4] * angstrom; + double xi1 = param[2] * angstromrec; + double xi2 = param[3] * angstromrec; + double etaend = param[4] * angstromrec; double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; @@ -1187,7 +1266,7 @@ double PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, const double *p2) { using namespace MathExtra; - double r[3], p[3], delr[3], delp[3], delrp[3]; + double r[3], p[3]; double rho, rhoc, rhomin; add3(r1,r2,r); diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index f8d2cf9264..6b20d906ea 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -31,8 +31,10 @@ class PairMesoCNT : public Pair { double *starth_usemi, *startzeta_phi; double *delh_usemi, *delzeta_phi; double *gamma_data, *uinf_data; + double *p1, *p2, *param; double **usemi_data, **phi_data; double **gamma_coeff, **uinf_coeff; + double **flocal,**basis; double ***usemi_coeff, ***phi_coeff; char *gamma_file, *uinf_file, *usemi_file, *phi_file; From 9f3923e784ba7f462d2f81ac01e4835b56a79b73 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Wed, 29 May 2019 18:03:42 +0100 Subject: [PATCH 013/443] Fixed numerous bugs, nealy working? --- src/MESOCNT/pair_mesocnt.cpp | 307 +++++++++++++++++++++++++++-------- src/MESOCNT/pair_mesocnt.h | 2 +- 2 files changed, 238 insertions(+), 71 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index ec5d2d7f75..d904ac8fb4 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -99,9 +99,11 @@ void PairMesoCNT::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; + //printf("Number of bonds: %d\n",nbondlist); for(n = 0; n < nbondlist; n++){ i1 = bondlist[n][0]; i2 = bondlist[n][1]; + //printf("Local IDs in bond: %d %d\n",i1,i2); r1 = x[i1]; r2 = x[i2]; @@ -113,11 +115,16 @@ void PairMesoCNT::compute(int eflag, int vflag) j1num = numneigh[i1]; j2num = numneigh[i2]; + //printf("Bond neighbours: %d\n",j1num + j2num); + if(j1num + j2num == 0) continue; memory->create(redlist,j1num+j2num,"pair:redlist"); numred = 0; - for(jj1 = 0; jj1 < j1num; jj1++) redlist[numred++] = j1list[jj1]; + for(jj1 = 0; jj1 < j1num; jj1++){ + int ind = j1list[jj1]; + if (ind != i1 && ind != i2) redlist[numred++] = ind; + } for(jj2 = 0; jj2 < j2num; jj2++){ for(jj1 = 0; jj1 < j1num; jj1++){ if(j1list[jj1] == j2list[jj2]){ @@ -129,9 +136,23 @@ void PairMesoCNT::compute(int eflag, int vflag) inflag = 0; continue; } - redlist[numred++] = j2list[jj2]; + int ind = j2list[jj2]; + if (ind != i1 && ind != i2) redlist[numred++] = ind; } + + //printf("Unsorted:\n"); + for(int mm = 0; mm < numred; mm++){ + //printf("%d ",redlist[mm]); + } + //printf("\n"); + //printf("ID:\n"); + for(int mm = 0; mm < numred; mm++){ + //printf("%d ",tag[redlist[mm]]); + } + //printf("\n"); + + // insertion sort according to atom-id for(int mm = 1; mm < numred; mm++){ @@ -139,24 +160,42 @@ void PairMesoCNT::compute(int eflag, int vflag) int loc1 = redlist[m-1]; int loc2 = redlist[m]; while(m > 0 && tag[loc1] > tag[loc2]){ - loc1 = redlist[m-1]; - loc2 = redlist[m]; - m--; redlist[m] = loc1; - redlist[m-1]; + redlist[m-1] = loc2; + m--; + loc1 = redlist[m-1]; + loc2 = redlist[m]; } } + + //printf("Sorted:\n"); + for(int mm = 0; mm < numred; mm++){ + //printf("%d ",redlist[mm]); + } + //printf("\n"); + //printf("ID:\n"); + for(int mm = 0; mm < numred; mm++){ + //printf("%d ",tag[redlist[mm]]); + } + //printf("\n"); + + fflush(stdout); + + // split into connected chains + //printf("Splitting chains\n"); int cid = 0; int cnum = 0; memory->create(chain,numred,numred,"pair:chain"); memory->create(nchain,numred,"pair:nchain"); for(jj = 0; jj < numred-1; jj++){ - int j = redlist[jj]; - chain[cid][cnum++] = j; - if(abs(tag[j] - tag[j+1]) != 1 || mol[j] != mol[j+1]){ + int j1 = redlist[jj]; + int j2 = redlist[jj+1]; + chain[cid][cnum++] = j1; + //printf("%d %d %d %d\n",cid,tag[j1],tag[j2],abs(tag[j1] - tag[j2])); + if(abs(tag[j1] - tag[j2]) != 1 || mol[j1] != mol[j2]){ nchain[cid++] = cnum; cnum = 0; } @@ -164,6 +203,17 @@ void PairMesoCNT::compute(int eflag, int vflag) chain[cid][cnum++] = redlist[numred-1]; nchain[cid++] = cnum; + //printf("Chains:\n"); + for(int i = 0; i < cid; i++){ + int cn = nchain[i]; + //printf("Chain %d: ",i); + for(int j = 0; j < cn; j++){ + //printf("%d ", chain[i][j]); + } + //printf("\n"); + } + fflush(stdout); + // check for ends memory->create(end,cid,"pair:end"); @@ -189,30 +239,31 @@ void PairMesoCNT::compute(int eflag, int vflag) double w,sumwreq,sumw; for(int i = 0; i < cid; i++){ + //printf("Chain length: %d\n",nchain[i]); if(nchain[i] < 2) continue; zero3(p1); zero3(p2); sumw = 0; + + //printf("Vectors r:\n"); + //printf("%e %e %e\n",r1[0],r1[1],r1[2]); + //printf("%e %e %e\n",r2[0],r2[1],r2[2]); + for(int j = 0; j < nchain[i]-1; j++){ q1 = x[chain[i][j]]; q2 = x[chain[i][j+1]]; - - /* - if(rank == 1){ - printf("Vectors r:\n"); - printf("%e %e %e\n",r1[0],r1[1],r1[2]); - printf("%e %e %e\n",r2[0],r2[1],r2[2]); - printf("Vectors q:\n"); - printf("%e %e %e\n",q1[0],q1[1],q1[2]); - printf("%e %e %e\n",q2[0],q2[1],q2[2]); - fflush(stdout); - } - */ - w = weight(r1,r2,q1,q2); + w = weight(r1,r2,q1,q2); sumw += w; - for(int ax = 0; ax < 3; ax++){ + + //printf("Vectors q %d:\n",j); + //printf("%e %e %e\n",q1[0],q1[1],q1[2]); + //printf("%e %e %e\n",q2[0],q2[1],q2[2]); + //printf("Weight: %e\n",w); + fflush(stdout); + + for(int ax = 0; ax < 3; ax++){ p1[ax] += w * q1[ax]; p2[ax] += w * q2[ax]; } @@ -223,32 +274,38 @@ void PairMesoCNT::compute(int eflag, int vflag) scale3(sumwreq,p1); scale3(sumwreq,p2); - /* - if(rank == 1){ - printf("Weight sum:\n"); - printf("%e\n",sumw); - printf("Vectors p:\n"); - printf("%e %e %e\n",p1[0],p1[1],p1[2]); - printf("%e %e %e\n",p2[0],p2[1],p2[2]); + //printf("Weight sum:\n"); + //printf("%e\n",sumw); + //printf("Vectors p:\n"); + //printf("%e %e %e\n",p1[0],p1[1],p1[2]); + //printf("%e %e %e\n",p2[0],p2[1],p2[2]); fflush(stdout); - } - */ + geom(r1,r2,p1,p2,param,basis); + //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + if(param[0] > cutoff || param[0] < diameter) continue; + finf(param,flocal); + + /* if(end[i] == 1){ geom(r1,r2,p1,p2,param,basis); - if(param[0] > cutoff) continue; + //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + if(param[0] > cutoff || param[0] < diameter) continue; fsemi(param,flocal); } else if(end[i] == 2){ geom(r1,r2,p2,p1,param,basis); - if(param[0] > cutoff) continue; + //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + if(param[0] > cutoff || param[0] < diameter) continue; fsemi(param,flocal); } else{ - geom(r1,r2,p2,p1,param,basis); - if(param[0] > cutoff) continue; + geom(r1,r2,p1,p2,param,basis); + //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + if(param[0] > cutoff || param[0] < diameter) continue; finf(param,flocal); } + */ if(eflag){ if(end[i] == 0) evdwl = uinf(param); @@ -276,33 +333,35 @@ void PairMesoCNT::compute(int eflag, int vflag) + flocal[1][1]*basis[1][2] + flocal[1][2]*basis[2][2]; - f[i1][0] = flocal[0][0]*basis[0][0] + f[i1][0] += flocal[0][0]*basis[0][0] + flocal[0][1]*basis[1][0] + flocal[0][2]*basis[2][0]; - f[i1][1] = flocal[0][0]*basis[0][1] + f[i1][1] += flocal[0][0]*basis[0][1] + flocal[0][1]*basis[1][1] + flocal[0][2]*basis[2][1]; - f[i1][2] = flocal[0][0]*basis[0][2] + f[i1][2] += flocal[0][0]*basis[0][2] + flocal[0][1]*basis[1][2] + flocal[0][2]*basis[2][2]; - f[i2][0] = flocal[1][0]*basis[0][0] + f[i2][0] += flocal[1][0]*basis[0][0] + flocal[1][1]*basis[1][0] + flocal[1][2]*basis[2][0]; - f[i2][1] = flocal[1][0]*basis[0][1] + f[i2][1] += flocal[1][0]*basis[0][1] + flocal[1][1]*basis[1][1] + flocal[1][2]*basis[2][1]; - f[i2][2] = flocal[1][0]*basis[0][2] + f[i2][2] += flocal[1][0]*basis[0][2] + flocal[1][1]*basis[1][2] + flocal[1][2]*basis[2][2]; - - /* - printf("Forces:\n"); - printf("%e %e %e\n",f1x,f1y,f1z); - printf("%e %e %e\n",f2x,f2y,f2z); - printf("Parameters:\n"); - printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + + //printf("Forces:\n"); + //printf("%e %e %e\n",f1x,f1y,f1z); + //printf("%e %e %e\n",f2x,f2y,f2z); + //printf("Forces local:\n"); + //printf("%e %e %e\n",flocal[0][0],flocal[0][1],flocal[0][2]); + //printf("%e %e %e\n",flocal[1][0],flocal[1][1],flocal[1][2]); + //printf("Parameters:\n"); + //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); fflush(stdout); - */ + } memory->destroy(redlist); @@ -318,6 +377,8 @@ void PairMesoCNT::init_style() { int irequest; irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; } /* ---------------------------------------------------------------------- */ @@ -404,9 +465,10 @@ void PairMesoCNT::coeff(int narg, char **arg) radius = 1.421*3*n / MY_2PI * angstrom; radiussq = radius * radius; + diameter = 2 * radius; rc = 3 * sigma; - comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius/angstrom)); - ctheta = 0.35 + 0.0226*(radius/angstrom - 6.785); + comega = 0.275*(1.0 - 1.0/(1.0 + 0.59*radius*angstromrec)); + ctheta = 0.35 + 0.0226*(radius*angstromrec - 6.785); //Parse and bcast data int me; @@ -447,9 +509,15 @@ void PairMesoCNT::coeff(int narg, char **arg) int n = atom->ntypes; - cutoff = rc + 2*radius; + cutoff = rc + diameter; double cutoffsq = cutoff * cutoff; + //printf("Radius: %e\n",radius); + //printf("Diameter: %e\n",diameter); + //printf("Sigma: %e\n",sigma); + //printf("Critical distance: %e\n",rc); + //printf("Cutoff: %e\n",cutoff); + for (int i = 1; i <= n; i++){ for (int j = i; j <= n; j++){ setflag[i][j] = 1; @@ -457,6 +525,95 @@ void PairMesoCNT::coeff(int narg, char **arg) } } + std::ofstream outFile1; + std::ofstream outFile2; + std::ofstream outFile3; + outFile1.open("test1.dat"); + outFile2.open("test2.dat"); + outFile3.open("test3.dat"); + double u[1000],f[1000]; + for(int i = 0; i < 1000; i++){ + double angle = 0 + i*1/1000.0 * M_PI; + //double h = diameter + 1.0e-10 + i*0.01e-10; + double h = 1.663866e-09; + double y = 0;//-10e-10 + i*0.02e-10; + double f1x,f1y,f1z,f2x,f2y,f2z; + double r1[3] = {-1.0e-9,y,0}; + double r2[3] = {1.0e-9,y,0}; + double p1[3] = {-1.0e-7*cos(angle),-1.0e-7*sin(angle),h}; + double p2[3] = {1.0e-7*cos(angle),1.0e-7*sin(angle),h}; + double param[6]; + double **basis, **flocal; + memory->create(basis,3,3,"pair:basis"); + memory->create(flocal,2,3,"pair:flocal"); + geom(r1,r2,p1,p2,param,basis); + finf(param,flocal); + f[i] = flocal[0][0]; + u[i] = uinf(param); + memory->destroy(flocal); + memory->destroy(basis); + } + for(int i = 0; i < 1000; i++){ + //double h = diameter + 1.0e-10 + i*0.01e-10; + //double y = -10e-10 + i*0.02e-10; + double h = 1.663866e-09; + double angle = 0 + i*1/1000.0 * M_PI; + outFile1 << angle << " " << u[i] << std::endl; + outFile2 << angle << " " << f[i] << std::endl; + if(i != 0 && i != 999){ + double d = (u[i+1] - u[i-1])/0.04e-10; + outFile3 << angle << " " << d << std::endl; + } + } + outFile1.close(); + outFile2.close(); + outFile3.close(); + + double angle = 0.0/180.0 * M_PI; + double f1x,f1y,f1z,f2x,f2y,f2z; + double r1[3] = {-1.0e-9,0,0}; + double r2[3] = {1.0e-9,0,0}; + double p1[3] = {-1.0e-9*cos(angle),-1.0e-9*sin(angle),1.5e-9}; + double p2[3] = {1.0e-9*cos(angle),1.0e-9*sin(angle),1.5e-9}; + double param[6]; + double **basis, **flocal; + memory->create(basis,3,3,"pair:basis"); + memory->create(flocal,2,3,"pair:flocal"); + geom(r1,r2,p1,p2,param,basis); + finf(param,flocal); + f1x = flocal[0][0]*basis[0][0] + + flocal[0][1]*basis[1][0] + + flocal[0][2]*basis[2][0]; + f1y = flocal[0][0]*basis[0][1] + + flocal[0][1]*basis[1][1] + + flocal[0][2]*basis[2][1]; + f1z = flocal[0][0]*basis[0][2] + + flocal[0][1]*basis[1][2] + + flocal[0][2]*basis[2][2]; + f2x = flocal[1][0]*basis[0][0] + + flocal[1][1]*basis[1][0] + + flocal[1][2]*basis[2][0]; + f2y = flocal[1][0]*basis[0][1] + + flocal[1][1]*basis[1][1] + + flocal[1][2]*basis[2][1]; + f2z = flocal[1][0]*basis[0][2] + + flocal[1][1]*basis[1][2] + + flocal[1][2]*basis[2][2]; + + //printf("Param: %e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + //printf("Forces: \n"); + //printf("%e %e %e\n",f1x,f1y,f1z); + //printf("%e %e %e\n",f2x,f2y,f2z); + //printf("Forces local:\n"); + //printf("%e %e %e \n", flocal[0][0],flocal[0][1],flocal[0][2]); + //printf("%e %e %e \n", flocal[1][0],flocal[1][1],flocal[1][2]); + //printf("Basis: \n"); + //printf("%e %e %e \n",basis[0][0], basis[0][1], basis[0][2]); + //printf("%e %e %e \n",basis[1][0], basis[1][1], basis[1][2]); + //printf("%e %e %e \n",basis[2][0], basis[2][1], basis[2][2]); + + memory->destroy(basis); + memory->destroy(flocal); } /* ---------------------------------------------------------------------- */ @@ -913,7 +1070,8 @@ double PairMesoCNT::uinf(double *param) double sin_alpha = sin(alpha); double sin_alphasq = sin_alpha*sin_alpha; if(sin_alphasq < SMALL){ - return (xi2 - xi1) * spline(h,start_uinf,del_uinf,uinf_coeff,pot_points); + return (xi2 - xi1) * spline(h,start_uinf,del_uinf,uinf_coeff,pot_points) + * qelectron; } else{ double omega = 1.0 / (1.0 - comega*sin_alphasq); @@ -997,7 +1155,7 @@ void PairMesoCNT::finf(double *param, double **f) double sin_alphasq = sin_alpha*sin_alpha; if(sin_alphasq < SMALL){ - f[0][0] = -0.5*(xi2 - xi1)*dspline(h,start_uinf,del_uinf, + f[0][0] = -0.5*(xi1 - xi2)*dspline(h,start_uinf,del_uinf, uinf_coeff,pot_points) * forceunit; f[1][0] = f[0][0]; f[0][1] = 0; @@ -1032,7 +1190,7 @@ void PairMesoCNT::finf(double *param, double **f) if(zeta1 < 0){ phi1 = -spline(-zeta1,h,startzeta_phi,starth_phi, delzeta_phi,delh_phi,phi_coeff,pot_points); - dzeta_phi1 = -dxspline(-zeta1,h,startzeta_phi,starth_phi, + dzeta_phi1 = dxspline(-zeta1,h,startzeta_phi,starth_phi, delzeta_phi,delh_phi,phi_coeff,pot_points); dh_phi1 = -dyspline(-zeta1,h,startzeta_phi,starth_phi, delzeta_phi,delh_phi,phi_coeff,pot_points); @@ -1048,7 +1206,7 @@ void PairMesoCNT::finf(double *param, double **f) if(zeta2 < 0){ phi2 = -spline(-zeta2,h,startzeta_phi,starth_phi, delzeta_phi,delh_phi,phi_coeff,pot_points); - dzeta_phi2 = -dxspline(-zeta2,h,startzeta_phi,starth_phi, + dzeta_phi2 = dxspline(-zeta2,h,startzeta_phi,starth_phi, delzeta_phi,delh_phi,phi_coeff,pot_points); dh_phi2 = -dyspline(-zeta2,h,startzeta_phi,starth_phi, delzeta_phi,delh_phi,phi_coeff,pot_points); @@ -1177,8 +1335,8 @@ void PairMesoCNT::fsemi(double *param, double **f) double cz2 = a1sq*jh2 + cos_alpha*jxi1; double lrec = 1.0 / (xi2 - xi1); - f[0][0] = lrec * (xi2*dh_ubar - cx) * forceunit; - f[1][0] = lrec * (cx - xi1*dh_ubar) * forceunit; + f[0][0] = lrec * (cx - xi2*dh_ubar) * forceunit; + f[1][0] = lrec * (xi1*dh_ubar - cx) * forceunit; f[0][1] = lrec * (dalpha_ubar - xi2*cy) * forceunit; f[1][1] = lrec * (xi1*cy - dalpha_ubar) * forceunit; f[0][2] = lrec * (cz2 + ubar - xi2*cz1) * forceunit; @@ -1196,7 +1354,7 @@ void PairMesoCNT::geom(const double *r1, const double *r2, double psil[3], psim[3], dell_psim[3], delpsil_m[3]; double delr1[3], delr2[3], delp1[3], delp2[3]; double *ex, *ey, *ez; - double psi, frac, taur, taup; + double psi, denom, frac, taur, taup, rhoe; double h, alpha, xi1, xi2, eta1, eta2; ex = basis[0]; @@ -1214,26 +1372,35 @@ void PairMesoCNT::geom(const double *r1, const double *r2, normalize3(l,l); sub3(p2,p1,m); normalize3(m,m); - + psi = dot3(l,m); - frac = 1.0 / (1.0 - psi*psi); - + if(psi > 1.0) psi = 1.0; + else if(psi < -1.0) psi = -1.0; + denom = 1.0 - psi*psi; + copy3(l,psil); scale3(psi,psil); copy3(m,psim); scale3(psi,psim); - sub3(l,psim,dell_psim); - sub3(psil,m,delpsil_m); - taur = dot3(delr,dell_psim) * frac; - taup = dot3(delr,delpsil_m) * frac; + if(denom < SMALL){ + taur = dot3(delr,l); + taup = 0; + } + else{ + frac = 1.0 / denom; + sub3(l,psim,dell_psim); + sub3(psil,m,delpsil_m); + taur = dot3(delr,dell_psim) * frac; + taup = dot3(delr,delpsil_m) * frac; + } scaleadd3(taur,l,r,rbar); scaleadd3(taup,m,p,pbar); sub3(pbar,rbar,delrbar); - - h = len3(delrbar); + h = len3(delrbar); + copy3(delrbar,ex); copy3(l,ez); scale3(1/h,ex); @@ -1274,7 +1441,7 @@ double PairMesoCNT::weight(const double *r1, const double *r2, rhoc = sqrt(0.25*distsq3(r1,r2) + radiussq) + sqrt(0.25*distsq3(p1,p2) + radiussq) + rc; - rhomin = 1.39 * rhoc; + rhomin = 0.72 * rhoc; rho = 0.5 * sqrt(distsq3(r,p)); return s((rho - rhomin)/(rhoc - rhomin)); diff --git a/src/MESOCNT/pair_mesocnt.h b/src/MESOCNT/pair_mesocnt.h index 6b20d906ea..90743499e0 100644 --- a/src/MESOCNT/pair_mesocnt.h +++ b/src/MESOCNT/pair_mesocnt.h @@ -25,7 +25,7 @@ class PairMesoCNT : public Pair { int n, gamma_points, pot_points; double cutoff; double angstrom, angstromrec, qelectron, qelectronrec, forceunit; - double sigma, epsilon, n_sigma, radius, radiussq, rc, rc0, comega, ctheta; + double sigma, epsilon, n_sigma, radius, radiussq, diameter, rc, rc0, comega, ctheta; double start_gamma, start_uinf, startxi_usemi, starth_phi; double del_gamma, del_uinf, delxi_usemi, delh_phi; double *starth_usemi, *startzeta_phi; From 671d6b90ff3667999b250a1bd2e25356001e5ddc Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Thu, 30 May 2019 19:31:38 +0100 Subject: [PATCH 014/443] Fixed bug where segments wouldnt interact and system was blowing up, workin! --- src/MESOCNT/pair_mesocnt.cpp | 85 +++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 25 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index d904ac8fb4..e234d35565 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -123,7 +123,8 @@ void PairMesoCNT::compute(int eflag, int vflag) numred = 0; for(jj1 = 0; jj1 < j1num; jj1++){ int ind = j1list[jj1]; - if (ind != i1 && ind != i2) redlist[numred++] = ind; + if (mol[ind] == mol[i1] && abs(tag[ind] - tag[i1]) < 5) continue; + redlist[numred++] = ind; } for(jj2 = 0; jj2 < j2num; jj2++){ for(jj1 = 0; jj1 < j1num; jj1++){ @@ -137,7 +138,8 @@ void PairMesoCNT::compute(int eflag, int vflag) continue; } int ind = j2list[jj2]; - if (ind != i1 && ind != i2) redlist[numred++] = ind; + if (mol[ind] == mol[i2] && abs(tag[ind] - tag[i2]) < 5) continue; + redlist[numred++] = ind; } @@ -221,6 +223,7 @@ void PairMesoCNT::compute(int eflag, int vflag) int cn = nchain[i]; int tag1 = tag[chain[i][0]]; int tag2 = tag[chain[i][cn-1]]; + end[i] = 0; if(tag1 == 1) end[i] = 1; else{ int idprev = atom->map(tag1-1); @@ -245,6 +248,8 @@ void PairMesoCNT::compute(int eflag, int vflag) zero3(p1); zero3(p2); sumw = 0; + double sumindex1 = 0; + double sumindex2 = 0; //printf("Vectors r:\n"); //printf("%e %e %e\n",r1[0],r1[1],r1[2]); @@ -257,6 +262,8 @@ void PairMesoCNT::compute(int eflag, int vflag) w = weight(r1,r2,q1,q2); sumw += w; + sumindex1 += w * chain[i][j]; + sumindex2 += w * chain[i][j+1]; //printf("Vectors q %d:\n",j); //printf("%e %e %e\n",q1[0],q1[1],q1[2]); //printf("%e %e %e\n",q2[0],q2[1],q2[2]); @@ -271,6 +278,8 @@ void PairMesoCNT::compute(int eflag, int vflag) if(sumw == 0) continue; sumwreq = 1 / sumw; + sumindex1 *= sumwreq; + sumindex2 *= sumwreq; scale3(sumwreq,p1); scale3(sumwreq,p2); @@ -281,31 +290,39 @@ void PairMesoCNT::compute(int eflag, int vflag) //printf("%e %e %e\n",p2[0],p2[1],p2[2]); fflush(stdout); + /* geom(r1,r2,p1,p2,param,basis); //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); if(param[0] > cutoff || param[0] < diameter) continue; finf(param,flocal); + */ /* + printf("End index: %d\n",end[i]); + if(end[i] == 1) printf("Chain end: %d\n",tag[chain[i][0]]); + else if(end[i] == 2) printf("Chain end: %d\n",tag[chain[i][nchain[i]-1]]); + */ + + if(end[i] == 1){ geom(r1,r2,p1,p2,param,basis); //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); - if(param[0] > cutoff || param[0] < diameter) continue; + if(param[0] > cutoff) continue; fsemi(param,flocal); } else if(end[i] == 2){ geom(r1,r2,p2,p1,param,basis); //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); - if(param[0] > cutoff || param[0] < diameter) continue; + if(param[0] > cutoff) continue; fsemi(param,flocal); } else{ geom(r1,r2,p1,p2,param,basis); //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); - if(param[0] > cutoff || param[0] < diameter) continue; + if(param[0] > cutoff) continue; finf(param,flocal); } - */ + if(eflag){ if(end[i] == 0) evdwl = uinf(param); @@ -352,16 +369,34 @@ void PairMesoCNT::compute(int eflag, int vflag) + flocal[1][1]*basis[1][2] + flocal[1][2]*basis[2][2]; - //printf("Forces:\n"); - //printf("%e %e %e\n",f1x,f1y,f1z); - //printf("%e %e %e\n",f2x,f2y,f2z); - //printf("Forces local:\n"); - //printf("%e %e %e\n",flocal[0][0],flocal[0][1],flocal[0][2]); - //printf("%e %e %e\n",flocal[1][0],flocal[1][1],flocal[1][2]); - //printf("Parameters:\n"); - //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); - fflush(stdout); + double fabs1 = flocal[0][0]*flocal[0][0] + + flocal[0][1]*flocal[0][1] + + flocal[0][2]*flocal[0][2]; + double fabs2 = flocal[1][0]*flocal[1][0] + + flocal[1][1]*flocal[1][1] + + flocal[1][2]*flocal[1][2]; + /* + printf("Vectors r:\n"); + printf("%e %e %e\n",r1[0],r1[1],r1[2]); + printf("%e %e %e\n",r2[0],r2[1],r2[2]); + printf("Vectors p:\n"); + printf("%e %e %e\n",p1[0],p1[1],p1[2]); + printf("%e %e %e\n",p2[0],p2[1],p2[2]); + //printf("Indices current segments:\n"); + //printf("%d %d\n",i1,i2); + //printf("Indices chain:\n"); + //printf("%e %e\n",sumindex1,sumindex2); + printf("Forces:\n"); + printf("%e %e %e\n",f1x,f1y,f1z); + printf("%e %e %e\n",f2x,f2y,f2z); + printf("Forces local:\n"); + printf("%e %e %e\n",flocal[0][0],flocal[0][1],flocal[0][2]); + printf("%e %e %e\n",flocal[1][0],flocal[1][1],flocal[1][2]); + printf("Parameters:\n"); + printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + fflush(stdout); + */ } memory->destroy(redlist); @@ -533,13 +568,13 @@ void PairMesoCNT::coeff(int narg, char **arg) outFile3.open("test3.dat"); double u[1000],f[1000]; for(int i = 0; i < 1000; i++){ - double angle = 0 + i*1/1000.0 * M_PI; + double angle = i * 2*M_PI/1000.0; //double h = diameter + 1.0e-10 + i*0.01e-10; double h = 1.663866e-09; double y = 0;//-10e-10 + i*0.02e-10; double f1x,f1y,f1z,f2x,f2y,f2z; double r1[3] = {-1.0e-9,y,0}; - double r2[3] = {1.0e-9,y,0}; + double r2[3] = {1.0-9,y,0}; double p1[3] = {-1.0e-7*cos(angle),-1.0e-7*sin(angle),h}; double p2[3] = {1.0e-7*cos(angle),1.0e-7*sin(angle),h}; double param[6]; @@ -557,7 +592,7 @@ void PairMesoCNT::coeff(int narg, char **arg) //double h = diameter + 1.0e-10 + i*0.01e-10; //double y = -10e-10 + i*0.02e-10; double h = 1.663866e-09; - double angle = 0 + i*1/1000.0 * M_PI; + double angle = 0 + i*2*M_PI/1000.0; outFile1 << angle << " " << u[i] << std::endl; outFile2 << angle << " " << f[i] << std::endl; if(i != 0 && i != 999){ @@ -611,7 +646,7 @@ void PairMesoCNT::coeff(int narg, char **arg) //printf("%e %e %e \n",basis[0][0], basis[0][1], basis[0][2]); //printf("%e %e %e \n",basis[1][0], basis[1][1], basis[1][2]); //printf("%e %e %e \n",basis[2][0], basis[2][1], basis[2][2]); - + memory->destroy(basis); memory->destroy(flocal); } @@ -1155,8 +1190,8 @@ void PairMesoCNT::finf(double *param, double **f) double sin_alphasq = sin_alpha*sin_alpha; if(sin_alphasq < SMALL){ - f[0][0] = -0.5*(xi1 - xi2)*dspline(h,start_uinf,del_uinf, - uinf_coeff,pot_points) * forceunit; + f[0][0] = 0.5 * (xi2 - xi1) * dspline(h,start_uinf,del_uinf, + uinf_coeff,pot_points) * forceunit; f[1][0] = f[0][0]; f[0][1] = 0; f[1][1] = 0; @@ -1262,7 +1297,7 @@ void PairMesoCNT::fsemi(double *param, double **f) double omega = 1.0 / (1.0 - comega*sin_alphasq); double omegasq = omega * omega; - double domega = 2 * comega * sin_alpha * cos_alpha * omega * omega; + double domega = 2 * comega * sin_alpha * cos_alpha * omegasq; double theta = 1.0 - ctheta*sin_alphasq; double dtheta = -2 * ctheta * sin_alpha * cos_alpha; @@ -1281,7 +1316,7 @@ void PairMesoCNT::fsemi(double *param, double **f) gamma_coeff,gamma_points) * sin_alphasq; int points = 100; - double delxi = (xi2 - xi1) / (points -1); + double delxi = (xi2 - xi1) / (points - 1); double a3 = delxi * gamma; double jh = 0; @@ -1335,8 +1370,8 @@ void PairMesoCNT::fsemi(double *param, double **f) double cz2 = a1sq*jh2 + cos_alpha*jxi1; double lrec = 1.0 / (xi2 - xi1); - f[0][0] = lrec * (cx - xi2*dh_ubar) * forceunit; - f[1][0] = lrec * (xi1*dh_ubar - cx) * forceunit; + f[0][0] = lrec * (xi2*dh_ubar - cx) * forceunit; + f[1][0] = lrec * (cx - xi1*dh_ubar) * forceunit; f[0][1] = lrec * (dalpha_ubar - xi2*cy) * forceunit; f[1][1] = lrec * (xi1*cy - dalpha_ubar) * forceunit; f[0][2] = lrec * (cz2 + ubar - xi2*cz1) * forceunit; From 6f72db4535eda8e3b925b09beb89ef3b2a5fb09d Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Mon, 3 Jun 2019 11:01:46 +0100 Subject: [PATCH 015/443] checkpoint for Cottrell --- src/MESOCNT/pair_mesocnt.cpp | 137 ++++++++++++++--------------------- 1 file changed, 56 insertions(+), 81 deletions(-) diff --git a/src/MESOCNT/pair_mesocnt.cpp b/src/MESOCNT/pair_mesocnt.cpp index e234d35565..99b5ee1d2e 100644 --- a/src/MESOCNT/pair_mesocnt.cpp +++ b/src/MESOCNT/pair_mesocnt.cpp @@ -99,11 +99,9 @@ void PairMesoCNT::compute(int eflag, int vflag) numneigh = list->numneigh; firstneigh = list->firstneigh; - //printf("Number of bonds: %d\n",nbondlist); for(n = 0; n < nbondlist; n++){ i1 = bondlist[n][0]; i2 = bondlist[n][1]; - //printf("Local IDs in bond: %d %d\n",i1,i2); r1 = x[i1]; r2 = x[i2]; @@ -115,8 +113,6 @@ void PairMesoCNT::compute(int eflag, int vflag) j1num = numneigh[i1]; j2num = numneigh[i2]; - //printf("Bond neighbours: %d\n",j1num + j2num); - if(j1num + j2num == 0) continue; memory->create(redlist,j1num+j2num,"pair:redlist"); @@ -141,7 +137,8 @@ void PairMesoCNT::compute(int eflag, int vflag) if (mol[ind] == mol[i2] && abs(tag[ind] - tag[i2]) < 5) continue; redlist[numred++] = ind; } - + + if (numred < 2) continue; //printf("Unsorted:\n"); for(int mm = 0; mm < numred; mm++){ @@ -182,7 +179,7 @@ void PairMesoCNT::compute(int eflag, int vflag) } //printf("\n"); - fflush(stdout); + //fflush(stdout); // split into connected chains @@ -196,7 +193,6 @@ void PairMesoCNT::compute(int eflag, int vflag) int j1 = redlist[jj]; int j2 = redlist[jj+1]; chain[cid][cnum++] = j1; - //printf("%d %d %d %d\n",cid,tag[j1],tag[j2],abs(tag[j1] - tag[j2])); if(abs(tag[j1] - tag[j2]) != 1 || mol[j1] != mol[j2]){ nchain[cid++] = cnum; cnum = 0; @@ -205,17 +201,6 @@ void PairMesoCNT::compute(int eflag, int vflag) chain[cid][cnum++] = redlist[numred-1]; nchain[cid++] = cnum; - //printf("Chains:\n"); - for(int i = 0; i < cid; i++){ - int cn = nchain[i]; - //printf("Chain %d: ",i); - for(int j = 0; j < cn; j++){ - //printf("%d ", chain[i][j]); - } - //printf("\n"); - } - fflush(stdout); - // check for ends memory->create(end,cid,"pair:end"); @@ -250,6 +235,7 @@ void PairMesoCNT::compute(int eflag, int vflag) sumw = 0; double sumindex1 = 0; double sumindex2 = 0; + int chainnumber = 0; //printf("Vectors r:\n"); //printf("%e %e %e\n",r1[0],r1[1],r1[2]); @@ -260,65 +246,46 @@ void PairMesoCNT::compute(int eflag, int vflag) q2 = x[chain[i][j+1]]; w = weight(r1,r2,q1,q2); + //if(w < SMALL) continue; + chainnumber++; sumw += w; - - sumindex1 += w * chain[i][j]; - sumindex2 += w * chain[i][j+1]; - //printf("Vectors q %d:\n",j); - //printf("%e %e %e\n",q1[0],q1[1],q1[2]); - //printf("%e %e %e\n",q2[0],q2[1],q2[2]); - //printf("Weight: %e\n",w); - fflush(stdout); - - for(int ax = 0; ax < 3; ax++){ - p1[ax] += w * q1[ax]; - p2[ax] += w * q2[ax]; - } + sumindex1 += w*chain[i][j]; + sumindex2 += w*chain[i][j+1]; + MathExtra::scaleadd3(w,q1,p1,p1); + MathExtra::scaleadd3(w,q2,p2,p2); } - - if(sumw == 0) continue; + if (sumw < SMALL) continue; + sumwreq = 1 / sumw; sumindex1 *= sumwreq; sumindex2 *= sumwreq; scale3(sumwreq,p1); scale3(sumwreq,p2); - - //printf("Weight sum:\n"); - //printf("%e\n",sumw); - //printf("Vectors p:\n"); - //printf("%e %e %e\n",p1[0],p1[1],p1[2]); - //printf("%e %e %e\n",p2[0],p2[1],p2[2]); - fflush(stdout); - - /* - geom(r1,r2,p1,p2,param,basis); - //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); - if(param[0] > cutoff || param[0] < diameter) continue; - finf(param,flocal); - */ - + /* printf("End index: %d\n",end[i]); if(end[i] == 1) printf("Chain end: %d\n",tag[chain[i][0]]); else if(end[i] == 2) printf("Chain end: %d\n",tag[chain[i][nchain[i]-1]]); */ + /* + geom(r1,r2,p1,p2,param,basis); + if(param[0] > cutoff) continue; + finf(param,flocal); + */ if(end[i] == 1){ geom(r1,r2,p1,p2,param,basis); - //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); if(param[0] > cutoff) continue; fsemi(param,flocal); } else if(end[i] == 2){ geom(r1,r2,p2,p1,param,basis); - //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); if(param[0] > cutoff) continue; fsemi(param,flocal); } else{ geom(r1,r2,p1,p2,param,basis); - //printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); if(param[0] > cutoff) continue; finf(param,flocal); } @@ -368,25 +335,21 @@ void PairMesoCNT::compute(int eflag, int vflag) f[i2][2] += flocal[1][0]*basis[0][2] + flocal[1][1]*basis[1][2] + flocal[1][2]*basis[2][2]; - - double fabs1 = flocal[0][0]*flocal[0][0] - + flocal[0][1]*flocal[0][1] - + flocal[0][2]*flocal[0][2]; - double fabs2 = flocal[1][0]*flocal[1][0] - + flocal[1][1]*flocal[1][1] - + flocal[1][2]*flocal[1][2]; - /* + if(false){//update->ntimestep > 2039 && i1 > 500){ + //if(uinf(param)>0){ + printf("Timestep: %d\n",update->ntimestep); printf("Vectors r:\n"); printf("%e %e %e\n",r1[0],r1[1],r1[2]); printf("%e %e %e\n",r2[0],r2[1],r2[2]); printf("Vectors p:\n"); printf("%e %e %e\n",p1[0],p1[1],p1[2]); printf("%e %e %e\n",p2[0],p2[1],p2[2]); - //printf("Indices current segments:\n"); - //printf("%d %d\n",i1,i2); - //printf("Indices chain:\n"); - //printf("%e %e\n",sumindex1,sumindex2); + printf("Indices current segments:\n"); + printf("%d %d\n",i1,i2); + printf("Average indices chain with weight:\n"); + printf("%f %f %f %d\n",sumindex1,sumindex2,sumw,chainnumber); + printf("Energy: %e\n",uinf(param)); printf("Forces:\n"); printf("%e %e %e\n",f1x,f1y,f1z); printf("%e %e %e\n",f2x,f2y,f2z); @@ -395,8 +358,13 @@ void PairMesoCNT::compute(int eflag, int vflag) printf("%e %e %e\n",flocal[1][0],flocal[1][1],flocal[1][2]); printf("Parameters:\n"); printf("%e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); + printf("End index: %d\n",end[i]); + if(end[i] == 1) printf("Chain end: %d\n",tag[chain[i][0]]); + else if(end[i] == 2) printf("Chain end: %d\n",tag[chain[i][nchain[i]-1]]); + printf("\n"); fflush(stdout); - */ + } + } memory->destroy(redlist); @@ -560,23 +528,25 @@ void PairMesoCNT::coeff(int narg, char **arg) } } + /* std::ofstream outFile1; std::ofstream outFile2; std::ofstream outFile3; outFile1.open("test1.dat"); outFile2.open("test2.dat"); outFile3.open("test3.dat"); - double u[1000],f[1000]; + double u[1000][1000],f[1000]; for(int i = 0; i < 1000; i++){ - double angle = i * 2*M_PI/1000.0; - //double h = diameter + 1.0e-10 + i*0.01e-10; - double h = 1.663866e-09; - double y = 0;//-10e-10 + i*0.02e-10; + //double angle = i * 2*M_PI; + for(int j = 0; j < 1000; j++){ + double h = 1.67e-09; + double xpos = -4e-09 + i*8e-12; + double ypos = -1e-09 + j*2e-12; double f1x,f1y,f1z,f2x,f2y,f2z; - double r1[3] = {-1.0e-9,y,0}; - double r2[3] = {1.0-9,y,0}; - double p1[3] = {-1.0e-7*cos(angle),-1.0e-7*sin(angle),h}; - double p2[3] = {1.0e-7*cos(angle),1.0e-7*sin(angle),h}; + double r1[3] = {-0.835e-9 + xpos,ypos,0}; + double r2[3] = {0.835e-9 + xpos,ypos,0}; + double p1[3] = {-1.0e-7,0,h}; + double p2[3] = {1.0e-7,0,h}; double param[6]; double **basis, **flocal; memory->create(basis,3,3,"pair:basis"); @@ -584,21 +554,23 @@ void PairMesoCNT::coeff(int narg, char **arg) geom(r1,r2,p1,p2,param,basis); finf(param,flocal); f[i] = flocal[0][0]; - u[i] = uinf(param); + u[i][j] = uinf(param) / qelectron; memory->destroy(flocal); - memory->destroy(basis); + memory->destroy(basis); + } } for(int i = 0; i < 1000; i++){ //double h = diameter + 1.0e-10 + i*0.01e-10; //double y = -10e-10 + i*0.02e-10; double h = 1.663866e-09; double angle = 0 + i*2*M_PI/1000.0; - outFile1 << angle << " " << u[i] << std::endl; - outFile2 << angle << " " << f[i] << std::endl; - if(i != 0 && i != 999){ - double d = (u[i+1] - u[i-1])/0.04e-10; - outFile3 << angle << " " << d << std::endl; + for(int j = 0; j < 1000; j++){ + double xpos = -4e-9 + i*8e-12; + double ypos = -1e-9 + j*2e-12; + outFile1 << xpos*1.0e10 << " " << ypos*1.0e10 << " " << u[i][j] << std::endl; + //outFile2 << angle << " " << f[i] << std::endl; } + outFile1 << std::endl; } outFile1.close(); outFile2.close(); @@ -634,7 +606,8 @@ void PairMesoCNT::coeff(int narg, char **arg) f2z = flocal[1][0]*basis[0][2] + flocal[1][1]*basis[1][2] + flocal[1][2]*basis[2][2]; - + + */ //printf("Param: %e %e %e %e %e %e\n",param[0],param[1],param[2],param[3],param[4],param[5]); //printf("Forces: \n"); //printf("%e %e %e\n",f1x,f1y,f1z); @@ -647,8 +620,10 @@ void PairMesoCNT::coeff(int narg, char **arg) //printf("%e %e %e \n",basis[1][0], basis[1][1], basis[1][2]); //printf("%e %e %e \n",basis[2][0], basis[2][1], basis[2][2]); + /* memory->destroy(basis); memory->destroy(flocal); + */ } /* ---------------------------------------------------------------------- */ From 8bd17765fd3a0867187455cdee6be25e2d44ea9c Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Wed, 5 Jun 2019 11:30:21 +0100 Subject: [PATCH 016/443] added mesocnt in make --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 3be4e3e78f..e5848d81d7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -54,7 +54,7 @@ endif # PACKEXT = subset that require an external (downloaded) library PACKAGE = asphere body class2 colloid compress coreshell dipole gpu \ - granular kim kokkos kspace latte manybody mc message misc \ + granular kim kokkos kspace latte manybody mc mesocnt message misc \ molecule mpiio mscg opt peri poems \ python qeq replica rigid shock snap spin srd voronoi From eb69bd20b1bcfca582397ee22ec0396b7be0ce69 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Fri, 8 Apr 2022 09:54:22 +0100 Subject: [PATCH 017/443] made rhomin a global macro --- src/MESONT/pair_mesocnt.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 9137b19e7c..03227fd483 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -42,6 +42,7 @@ using namespace MathExtra; #define SMALL 1.0e-6 #define SWITCH 1.0e-6 #define QUADRATURE 100 +#define RHOMIN 10.0 /* ---------------------------------------------------------------------- */ @@ -1515,7 +1516,7 @@ void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, c dr = sqrt(0.25 * distsq3(r1, r2) + rsq); dp = sqrt(0.25 * distsq3(p1, p2) + rsq); rhoc = dr + dp + rc; - rhomin = 20.0 * ang; + rhomin = RHOMIN * ang; rho = sqrt(distsq3(r, p)); frac = 1.0 / (rhoc - rhomin); From cc2b888f1d8e4405ffe21653e03a0bc4c8973e93 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 8 Apr 2022 09:56:08 +0100 Subject: [PATCH 018/443] reduced quadrature points for end interactions to 10 --- src/MESONT/pair_mesocnt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 03227fd483..3078bce082 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -41,7 +41,7 @@ using namespace MathExtra; #define SELF_CUTOFF 20 #define SMALL 1.0e-6 #define SWITCH 1.0e-6 -#define QUADRATURE 100 +#define QUADRATURE 10 #define RHOMIN 10.0 /* ---------------------------------------------------------------------- */ From e1ed62f8bb2134fe8b66650a4fda291b85c794f2 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 8 Apr 2022 10:12:38 +0100 Subject: [PATCH 019/443] added end types to pair_style arguments to find segment - chain end interactions --- src/MESONT/pair_mesocnt.cpp | 44 +++++++++++++++++++++++-------------- src/MESONT/pair_mesocnt.h | 5 ++++- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 3078bce082..1809001513 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -69,6 +69,8 @@ PairMesoCNT::~PairMesoCNT() memory->destroy(cutsq); memory->destroy(setflag); + memory->destroy(end_types); + memory->destroy(uinf_coeff); memory->destroy(gamma_coeff); memory->destroy(phi_coeff); @@ -397,6 +399,8 @@ void PairMesoCNT::allocate() for (int i = 1; i <= ntypes; i++) for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; + memory->create(end_types, nend_types, "pair:end_types"); + memory->create(uinf_coeff, uinf_points, 4, "pair:uinf_coeff"); memory->create(gamma_coeff, gamma_points, 4, "pair:gamma_coeff"); memory->create(phi_coeff, phi_points, phi_points, 4, 4, "pair:phi_coeff"); @@ -435,10 +439,17 @@ void PairMesoCNT::settings(int narg, char ** /* arg */) void PairMesoCNT::coeff(int narg, char **arg) { - if (narg != 3) error->all(FLERR, "Incorrect args for pair coefficients"); + if (narg < 4) error->all(FLERR, "Incorrect args for pair coefficients"); read_file(arg[2]); + + nend_types = narg - 3; + if (!allocated) allocate(); + // end atom types + for (int i = 3; i < narg; i++) + end_types[i - 3] = utils::inumeric(FLERR, arg[i], false, lmp); + // units, eV to energy unit conversion ang = force->angstrom; ang_inv = 1.0 / ang; @@ -771,21 +782,10 @@ void PairMesoCNT::chain_split(int *redlist, int numred, int *nchain, int **chain for (int j = 0; j < cid; j++) { int cstart = chain[j][0]; int cend = chain[j][nchain[j] - 1]; - tagint tagstart = tag[cstart]; - tagint tagend = tag[cend]; - end[j] = 0; - if (tagstart == 1) { - end[j] = 1; - } else { - int idprev = atom->map(tagstart - 1); - if (mol[cstart] != mol[idprev]) end[j] = 1; - } - if (tagend == atom->natoms) { - end[j] = 2; - } else { - int idnext = atom->map(tagend + 1); - if (mol[cend] != mol[idnext]) end[j] = 2; - } + + if (match_end(atom->type[cstart])) end[j] = 1; + else if (match_end(atom->type[cend])) end[j] = 2; + else end[j] = 0; } } @@ -811,6 +811,18 @@ void PairMesoCNT::sort(int *list, int size) } } +/* ---------------------------------------------------------------------- + insertion sort list according to corresponding atom ID +------------------------------------------------------------------------- */ + +bool PairMesoCNT::match_end(int type) +{ + for (int i = 0; i < nend_types; i++) + if (type == end_types[i]) return true; + + return false; +} + /* ---------------------------------------------------------------------- read mesocnt potential file ------------------------------------------------------------------------- */ diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index 795b27f8ff..fd34b7c231 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -33,8 +33,9 @@ class PairMesoCNT : public Pair { double init_one(int, int) override; protected: + int nend_types; int uinf_points, gamma_points, phi_points, usemi_points; - int *reduced_nlist, *numchainlist; + int *end_types, *reduced_nlist, *numchainlist; int **reduced_neighlist, **nchainlist, **endlist; int ***chainlist; @@ -56,6 +57,8 @@ class PairMesoCNT : public Pair { int count_chains(int *, int); + bool match_end(int); + void allocate(); void bond_neigh(); void neigh_common(int, int, int &, int *); From 6f53663b639b09505a16e2c8f68110c92f6e3a66 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 8 Apr 2022 10:17:30 +0100 Subject: [PATCH 020/443] inline spline functions + weight for performance --- src/MESONT/pair_mesocnt.cpp | 12 ++++++------ src/MESONT/pair_mesocnt.h | 17 +++++++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 1809001513..55128ee89f 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -1225,7 +1225,7 @@ void PairMesoCNT::spline_coeff(double **data, double ****coeff, double dx, doubl cubic spline evaluation ------------------------------------------------------------------------- */ -double PairMesoCNT::spline(double x, double xstart, double dx, double **coeff, int coeff_size) +inline double PairMesoCNT::spline(double x, double xstart, double dx, double **coeff, int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1253,7 +1253,7 @@ double PairMesoCNT::spline(double x, double xstart, double dx, double **coeff, i cubic spline derivative ------------------------------------------------------------------------- */ -double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, int coeff_size) +inline double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1281,7 +1281,7 @@ double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, bicubic spline evaluation ------------------------------------------------------------------------- */ -double PairMesoCNT::spline(double x, double y, double xstart, double ystart, double dx, double dy, +inline double PairMesoCNT::spline(double x, double y, double xstart, double ystart, double dx, double dy, double ****coeff, int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1328,7 +1328,7 @@ double PairMesoCNT::spline(double x, double y, double xstart, double ystart, dou bicubic spline partial x derivative ------------------------------------------------------------------------- */ -double PairMesoCNT::dxspline(double x, double y, double xstart, double ystart, double dx, double dy, +inline double PairMesoCNT::dxspline(double x, double y, double xstart, double ystart, double dx, double dy, double ****coeff, int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1373,7 +1373,7 @@ double PairMesoCNT::dxspline(double x, double y, double xstart, double ystart, d bicubic spline partial y derivative ------------------------------------------------------------------------- */ -double PairMesoCNT::dyspline(double x, double y, double xstart, double ystart, double dx, double dy, +inline double PairMesoCNT::dyspline(double x, double y, double xstart, double ystart, double dx, double dy, double ****coeff, int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1513,7 +1513,7 @@ void PairMesoCNT::geometry(const double *r1, const double *r2, const double *p1, weight for substitute CNT chain ------------------------------------------------------------------------- */ -void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, const double *p2, +inline void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, const double *p2, double &w, double *dr1_w, double *dr2_w, double *dp1_w, double *dp2_w) { double dr, dp, rhoc, rhomin, rho, frac, arg, factor; diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index fd34b7c231..329150d7b0 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -73,21 +73,22 @@ class PairMesoCNT : public Pair { void spline_coeff(double *, double **, double, int); void spline_coeff(double **, double ****, double, double, int); - double spline(double, double, double, double **, int); - double dspline(double, double, double, double **, int); - double spline(double, double, double, double, double, double, double ****, int); - double dxspline(double, double, double, double, double, double, double ****, int); - double dyspline(double, double, double, double, double, double, double ****, int); - void geometry(const double *, const double *, const double *, const double *, const double *, double *, double *, double *, double **); - void weight(const double *, const double *, const double *, const double *, double &, double *, - double *, double *, double *); void finf(const double *, double &, double **); void fsemi(const double *, double &, double &, double **); // inlined functions for efficiency + + inline void weight(const double *, const double *, const double *, const double *, double &, double *, + double *, double *, double *); + + inline double spline(double, double, double, double **, int); + inline double dspline(double, double, double, double **, int); + inline double spline(double, double, double, double, double, double, double ****, int); + inline double dxspline(double, double, double, double, double, double, double ****, int); + inline double dyspline(double, double, double, double, double, double, double ****, int); inline double heaviside(double x) { From 8d04b0f9acbce67fa529e6f5d6cbc51380cd62d7 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 8 Apr 2022 10:40:08 +0100 Subject: [PATCH 021/443] added torque correction from chain end --- src/MESONT/pair_mesocnt.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 55128ee89f..c5d33c656e 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -107,8 +107,8 @@ void PairMesoCNT::compute(int eflag, int vflag) double fend, lp, scale, sumw, sumw_inv; double evdwl, evdwl_chain; double *r1, *r2, *q1, *q2, *qe; - double ftotal[3], ftorque[3], torque[3], delr1[3], delr2[3]; - double t1[3], t2[3]; + double ftotal[3], ftorque[3], torque[3], delr1[3], delr2[3], delqe[3]; + double t1[3], t2[3], t3[3]; double dr1_sumw[3], dr2_sumw[3]; double dr1_w[3], dr2_w[3], dq1_w[3], dq2_w[3]; double fgrad_r1_p1[3], fgrad_r1_p2[3], fgrad_r2_p1[3], fgrad_r2_p2[3]; @@ -280,6 +280,15 @@ void PairMesoCNT::compute(int eflag, int vflag) cross3(delr2, fglobal[1], t2); add3(t1, t2, torque); + // additional torque contribution from chain end + + if (endflag) { + sub3(qe, p, delqe); + cross3(delqe, m, t3); + scale3(fend, t3); + add3(t3, torque, torque); + } + cross3(torque, m, ftorque); lp = param[5] - param[4]; scale3(1.0 / lp, ftorque); From fe502c71d379e18296d4fb2a3cc9b5223042ca94 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 8 Apr 2022 16:53:12 +0100 Subject: [PATCH 022/443] moved contents of compute to mesolj function for future modularity --- src/MESONT/pair_mesocnt.cpp | 339 +++++++++++++++++++----------------- src/MESONT/pair_mesocnt.h | 13 +- 2 files changed, 184 insertions(+), 168 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index c5d33c656e..20de200cc0 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -98,6 +98,159 @@ PairMesoCNT::~PairMesoCNT() /* ---------------------------------------------------------------------- */ void PairMesoCNT::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + mesolj(); + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::allocate() +{ + allocated = 1; + int ntypes = atom->ntypes; + int np1 = ntypes + 1; + int init_size = 1; + + memory->create(cutsq, np1, np1, "pair:cutsq"); + memory->create(setflag, np1, np1, "pair:setflag"); + for (int i = 1; i <= ntypes; i++) + for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; + + memory->create(end_types, nend_types, "pair:end_types"); + + memory->create(uinf_coeff, uinf_points, 4, "pair:uinf_coeff"); + memory->create(gamma_coeff, gamma_points, 4, "pair:gamma_coeff"); + memory->create(phi_coeff, phi_points, phi_points, 4, 4, "pair:phi_coeff"); + memory->create(usemi_coeff, usemi_points, usemi_points, 4, 4, "pair:usemi_coeff"); + + memory->create(numchainlist, init_size, "pair:numchainlist"); + memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); + memory->create(endlist, init_size, init_size, "pair:endlist"); + memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); + + memory->create(w, init_size, "pair:w"); + memory->create(wnode, init_size, "pair:wnode"); + memory->create(dq_w, init_size, 3, "pair:dq_w"); + memory->create(q1_dq_w, init_size, 3, 3, "pair:q1_dq_w"); + memory->create(q2_dq_w, init_size, 3, 3, "pair:q2_dq_w"); + + memory->create(param, 7, "pair:param"); + + memory->create(flocal, 2, 3, "pair:flocal"); + memory->create(fglobal, 4, 3, "pair:fglobal"); + memory->create(basis, 3, 3, "pair:basis"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairMesoCNT::settings(int narg, char ** /* arg */) +{ + if (narg != 0) error->all(FLERR, "Illegal pair_style command"); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairMesoCNT::coeff(int narg, char **arg) +{ + if (narg < 4) error->all(FLERR, "Incorrect args for pair coefficients"); + read_file(arg[2]); + + nend_types = narg - 3; + + if (!allocated) allocate(); + + // end atom types + for (int i = 3; i < narg; i++) end_types[i - 3] = utils::inumeric(FLERR, arg[i], false, lmp); + + // units, eV to energy unit conversion + ang = force->angstrom; + ang_inv = 1.0 / ang; + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Pair style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Pair style mesocnt does not recognize this units style"); + funit = eunit * ang_inv; + + // potential variables + sig = sig_ang * ang; + r = r_ang * ang; + rsq = r * r; + d = 2.0 * r; + d_ang = 2.0 * r_ang; + rc = 3.0 * sig; + cutoff = rc + d; + cutoffsq = cutoff * cutoff; + cutoff_ang = cutoff * ang_inv; + cutoffsq_ang = cutoff_ang * cutoff_ang; + comega = 0.275 * (1.0 - 1.0 / (1.0 + 0.59 * r_ang)); + ctheta = 0.35 + 0.0226 * (r_ang - 6.785); + + // compute spline coefficients + spline_coeff(uinf_data, uinf_coeff, delh_uinf, uinf_points); + spline_coeff(gamma_data, gamma_coeff, delh_gamma, gamma_points); + spline_coeff(phi_data, phi_coeff, delh_phi, delpsi_phi, phi_points); + spline_coeff(usemi_data, usemi_coeff, delh_usemi, delxi_usemi, usemi_points); + + memory->destroy(uinf_data); + memory->destroy(gamma_data); + memory->destroy(phi_data); + memory->destroy(usemi_data); + + int ntypes = atom->ntypes; + for (int i = 1; i <= ntypes; i++) + for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairMesoCNT::init_style() +{ + if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt requires atom IDs"); + if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt requires newton pair on"); + + // need a full neighbor list + + neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairMesoCNT::init_one(int /* i */, int /* j */) +{ + return cutoff; +} + +/* ---------------------------------------------------------------------- + calculate energy and forces due to mesoscopic LJ potential +------------------------------------------------------------------------- */ + +void PairMesoCNT::mesolj() { int i, j, k, i1, i2, j1, j2; int endflag, endindex; @@ -119,7 +272,6 @@ void PairMesoCNT::compute(int eflag, int vflag) double temp[3][3]; evdwl = 0.0; - ev_init(eflag, vflag); double **x = atom->x; double **f = atom->f; @@ -284,9 +436,9 @@ void PairMesoCNT::compute(int eflag, int vflag) if (endflag) { sub3(qe, p, delqe); - cross3(delqe, m, t3); - scale3(fend, t3); - add3(t3, torque, torque); + cross3(delqe, m, t3); + scale3(fend, t3); + add3(t3, torque, torque); } cross3(torque, m, ftorque); @@ -390,149 +542,6 @@ void PairMesoCNT::compute(int eflag, int vflag) } } } - - if (vflag_fdotr) virial_fdotr_compute(); -} - -/* ---------------------------------------------------------------------- */ - -void PairMesoCNT::allocate() -{ - allocated = 1; - int ntypes = atom->ntypes; - int np1 = ntypes + 1; - int init_size = 1; - - memory->create(cutsq, np1, np1, "pair:cutsq"); - memory->create(setflag, np1, np1, "pair:setflag"); - for (int i = 1; i <= ntypes; i++) - for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; - - memory->create(end_types, nend_types, "pair:end_types"); - - memory->create(uinf_coeff, uinf_points, 4, "pair:uinf_coeff"); - memory->create(gamma_coeff, gamma_points, 4, "pair:gamma_coeff"); - memory->create(phi_coeff, phi_points, phi_points, 4, 4, "pair:phi_coeff"); - memory->create(usemi_coeff, usemi_points, usemi_points, 4, 4, "pair:usemi_coeff"); - - memory->create(numchainlist, init_size, "pair:numchainlist"); - memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); - memory->create(endlist, init_size, init_size, "pair:endlist"); - memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); - - memory->create(w, init_size, "pair:w"); - memory->create(wnode, init_size, "pair:wnode"); - memory->create(dq_w, init_size, 3, "pair:dq_w"); - memory->create(q1_dq_w, init_size, 3, 3, "pair:q1_dq_w"); - memory->create(q2_dq_w, init_size, 3, 3, "pair:q2_dq_w"); - - memory->create(param, 7, "pair:param"); - - memory->create(flocal, 2, 3, "pair:flocal"); - memory->create(fglobal, 4, 3, "pair:fglobal"); - memory->create(basis, 3, 3, "pair:basis"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairMesoCNT::settings(int narg, char ** /* arg */) -{ - if (narg != 0) error->all(FLERR, "Illegal pair_style command"); -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairMesoCNT::coeff(int narg, char **arg) -{ - if (narg < 4) error->all(FLERR, "Incorrect args for pair coefficients"); - read_file(arg[2]); - - nend_types = narg - 3; - - if (!allocated) allocate(); - - // end atom types - for (int i = 3; i < narg; i++) - end_types[i - 3] = utils::inumeric(FLERR, arg[i], false, lmp); - - // units, eV to energy unit conversion - ang = force->angstrom; - ang_inv = 1.0 / ang; - if (strcmp(update->unit_style, "lj") == 0) - error->all(FLERR, "Pair style mesocnt does not support lj units"); - else if (strcmp(update->unit_style, "real") == 0) - eunit = 23.06054966; - else if (strcmp(update->unit_style, "metal") == 0) - eunit = 1.0; - else if (strcmp(update->unit_style, "si") == 0) - eunit = 1.6021765e-19; - else if (strcmp(update->unit_style, "cgs") == 0) - eunit = 1.6021765e-12; - else if (strcmp(update->unit_style, "electron") == 0) - eunit = 3.674932248e-2; - else if (strcmp(update->unit_style, "micro") == 0) - eunit = 1.6021765e-4; - else if (strcmp(update->unit_style, "nano") == 0) - eunit = 1.6021765e2; - else - error->all(FLERR, "Pair style mesocnt does not recognize this units style"); - funit = eunit * ang_inv; - - // potential variables - sig = sig_ang * ang; - r = r_ang * ang; - rsq = r * r; - d = 2.0 * r; - d_ang = 2.0 * r_ang; - rc = 3.0 * sig; - cutoff = rc + d; - cutoffsq = cutoff * cutoff; - cutoff_ang = cutoff * ang_inv; - cutoffsq_ang = cutoff_ang * cutoff_ang; - comega = 0.275 * (1.0 - 1.0 / (1.0 + 0.59 * r_ang)); - ctheta = 0.35 + 0.0226 * (r_ang - 6.785); - - // compute spline coefficients - spline_coeff(uinf_data, uinf_coeff, delh_uinf, uinf_points); - spline_coeff(gamma_data, gamma_coeff, delh_gamma, gamma_points); - spline_coeff(phi_data, phi_coeff, delh_phi, delpsi_phi, phi_points); - spline_coeff(usemi_data, usemi_coeff, delh_usemi, delxi_usemi, usemi_points); - - memory->destroy(uinf_data); - memory->destroy(gamma_data); - memory->destroy(phi_data); - memory->destroy(usemi_data); - - int ntypes = atom->ntypes; - for (int i = 1; i <= ntypes; i++) - for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairMesoCNT::init_style() -{ - if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt requires atom IDs"); - if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt requires newton pair on"); - - // need a full neighbor list - - neighbor->add_request(this, NeighConst::REQ_FULL); -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairMesoCNT::init_one(int /* i */, int /* j */) -{ - return cutoff; } /* ---------------------------------------------------------------------- @@ -792,9 +801,12 @@ void PairMesoCNT::chain_split(int *redlist, int numred, int *nchain, int **chain int cstart = chain[j][0]; int cend = chain[j][nchain[j] - 1]; - if (match_end(atom->type[cstart])) end[j] = 1; - else if (match_end(atom->type[cend])) end[j] = 2; - else end[j] = 0; + if (match_end(atom->type[cstart])) + end[j] = 1; + else if (match_end(atom->type[cend])) + end[j] = 2; + else + end[j] = 0; } } @@ -912,8 +924,8 @@ void PairMesoCNT::read_file(const char *file) MPI_Bcast(uinf_data, uinf_points, MPI_DOUBLE, 0, world); MPI_Bcast(gamma_data, gamma_points, MPI_DOUBLE, 0, world); - MPI_Bcast(&phi_data[0][0], phi_points*phi_points, MPI_DOUBLE, 0, world); - MPI_Bcast(&usemi_data[0][0], usemi_points*usemi_points, MPI_DOUBLE, 0, world); + MPI_Bcast(&phi_data[0][0], phi_points * phi_points, MPI_DOUBLE, 0, world); + MPI_Bcast(&usemi_data[0][0], usemi_points * usemi_points, MPI_DOUBLE, 0, world); } /* ---------------------------------------------------------------------- @@ -1234,7 +1246,8 @@ void PairMesoCNT::spline_coeff(double **data, double ****coeff, double dx, doubl cubic spline evaluation ------------------------------------------------------------------------- */ -inline double PairMesoCNT::spline(double x, double xstart, double dx, double **coeff, int coeff_size) +inline double PairMesoCNT::spline(double x, double xstart, double dx, double **coeff, + int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1262,7 +1275,8 @@ inline double PairMesoCNT::spline(double x, double xstart, double dx, double **c cubic spline derivative ------------------------------------------------------------------------- */ -inline double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, int coeff_size) +inline double PairMesoCNT::dspline(double x, double xstart, double dx, double **coeff, + int coeff_size) { int i = ceil((x - xstart) / dx); @@ -1290,8 +1304,8 @@ inline double PairMesoCNT::dspline(double x, double xstart, double dx, double ** bicubic spline evaluation ------------------------------------------------------------------------- */ -inline double PairMesoCNT::spline(double x, double y, double xstart, double ystart, double dx, double dy, - double ****coeff, int coeff_size) +inline double PairMesoCNT::spline(double x, double y, double xstart, double ystart, double dx, + double dy, double ****coeff, int coeff_size) { int i = ceil((x - xstart) / dx); int j = ceil((y - ystart) / dy); @@ -1337,8 +1351,8 @@ inline double PairMesoCNT::spline(double x, double y, double xstart, double ysta bicubic spline partial x derivative ------------------------------------------------------------------------- */ -inline double PairMesoCNT::dxspline(double x, double y, double xstart, double ystart, double dx, double dy, - double ****coeff, int coeff_size) +inline double PairMesoCNT::dxspline(double x, double y, double xstart, double ystart, double dx, + double dy, double ****coeff, int coeff_size) { int i = ceil((x - xstart) / dx); int j = ceil((y - ystart) / dy); @@ -1382,8 +1396,8 @@ inline double PairMesoCNT::dxspline(double x, double y, double xstart, double ys bicubic spline partial y derivative ------------------------------------------------------------------------- */ -inline double PairMesoCNT::dyspline(double x, double y, double xstart, double ystart, double dx, double dy, - double ****coeff, int coeff_size) +inline double PairMesoCNT::dyspline(double x, double y, double xstart, double ystart, double dx, + double dy, double ****coeff, int coeff_size) { int i = ceil((x - xstart) / dx); int j = ceil((y - ystart) / dy); @@ -1522,8 +1536,9 @@ void PairMesoCNT::geometry(const double *r1, const double *r2, const double *p1, weight for substitute CNT chain ------------------------------------------------------------------------- */ -inline void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, const double *p2, - double &w, double *dr1_w, double *dr2_w, double *dp1_w, double *dp2_w) +inline void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, + const double *p2, double &w, double *dr1_w, double *dr2_w, + double *dp1_w, double *dp2_w) { double dr, dp, rhoc, rhomin, rho, frac, arg, factor; double r[3], p[3]; diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index 329150d7b0..70445587e7 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -67,8 +67,7 @@ class PairMesoCNT : public Pair { void sort(int *, int); void read_file(const char *); void read_data(PotentialFileReader &, double *, double &, double &, int); - void read_data(PotentialFileReader &, double **, double &, double &, double &, double &, - int); + void read_data(PotentialFileReader &, double **, double &, double &, double &, double &, int); void spline_coeff(double *, double **, double, int); void spline_coeff(double **, double ****, double, double, int); @@ -79,11 +78,13 @@ class PairMesoCNT : public Pair { void finf(const double *, double &, double **); void fsemi(const double *, double &, double &, double **); + void mesolj(); + // inlined functions for efficiency - - inline void weight(const double *, const double *, const double *, const double *, double &, double *, - double *, double *, double *); - + + inline void weight(const double *, const double *, const double *, const double *, double &, + double *, double *, double *, double *); + inline double spline(double, double, double, double **, int); inline double dspline(double, double, double, double **, int); inline double spline(double, double, double, double, double, double, double ****, int); From add992d0dc9c1d2e0fbb72f845560de7847e2fe2 Mon Sep 17 00:00:00 2001 From: phankl Date: Mon, 11 Apr 2022 11:01:15 +0100 Subject: [PATCH 023/443] added viscous damping addition to mesocnt pair_style --- src/MESONT/pair_mesocnt_viscous.cpp | 188 ++++++++++++++++++++++++++++ src/MESONT/pair_mesocnt_viscous.h | 44 +++++++ 2 files changed, 232 insertions(+) create mode 100644 src/MESONT/pair_mesocnt_viscous.cpp create mode 100644 src/MESONT/pair_mesocnt_viscous.h diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp new file mode 100644 index 0000000000..b51e7a0f07 --- /dev/null +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -0,0 +1,188 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Philipp Kloza (University of Cambridge) + pak37@cam.ac.uk +------------------------------------------------------------------------- */ + +#include "pair_mesocnt_viscous.h" + +#include "atom.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "update.h" + +#include +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNTViscous::compute(int eflag, int vflag) +{ + ev_init(eflag, vflag); + + mesolj(); + viscous(); + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairMesoCNTViscous::coeff(int narg, char **arg) +{ + if (narg < 6) error->all(FLERR, "Incorrect args for pair coefficients"); + read_file(arg[2]); + + visc = utils::numeric(FLERR, arg[3], false, lmp); + visc_cutoff = utils::numeric(FLERR, arg[4], false, lmp); + visc_cutoffsq = visc_cutoff * visc_cutoff; + + nend_types = narg - 5; + + if (!allocated) allocate(); + + // end atom types + for (int i = 5; i < narg; i++) end_types[i - 5] = utils::inumeric(FLERR, arg[i], false, lmp); + + // units, eV to energy unit conversion + ang = force->angstrom; + ang_inv = 1.0 / ang; + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Pair style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Pair style mesocnt does not recognize this units style"); + funit = eunit * ang_inv; + + // potential variables + sig = sig_ang * ang; + r = r_ang * ang; + rsq = r * r; + d = 2.0 * r; + d_ang = 2.0 * r_ang; + rc = 3.0 * sig; + cutoff = rc + d; + cutoffsq = cutoff * cutoff; + cutoff_ang = cutoff * ang_inv; + cutoffsq_ang = cutoff_ang * cutoff_ang; + comega = 0.275 * (1.0 - 1.0 / (1.0 + 0.59 * r_ang)); + ctheta = 0.35 + 0.0226 * (r_ang - 6.785); + + // compute spline coefficients + spline_coeff(uinf_data, uinf_coeff, delh_uinf, uinf_points); + spline_coeff(gamma_data, gamma_coeff, delh_gamma, gamma_points); + spline_coeff(phi_data, phi_coeff, delh_phi, delpsi_phi, phi_points); + spline_coeff(usemi_data, usemi_coeff, delh_usemi, delxi_usemi, usemi_points); + + memory->destroy(uinf_data); + memory->destroy(gamma_data); + memory->destroy(phi_data); + memory->destroy(usemi_data); + + int ntypes = atom->ntypes; + for (int i = 1; i <= ntypes; i++) + for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairMesoCNTViscous::init_one(int /* i */, int /* j */) +{ + return (cutoff > visc_cutoff) ? cutoff : visc_cutoff; +} + + +/* ---------------------------------------------------------------------- + calculates viscous damping for all interacting segments within + visc_cutoff +------------------------------------------------------------------------- */ + +void PairMesoCNTViscous::viscous() +{ + int i, j, ii, jj, inum, jnum; + double xtmp, ytmp, ztmp, delx, dely, delz; + double vxtmp, vytmp, vztmp; + double fx, fy, fz; + double rsq; + int *ilist, *jlist, *numneigh, **firstneigh; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + for (ii = 0; ii < inum; i++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq < visc_cutoffsq) { + fx = visc * (v[j][0] - vxtmp); + fy = visc * (v[j][1] - vytmp); + fz = visc * (v[j][2] - vztmp); + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + } + } + } +} diff --git a/src/MESONT/pair_mesocnt_viscous.h b/src/MESONT/pair_mesocnt_viscous.h new file mode 100644 index 0000000000..c0c3d05f65 --- /dev/null +++ b/src/MESONT/pair_mesocnt_viscous.h @@ -0,0 +1,44 @@ +/* -*- 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 +PairStyle(mesocnt/viscous, PairMesoCNTViscous); +#else + +#ifndef LMP_PAIR_MESOCNT_VISCOUS_H +#define LMP_PAIR_MESOCNT_VISCOUS_H + +#include "pair_mesocnt.h" + +namespace LAMMPS_NS { +class PairMesoCNTViscous : public PairMesoCNT { + public: + using PairMesoCNT::PairMesoCNT; + + void compute(int, int) override; + void coeff(int, char **) override; + + double init_one(int, int) override; + + protected: + double visc; + double visc_cutoff, visc_cutoffsq; + + void viscous(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + From 36272b3267d5a987ff5477837cbb87be5aa3481c Mon Sep 17 00:00:00 2001 From: phankl Date: Mon, 11 Apr 2022 11:01:56 +0100 Subject: [PATCH 024/443] added buckling angle_style header file --- src/MESONT/angle_mesocnt.h | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/MESONT/angle_mesocnt.h diff --git a/src/MESONT/angle_mesocnt.h b/src/MESONT/angle_mesocnt.h new file mode 100644 index 0000000000..47e988866a --- /dev/null +++ b/src/MESONT/angle_mesocnt.h @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + 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 ANGLE_CLASS +AngleStyle(mesocnt, AngleMesoCNT); +#else + +#ifndef LMP_ANGLE_MESOCNT_H +#define LMP_ANGLE_MESOCNT_H + +#include "angle.h" + +namespace LAMMPS_NS { + +class AngleMesoCNT : public Angle { + public: + AngleMesoCNT(class LAMMPS *); + ~AngleMesoCNT() override; + void compute(int, int) override; + void coeff(int, char **) override; + double equilibrium_angle(int) override; + void write_restart(FILE *) override; + void read_restart(FILE *) override; + void write_data(FILE *) override; + double single(int, int, int, int) override; + + protected: + double *kh, *kb, *thetab; + + virtual void allocate(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Incorrect args for angle coefficients + +Self-explanatory. Check the input script or data file. + +*/ From fd348f3a81f8b9f6e43173f3a38a256999923e0c Mon Sep 17 00:00:00 2001 From: phankl Date: Tue, 12 Apr 2022 15:28:32 +0100 Subject: [PATCH 025/443] added bending buckling angle style cpp file --- src/MESONT/angle_mesocnt.cpp | 294 +++++++++++++++++++++++++++++++++++ src/MESONT/angle_mesocnt.h | 2 +- 2 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 src/MESONT/angle_mesocnt.cpp diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp new file mode 100644 index 0000000000..85a45b5c7e --- /dev/null +++ b/src/MESONT/angle_mesocnt.cpp @@ -0,0 +1,294 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#include "angle_mesocnt.h" + +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "math_const.h" +#include "memory.h" +#include "neighbor.h" + +#include + +using namespace LAMMPS_NS; +using MathConst::DEG2RAD; +using MathConst::RAD2DEG; + +static constexpr double SMALL = 0.001; + +/* ---------------------------------------------------------------------- */ + +AngleMesoCNT::AngleMesoCNT(LAMMPS *_lmp) : Angle(_lmp) +{ + kh = nullptr; + kb = nullptr; + thetab = nullptr; +} + +/* ---------------------------------------------------------------------- */ + +AngleMesoCNT::~AngleMesoCNT() +{ + if (allocated && !copymode) { + memory->destroy(setflag); + memory->destroy(kh); + memory->destroy(kb); + memory->destroy(thetab); + memory->destroy(theta0); + } +} + +/* ---------------------------------------------------------------------- */ + +void AngleMesoCNT::compute(int eflag, int vflag) +{ + int i1, i2, i3, n, type; + double delx1, dely1, delz1, delx2, dely2, delz2; + double eangle, f1[3], f3[3]; + double dtheta, tk; + double rsq1, rsq2, r1, r2, c, s, a, a11, a12, a22; + + eangle = 0.0; + ev_init(eflag, vflag); + + double **x = atom->x; + double **f = atom->f; + int **anglelist = neighbor->anglelist; + int nanglelist = neighbor->nanglelist; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + for (n = 0; n < nanglelist; n++) { + i1 = anglelist[n][0]; + i2 = anglelist[n][1]; + i3 = anglelist[n][2]; + type = anglelist[n][3]; + + // 1st bond + + delx1 = x[i1][0] - x[i2][0]; + dely1 = x[i1][1] - x[i2][1]; + delz1 = x[i1][2] - x[i2][2]; + + rsq1 = delx1 * delx1 + dely1 * dely1 + delz1 * delz1; + r1 = sqrt(rsq1); + + // 2nd bond + + delx2 = x[i3][0] - x[i2][0]; + dely2 = x[i3][1] - x[i2][1]; + delz2 = x[i3][2] - x[i2][2]; + + rsq2 = delx2 * delx2 + dely2 * dely2 + delz2 * delz2; + r2 = sqrt(rsq2); + + // angle (cos and sin) + + c = delx1 * delx2 + dely1 * dely2 + delz1 * delz2; + c /= r1 * r2; + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + s = sqrt(1.0 - c * c); + if (s < SMALL) s = SMALL; + s = 1.0 / s; + + // force & energy + + dtheta = acos(c) - theta0[type]; + + // harmonic bending + if (fabs(dtheta) < thetab[type]) { + tk = kh[type] * dtheta; + if (eflag) eangle = tk * dtheta; + a = -2.0 * tk * s; + } + // bending buckling + else { + if (eflag) eangle = kb[type] * fabs(dtheta) + thetab[type] * (kh[type] * thetab[type] - kb[type]); + if (dtheta < 0) a = kb[type] * s; + else a = -kb[type] * s; + } + a11 = a * c / rsq1; + a12 = -a / (r1 * r2); + a22 = a * c / rsq2; + + f1[0] = a11 * delx1 + a12 * delx2; + f1[1] = a11 * dely1 + a12 * dely2; + f1[2] = a11 * delz1 + a12 * delz2; + f3[0] = a22 * delx2 + a12 * delx1; + f3[1] = a22 * dely2 + a12 * dely1; + f3[2] = a22 * delz2 + a12 * delz1; + + // apply force to each of 3 atoms + + if (newton_bond || i1 < nlocal) { + f[i1][0] += f1[0]; + f[i1][1] += f1[1]; + f[i1][2] += f1[2]; + } + + if (newton_bond || i2 < nlocal) { + f[i2][0] -= f1[0] + f3[0]; + f[i2][1] -= f1[1] + f3[1]; + f[i2][2] -= f1[2] + f3[2]; + } + + if (newton_bond || i3 < nlocal) { + f[i3][0] += f3[0]; + f[i3][1] += f3[1]; + f[i3][2] += f3[2]; + } + + if (evflag) + ev_tally(i1, i2, i3, nlocal, newton_bond, eangle, f1, f3, delx1, dely1, delz1, delx2, dely2, + delz2); + } +} + +/* ---------------------------------------------------------------------- */ + +void AngleMesoCNT::allocate() +{ + allocated = 1; + const int np1 = atom->nangletypes + 1; + + memory->create(kh, np1, "angle:kh"); + memory->create(kb, np1, "angle:kb"); + memory->create(thetab, np1, "angle:thetab"); + memory->create(theta0, np1, "angle:theta0"); + + memory->create(setflag, np1, "angle:setflag"); + for (int i = 1; i < np1; i++) setflag[i] = 0; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more types +------------------------------------------------------------------------- */ + +void AngleMesoCNT::coeff(int narg, char **arg) +{ + if (narg != 4) error->all(FLERR, "Incorrect args for angle coefficients"); + if (!allocated) allocate(); + + int ilo, ihi; + utils::bounds(FLERR, arg[0], 1, atom->nangletypes, ilo, ihi, error); + + double kh_one = utils::numeric(FLERR, arg[1], false, lmp); + double kb_one = utils::numeric(FLERR, arg[2], false, lmp); + double thetab_one = utils::numeric(FLERR, arg[3], false, lmp); + + // convert thetab from degrees to radians + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + kh[i] = kh_one; + kb[i] = kb_one; + thetab[i] = DEG2RAD * thetab_one; + theta0[i] = DEG2RAD * 180.0; + setflag[i] = 1; + count++; + } + + if (count == 0) error->all(FLERR, "Incorrect args for angle coefficients"); +} + +/* ---------------------------------------------------------------------- */ + +double AngleMesoCNT::equilibrium_angle(int i) +{ + return 180.0; +} + +/* ---------------------------------------------------------------------- + proc 0 writes out coeffs to restart file +------------------------------------------------------------------------- */ + +void AngleMesoCNT::write_restart(FILE *fp) +{ + fwrite(&kh[1], sizeof(double), atom->nangletypes, fp); + fwrite(&kb[1], sizeof(double), atom->nangletypes, fp); + fwrite(&thetab[1], sizeof(double), atom->nangletypes, fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads coeffs from restart file, bcasts them +------------------------------------------------------------------------- */ + +void AngleMesoCNT::read_restart(FILE *fp) +{ + allocate(); + + if (comm->me == 0) { + utils::sfread(FLERR, &kh[1], sizeof(double), atom->nangletypes, fp, nullptr, error); + utils::sfread(FLERR, &kb[1], sizeof(double), atom->nangletypes, fp, nullptr, error); + utils::sfread(FLERR, &thetab[1], sizeof(double), atom->nangletypes, fp, nullptr, error); + } + MPI_Bcast(&kh[1], atom->nangletypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&kb[1], atom->nangletypes, MPI_DOUBLE, 0, world); + MPI_Bcast(&thetab[1], atom->nangletypes, MPI_DOUBLE, 0, world); + + for (int i = 1; i <= atom->nangletypes; i++) { + theta0[i] = 180.0; + setflag[i] = 1; + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void AngleMesoCNT::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->nangletypes; i++) + fprintf(fp, "%d %g %g %g\n", i, kh[i], kb[i], RAD2DEG * thetab[i]); +} + +/* ---------------------------------------------------------------------- */ + +double AngleMesoCNT::single(int type, int i1, int i2, int i3) +{ + double **x = atom->x; + + double delx1 = x[i1][0] - x[i2][0]; + double dely1 = x[i1][1] - x[i2][1]; + double delz1 = x[i1][2] - x[i2][2]; + domain->minimum_image(delx1, dely1, delz1); + double r1 = sqrt(delx1 * delx1 + dely1 * dely1 + delz1 * delz1); + + double delx2 = x[i3][0] - x[i2][0]; + double dely2 = x[i3][1] - x[i2][1]; + double delz2 = x[i3][2] - x[i2][2]; + domain->minimum_image(delx2, dely2, delz2); + double r2 = sqrt(delx2 * delx2 + dely2 * dely2 + delz2 * delz2); + + double c = delx1 * delx2 + dely1 * dely2 + delz1 * delz2; + c /= r1 * r2; + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + double dtheta = acos(c) - theta0[type]; + + // harmonic bending + if (dtheta < thetab[type]) { + double tk = kh[type] * dtheta; + return tk * dtheta; + } + // bending buckling + else return kb[type] * dtheta + thetab[type] * (kh[type] * thetab[type] - kb[type]); +} diff --git a/src/MESONT/angle_mesocnt.h b/src/MESONT/angle_mesocnt.h index 47e988866a..34960e4de8 100644 --- a/src/MESONT/angle_mesocnt.h +++ b/src/MESONT/angle_mesocnt.h @@ -35,7 +35,7 @@ class AngleMesoCNT : public Angle { double single(int, int, int, int) override; protected: - double *kh, *kb, *thetab; + double *kh, *kb, *thetab, *theta0; virtual void allocate(); }; From ac00cdb67f1189356edd3cccf107b1f8d41c7dab Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 20 Apr 2022 16:09:38 +0100 Subject: [PATCH 026/443] fixed typo in viscous loop increment --- src/MESONT/pair_mesocnt_viscous.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index b51e7a0f07..46e8f289e3 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -150,7 +150,7 @@ void PairMesoCNTViscous::viscous() numneigh = list->numneigh; firstneigh = list->firstneigh; - for (ii = 0; ii < inum; i++) { + for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; From 95269980dd2d25f59ee41515cd053dc2bee11620 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 29 Apr 2022 15:28:07 +0100 Subject: [PATCH 027/443] viscosity changed to two piecewise linear regimes + weighted chain approach for velocity --- src/MESONT/pair_mesocnt.cpp | 1 + src/MESONT/pair_mesocnt_viscous.cpp | 452 ++++++++++++++++++++++++---- src/MESONT/pair_mesocnt_viscous.h | 7 +- 3 files changed, 388 insertions(+), 72 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 20de200cc0..4fe99fbe94 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -1534,6 +1534,7 @@ void PairMesoCNT::geometry(const double *r1, const double *r2, const double *p1, /* ---------------------------------------------------------------------- weight for substitute CNT chain + computes gradients with respect to positions ------------------------------------------------------------------------- */ inline void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 46e8f289e3..9d8e72b443 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -21,6 +21,7 @@ #include "atom.h" #include "error.h" #include "force.h" +#include "math_extra.h" #include "memory.h" #include "neigh_list.h" #include "neighbor.h" @@ -30,15 +31,348 @@ #include using namespace LAMMPS_NS; +using namespace MathExtra; + +#define RHOMIN 10.0 /* ---------------------------------------------------------------------- */ void PairMesoCNTViscous::compute(int eflag, int vflag) { ev_init(eflag, vflag); + + int i, j, k, i1, i2, j1, j2; + int endflag, endindex; + int clen, numchain; + int *end, *nchain; + int **chain; + double fend, lp, scale, sumw, sumw_inv; + double evdwl, evdwl_chain; + double vtot, fvisc_tot; + double *r1, *r2, *q1, *q2, *qe; + double *vr1, *vr2, *vq1, *vq2; + double vr[3], vp1[3], vp2[3], vp[3], vrel[3], fvisc[3]; + double ftotal[3], ftorque[3], torque[3], delr1[3], delr2[3], delqe[3]; + double t1[3], t2[3], t3[3]; + double dr1_sumw[3], dr2_sumw[3]; + double dr1_w[3], dr2_w[3], dq1_w[3], dq2_w[3]; + double fgrad_r1_p1[3], fgrad_r1_p2[3], fgrad_r2_p1[3], fgrad_r2_p2[3]; + double fgrad_q_p1[3], fgrad_q_p2[3]; + double q1_dr1_w[3][3], q1_dr2_w[3][3], q2_dr1_w[3][3], q2_dr2_w[3][3]; + double dr1_p1[3][3], dr1_p2[3][3], dr2_p1[3][3], dr2_p2[3][3]; + double dq_p1[3][3], dq_p2[3][3]; + double temp[3][3]; - mesolj(); - viscous(); + evdwl = 0.0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + + // update bond neighbor list when necessary + + if (update->ntimestep == neighbor->lastcall) bond_neigh(); + + // iterate over all bonds + + for (i = 0; i < nbondlist; i++) { + i1 = bondlist[i][0]; + i2 = bondlist[i][1]; + + r1 = x[i1]; + r2 = x[i2]; + + vr1 = v[i1]; + vr2 = v[i2]; + add3(vr1, vr2, vr); + scale3(0.5, vr); + + numchain = numchainlist[i]; + end = endlist[i]; + nchain = nchainlist[i]; + chain = chainlist[i]; + + // iterate over all neighbouring chains + + for (j = 0; j < numchain; j++) { + clen = nchain[j]; + if (clen < 2) continue; + + // assign end position + + endflag = end[j]; + if (endflag == 1) { + endindex = chain[j][0]; + qe = x[endindex]; + } else if (endflag == 2) { + endindex = chain[j][clen - 1]; + qe = x[endindex]; + } + + // compute substitute straight (semi-)infinite CNT + + zero3(p1); + zero3(p2); + zero3(dr1_sumw); + zero3(dr2_sumw); + zero3(vp1); + zero3(vp2); + zeromat3(q1_dr1_w); + zeromat3(q2_dr1_w); + zeromat3(q1_dr2_w); + zeromat3(q2_dr2_w); + for (k = 0; k < clen; k++) { + wnode[k] = 0.0; + zero3(dq_w[k]); + zeromat3(q1_dq_w[k]); + zeromat3(q2_dq_w[k]); + } + sumw = 0.0; + + for (k = 0; k < clen - 1; k++) { + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + q1 = x[j1]; + q2 = x[j2]; + vq1 = v[j1]; + vq2 = v[j2]; + + weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); + + if (w[k] == 0.0) { + if (endflag == 1 && k == 0) + endflag = 0; + else if (endflag == 2 && k == clen - 2) + endflag = 0; + continue; + } + + sumw += w[k]; + wnode[k] += w[k]; + wnode[k + 1] += w[k]; + + scaleadd3(w[k], q1, p1, p1); + scaleadd3(w[k], q2, p2, p2); + + // weighted velocity for friction + + scaleadd3(w[k], vq1, vp1, vp1); + scaleadd3(w[k], vq2, vp2, vp2); + + // weight gradient terms + + add3(dr1_w, dr1_sumw, dr1_sumw); + add3(dr2_w, dr2_sumw, dr2_sumw); + + outer3(q1, dr1_w, temp); + plus3(temp, q1_dr1_w, q1_dr1_w); + outer3(q2, dr1_w, temp); + plus3(temp, q2_dr1_w, q2_dr1_w); + outer3(q1, dr2_w, temp); + plus3(temp, q1_dr2_w, q1_dr2_w); + outer3(q2, dr2_w, temp); + plus3(temp, q2_dr2_w, q2_dr2_w); + + add3(dq1_w, dq_w[k], dq_w[k]); + add3(dq2_w, dq_w[k + 1], dq_w[k + 1]); + + outer3(q1, dq1_w, temp); + plus3(temp, q1_dq_w[k], q1_dq_w[k]); + outer3(q1, dq2_w, temp); + plus3(temp, q1_dq_w[k + 1], q1_dq_w[k + 1]); + outer3(q2, dq1_w, temp); + plus3(temp, q2_dq_w[k], q2_dq_w[k]); + outer3(q2, dq2_w, temp); + plus3(temp, q2_dq_w[k + 1], q2_dq_w[k + 1]); + } + + if (sumw == 0.0) continue; + + sumw_inv = 1.0 / sumw; + scale3(sumw_inv, p1); + scale3(sumw_inv, p2); + + // compute geometry and forces + + // infinite CNT case + + if (endflag == 0) { + geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); + if (param[0] > cutoff) continue; + finf(param, evdwl, flocal); + + // semi-infinite CNT case with end at start of chain + + } else if (endflag == 1) { + geometry(r1, r2, p1, p2, qe, p, m, param, basis); + if (param[0] > cutoff) continue; + fsemi(param, evdwl, fend, flocal); + + // semi-infinite CNT case with end at end of chain + + } else { + geometry(r1, r2, p2, p1, qe, p, m, param, basis); + if (param[0] > cutoff) continue; + fsemi(param, evdwl, fend, flocal); + } + + evdwl *= 0.5; + + // transform to global coordinate system + + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + + // mean chain velocity and relative velocity + + add3(vp1, vp2, vp); + scale3(0.5*sumw_inv, vp); + sub3(vp, vr, vrel); + + // friction forces + + vtot = len3(vrel); + if (vtot < vswitch) scale3(0.25*a1, vrel, fvisc); + else { + fvisc_tot = b2 / vtot - a2; + if (fvisc_tot < 0.0) zero3(fvisc); + else scale3(0.25*fvisc_tot, vrel, fvisc); + } + + add3(fvisc, f[i1], f[i1]); + add3(fvisc, f[i2], f[i2]); + + // forces acting on approximate chain + + add3(fglobal[0], fglobal[1], ftotal); + if (endflag) scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); + + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); + + // additional torque contribution from chain end + + if (endflag) { + sub3(qe, p, delqe); + cross3(delqe, m, t3); + scale3(fend, t3); + add3(t3, torque, torque); + } + + cross3(torque, m, ftorque); + lp = param[5] - param[4]; + scale3(1.0 / lp, ftorque); + + if (endflag == 2) { + add3(ftotal, ftorque, fglobal[3]); + sub3(ftotal, ftorque, fglobal[2]); + } else { + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + } + + scale3(0.5, fglobal[0]); + scale3(0.5, fglobal[1]); + scale3(0.5, fglobal[2]); + scale3(0.5, fglobal[3]); + + // weight gradient terms acting on current segment + + outer3(p1, dr1_sumw, temp); + minus3(q1_dr1_w, temp, dr1_p1); + outer3(p2, dr1_sumw, temp); + minus3(q2_dr1_w, temp, dr1_p2); + outer3(p1, dr2_sumw, temp); + minus3(q1_dr2_w, temp, dr2_p1); + outer3(p2, dr2_sumw, temp); + minus3(q2_dr2_w, temp, dr2_p2); + + transpose_matvec(dr1_p1, fglobal[2], fgrad_r1_p1); + transpose_matvec(dr1_p2, fglobal[3], fgrad_r1_p2); + transpose_matvec(dr2_p1, fglobal[2], fgrad_r2_p1); + transpose_matvec(dr2_p2, fglobal[3], fgrad_r2_p2); + + // add forces to nodes in current segment + + add3(fglobal[0], f[i1], f[i1]); + add3(fglobal[1], f[i2], f[i2]); + + scaleadd3(sumw_inv, fgrad_r1_p1, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r1_p2, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r2_p1, f[i2], f[i2]); + scaleadd3(sumw_inv, fgrad_r2_p2, f[i2], f[i2]); + + // add forces in approximate chain + + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + scale = w[k] * sumw_inv; + scaleadd3(scale, fglobal[2], f[j1], f[j1]); + scaleadd3(scale, fglobal[3], f[j2], f[j2]); + + // friction forces + + scaleadd3(-scale, fvisc, f[j1], f[j1]); + scaleadd3(-scale, fvisc, f[j2], f[j2]); + } + + // weight gradient terms acting on approximate chain + // iterate over nodes instead of segments + + for (k = 0; k < clen; k++) { + if (wnode[k] == 0.0) continue; + j1 = chain[j][k]; + j1 &= NEIGHMASK; + + outer3(p1, dq_w[k], temp); + minus3(q1_dq_w[k], temp, dq_p1); + outer3(p2, dq_w[k], temp); + minus3(q2_dq_w[k], temp, dq_p2); + + transpose_matvec(dq_p1, fglobal[2], fgrad_q_p1); + transpose_matvec(dq_p2, fglobal[3], fgrad_q_p2); + + scaleadd3(sumw_inv, fgrad_q_p1, f[j1], f[j1]); + scaleadd3(sumw_inv, fgrad_q_p2, f[j1], f[j1]); + } + + // force on node at CNT end + + if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); + + // compute energy + + if (eflag_either) { + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += 0.25 * evdwl; + eatom[i2] += 0.25 * evdwl; + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + evdwl_chain = 0.5 * w[k] * sumw_inv * evdwl; + eatom[j1] += evdwl_chain; + eatom[j2] += evdwl_chain; + } + } + } + } + } if (vflag_fdotr) virial_fdotr_compute(); } @@ -52,16 +386,18 @@ void PairMesoCNTViscous::coeff(int narg, char **arg) if (narg < 6) error->all(FLERR, "Incorrect args for pair coefficients"); read_file(arg[2]); - visc = utils::numeric(FLERR, arg[3], false, lmp); - visc_cutoff = utils::numeric(FLERR, arg[4], false, lmp); - visc_cutoffsq = visc_cutoff * visc_cutoff; + a1 = utils::numeric(FLERR, arg[3], false, lmp); + a2 = utils::numeric(FLERR, arg[4], false, lmp); + vswitch = utils::numeric(FLERR, arg[5], false, lmp); + + b2 = (a1 + a2) * vswitch; - nend_types = narg - 5; + nend_types = narg - 6; if (!allocated) allocate(); // end atom types - for (int i = 5; i < narg; i++) end_types[i - 5] = utils::inumeric(FLERR, arg[i], false, lmp); + for (int i = 6; i < narg; i++) end_types[i - 6] = utils::inumeric(FLERR, arg[i], false, lmp); // units, eV to energy unit conversion ang = force->angstrom; @@ -116,73 +452,57 @@ void PairMesoCNTViscous::coeff(int narg, char **arg) for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; } -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairMesoCNTViscous::init_one(int /* i */, int /* j */) -{ - return (cutoff > visc_cutoff) ? cutoff : visc_cutoff; -} - /* ---------------------------------------------------------------------- - calculates viscous damping for all interacting segments within - visc_cutoff + weight for substitute CNT chain ------------------------------------------------------------------------- */ -void PairMesoCNTViscous::viscous() +inline void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, + const double *p2, double &w, double *dr1_w, double *dr2_w, + double *dp1_w, double *dp2_w) { - int i, j, ii, jj, inum, jnum; - double xtmp, ytmp, ztmp, delx, dely, delz; - double vxtmp, vytmp, vztmp; - double fx, fy, fz; - double rsq; - int *ilist, *jlist, *numneigh, **firstneigh; + double dr, dp, rhoc, rhomin, rho, frac, arg, factor; + double r[3], p[3]; + double dr_rho[3], dr_rhoc[3], dp_rhoc[3]; - double **x = atom->x; - double **v = atom->v; - double **f = atom->f; - int *type = atom->type; + add3(r1, r2, r); + add3(p1, p2, p); + scale3(0.5, r); + scale3(0.5, p); - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - vxtmp = v[i][0]; - vytmp = v[i][1]; - vztmp = v[i][2]; - jlist = firstneigh[i]; - jnum = numneigh[i]; + dr = sqrt(0.25 * distsq3(r1, r2) + rsq); + dp = sqrt(0.25 * distsq3(p1, p2) + rsq); + rhoc = dr + dp + rc; + rhomin = RHOMIN * ang; + rho = sqrt(distsq3(r, p)); - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; + frac = 1.0 / (rhoc - rhomin); + arg = frac * (rho - rhomin); + w = s(arg); - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx * delx + dely * dely + delz * delz; - - if (rsq < visc_cutoffsq) { - fx = visc * (v[j][0] - vxtmp); - fy = visc * (v[j][1] - vytmp); - fz = visc * (v[j][2] - vztmp); - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - f[j][0] -= fx; - f[j][1] -= fy; - f[j][2] -= fz; - } - } + if (w == 0.0 || w == 1.0) { + zero3(dr1_w); + zero3(dr2_w); + zero3(dp1_w); + zero3(dp2_w); + } else { + factor = ds(arg) * frac; + + sub3(r, p, dr_rho); + sub3(r1, r2, dr_rhoc); + sub3(p1, p2, dp_rhoc); + scale3(0.5 / rho, dr_rho); + scale3(0.25 / dr, dr_rhoc); + scale3(0.25 / dp, dp_rhoc); + + scaleadd3(-arg, dr_rhoc, dr_rho, dr1_w); + scaleadd3(arg, dr_rhoc, dr_rho, dr2_w); + negate3(dr_rho); + scaleadd3(-arg, dp_rhoc, dr_rho, dp1_w); + scaleadd3(arg, dp_rhoc, dr_rho, dp2_w); + scale3(factor, dr1_w); + scale3(factor, dr2_w); + scale3(factor, dp1_w); + scale3(factor, dp2_w); } } diff --git a/src/MESONT/pair_mesocnt_viscous.h b/src/MESONT/pair_mesocnt_viscous.h index c0c3d05f65..3c86329479 100644 --- a/src/MESONT/pair_mesocnt_viscous.h +++ b/src/MESONT/pair_mesocnt_viscous.h @@ -28,13 +28,8 @@ class PairMesoCNTViscous : public PairMesoCNT { void compute(int, int) override; void coeff(int, char **) override; - double init_one(int, int) override; - protected: - double visc; - double visc_cutoff, visc_cutoffsq; - - void viscous(); + double a1, a2, b2, vswitch; }; } // namespace LAMMPS_NS From a7b6dc7b5954077cd3da19a3c77798eca683739b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 30 Apr 2022 19:03:28 -0400 Subject: [PATCH 028/443] initial implementation of minimizer support in fix shake/rattle --- doc/src/fix_shake.rst | 27 ++-- src/KOKKOS/fix_shake_kokkos.cpp | 15 +- src/RIGID/fix_rattle.cpp | 104 ++++++-------- src/RIGID/fix_shake.cpp | 233 ++++++++++++++++++++++---------- src/RIGID/fix_shake.h | 15 +- src/fix_restrain.cpp | 21 ++- 6 files changed, 249 insertions(+), 166 deletions(-) diff --git a/doc/src/fix_shake.rst b/doc/src/fix_shake.rst index f0c847cb5e..d723f28fc0 100644 --- a/doc/src/fix_shake.rst +++ b/doc/src/fix_shake.rst @@ -33,12 +33,14 @@ Syntax *m* value = one or more mass values * zero or more keyword/value pairs may be appended -* keyword = *mol* +* keyword = *mol* or *kbond* .. parsed-literal:: *mol* value = template-ID template-ID = ID of molecule template specified in a separate :doc:`molecule ` command + *kbond* value = force constant + force constant = force constant used to apply a restraint force when used during minimization Examples """""""" @@ -152,17 +154,23 @@ for. ---------- -The *mol* keyword should be used when other commands, such as :doc:`fix deposit ` or :doc:`fix pour `, add molecules +The *mol* keyword should be used when other commands, such as :doc:`fix +deposit ` or :doc:`fix pour `, add molecules on-the-fly during a simulation, and you wish to constrain the new molecules via SHAKE. You specify a *template-ID* previously defined using the :doc:`molecule ` command, which reads a file that defines the molecule. You must use the same *template-ID* that the command adding molecules uses. The coordinates, atom types, special -bond restrictions, and SHAKE info can be specified in the molecule -file. See the :doc:`molecule ` command for details. The only +bond restrictions, and SHAKE info can be specified in the molecule file. +See the :doc:`molecule ` command for details. The only settings required to be in this file (by this command) are the SHAKE info of atoms in the molecule. +The *kbond* keyword allows to set the restraint force constant when +fix shake or fix rattle are used during minimization. In that case +the constraint algorithms are **not** applied and restraint +forces are used instead to help maintaining the geometries. + ---------- .. include:: accel_styles.rst @@ -205,8 +213,10 @@ setting for this fix is :doc:`fix_modify virial yes `. No global or per-atom quantities are stored by these fixes for access by various :doc:`output commands `. No parameter of these fixes can be used with the *start/stop* keywords of the -:doc:`run ` command. These fixes are not invoked during -:doc:`energy minimization `. +:doc:`run ` command. + +When used during minimization, the SHAKE or RATTLE algorithms are **not** +applied. Strong restraint forces are applied instead. Restrictions """""""""""" @@ -232,13 +242,14 @@ make a linear molecule rigid. Related commands """""""""""""""" -none +`fix rigid `, `fix ehex `, +`fix nve/manifold/rattle ` Default """"""" -none +kbond = 1.0e6 ---------- diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index a24c47c1e2..5ed8cfccb3 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -12,12 +12,8 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include -#include -#include -#include -#include #include "fix_shake_kokkos.h" + #include "fix_rattle.h" #include "atom_kokkos.h" #include "atom_vec.h" @@ -38,6 +34,9 @@ #include "kokkos.h" #include "atom_masks.h" +#include +#include + using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; @@ -292,7 +291,7 @@ void FixShakeKokkos::pre_neighbor() if (h_error_flag() == 1) { error->one(FLERR,"Shake atoms missing on proc " - "{} at step {}",me,update->ntimestep); + "{} at step {}",comm->me,update->ntimestep); } } @@ -341,7 +340,7 @@ void FixShakeKokkos::post_force(int vflag) // communicate results if necessary unconstrained_update(); - if (nprocs > 1) comm->forward_comm(this); + if (comm->nprocs > 1) comm->forward_comm(this); k_xshake.sync(); // virial setup @@ -1702,7 +1701,7 @@ void FixShakeKokkos::correct_coordinates(int vflag) { double **xtmp = xshake; xshake = x; - if (nprocs > 1) { + if (comm->nprocs > 1) { forward_comm_device = 0; comm->forward_comm(this); forward_comm_device = 1; diff --git a/src/RIGID/fix_rattle.cpp b/src/RIGID/fix_rattle.cpp index afe08415c3..1d6336712b 100644 --- a/src/RIGID/fix_rattle.cpp +++ b/src/RIGID/fix_rattle.cpp @@ -81,7 +81,7 @@ FixRattle::~FixRattle() { memory->destroy(vp); - if (RATTLE_DEBUG) { +#if RATTLE_DEBUG // communicate maximum distance error @@ -91,13 +91,11 @@ FixRattle::~FixRattle() MPI_Reduce(&derr_max, &global_derr_max, 1 , MPI_DOUBLE, MPI_MAX, 0, world); MPI_Reduce(&verr_max, &global_verr_max, 1 , MPI_DOUBLE, MPI_MAX, 0, world); - MPI_Comm_rank (world, &npid); // Find out process rank - - if (npid == 0 && screen) { + if (comm->me == 0 && screen) { fprintf(screen, "RATTLE: Maximum overall relative position error ( (r_ij-d_ij)/d_ij ): %.10g\n", global_derr_max); fprintf(screen, "RATTLE: Maximum overall absolute velocity error (r_ij * v_ij): %.10g\n", global_verr_max); } - } +#endif } /* ---------------------------------------------------------------------- */ @@ -110,7 +108,10 @@ int FixRattle::setmask() mask |= POST_FORCE_RESPA; mask |= FINAL_INTEGRATE; mask |= FINAL_INTEGRATE_RESPA; - if (RATTLE_DEBUG) mask |= END_OF_STEP; + mask |= MIN_POST_FORCE; +#if RATTLE_DEBUG + mask |= END_OF_STEP; +#endif return mask; } @@ -156,7 +157,7 @@ void FixRattle::post_force(int vflag) // communicate the unconstrained velocities - if (nprocs > 1) { + if (comm->nprocs > 1) { comm_mode = VP; comm->forward_comm(this); } @@ -188,7 +189,7 @@ void FixRattle::post_force_respa(int vflag, int ilevel, int /*iloop*/) // communicate the unconstrained velocities - if (nprocs > 1) { + if (comm->nprocs > 1) { comm_mode = VP; comm->forward_comm(this); } @@ -718,7 +719,7 @@ void FixRattle::unpack_forward_comm(int n, int first, double *buf) void FixRattle::shake_end_of_step(int vflag) { - if (nprocs > 1) { + if (comm->nprocs > 1) { comm_mode = V; comm->forward_comm(this); } @@ -738,7 +739,6 @@ void FixRattle::correct_coordinates(int vflag) { FixShake::correct_coordinates(vflag); } - /* ---------------------------------------------------------------------- Remove the velocity component along any bond. ------------------------------------------------------------------------- */ @@ -759,7 +759,7 @@ void FixRattle::correct_velocities() { // communicate the unconstrained velocities - if (nprocs > 1) { + if (comm->nprocs > 1) { comm_mode = VP; comm->forward_comm(this); } @@ -769,14 +769,13 @@ void FixRattle::correct_velocities() { int m; for (int i = 0; i < nlist; i++) { m = list[i]; - if (shake_flag[m] == 2) vrattle2(m); - else if (shake_flag[m] == 3) vrattle3(m); - else if (shake_flag[m] == 4) vrattle4(m); - else vrattle3angle(m); + if (shake_flag[m] == 2) vrattle2(m); + else if (shake_flag[m] == 3) vrattle3(m); + else if (shake_flag[m] == 4) vrattle4(m); + else vrattle3angle(m); } } - /* ---------------------------------------------------------------------- DEBUGGING methods The functions below allow you to check whether the @@ -788,16 +787,16 @@ void FixRattle::correct_velocities() { void FixRattle::end_of_step() { - if (nprocs > 1) { - comm_mode = V; - comm->forward_comm(this); + if (comm->nprocs > 1) { + comm_mode = V; + comm->forward_comm(this); } - if (!check_constraints(v, RATTLE_TEST_POS, RATTLE_TEST_VEL) && RATTLE_RAISE_ERROR) { +#if RATTLE_RAISE_ERROR + if (!check_constraints(v, RATTLE_TEST_POS, RATTLE_TEST_VEL)) error->one(FLERR, "Rattle failed "); - } +#endif } - /* ---------------------------------------------------------------------- */ bool FixRattle::check_constraints(double **v, bool checkr, bool checkv) @@ -807,12 +806,11 @@ bool FixRattle::check_constraints(double **v, bool checkr, bool checkv) int i=0; while (i < nlist && ret) { m = list[i]; - if (shake_flag[m] == 2) ret = check2(v,m,checkr,checkv); - else if (shake_flag[m] == 3) ret = check3(v,m,checkr,checkv); - else if (shake_flag[m] == 4) ret = check4(v,m,checkr,checkv); - else ret = check3angle(v,m,checkr,checkv); + if (shake_flag[m] == 2) ret = check2(v,m,checkr,checkv); + else if (shake_flag[m] == 3) ret = check3(v,m,checkr,checkv); + else if (shake_flag[m] == 4) ret = check4(v,m,checkr,checkv); + else ret = check3angle(v,m,checkr,checkv); i++; - if (!RATTLE_RAISE_ERROR) ret = true; } return ret; } @@ -834,14 +832,10 @@ bool FixRattle::check2(double **v, int m, bool checkr, bool checkv) MathExtra::sub3(v[i1],v[i0],v01); stat = !(checkr && (fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1) > tol)); - if (!stat) - error->one(FLERR,"Coordinate constraints are not satisfied " - "up to desired tolerance "); + if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance "); stat = !(checkv && (fabs(MathExtra::dot3(r01,v01)) > tol)); - if (!stat) - error->one(FLERR,"Velocity constraints are not satisfied " - "up to desired tolerance "); + if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance "); return stat; } @@ -871,15 +865,11 @@ bool FixRattle::check3(double **v, int m, bool checkr, bool checkv) stat = !(checkr && (fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1) > tol || fabs(sqrt(MathExtra::dot3(r02,r02))-bond2) > tol)); - if (!stat) - error->one(FLERR,"Coordinate constraints are not satisfied " - "up to desired tolerance "); + if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance "); stat = !(checkv && (fabs(MathExtra::dot3(r01,v01)) > tol || fabs(MathExtra::dot3(r02,v02)) > tol)); - if (!stat) - error->one(FLERR,"Velocity constraints are not satisfied " - "up to desired tolerance "); + if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance "); return stat; } @@ -914,16 +904,12 @@ bool FixRattle::check4(double **v, int m, bool checkr, bool checkv) stat = !(checkr && (fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1) > tol || fabs(sqrt(MathExtra::dot3(r02,r02))-bond2) > tol || fabs(sqrt(MathExtra::dot3(r03,r03))-bond3) > tol)); - if (!stat) - error->one(FLERR,"Coordinate constraints are not satisfied " - "up to desired tolerance "); + if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance "); stat = !(checkv && (fabs(MathExtra::dot3(r01,v01)) > tol || fabs(MathExtra::dot3(r02,v02)) > tol || fabs(MathExtra::dot3(r03,v03)) > tol)); - if (!stat) - error->one(FLERR,"Velocity constraints are not satisfied " - "up to desired tolerance "); + if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance "); return stat; } @@ -954,25 +940,19 @@ bool FixRattle::check3angle(double **v, int m, bool checkr, bool checkv) MathExtra::sub3(v[i2],v[i0],v02); MathExtra::sub3(v[i2],v[i1],v12); - - double db1 = fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1); double db2 = fabs(sqrt(MathExtra::dot3(r02,r02))-bond2); double db12 = fabs(sqrt(MathExtra::dot3(r12,r12))-bond12); - - stat = !(checkr && (db1 > tol || - db2 > tol || - db12 > tol)); + stat = !(checkr && (db1 > tol || db2 > tol || db12 > tol)); if (derr_max < db1/bond1) derr_max = db1/bond1; if (derr_max < db2/bond2) derr_max = db2/bond2; if (derr_max < db12/bond12) derr_max = db12/bond12; - - if (!stat && RATTLE_RAISE_ERROR) - error->one(FLERR,"Coordinate constraints are not satisfied " - "up to desired tolerance "); +#if RATTLE_RAISE_ERROR + if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance "); +#endif double dv1 = fabs(MathExtra::dot3(r01,v01)); double dv2 = fabs(MathExtra::dot3(r02,v02)); @@ -982,16 +962,10 @@ bool FixRattle::check3angle(double **v, int m, bool checkr, bool checkv) if (verr_max < dv2) verr_max = dv2; if (verr_max < dv12) verr_max = dv12; + stat = !(checkv && (dv1 > tol || dv2 > tol || dv12> tol)); - stat = !(checkv && (dv1 > tol || - dv2 > tol || - dv12> tol)); - - - if (!stat && RATTLE_RAISE_ERROR) - error->one(FLERR,"Velocity constraints are not satisfied " - "up to desired tolerance!"); - - +#if RATTLE_RAISE_ERROR + if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance!"); +#endif return stat; } diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index d74f72fb69..41d8c1599c 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -41,8 +41,8 @@ using namespace MathConst; #define RVOUS 1 // 0 for irregular, 1 for all2all -#define BIG 1.0e20 -#define MASSDELTA 0.1 +static constexpr double BIG = 1.0e20; +static constexpr double MASSDELTA = 0.1; /* ---------------------------------------------------------------------- */ @@ -57,21 +57,20 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : a_count_all(nullptr), a_ave(nullptr), a_max(nullptr), a_min(nullptr), a_ave_all(nullptr), a_max_all(nullptr), a_min_all(nullptr), atommols(nullptr), onemols(nullptr) { - MPI_Comm_rank(world,&me); - MPI_Comm_size(world,&nprocs); - + energy_global_flag = energy_peratom_flag = 1; virial_global_flag = virial_peratom_flag = 1; - thermo_virial = 1; + thermo_energy = thermo_virial = 1; create_attribute = 1; dof_flag = 1; stores_ids = 1; centroidstressflag = CENTROID_AVAIL; + next_output = -1; // error check molecular = atom->molecular; if (molecular == Atom::ATOMIC) - error->all(FLERR,"Cannot use fix shake with non-molecular system"); + error->all(FLERR,"Cannot use fix {} with non-molecular system", style); // perform initial allocation of atom-based arrays // register with Atom class @@ -92,8 +91,9 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : comm_forward = 3; // parse SHAKE args + auto mystyle = fmt::format("fix {}",style); - if (narg < 8) error->all(FLERR,"Illegal fix shake command"); + if (narg < 8) utils::missing_cmd_args(FLERR,mystyle, error); tolerance = utils::numeric(FLERR,arg[3],false,lmp); max_iter = utils::inumeric(FLERR,arg[4],false,lmp); @@ -133,49 +133,55 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : else if (mode == 'b') { int i = utils::inumeric(FLERR,arg[next],false,lmp); if (i < 1 || i > atom->nbondtypes) - error->all(FLERR,"Invalid bond type index for fix shake"); + error->all(FLERR,"Invalid bond type index for {}", mystyle); bond_flag[i] = 1; } else if (mode == 'a') { int i = utils::inumeric(FLERR,arg[next],false,lmp); if (i < 1 || i > atom->nangletypes) - error->all(FLERR,"Invalid angle type index for fix shake"); + error->all(FLERR,"Invalid angle type index for {}", mystyle); angle_flag[i] = 1; } else if (mode == 't') { int i = utils::inumeric(FLERR,arg[next],false,lmp); if (i < 1 || i > atom->ntypes) - error->all(FLERR,"Invalid atom type index for fix shake"); + error->all(FLERR,"Invalid atom type index for {}", mystyle); type_flag[i] = 1; } else if (mode == 'm') { double massone = utils::numeric(FLERR,arg[next],false,lmp); - if (massone == 0.0) error->all(FLERR,"Invalid atom mass for fix shake"); + if (massone == 0.0) error->all(FLERR,"Invalid atom mass for {}", mystyle); if (nmass == atom->ntypes) - error->all(FLERR,"Too many masses for fix shake"); + error->all(FLERR,"Too many masses for {}", mystyle); mass_list[nmass++] = massone; - } else error->all(FLERR,"Illegal fix shake command"); + } else error->all(FLERR,"Unknown {} command option: {}", mystyle, arg[next]); next++; } // parse optional args onemols = nullptr; + kbond = 1.0e6; int iarg = next; while (iarg < narg) { - if (strcmp(arg[next],"mol") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix shake command"); + if (strcmp(arg[iarg],"mol") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR,mystyle+" mol",error); int imol = atom->find_molecule(arg[iarg+1]); if (imol == -1) - error->all(FLERR,"Molecule template ID for fix shake does not exist"); - if (atom->molecules[imol]->nset > 1 && comm->me == 0) - error->warning(FLERR,"Molecule template for fix shake has multiple molecules"); + error->all(FLERR,"Molecule template ID {} for {} does not exist", mystyle, arg[iarg+1]); + if ((atom->molecules[imol]->nset > 1) && (comm->me == 0)) + error->warning(FLERR,"Molecule template for {} has multiple molecules", mystyle); onemols = &atom->molecules[imol]; nmol = onemols[0]->nset; iarg += 2; - } else error->all(FLERR,"Illegal fix shake command"); + } else if (strcmp(arg[iarg],"kbond") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR,mystyle+" kbond",error); + kbond = utils::numeric(FLERR, arg[iarg+1], false, lmp); + if (kbond < 0) error->all(FLERR,"Illegal {} kbond value {}. Must be >= 0.0", mystyle, kbond); + iarg += 2; + } else error->all(FLERR,"Unknown {} command option: {}", mystyle, arg[iarg]); } // error check for Molecule template @@ -183,7 +189,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : if (onemols) { for (int i = 0; i < nmol; i++) if (onemols[i]->shakeflag == 0) - error->all(FLERR,"Fix shake molecule template must have shake info"); + error->all(FLERR,"Fix {} molecule template must have shake info", style); } // allocate bond and angle distance arrays, indexed from 1 to n @@ -321,6 +327,7 @@ int FixShake::setmask() mask |= PRE_NEIGHBOR; mask |= POST_FORCE; mask |= POST_FORCE_RESPA; + mask |= MIN_POST_FORCE; return mask; } @@ -335,28 +342,24 @@ void FixShake::init() double rsq,angle; // error if more than one shake fix + auto pattern = fmt::format("^{}",style); - int count = 0; - for (i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"shake") == 0) count++; - if (count > 1) error->all(FLERR,"More than one fix shake"); + if (modify->get_fix_by_style(pattern).size() > 1) + error->all(FLERR,"More than one fix {} instance",style); // cannot use with minimization since SHAKE turns off bonds // that should contribute to potential energy - if (update->whichflag == 2) - error->all(FLERR,"Fix shake cannot be used with minimization"); + if ((comm->me == 0) && (update->whichflag == 2)) + error->warning(FLERR,"Using fix {} with minimization. Substituting constraints with " + "restraint forces using k={:.4g}", style, kbond); - // error if npt,nph fix comes before shake fix - - for (i = 0; i < modify->nfix; i++) { - if (strcmp(modify->fix[i]->style,"npt") == 0) break; - if (strcmp(modify->fix[i]->style,"nph") == 0) break; - } - if (i < modify->nfix) { - for (int j = i; j < modify->nfix; j++) - if (strcmp(modify->fix[j]->style,"shake") == 0) - error->all(FLERR,"Shake fix must come before NPT/NPH fix"); + // error if a fix changing the box comes before shake fix + bool boxflag = false; + for (auto ifix : modify->get_fix_list()) { + if (boxflag && utils::strmatch(ifix->style,pattern)) + error->all(FLERR,"Fix {} must come before any box changing fix", style); + if (ifix->box_change) boxflag = true; } // if rRESPA, find associated fix that must exist @@ -379,7 +382,7 @@ void FixShake::init() // set equilibrium bond distances if (force->bond == nullptr) - error->all(FLERR,"Bond potential must be defined for SHAKE"); + error->all(FLERR,"Bond style must be defined for fix {}",style); for (i = 1; i <= atom->nbondtypes; i++) bond_distance[i] = force->bond->equilibrium_distance(i); @@ -390,7 +393,7 @@ void FixShake::init() for (i = 1; i <= atom->nangletypes; i++) { if (angle_flag[i] == 0) continue; if (force->angle == nullptr) - error->all(FLERR,"Angle potential must be defined for SHAKE"); + error->all(FLERR,"Angle style must be defined for fix {}",style); // scan all atoms for a SHAKE angle cluster // extract bond types for the 2 bonds in the cluster @@ -417,7 +420,7 @@ void FixShake::init() // error check for any bond types that are not the same MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world); - if (flag_all) error->all(FLERR,"Shake angles have different bond types"); + if (flag_all) error->all(FLERR,"Fix {} angles have different bond types", style); // insure all procs have bond types @@ -494,6 +497,16 @@ void FixShake::setup(int vflag) shake_end_of_step(vflag); } +/* ---------------------------------------------------------------------- + during minimization fix SHAKE adds strong bond forces +------------------------------------------------------------------------- */ + +void FixShake::min_setup(int vflag) +{ + pre_neighbor(); + min_post_force(vflag); +} + /* ---------------------------------------------------------------------- build list of SHAKE clusters to constrain if one or more atoms in cluster are on this proc, @@ -533,19 +546,17 @@ void FixShake::pre_neighbor() atom1 = atom->map(shake_atom[i][0]); atom2 = atom->map(shake_atom[i][1]); if (atom1 == -1 || atom2 == -1) - error->one(FLERR,"Shake atoms {} {} missing on proc " - "{} at step {}",shake_atom[i][0], - shake_atom[i][1],me,update->ntimestep); + error->one(FLERR,"Shake atoms {} {} missing on proc {} at step {}",shake_atom[i][0], + shake_atom[i][1],comm->me,update->ntimestep); if (i <= atom1 && i <= atom2) list[nlist++] = i; } else if (shake_flag[i] % 2 == 1) { atom1 = atom->map(shake_atom[i][0]); atom2 = atom->map(shake_atom[i][1]); atom3 = atom->map(shake_atom[i][2]); if (atom1 == -1 || atom2 == -1 || atom3 == -1) - error->one(FLERR,"Shake atoms {} {} {} missing on proc " - "{} at step {}",shake_atom[i][0], + error->one(FLERR,"Shake atoms {} {} {} missing on proc {} at step {}",shake_atom[i][0], shake_atom[i][1],shake_atom[i][2], - me,update->ntimestep); + comm->me,update->ntimestep); if (i <= atom1 && i <= atom2 && i <= atom3) list[nlist++] = i; } else { atom1 = atom->map(shake_atom[i][0]); @@ -553,10 +564,9 @@ void FixShake::pre_neighbor() atom3 = atom->map(shake_atom[i][2]); atom4 = atom->map(shake_atom[i][3]); if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) - error->one(FLERR,"Shake atoms {} {} {} {} missing on " - "proc {} at step {}",shake_atom[i][0], + error->one(FLERR,"Shake atoms {} {} {} {} missing on proc {} at step {}",shake_atom[i][0], shake_atom[i][1],shake_atom[i][2], - shake_atom[i][3],me,update->ntimestep); + shake_atom[i][3],comm->me,update->ntimestep); if (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4) list[nlist++] = i; } @@ -575,7 +585,7 @@ void FixShake::post_force(int vflag) // communicate results if necessary unconstrained_update(); - if (nprocs > 1) comm->forward_comm(this); + if (comm->nprocs > 1) comm->forward_comm(this); // virial setup @@ -619,7 +629,7 @@ void FixShake::post_force_respa(int vflag, int ilevel, int iloop) // communicate results if necessary unconstrained_update_respa(ilevel); - if (nprocs > 1) comm->forward_comm(this); + if (comm->nprocs > 1) comm->forward_comm(this); // virial setup only needed on last iteration of innermost level // and if pressure is requested @@ -644,6 +654,48 @@ void FixShake::post_force_respa(int vflag, int ilevel, int iloop) vflag_post_force = vflag; } +/* ---------------------------------------------------------------------- + substitute shake constraints with very strong bonds +------------------------------------------------------------------------- */ + +void FixShake::min_post_force(int vflag) +{ + if (output_every) { + bigint ntimestep = update->ntimestep; + if (next_output == ntimestep) stats(); + + next_output = ntimestep + output_every; + if (ntimestep % output_every != 0) + next_output = (ntimestep/output_every)*output_every + output_every; + } else next_output = -1; + + v_init(vflag); + + x = atom->x; + f = atom->f; + nlocal = atom->nlocal; + + // loop over clusters to add strong restraint forces + + for (int i = 0; i < nlist; i++) { + int m = list[i]; + if (shake_flag[m] == 2) { + bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]); + } else if (shake_flag[m] == 3) { + bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]); + bond_force(shake_atom[m][0], shake_atom[m][2], bond_distance[shake_type[m][1]]); + } else if (shake_flag[m] == 4) { + bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]); + bond_force(shake_atom[m][0], shake_atom[m][2], bond_distance[shake_type[m][1]]); + bond_force(shake_atom[m][0], shake_atom[m][3], bond_distance[shake_type[m][2]]); + } else { + bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]); + bond_force(shake_atom[m][0], shake_atom[m][2], bond_distance[shake_type[m][1]]); + bond_force(shake_atom[m][1], shake_atom[m][2], angle_distance[shake_type[m][2]]); + } + } +} + /* ---------------------------------------------------------------------- count # of degrees-of-freedom removed by SHAKE for atoms in igroup ------------------------------------------------------------------------- */ @@ -690,10 +742,7 @@ void FixShake::find_clusters() tagint tagprev; double massone; - if ((me == 0) && screen) { - if (!rattle) fputs("Finding SHAKE clusters ...\n",screen); - else fputs("Finding RATTLE clusters ...\n",screen); - } + if (comm->me == 0) utils::logmesg(lmp, "Finding {} clusters ...\n",utils::uppercase(style)); atommols = atom->avec->onemols; tagint *tag = atom->tag; @@ -805,7 +854,7 @@ void FixShake::find_clusters() } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all(FLERR,"Did not find fix shake partner info"); + if (flag_all) error->all(FLERR,"Did not find fix {} partner info", style); // ----------------------------------------------------- // identify SHAKEable bonds @@ -1015,7 +1064,7 @@ void FixShake::find_clusters() tmp = count4; MPI_Allreduce(&tmp,&count4,1,MPI_INT,MPI_SUM,world); - if (me == 0) { + if (comm->me == 0) { utils::logmesg(lmp,"{:>8} = # of size 2 clusters\n" "{:>8} = # of size 3 clusters\n" "{:>8} = # of size 4 clusters\n" @@ -1043,8 +1092,8 @@ void FixShake::atom_owners() // one datum for each owned atom: datum = owning proc, atomID for (int i = 0; i < nlocal; i++) { - proclist[i] = tag[i] % nprocs; - idbuf[i].me = me; + proclist[i] = tag[i] % comm->nprocs; + idbuf[i].me = comm->me; idbuf[i].atomID = tag[i]; } @@ -1089,7 +1138,7 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag, // set values in 4 partner arrays for all partner atoms I own // also setup input buf to rendezvous comm // input datums = pair of bonded atoms where I do not own partner - // owning proc for each datum = partner_tag % nprocs + // owning proc for each datum = partner_tag % comm->nprocs // datum: atomID = partner_tag (off-proc), partnerID = tag (on-proc) // 4 values for my owned atom @@ -1127,7 +1176,7 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag, } } else { - proclist[nsend] = partner_tag[i][j] % nprocs; + proclist[nsend] = partner_tag[i][j] % comm->nprocs; inbuf[nsend].atomID = partner_tag[i][j]; inbuf[nsend].partnerID = tag[i]; inbuf[nsend].mask = mask[i]; @@ -1217,7 +1266,7 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag, // set partner_nshake for all partner atoms I own // also setup input buf to rendezvous comm // input datums = pair of bonded atoms where I do not own partner - // owning proc for each datum = partner_tag % nprocs + // owning proc for each datum = partner_tag % comm->nprocs // datum: atomID = partner_tag (off-proc), partnerID = tag (on-proc) // nshake value for my owned atom @@ -1231,7 +1280,7 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag, if (m >= 0 && m < nlocal) { partner_nshake[i][j] = nshake[m]; } else { - proclist[nsend] = partner_tag[i][j] % nprocs; + proclist[nsend] = partner_tag[i][j] % comm->nprocs; inbuf[nsend].atomID = partner_tag[i][j]; inbuf[nsend].partnerID = tag[i]; inbuf[nsend].nshake = nshake[i]; @@ -1295,7 +1344,7 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag, // set 3 shake arrays for all partner atoms I own // also setup input buf to rendezvous comm // input datums = partner atom where I do not own partner - // owning proc for each datum = partner_tag % nprocs + // owning proc for each datum = partner_tag % comm->nprocs // datum: atomID = partner_tag (off-proc) // values in 3 shake arrays @@ -1317,7 +1366,7 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag, shake_type[m][2] = shake_type[i][2]; } else { - proclist[nsend] = partner_tag[i][j] % nprocs; + proclist[nsend] = partner_tag[i][j] % comm->nprocs; inbuf[nsend].atomID = partner_tag[i][j]; inbuf[nsend].shake_flag = shake_flag[i]; inbuf[nsend].shake_atom[0] = shake_atom[i][0]; @@ -2451,6 +2500,53 @@ void FixShake::shake3angle(int m) } } +/* ---------------------------------------------------------------------- + apply bond force for minimization +------------------------------------------------------------------------- */ + +void FixShake::bond_force(tagint id1, tagint id2, double length) +{ + + int i1 = atom->map(id1); + int i2 = atom->map(id2); + + if ((i1 < 0) || (i2 < 0)) return; + + // distance vec between atoms, with PBC + + double delx = x[i1][0] - x[i2][0]; + double dely = x[i1][1] - x[i2][1]; + double delz = x[i1][2] - x[i2][2]; + domain->minimum_image(delx, dely, delz); + + // compute and apply force + + const double r = sqrt(delx * delx + dely * dely + delz * delz); + const double dr = r - length; + const double rk = kbond * dr; + const double fbond = (r > 0.0) ? -2.0 * rk / r : 0.0; + double v[6]; + v[0] = 0.5 * delx * delx * fbond; + v[1] = 0.5 * dely * dely * fbond; + v[2] = 0.5 * delz * delz * fbond; + v[3] = 0.5 * delx * dely * fbond; + v[4] = 0.5 * delx * delz * fbond; + v[5] = 0.5 * dely * delz * fbond; + + if (i1 < nlocal) { + f[i1][0] += delx * fbond; + f[i1][1] += dely * fbond; + f[i1][2] += delz * fbond; + if (evflag) v_tally(i1, v); + } + if (i2 < nlocal) { + f[i2][0] -= delx * fbond; + f[i2][1] -= dely * fbond; + f[i2][2] -= delz * fbond; + if (evflag) v_tally(i2, v); + } +} + /* ---------------------------------------------------------------------- print-out bond & angle statistics ------------------------------------------------------------------------- */ @@ -2558,9 +2654,10 @@ void FixShake::stats() // print stats only for non-zero counts - if (me == 0) { + if (comm->me == 0) { const int width = log10((MAX(MAX(1,nb),na)))+2; - auto mesg = fmt::format("SHAKE stats (type/ave/delta/count) on step {}\n", update->ntimestep); + auto mesg = fmt::format("{} stats (type/ave/delta/count) on step {}\n", + utils::uppercase(style), update->ntimestep); for (i = 1; i < nb; i++) { const auto bcnt = b_count_all[i]; if (bcnt) @@ -3109,7 +3206,7 @@ void FixShake::correct_coordinates(int vflag) { double **xtmp = xshake; xshake = x; - if (nprocs > 1) { + if (comm->nprocs > 1) { comm->forward_comm(this); } xshake = xtmp; diff --git a/src/RIGID/fix_shake.h b/src/RIGID/fix_shake.h index 12e24fb350..a0f743d7d2 100644 --- a/src/RIGID/fix_shake.h +++ b/src/RIGID/fix_shake.h @@ -34,9 +34,11 @@ class FixShake : public Fix { int setmask() override; void init() override; void setup(int) override; + void min_setup(int) override; void pre_neighbor() override; void post_force(int) override; void post_force_respa(int, int, int) override; + void min_post_force(int) override; double memory_usage() override; void grow_arrays(int) override; @@ -61,12 +63,11 @@ class FixShake : public Fix { protected: int vflag_post_force; // store the vflag of last post_force call int respa; // 0 = vel. Verlet, 1 = respa - int me, nprocs; - int rattle; // 0 = SHAKE, 1 = RATTLE - double tolerance; // SHAKE tolerance - int max_iter; // max # of SHAKE iterations - int output_every; // SHAKE stat output every so often - bigint next_output; // timestep for next output + int rattle; // 0 = SHAKE, 1 = RATTLE + double tolerance; // SHAKE tolerance + int max_iter; // max # of SHAKE iterations + int output_every; // SHAKE stat output every so often + bigint next_output; // timestep for next output // settings from input command int *bond_flag, *angle_flag; // bond/angle types to constrain @@ -76,6 +77,7 @@ class FixShake : public Fix { int molecular; // copy of atom->molecular double *bond_distance, *angle_distance; // constraint distances + double kbond; // force constant for restraint class FixRespa *fix_respa; // rRESPA fix needed by SHAKE int nlevels_respa; // copies of needed rRESPA variables @@ -133,6 +135,7 @@ class FixShake : public Fix { void shake3(int); void shake4(int); void shake3angle(int); + void bond_force(tagint, tagint, double); void stats(); int bondtype_findset(int, tagint, tagint, int); int angletype_findset(int, tagint, tagint, int); diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp index 8b97715ff6..e5440830f5 100644 --- a/src/fix_restrain.cpp +++ b/src/fix_restrain.cpp @@ -19,17 +19,18 @@ #include "fix_restrain.h" -#include -#include #include "atom.h" -#include "force.h" -#include "update.h" -#include "domain.h" #include "comm.h" -#include "respa.h" +#include "domain.h" +#include "error.h" +#include "force.h" #include "math_const.h" #include "memory.h" -#include "error.h" +#include "respa.h" +#include "update.h" + +#include +#include using namespace LAMMPS_NS; using namespace FixConst; @@ -271,14 +272,12 @@ void FixRestrain::restrain_bond(int m) if (newton_bond) { if (i2 == -1 || i2 >= nlocal) return; if (i1 == -1) - error->one(FLERR,"Restrain atoms {} {} missing on " - "proc {} at step {}", ids[m][0],ids[m][1], + error->one(FLERR,"Restrain atoms {} {} missing on proc {} at step {}", ids[m][0],ids[m][1], comm->me,update->ntimestep); } else { if ((i1 == -1 || i1 >= nlocal) && (i2 == -1 || i2 >= nlocal)) return; if (i1 == -1 || i2 == -1) - error->one(FLERR,"Restrain atoms {} {} missing on " - "proc {} at step {}", ids[m][0],ids[m][1], + error->one(FLERR,"Restrain atoms {} {} missing on proc {} at step {}", ids[m][0],ids[m][1], comm->me,update->ntimestep); } From 7d17cc9e45598547c2f02c9c70d1fe5c0c9abb7d Mon Sep 17 00:00:00 2001 From: phankl Date: Mon, 2 May 2022 13:05:09 +0100 Subject: [PATCH 029/443] bond topology chain generation implemented, need to fix segfault --- src/MESONT/pair_mesocnt.cpp | 154 +++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 37 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 4fe99fbe94..5e864ac547 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -554,8 +554,13 @@ void PairMesoCNT::bond_neigh() int **bondlist = neighbor->bondlist; int nbondlist = neighbor->nbondlist; + int *type = atom->type; + tagint *tag = atom->tag; + tagint **bond_atom = atom->bond_atom; + int *numneigh = list->numneigh; - int numneigh_max = 0; + int *numneigh_max; + memory->create(numneigh_max, nbondlist, "pair:numneigh_max"); for (int i = 0; i < nbondlist; i++) { int i1 = bondlist[i][0]; int i2 = bondlist[i][1]; @@ -571,31 +576,26 @@ void PairMesoCNT::bond_neigh() numneigh2 = 0; else numneigh2 = numneigh[i2]; - - int numneigh_max_local = numneigh1 + numneigh2; - if (numneigh_max_local > numneigh_max) numneigh_max = numneigh_max_local; + numneigh_max[i] = numneigh1 + numneigh2; } // create temporary arrays for chain creation memory->create(reduced_nlist, nbondlist, "pair:reduced_nlist"); - memory->create(reduced_neighlist, nbondlist, numneigh_max, "pair:reduced_neighlist"); + memory->create_ragged(reduced_neighlist, nbondlist, numneigh_max, "pair:reduced_neighlist"); + memory->destroy(numneigh_max); // reduce neighbors to common list and find longest common list size - numneigh_max = 0; for (int i = 0; i < nbondlist; i++) { int i1 = bondlist[i][0]; int i2 = bondlist[i][1]; - int *reduced_neigh = reduced_neighlist[i]; - neigh_common(i1, i2, reduced_nlist[i], reduced_neigh); + neigh_common(i1, i2, reduced_nlist[i], reduced_neighlist[i]); // sort list according to atom-id - sort(reduced_neigh, reduced_nlist[i]); - - if (numneigh_max < reduced_nlist[i]) numneigh_max = reduced_nlist[i]; + sort(reduced_neighlist[i], reduced_nlist[i]); } // resize chain arrays @@ -605,48 +605,133 @@ void PairMesoCNT::bond_neigh() memory->destroy(endlist); memory->destroy(chainlist); - // count neighbor chains per bond - + // split neighbor list into neighbor chains based on bond topology + + int **chainid, **chainpos; + memory->create_ragged(chainid, nbondlist, reduced_nlist, "pair:chainid"); + memory->create_ragged(chainpos, nbondlist, reduced_nlist, "pair:chainpos"); memory->create(numchainlist, nbondlist, "pair:numchainlist"); - int numchain_max = 0; + bool empty_neigh = true; for (int i = 0; i < nbondlist; i++) { - numchainlist[i] = count_chains(reduced_neighlist[i], reduced_nlist[i]); - if (numchain_max < numchainlist[i]) numchain_max = numchainlist[i]; - } + if (reduced_nlist[i] == 0) continue; + + // first atom starts new chain + + chainid[i][0] = 0; + chainpos[i][0] = 0; + int nchain = 1; + + empty_neigh = false; + + // assign all other atoms + + for (int j = 1; j < reduced_nlist[i]; j++) { + int jj = reduced_neighlist[i][j]; + int jtag = tag[jj]; + int jbond = bond_atom[jj][0]; + + int tag1 = tag[j]; + bool newchain = true; + for (int k = 0; k < j; k++) { + int kk = reduced_neighlist[i][k]; + int ktag = tag[kk]; + int kbond = bond_atom[kk][0]; + + // check if atoms are bonded + + if (jtag == kbond || jbond == ktag) { + chainid[i][j] = chainid[i][k]; + if (chainpos[i][k] < 0) chainpos[i][j] = chainpos[i][k] - 1; + else chainpos[i][j] = chainpos[i][k] + 1; + + newchain = false; + break; + } + } + + // start new chain + + if (newchain) { + chainid[i][j] = nchain++; + chainpos[i][j] = 0; + + numchainlist[i] = nchain; + } + } + } + // count neighbor chain lengths per bond + int **chainpos_min, **chainpos_max; + memory->create_ragged(chainpos_min, nbondlist, numchainlist, "pair:chainpos_min"); + memory->create_ragged(chainpos_max, nbondlist, numchainlist, "pair:chainpos_max"); memory->create_ragged(nchainlist, nbondlist, numchainlist, "pair:nchainlist"); - for (int i = 0; i < nbondlist; i++) - chain_lengths(reduced_neighlist[i], reduced_nlist[i], nchainlist[i]); + int nchain_max = 0; + for (int i = 0; i < nbondlist; i++) { + for (int j = 0; j < numchainlist[i]; j++) { + chainpos_min[i][j] = 0; + chainpos_max[i][j] = 0; + } + for (int j = 0; j < reduced_nlist[i]; j++) { + int cid = chainid[i][j]; + int cpos = chainpos[i][j]; + if (cpos < chainpos_min[i][cid]) chainpos_min[i][cid] = cpos; + if (cpos > chainpos_max[i][cid]) chainpos_max[i][cid] = cpos; + } + + for (int j = 0; j < numchainlist[i]; j++) { + int clen = chainpos_max[i][j] - chainpos_max[i][j] + 1; + nchainlist[i][j] = clen; + if (clen > nchain_max) nchain_max = clen; + } + } + + memory->destroy(chainpos_max); + // create connected neighbor chains and check for ends // MEMORY: prevent zero-size array creation for chainlist memory->create_ragged(endlist, nbondlist, numchainlist, "pair:endlist"); - if (numchain_max > 0) - memory->create_ragged(chainlist, nbondlist, numchainlist, nchainlist, "pair:chainlist"); - else + if (empty_neigh > 0) memory->create(chainlist, 1, 1, 1, "pair:chainlist"); + else + memory->create_ragged(chainlist, nbondlist, numchainlist, nchainlist, "pair:chainlist"); - int nchain_max = 0; for (int i = 0; i < nbondlist; i++) { - int *reduced_neigh = reduced_neighlist[i]; - int *end = endlist[i]; - int *nchain = nchainlist[i]; - int **chain = chainlist[i]; - // set up connected chains and check for ends + // sort atoms into chain lists + + for (int j = 0; j < reduced_nlist[i]; j++) { + int cid = chainid[i][j]; + int cpos = chainpos[i][j] - chainpos_min[i][cid]; + chainlist[i][cid][cpos] = reduced_neighlist[i][j]; + } - chain_split(reduced_neigh, reduced_nlist[i], nchain, chain, end); + // check for ends - // find longest chain + for (int j = 0; j < numchainlist[i]; j++) { + int clen = nchainlist[i][j]; + int cstart = chainlist[i][j][0]; + int cend = chainlist[i][j][clen-1]; - for (int j = 0; j < numchainlist[i]; j++) - if (nchain_max < nchain[j]) nchain_max = nchain[j]; + if (match_end(type[cstart])) endlist[i][j] = 1; + else if (match_end(type[cend])) endlist[i][j] = 2; + else endlist[i][j] = 0; + } } + + // destroy remaining temporary arrays for chain creation + + memory->destroy(reduced_neighlist); + memory->destroy(reduced_nlist); + + memory->destroy(chainpos_min); + memory->destroy(chainid); + memory->destroy(chainpos); // resize potential arrays @@ -655,11 +740,6 @@ void PairMesoCNT::bond_neigh() memory->grow(dq_w, nchain_max, 3, "pair:dq_w"); memory->grow(q1_dq_w, nchain_max, 3, 3, "pair:q1_dq_w"); memory->grow(q2_dq_w, nchain_max, 3, 3, "pair:q2_dq_w"); - - // destroy temporary arrays for chain creation - - memory->destroy(reduced_neighlist); - memory->destroy(reduced_nlist); } /* ---------------------------------------------------------------------- From 7d8b6be614344f0aea6fd3c17c6f2befe4a45a36 Mon Sep 17 00:00:00 2001 From: phankl Date: Mon, 2 May 2022 15:24:41 +0100 Subject: [PATCH 030/443] fixed segfaults, but logic is flawed --- src/MESONT/pair_mesocnt.cpp | 54 ++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 5e864ac547..a86f5c6921 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -583,7 +583,6 @@ void PairMesoCNT::bond_neigh() memory->create(reduced_nlist, nbondlist, "pair:reduced_nlist"); memory->create_ragged(reduced_neighlist, nbondlist, numneigh_max, "pair:reduced_neighlist"); - memory->destroy(numneigh_max); // reduce neighbors to common list and find longest common list size @@ -615,19 +614,15 @@ void PairMesoCNT::bond_neigh() bool empty_neigh = true; for (int i = 0; i < nbondlist; i++) { - if (reduced_nlist[i] == 0) continue; - - // first atom starts new chain - - chainid[i][0] = 0; - chainpos[i][0] = 0; - int nchain = 1; + if (reduced_nlist[i] == 0) { + numchainlist[i] = 0; + continue; + } empty_neigh = false; - - // assign all other atoms + int nchain = 0; - for (int j = 1; j < reduced_nlist[i]; j++) { + for (int j = 0; j < reduced_nlist[i]; j++) { int jj = reduced_neighlist[i][j]; int jtag = tag[jj]; int jbond = bond_atom[jj][0]; @@ -641,11 +636,17 @@ void PairMesoCNT::bond_neigh() // check if atoms are bonded - if (jtag == kbond || jbond == ktag) { + if (jtag == kbond) { chainid[i][j] = chainid[i][k]; - if (chainpos[i][k] < 0) chainpos[i][j] = chainpos[i][k] - 1; - else chainpos[i][j] = chainpos[i][k] + 1; - + chainpos[i][j] = chainpos[i][k] + 1; + + newchain = false; + break; + } + else if (jbond == ktag) { + chainid[i][j] = chainid[i][k]; + chainpos[i][j] = chainpos[i][k] - 1; + newchain = false; break; } @@ -656,10 +657,10 @@ void PairMesoCNT::bond_neigh() if (newchain) { chainid[i][j] = nchain++; chainpos[i][j] = 0; - - numchainlist[i] = nchain; } } + + numchainlist[i] = nchain; } // count neighbor chain lengths per bond @@ -684,7 +685,7 @@ void PairMesoCNT::bond_neigh() } for (int j = 0; j < numchainlist[i]; j++) { - int clen = chainpos_max[i][j] - chainpos_max[i][j] + 1; + int clen = chainpos_max[i][j] - chainpos_min[i][j] + 1; nchainlist[i][j] = clen; if (clen > nchain_max) nchain_max = clen; } @@ -696,7 +697,7 @@ void PairMesoCNT::bond_neigh() // MEMORY: prevent zero-size array creation for chainlist memory->create_ragged(endlist, nbondlist, numchainlist, "pair:endlist"); - if (empty_neigh > 0) + if (empty_neigh) memory->create(chainlist, 1, 1, 1, "pair:chainlist"); else memory->create_ragged(chainlist, nbondlist, numchainlist, nchainlist, "pair:chainlist"); @@ -722,6 +723,19 @@ void PairMesoCNT::bond_neigh() else if (match_end(type[cend])) endlist[i][j] = 2; else endlist[i][j] = 0; } + + printf("bond_id: %d\n", i); + printf("reduced_neighlist: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", tag[reduced_neighlist[i][j]]); + printf("\n"); + for (int j = 0; j < numchainlist[i]; j++) { + printf("chain %d: ", j+1); + for (int k = 0; k < nchainlist[i][j]; k++) { + printf("%d ", tag[chainlist[i][j][k]]); + } + printf("\n"); + } } // destroy remaining temporary arrays for chain creation @@ -732,6 +746,8 @@ void PairMesoCNT::bond_neigh() memory->destroy(chainpos_min); memory->destroy(chainid); memory->destroy(chainpos); + + memory->destroy(numneigh_max); // resize potential arrays From 2222d21e331e871bd49526e594acb92e00a24f54 Mon Sep 17 00:00:00 2001 From: phankl Date: Tue, 3 May 2022 12:24:56 +0100 Subject: [PATCH 031/443] use bond topology to construct connected chains, working + print statements version --- src/MESONT/pair_mesocnt.cpp | 141 ++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 31 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index a86f5c6921..de7d2abae8 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -606,61 +606,109 @@ void PairMesoCNT::bond_neigh() // split neighbor list into neighbor chains based on bond topology - int **chainid, **chainpos; + int **chainid, **chainpos, **bonded_atom1, **bonded_atom2; memory->create_ragged(chainid, nbondlist, reduced_nlist, "pair:chainid"); memory->create_ragged(chainpos, nbondlist, reduced_nlist, "pair:chainpos"); + memory->create_ragged(bonded_atom1, nbondlist, reduced_nlist, "pair::bonded_atom1"); + memory->create_ragged(bonded_atom2, nbondlist, reduced_nlist, "pair::bonded_atom2"); memory->create(numchainlist, nbondlist, "pair:numchainlist"); bool empty_neigh = true; for (int i = 0; i < nbondlist; i++) { - if (reduced_nlist[i] == 0) { - numchainlist[i] = 0; - continue; - } + numchainlist[i] = 0; + if (reduced_nlist[i] == 0) continue; empty_neigh = false; - int nchain = 0; for (int j = 0; j < reduced_nlist[i]; j++) { int jj = reduced_neighlist[i][j]; int jtag = tag[jj]; - int jbond = bond_atom[jj][0]; + int jbond = bond_atom[atom->map(jtag)][0]; + + bonded_atom1[i][j] = -1; + bonded_atom2[i][j] = -1; + chainid[i][j] = -1; - int tag1 = tag[j]; bool newchain = true; for (int k = 0; k < j; k++) { int kk = reduced_neighlist[i][k]; int ktag = tag[kk]; - int kbond = bond_atom[kk][0]; + int kbond = bond_atom[atom->map(ktag)][0]; // check if atoms are bonded - if (jtag == kbond) { - chainid[i][j] = chainid[i][k]; - chainpos[i][j] = chainpos[i][k] + 1; - - newchain = false; - break; + if (jtag == kbond || jbond == ktag) { + /* + if (i == 0) { + printf("jtag: %d, jbond: %d, ktag: %d, kbond: %d\n", jtag, jbond, ktag, kbond); + printf("pre-assignment\n"); + printf("bonded_atom1[i][j]: %d, bonded_atom2[i][j]: %d, bonded_atom1[i][k]: %d, bonded_atom2[i][k]: %d\n", bonded_atom1[i][j], bonded_atom2[i][j], bonded_atom1[i][k], bonded_atom2[i][k]); + } + */ + if (bonded_atom1[i][j] == -1) bonded_atom1[i][j] = k; + else bonded_atom2[i][j] = k; + if (bonded_atom1[i][k] == -1) bonded_atom1[i][k] = j; + else bonded_atom2[i][k] = j; + /* + if (i == 0) { + printf("post-assignment\n"); + printf("bonded_atom1[i][j]: %d, bonded_atom2[i][j]: %d, bonded_atom1[i][k]: %d, bonded_atom2[i][k]: %d\n", bonded_atom1[i][j], bonded_atom2[i][j], bonded_atom1[i][k], bonded_atom2[i][k]); + } + */ } - else if (jbond == ktag) { - chainid[i][j] = chainid[i][k]; - chainpos[i][j] = chainpos[i][k] - 1; - - newchain = false; - break; - } - } - - // start new chain - - if (newchain) { - chainid[i][j] = nchain++; - chainpos[i][j] = 0; } } + + // assign chain ids and positions - numchainlist[i] = nchain; + for (int j = 0; j < reduced_nlist[i]; j++) { + + // skip if atom is already assigned to a chain + + if (chainid[i][j] != -1) continue; + + // iterate along bonded atoms in both directions + + chainid[i][j] = numchainlist[i]; + chainpos[i][j] = 0; + + // down the chain + + int current_atom = j; + int next_atom = bonded_atom1[i][j]; + while (next_atom != -1) { + chainid[i][next_atom] = numchainlist[i]; + chainpos[i][next_atom] = chainpos[i][current_atom] - 1; + if (bonded_atom1[i][next_atom] != current_atom) { + current_atom = next_atom; + next_atom = bonded_atom1[i][next_atom]; + } + else { + current_atom = next_atom; + next_atom = bonded_atom2[i][next_atom]; + } + } + + // up the chain + + current_atom = j; + next_atom = bonded_atom2[i][j]; + while (next_atom != -1) { + chainid[i][next_atom] = numchainlist[i]; + chainpos[i][next_atom] = chainpos[i][current_atom] + 1; + if (bonded_atom1[i][next_atom] != current_atom) { + current_atom = next_atom; + next_atom = bonded_atom1[i][next_atom]; + } + else { + current_atom = next_atom; + next_atom = bonded_atom2[i][next_atom]; + } + } + + numchainlist[i]++; + } } // count neighbor chain lengths per bond @@ -702,6 +750,8 @@ void PairMesoCNT::bond_neigh() else memory->create_ragged(chainlist, nbondlist, numchainlist, nchainlist, "pair:chainlist"); + // printf("nlocal: %d\n", nlocal); + for (int i = 0; i < nbondlist; i++) { // sort atoms into chain lists @@ -724,11 +774,37 @@ void PairMesoCNT::bond_neigh() else endlist[i][j] = 0; } + /* printf("bond_id: %d\n", i); printf("reduced_neighlist: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", reduced_neighlist[i][j]); + printf("\n"); + printf("map tag reduced_neighlist: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", atom->map(tag[reduced_neighlist[i][j]])); + printf("\n"); + printf("reduced_neighlist tags: "); for (int j = 0; j < reduced_nlist[i]; j++) printf("%d ", tag[reduced_neighlist[i][j]]); printf("\n"); + printf("num_bond: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", atom->num_bond[reduced_neighlist[i][j]]); + printf("\n"); + printf("bond_atom: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", bond_atom[reduced_neighlist[i][j]][0]); + printf("\n"); + printf("map tag bond_atom: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", bond_atom[atom->map(tag[reduced_neighlist[i][j]])][0]); + printf("\n"); + printf("bonded atoms: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("(%d, %d) ", tag[reduced_neighlist[i][bonded_atom1[i][j]]], reduced_neighlist[i][tag[bonded_atom2[i][j]]]); + printf("\n"); + for (int j = 0; j < numchainlist[i]; j++) { printf("chain %d: ", j+1); for (int k = 0; k < nchainlist[i][j]; k++) { @@ -736,6 +812,7 @@ void PairMesoCNT::bond_neigh() } printf("\n"); } + */ } // destroy remaining temporary arrays for chain creation @@ -746,7 +823,9 @@ void PairMesoCNT::bond_neigh() memory->destroy(chainpos_min); memory->destroy(chainid); memory->destroy(chainpos); - + memory->destroy(bonded_atom1); + memory->destroy(bonded_atom2); + memory->destroy(numneigh_max); // resize potential arrays From 8aac52c8bda07249f9563c66c63181e884108ece Mon Sep 17 00:00:00 2001 From: phankl Date: Tue, 3 May 2022 12:31:22 +0100 Subject: [PATCH 032/443] removed print statements --- src/MESONT/pair_mesocnt.cpp | 63 +++---------------------------------- 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index de7d2abae8..e69c5f70bc 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -639,23 +639,10 @@ void PairMesoCNT::bond_neigh() // check if atoms are bonded if (jtag == kbond || jbond == ktag) { - /* - if (i == 0) { - printf("jtag: %d, jbond: %d, ktag: %d, kbond: %d\n", jtag, jbond, ktag, kbond); - printf("pre-assignment\n"); - printf("bonded_atom1[i][j]: %d, bonded_atom2[i][j]: %d, bonded_atom1[i][k]: %d, bonded_atom2[i][k]: %d\n", bonded_atom1[i][j], bonded_atom2[i][j], bonded_atom1[i][k], bonded_atom2[i][k]); - } - */ if (bonded_atom1[i][j] == -1) bonded_atom1[i][j] = k; else bonded_atom2[i][j] = k; if (bonded_atom1[i][k] == -1) bonded_atom1[i][k] = j; else bonded_atom2[i][k] = j; - /* - if (i == 0) { - printf("post-assignment\n"); - printf("bonded_atom1[i][j]: %d, bonded_atom2[i][j]: %d, bonded_atom1[i][k]: %d, bonded_atom2[i][k]: %d\n", bonded_atom1[i][j], bonded_atom2[i][j], bonded_atom1[i][k], bonded_atom2[i][k]); - } - */ } } } @@ -706,11 +693,15 @@ void PairMesoCNT::bond_neigh() next_atom = bonded_atom2[i][next_atom]; } } - numchainlist[i]++; } } + // destroy temporary arrays + + memory->destroy(bonded_atom1); + memory->destroy(bonded_atom2); + // count neighbor chain lengths per bond int **chainpos_min, **chainpos_max; @@ -750,8 +741,6 @@ void PairMesoCNT::bond_neigh() else memory->create_ragged(chainlist, nbondlist, numchainlist, nchainlist, "pair:chainlist"); - // printf("nlocal: %d\n", nlocal); - for (int i = 0; i < nbondlist; i++) { // sort atoms into chain lists @@ -773,46 +762,6 @@ void PairMesoCNT::bond_neigh() else if (match_end(type[cend])) endlist[i][j] = 2; else endlist[i][j] = 0; } - - /* - printf("bond_id: %d\n", i); - printf("reduced_neighlist: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", reduced_neighlist[i][j]); - printf("\n"); - printf("map tag reduced_neighlist: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", atom->map(tag[reduced_neighlist[i][j]])); - printf("\n"); - printf("reduced_neighlist tags: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", tag[reduced_neighlist[i][j]]); - printf("\n"); - printf("num_bond: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", atom->num_bond[reduced_neighlist[i][j]]); - printf("\n"); - printf("bond_atom: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", bond_atom[reduced_neighlist[i][j]][0]); - printf("\n"); - printf("map tag bond_atom: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", bond_atom[atom->map(tag[reduced_neighlist[i][j]])][0]); - printf("\n"); - printf("bonded atoms: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("(%d, %d) ", tag[reduced_neighlist[i][bonded_atom1[i][j]]], reduced_neighlist[i][tag[bonded_atom2[i][j]]]); - printf("\n"); - - for (int j = 0; j < numchainlist[i]; j++) { - printf("chain %d: ", j+1); - for (int k = 0; k < nchainlist[i][j]; k++) { - printf("%d ", tag[chainlist[i][j][k]]); - } - printf("\n"); - } - */ } // destroy remaining temporary arrays for chain creation @@ -823,8 +772,6 @@ void PairMesoCNT::bond_neigh() memory->destroy(chainpos_min); memory->destroy(chainid); memory->destroy(chainpos); - memory->destroy(bonded_atom1); - memory->destroy(bonded_atom2); memory->destroy(numneigh_max); From 354db3468282757f5af7346e856610f3bb7b812b Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 4 May 2022 13:47:35 +0100 Subject: [PATCH 033/443] added print statements for neighbor debug --- src/MESONT/pair_mesocnt.cpp | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index e69c5f70bc..3a2630b4ca 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -551,12 +551,57 @@ void PairMesoCNT::mesolj() void PairMesoCNT::bond_neigh() { int nlocal = atom->nlocal; + int nghost = atom->nghost; int **bondlist = neighbor->bondlist; int nbondlist = neighbor->nbondlist; int *type = atom->type; tagint *tag = atom->tag; tagint **bond_atom = atom->bond_atom; + int **nspecial = atom->nspecial; + tagint **special = atom->special; + + printf("nlocal: %d, nghost: %d\n", nlocal, nghost); + printf("local atoms: "); + for (int j = 0; j < nlocal; j++) + printf("%d ", tag[j]); + printf("\n"); + printf("ghost atoms: "); + for (int j = nlocal; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("%d | ", tag[j]); + else + printf("%d ", tag[j]); + printf("\n"); + printf("map(tag): "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("%d | ", atom->map(tag[j])); + else + printf("%d ", atom->map(tag[j])); + printf("\n"); + printf("bond_atom: "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("%d | ", atom->map(tag[j])); + else + printf("%d ", bond_atom[j][0]); + printf("\n"); + printf("nspecial: "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("(%d, %d, %d) | ", nspecial[j][0], nspecial[j][1], nspecial[j][2]); + else + printf("(%d, %d, %d) ", nspecial[j][0], nspecial[j][1], nspecial[j][2]); + printf("\n"); + printf("special: "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("(%d, %d) | ", special[j][0], special[j][1]); + else + printf("(%d, %d) ", special[j][0], special[j][1]); + printf("\n"); + int *numneigh = list->numneigh; int *numneigh_max; @@ -715,7 +760,7 @@ void PairMesoCNT::bond_neigh() chainpos_min[i][j] = 0; chainpos_max[i][j] = 0; } - + for (int j = 0; j < reduced_nlist[i]; j++) { int cid = chainid[i][j]; int cpos = chainpos[i][j]; @@ -729,9 +774,7 @@ void PairMesoCNT::bond_neigh() if (clen > nchain_max) nchain_max = clen; } } - - memory->destroy(chainpos_max); - + // create connected neighbor chains and check for ends // MEMORY: prevent zero-size array creation for chainlist @@ -770,6 +813,7 @@ void PairMesoCNT::bond_neigh() memory->destroy(reduced_nlist); memory->destroy(chainpos_min); + memory->destroy(chainpos_max); memory->destroy(chainid); memory->destroy(chainpos); From 30f66c643860d2f9e23447010eca9356d4d7b5db Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 4 May 2022 19:00:45 +0100 Subject: [PATCH 034/443] added comm_forward of atom::special for ghost atoms --- src/MESONT/pair_mesocnt.cpp | 233 +++++++++++++++++++++--------------- src/MESONT/pair_mesocnt.h | 3 + 2 files changed, 140 insertions(+), 96 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 3a2630b4ca..daa33ffafb 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -32,6 +32,7 @@ #include #include +#include using namespace LAMMPS_NS; using namespace MathConst; @@ -57,6 +58,8 @@ PairMesoCNT::PairMesoCNT(LAMMPS *lmp) : Pair(lmp) no_virial_fdotr_compute = 0; writedata = 0; ghostneigh = 0; + + comm_forward = 2; } /* ---------------------------------------------------------------------- @@ -557,51 +560,39 @@ void PairMesoCNT::bond_neigh() int *type = atom->type; tagint *tag = atom->tag; - tagint **bond_atom = atom->bond_atom; - int **nspecial = atom->nspecial; tagint **special = atom->special; - printf("nlocal: %d, nghost: %d\n", nlocal, nghost); - printf("local atoms: "); - for (int j = 0; j < nlocal; j++) - printf("%d ", tag[j]); - printf("\n"); - printf("ghost atoms: "); - for (int j = nlocal; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("%d | ", tag[j]); - else - printf("%d ", tag[j]); - printf("\n"); - printf("map(tag): "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("%d | ", atom->map(tag[j])); - else - printf("%d ", atom->map(tag[j])); - printf("\n"); - printf("bond_atom: "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("%d | ", atom->map(tag[j])); - else - printf("%d ", bond_atom[j][0]); - printf("\n"); - printf("nspecial: "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("(%d, %d, %d) | ", nspecial[j][0], nspecial[j][1], nspecial[j][2]); - else - printf("(%d, %d, %d) ", nspecial[j][0], nspecial[j][1], nspecial[j][2]); - printf("\n"); - printf("special: "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("(%d, %d) | ", special[j][0], special[j][1]); - else - printf("(%d, %d) ", special[j][0], special[j][1]); - printf("\n"); + comm->forward_comm(this); + if (comm->me == 0) { + printf("nlocal: %d, nghost: %d\n", nlocal, nghost); + printf("tag: "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("%d | ", tag[j]); + else + printf("%d ", tag[j]); + printf("\n"); + printf("image: "); + for (int j = 0; j < nlocal+nghost; j++) { + + int i1 = (atom->image[j] & IMGMASK) - IMGMAX; + int i2 = (atom->image[j] >> IMGBITS & IMGMASK) - IMGMAX; + int i3 = (atom->image[j] >> IMG2BITS) - IMGMAX; + if (j == nlocal-1) + printf("(%d %d %d)| ", i1, i2, i3); + else + printf("(%d %d %d)", i1, i2, i3); + } + printf("\n"); + printf("special: "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("(%d, %d) | ", special[j][0], special[j][1]); + else + printf("(%d, %d) ", special[j][0], special[j][1]); + printf("\n"); + } int *numneigh = list->numneigh; int *numneigh_max; @@ -651,11 +642,9 @@ void PairMesoCNT::bond_neigh() // split neighbor list into neighbor chains based on bond topology - int **chainid, **chainpos, **bonded_atom1, **bonded_atom2; + int **chainid, **chainpos; memory->create_ragged(chainid, nbondlist, reduced_nlist, "pair:chainid"); memory->create_ragged(chainpos, nbondlist, reduced_nlist, "pair:chainpos"); - memory->create_ragged(bonded_atom1, nbondlist, reduced_nlist, "pair::bonded_atom1"); - memory->create_ragged(bonded_atom2, nbondlist, reduced_nlist, "pair::bonded_atom2"); memory->create(numchainlist, nbondlist, "pair:numchainlist"); bool empty_neigh = true; @@ -666,32 +655,16 @@ void PairMesoCNT::bond_neigh() empty_neigh = false; - for (int j = 0; j < reduced_nlist[i]; j++) { - int jj = reduced_neighlist[i][j]; - int jtag = tag[jj]; - int jbond = bond_atom[atom->map(jtag)][0]; - - bonded_atom1[i][j] = -1; - bonded_atom2[i][j] = -1; - chainid[i][j] = -1; - - bool newchain = true; - for (int k = 0; k < j; k++) { - int kk = reduced_neighlist[i][k]; - int ktag = tag[kk]; - int kbond = bond_atom[atom->map(ktag)][0]; - - // check if atoms are bonded - - if (jtag == kbond || jbond == ktag) { - if (bonded_atom1[i][j] == -1) bonded_atom1[i][j] = k; - else bonded_atom2[i][j] = k; - if (bonded_atom1[i][k] == -1) bonded_atom1[i][k] = j; - else bonded_atom2[i][k] = j; - } - } - } + // map local ids to reduced neighbor list ids + std::unordered_map reduced_map; + for (int j = 0; j < reduced_nlist[i]; j++) { + reduced_map[reduced_neighlist[i][j]] = j; + chainid[i][j] = -1; + printf("(%d, %d, %d) ", j, reduced_neighlist[i][j], tag[reduced_neighlist[i][j]]); + } + printf("\n"); + // assign chain ids and positions for (int j = 0; j < reduced_nlist[i]; j++) { @@ -707,45 +680,82 @@ void PairMesoCNT::bond_neigh() // down the chain - int current_atom = j; - int next_atom = bonded_atom1[i][j]; - while (next_atom != -1) { - chainid[i][next_atom] = numchainlist[i]; - chainpos[i][next_atom] = chainpos[i][current_atom] - 1; - if (bonded_atom1[i][next_atom] != current_atom) { - current_atom = next_atom; - next_atom = bonded_atom1[i][next_atom]; + int curr_local = reduced_neighlist[i][j]; + int next_local = atom->map(special[curr_local][0]); + int curr_reduced, next_reduced; + + printf("up: "); + while (next_local != -1) { + printf("%d %d ", curr_local, next_local); + try { + curr_reduced = reduced_map.at(curr_local); + next_reduced = reduced_map.at(next_local); + } + catch (const std::out_of_range& e) { + break; + } + printf("| "); + + chainid[i][next_reduced] = numchainlist[i]; + chainpos[i][next_reduced] = chainpos[i][curr_reduced] - 1; + if (special[next_local][0] != tag[curr_local]) { + curr_local = next_local; + next_local = atom->map(special[next_local][0]); } else { - current_atom = next_atom; - next_atom = bonded_atom2[i][next_atom]; + curr_local = next_local; + next_local = atom->map(special[next_local][1]); } } + printf("\n"); // up the chain - - current_atom = j; - next_atom = bonded_atom2[i][j]; - while (next_atom != -1) { - chainid[i][next_atom] = numchainlist[i]; - chainpos[i][next_atom] = chainpos[i][current_atom] + 1; - if (bonded_atom1[i][next_atom] != current_atom) { - current_atom = next_atom; - next_atom = bonded_atom1[i][next_atom]; + + curr_local = reduced_neighlist[i][j]; + next_local = atom->map(special[curr_local][1]); + + printf("down: "); + while (next_local != -1) { + printf("%d %d ", curr_local, next_local); + try { + curr_reduced = reduced_map.at(curr_local); + next_reduced = reduced_map.at(next_local); + } + catch (const std::out_of_range& e) { + break; + } + printf("| "); + + chainid[i][next_reduced] = numchainlist[i]; + chainpos[i][next_reduced] = chainpos[i][curr_reduced] + 1; + if (special[next_local][0] != tag[curr_local]) { + curr_local = next_local; + next_local = atom->map(special[next_local][0]); } else { - current_atom = next_atom; - next_atom = bonded_atom2[i][next_atom]; + curr_local = next_local; + next_local = atom->map(special[next_local][1]); } } + numchainlist[i]++; } - } - - // destroy temporary arrays - memory->destroy(bonded_atom1); - memory->destroy(bonded_atom2); + printf("bond: %d\n", i); + printf("tag: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", tag[reduced_neighlist[i][j]]); + printf("\n"); + printf("chainid: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", chainid[i][j]); + printf("\n"); + printf("chainpos: "); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", chainpos[i][j]); + printf("\n"); + fflush(stdout); + } // count neighbor chain lengths per bond @@ -884,6 +894,37 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) } } + +/* ---------------------------------------------------------------------- */ + +int PairMesoCNT::pack_forward_comm(int n, int *list, double *buf, + int /*pbc_flag*/, int * /*pbc*/) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(atom->special[j][0]).d; + buf[m++] = ubuf(atom->special[j][1]).d; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + atom->special[i][0] = (tagint) ubuf(buf[m++]).i; + atom->special[i][1] = (tagint) ubuf(buf[m++]).i; + } +} + /* ---------------------------------------------------------------------- count neighbor chains of given bond ------------------------------------------------------------------------- */ diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index 70445587e7..fde5feb36b 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -31,6 +31,9 @@ class PairMesoCNT : public Pair { void coeff(int, char **) override; void init_style() override; double init_one(int, int) override; + + int pack_forward_comm(int, int *, double *, int, int *) override; + void unpack_forward_comm(int, int, double *) override; protected: int nend_types; From ee6e47388a6687ce78cff74985d224ec5ce47172 Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 5 May 2022 11:41:30 +0100 Subject: [PATCH 035/443] used domain->closest_image to find proper local ids for bonded atoms, method works --- src/MESONT/pair_mesocnt.cpp | 46 +++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index daa33ffafb..6c8a0e8f36 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -20,6 +20,7 @@ #include "atom.h" #include "comm.h" +#include "domain.h" #include "error.h" #include "force.h" #include "math_const.h" @@ -564,6 +565,19 @@ void PairMesoCNT::bond_neigh() comm->forward_comm(this); + // create version of atom->special with local ids and correct images + + int atom1, atom2; + int **special_local; + memory->create(special_local, nlocal+nghost, 2, "pair:special_local"); + for (int i = 0; i < nlocal+nghost; i++) { + atom1 = atom->map(special[i][0]); + atom2 = atom->map(special[i][1]); + special_local[i][0] = domain->closest_image(i, atom1); + special_local[i][1] = domain->closest_image(i, atom2); + printf("atom1: %d, atom2: %d, closest1: %d, closest2: %d\n", atom1, atom2, special_local[i][0], special_local[i][1]); + } + if (comm->me == 0) { printf("nlocal: %d, nghost: %d\n", nlocal, nghost); printf("tag: "); @@ -573,9 +587,23 @@ void PairMesoCNT::bond_neigh() else printf("%d ", tag[j]); printf("\n"); + printf("sametag: "); + for (int j = 0; j < nlocal+nghost; j++) + if (j == nlocal-1) + printf("%d | ", atom->sametag[j]); + else + printf("%d ", atom->sametag[j]); + printf("\n"); + printf("x: "); + for (int j = 0; j < nlocal+nghost; j++) { + if (j == nlocal-1) + printf("%f | ", atom->x[j][0]); + else + printf("%f ", atom->x[j][0]); + } + printf("\n"); printf("image: "); for (int j = 0; j < nlocal+nghost; j++) { - int i1 = (atom->image[j] & IMGMASK) - IMGMAX; int i2 = (atom->image[j] >> IMGBITS & IMGMASK) - IMGMAX; int i3 = (atom->image[j] >> IMG2BITS) - IMGMAX; @@ -681,7 +709,7 @@ void PairMesoCNT::bond_neigh() // down the chain int curr_local = reduced_neighlist[i][j]; - int next_local = atom->map(special[curr_local][0]); + int next_local = special_local[curr_local][0]; int curr_reduced, next_reduced; printf("up: "); @@ -698,13 +726,13 @@ void PairMesoCNT::bond_neigh() chainid[i][next_reduced] = numchainlist[i]; chainpos[i][next_reduced] = chainpos[i][curr_reduced] - 1; - if (special[next_local][0] != tag[curr_local]) { + if (special_local[next_local][0] != curr_local) { curr_local = next_local; - next_local = atom->map(special[next_local][0]); + next_local = special_local[next_local][0]; } else { curr_local = next_local; - next_local = atom->map(special[next_local][1]); + next_local = special_local[next_local][1]; } } printf("\n"); @@ -712,7 +740,7 @@ void PairMesoCNT::bond_neigh() // up the chain curr_local = reduced_neighlist[i][j]; - next_local = atom->map(special[curr_local][1]); + next_local = special_local[curr_local][1]; printf("down: "); while (next_local != -1) { @@ -728,13 +756,13 @@ void PairMesoCNT::bond_neigh() chainid[i][next_reduced] = numchainlist[i]; chainpos[i][next_reduced] = chainpos[i][curr_reduced] + 1; - if (special[next_local][0] != tag[curr_local]) { + if (special_local[next_local][0] != curr_local) { curr_local = next_local; - next_local = atom->map(special[next_local][0]); + next_local = special_local[next_local][0]; } else { curr_local = next_local; - next_local = atom->map(special[next_local][1]); + next_local = special_local[next_local][1]; } } From 055ed246532ab2e08e8f2cea4521a4dc0f247480 Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 5 May 2022 11:43:37 +0100 Subject: [PATCH 036/443] removed print statements again --- src/MESONT/pair_mesocnt.cpp | 69 ------------------------------------- 1 file changed, 69 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 6c8a0e8f36..c22fe56c20 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -575,51 +575,6 @@ void PairMesoCNT::bond_neigh() atom2 = atom->map(special[i][1]); special_local[i][0] = domain->closest_image(i, atom1); special_local[i][1] = domain->closest_image(i, atom2); - printf("atom1: %d, atom2: %d, closest1: %d, closest2: %d\n", atom1, atom2, special_local[i][0], special_local[i][1]); - } - - if (comm->me == 0) { - printf("nlocal: %d, nghost: %d\n", nlocal, nghost); - printf("tag: "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("%d | ", tag[j]); - else - printf("%d ", tag[j]); - printf("\n"); - printf("sametag: "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("%d | ", atom->sametag[j]); - else - printf("%d ", atom->sametag[j]); - printf("\n"); - printf("x: "); - for (int j = 0; j < nlocal+nghost; j++) { - if (j == nlocal-1) - printf("%f | ", atom->x[j][0]); - else - printf("%f ", atom->x[j][0]); - } - printf("\n"); - printf("image: "); - for (int j = 0; j < nlocal+nghost; j++) { - int i1 = (atom->image[j] & IMGMASK) - IMGMAX; - int i2 = (atom->image[j] >> IMGBITS & IMGMASK) - IMGMAX; - int i3 = (atom->image[j] >> IMG2BITS) - IMGMAX; - if (j == nlocal-1) - printf("(%d %d %d)| ", i1, i2, i3); - else - printf("(%d %d %d)", i1, i2, i3); - } - printf("\n"); - printf("special: "); - for (int j = 0; j < nlocal+nghost; j++) - if (j == nlocal-1) - printf("(%d, %d) | ", special[j][0], special[j][1]); - else - printf("(%d, %d) ", special[j][0], special[j][1]); - printf("\n"); } int *numneigh = list->numneigh; @@ -689,9 +644,7 @@ void PairMesoCNT::bond_neigh() for (int j = 0; j < reduced_nlist[i]; j++) { reduced_map[reduced_neighlist[i][j]] = j; chainid[i][j] = -1; - printf("(%d, %d, %d) ", j, reduced_neighlist[i][j], tag[reduced_neighlist[i][j]]); } - printf("\n"); // assign chain ids and positions @@ -712,9 +665,7 @@ void PairMesoCNT::bond_neigh() int next_local = special_local[curr_local][0]; int curr_reduced, next_reduced; - printf("up: "); while (next_local != -1) { - printf("%d %d ", curr_local, next_local); try { curr_reduced = reduced_map.at(curr_local); next_reduced = reduced_map.at(next_local); @@ -722,7 +673,6 @@ void PairMesoCNT::bond_neigh() catch (const std::out_of_range& e) { break; } - printf("| "); chainid[i][next_reduced] = numchainlist[i]; chainpos[i][next_reduced] = chainpos[i][curr_reduced] - 1; @@ -735,16 +685,13 @@ void PairMesoCNT::bond_neigh() next_local = special_local[next_local][1]; } } - printf("\n"); // up the chain curr_local = reduced_neighlist[i][j]; next_local = special_local[curr_local][1]; - printf("down: "); while (next_local != -1) { - printf("%d %d ", curr_local, next_local); try { curr_reduced = reduced_map.at(curr_local); next_reduced = reduced_map.at(next_local); @@ -752,7 +699,6 @@ void PairMesoCNT::bond_neigh() catch (const std::out_of_range& e) { break; } - printf("| "); chainid[i][next_reduced] = numchainlist[i]; chainpos[i][next_reduced] = chainpos[i][curr_reduced] + 1; @@ -768,21 +714,6 @@ void PairMesoCNT::bond_neigh() numchainlist[i]++; } - - printf("bond: %d\n", i); - printf("tag: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", tag[reduced_neighlist[i][j]]); - printf("\n"); - printf("chainid: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", chainid[i][j]); - printf("\n"); - printf("chainpos: "); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", chainpos[i][j]); - printf("\n"); - fflush(stdout); } // count neighbor chain lengths per bond From 09f82d5fea134fb4495be8c158504aa42ade4796 Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 5 May 2022 12:35:44 +0100 Subject: [PATCH 037/443] removed old neighbor chain construction functions --- src/MESONT/pair_mesocnt.cpp | 201 ++++++------------------------------ src/MESONT/pair_mesocnt.h | 5 - 2 files changed, 33 insertions(+), 173 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index c22fe56c20..c962b87b0c 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -560,7 +560,6 @@ void PairMesoCNT::bond_neigh() int nbondlist = neighbor->nbondlist; int *type = atom->type; - tagint *tag = atom->tag; tagint **special = atom->special; comm->forward_comm(this); @@ -570,6 +569,7 @@ void PairMesoCNT::bond_neigh() int atom1, atom2; int **special_local; memory->create(special_local, nlocal+nghost, 2, "pair:special_local"); + for (int i = 0; i < nlocal+nghost; i++) { atom1 = atom->map(special[i][0]); atom2 = atom->map(special[i][1]); @@ -580,6 +580,7 @@ void PairMesoCNT::bond_neigh() int *numneigh = list->numneigh; int *numneigh_max; memory->create(numneigh_max, nbondlist, "pair:numneigh_max"); + for (int i = 0; i < nbondlist; i++) { int i1 = bondlist[i][0]; int i2 = bondlist[i][1]; @@ -608,12 +609,7 @@ void PairMesoCNT::bond_neigh() for (int i = 0; i < nbondlist; i++) { int i1 = bondlist[i][0]; int i2 = bondlist[i][1]; - neigh_common(i1, i2, reduced_nlist[i], reduced_neighlist[i]); - - // sort list according to atom-id - - sort(reduced_neighlist[i], reduced_nlist[i]); } // resize chain arrays @@ -659,63 +655,46 @@ void PairMesoCNT::bond_neigh() chainid[i][j] = numchainlist[i]; chainpos[i][j] = 0; - // down the chain - - int curr_local = reduced_neighlist[i][j]; - int next_local = special_local[curr_local][0]; + int curr_local, next_local; int curr_reduced, next_reduced; - while (next_local != -1) { - try { - curr_reduced = reduced_map.at(curr_local); - next_reduced = reduced_map.at(next_local); - } - catch (const std::out_of_range& e) { - break; - } + // down the chain: k = 0; up the chain: k = 1 - chainid[i][next_reduced] = numchainlist[i]; - chainpos[i][next_reduced] = chainpos[i][curr_reduced] - 1; - if (special_local[next_local][0] != curr_local) { - curr_local = next_local; - next_local = special_local[next_local][0]; - } - else { - curr_local = next_local; - next_local = special_local[next_local][1]; + for (int k = 0; k < 2; k++) { + curr_local = reduced_neighlist[i][j]; + next_local = special_local[curr_local][k]; + + while (next_local != -1) { + try { + curr_reduced = reduced_map.at(curr_local); + next_reduced = reduced_map.at(next_local); + } + catch (const std::out_of_range& e) { + break; + } + + chainid[i][next_reduced] = numchainlist[i]; + if (k == 0) + chainpos[i][next_reduced] = chainpos[i][curr_reduced] - 1; + else + chainpos[i][next_reduced] = chainpos[i][curr_reduced] + 1; + if (special_local[next_local][0] != curr_local) { + curr_local = next_local; + next_local = special_local[next_local][0]; + } + else { + curr_local = next_local; + next_local = special_local[next_local][1]; + } } } - // up the chain - - curr_local = reduced_neighlist[i][j]; - next_local = special_local[curr_local][1]; - - while (next_local != -1) { - try { - curr_reduced = reduced_map.at(curr_local); - next_reduced = reduced_map.at(next_local); - } - catch (const std::out_of_range& e) { - break; - } - - chainid[i][next_reduced] = numchainlist[i]; - chainpos[i][next_reduced] = chainpos[i][curr_reduced] + 1; - if (special_local[next_local][0] != curr_local) { - curr_local = next_local; - next_local = special_local[next_local][0]; - } - else { - curr_local = next_local; - next_local = special_local[next_local][1]; - } - } - numchainlist[i]++; } } + memory->destroy(special_local); + // count neighbor chain lengths per bond int **chainpos_min, **chainpos_max; @@ -885,121 +864,7 @@ void PairMesoCNT::unpack_forward_comm(int n, int first, double *buf) } /* ---------------------------------------------------------------------- - count neighbor chains of given bond -------------------------------------------------------------------------- */ - -int PairMesoCNT::count_chains(int *redlist, int numred) -{ - if (numred == 0) return 0; - - tagint *tag = atom->tag; - tagint *mol = atom->molecule; - int count = 1; - - // split neighbor list and count chains - - for (int j = 0; j < numred - 1; j++) { - int j1 = redlist[j]; - int j2 = redlist[j + 1]; - if (tag[j2] - tag[j1] != 1 || mol[j1] != mol[j2]) count++; - } - - return count; -} -/* ---------------------------------------------------------------------- - count lengths of neighbor chains of given bond -------------------------------------------------------------------------- */ - -void PairMesoCNT::chain_lengths(int *redlist, int numred, int *nchain) -{ - if (numred == 0) return; - - tagint *tag = atom->tag; - tagint *mol = atom->molecule; - int clen = 0; - int cid = 0; - - // split neighbor list into connected chains - - for (int j = 0; j < numred - 1; j++) { - int j1 = redlist[j]; - int j2 = redlist[j + 1]; - clen++; - if (tag[j2] - tag[j1] != 1 || mol[j1] != mol[j2]) { - nchain[cid++] = clen; - clen = 0; - } - } - clen++; - nchain[cid++] = clen; -} - -/* ---------------------------------------------------------------------- - split neighbors into chains and identify ends -------------------------------------------------------------------------- */ - -void PairMesoCNT::chain_split(int *redlist, int numred, int *nchain, int **chain, int *end) -{ - if (numred == 0) return; - - tagint *tag = atom->tag; - tagint *mol = atom->molecule; - int clen = 0; - int cid = 0; - - // split neighbor list into connected chains - - for (int j = 0; j < numred - 1; j++) { - int j1 = redlist[j]; - int j2 = redlist[j + 1]; - chain[cid][clen++] = j1; - if (tag[j2] - tag[j1] != 1 || mol[j1] != mol[j2]) { - cid++; - clen = 0; - } - } - chain[cid][clen++] = redlist[numred - 1]; - cid++; - - // check for chain ends - - for (int j = 0; j < cid; j++) { - int cstart = chain[j][0]; - int cend = chain[j][nchain[j] - 1]; - - if (match_end(atom->type[cstart])) - end[j] = 1; - else if (match_end(atom->type[cend])) - end[j] = 2; - else - end[j] = 0; - } -} - -/* ---------------------------------------------------------------------- - insertion sort list according to corresponding atom ID -------------------------------------------------------------------------- */ - -void PairMesoCNT::sort(int *list, int size) -{ - int i, j, temp1, temp2; - tagint *tag = atom->tag; - for (i = 1; i < size; i++) { - j = i; - temp1 = list[j - 1]; - temp2 = list[j]; - while (j > 0 && tag[temp1] > tag[temp2]) { - list[j] = temp1; - list[j - 1] = temp2; - j--; - temp1 = list[j - 1]; - temp2 = list[j]; - } - } -} - -/* ---------------------------------------------------------------------- - insertion sort list according to corresponding atom ID + check if type is in end_types ------------------------------------------------------------------------- */ bool PairMesoCNT::match_end(int type) diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index fde5feb36b..4933edeb5c 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -58,16 +58,11 @@ class PairMesoCNT : public Pair { double **uinf_coeff, **gamma_coeff, ****phi_coeff, ****usemi_coeff; double **flocal, **fglobal, **basis; - int count_chains(int *, int); - bool match_end(int); void allocate(); void bond_neigh(); void neigh_common(int, int, int &, int *); - void chain_lengths(int *, int, int *); - void chain_split(int *, int, int *, int **, int *); - void sort(int *, int); void read_file(const char *); void read_data(PotentialFileReader &, double *, double &, double &, int); void read_data(PotentialFileReader &, double **, double &, double &, double &, double &, int); From dd5305bfd09a1c26e55274395b4588d86c047eaa Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 11 May 2022 17:43:44 +0100 Subject: [PATCH 038/443] added self-interaction chain identification, now needs to be removed --- src/MESONT/pair_mesocnt.cpp | 42 +++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index c962b87b0c..22126ea32a 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -596,7 +596,7 @@ void PairMesoCNT::bond_neigh() numneigh2 = 0; else numneigh2 = numneigh[i2]; - numneigh_max[i] = numneigh1 + numneigh2; + numneigh_max[i] = numneigh1 + numneigh2 + 2; } // create temporary arrays for chain creation @@ -642,6 +642,8 @@ void PairMesoCNT::bond_neigh() chainid[i][j] = -1; } + int selfid = -1; + // assign chain ids and positions for (int j = 0; j < reduced_nlist[i]; j++) { @@ -654,6 +656,9 @@ void PairMesoCNT::bond_neigh() chainid[i][j] = numchainlist[i]; chainpos[i][j] = 0; + + if (reduced_neighlist[i][j] == bondlist[i][0]) + selfid = numchainlist[i]; int curr_local, next_local; int curr_reduced, next_reduced; @@ -686,6 +691,8 @@ void PairMesoCNT::bond_neigh() curr_local = next_local; next_local = special_local[next_local][1]; } + + if (curr_local == bondlist[i][0]) selfid = numchainlist[i]; } } @@ -754,6 +761,19 @@ void PairMesoCNT::bond_neigh() else endlist[i][j] = 0; } } + + for (int i = 0; i < nbondlist; i++) { + printf("bond: %d\n", i + 1); + for (int j = 0; j < reduced_nlist[i]; j++) + printf("%d ", atom->tag[reduced_neighlist[i][j]]); + printf("\n"); + for (int j = 0; j < numchainlist[i]; j++) { + printf("chain %d: ", j + 1); + for (int k = 0; k < nchainlist[i][j]; k++) + printf("%d ", atom->tag[chainlist[i][j][k]]); + printf("\n"); + } + } // destroy remaining temporary arrays for chain creation @@ -805,19 +825,21 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) numneigh2 = numneigh[i2]; } - int numneigh_max = numneigh1 + numneigh2; numred = 0; - if (numneigh_max < 2) return; for (int j = 0; j < numneigh1; j++) { - int ind = neighlist1[j]; - if (mol[ind] == mol[i1] && abs(tag[ind] - tag[i1]) < SELF_CUTOFF) continue; + int ind = neighlist1[j] & NEIGHMASK; redlist[numred++] = ind; } int inflag = 0; - for (int j2 = 0; j2 < numneigh2; j2++) { - for (int j1 = 0; j1 < numneigh1; j1++) { - if (neighlist1[j1] == neighlist2[j2]) { + for (int j2 = 0; j2 < numneigh2 + 2; j2++) { + int ind2; + if (j2 == numneigh2) ind2 = i1; + else if (j2 == numneigh2 + 1) ind2 = i2; + else ind2 = neighlist2[j2] & NEIGHMASK; + for (int j1 = 0; j1 < numred; j1++) { + int ind1 = redlist[j1] & NEIGHMASK; + if (ind1 == ind2) { inflag = 1; break; } @@ -826,9 +848,7 @@ void PairMesoCNT::neigh_common(int i1, int i2, int &numred, int *redlist) inflag = 0; continue; } - int ind = neighlist2[j2]; - if (mol[ind] == mol[i2] && abs(tag[ind] - tag[i2]) < SELF_CUTOFF) continue; - redlist[numred++] = ind; + redlist[numred++] = ind2; } } From 2a7d6adb314304e2bfe5bc40bf1d791ded728c64 Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 11 May 2022 19:07:32 +0100 Subject: [PATCH 039/443] added self-interaction exclusion based on bond topology --- src/MESONT/pair_mesocnt.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 22126ea32a..01781803bc 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -621,9 +621,11 @@ void PairMesoCNT::bond_neigh() // split neighbor list into neighbor chains based on bond topology + int *selfid; int **chainid, **chainpos; memory->create_ragged(chainid, nbondlist, reduced_nlist, "pair:chainid"); memory->create_ragged(chainpos, nbondlist, reduced_nlist, "pair:chainpos"); + memory->create(selfid, nbondlist, "pair:selfid"); memory->create(numchainlist, nbondlist, "pair:numchainlist"); bool empty_neigh = true; @@ -642,8 +644,6 @@ void PairMesoCNT::bond_neigh() chainid[i][j] = -1; } - int selfid = -1; - // assign chain ids and positions for (int j = 0; j < reduced_nlist[i]; j++) { @@ -658,7 +658,7 @@ void PairMesoCNT::bond_neigh() chainpos[i][j] = 0; if (reduced_neighlist[i][j] == bondlist[i][0]) - selfid = numchainlist[i]; + selfid[i] = numchainlist[i]; int curr_local, next_local; int curr_reduced, next_reduced; @@ -692,12 +692,14 @@ void PairMesoCNT::bond_neigh() next_local = special_local[next_local][1]; } - if (curr_local == bondlist[i][0]) selfid = numchainlist[i]; + if (curr_local == bondlist[i][0]) + selfid[i] = numchainlist[i]; } } numchainlist[i]++; } + numchainlist[i]--; } memory->destroy(special_local); @@ -718,9 +720,16 @@ void PairMesoCNT::bond_neigh() for (int j = 0; j < reduced_nlist[i]; j++) { int cid = chainid[i][j]; - int cpos = chainpos[i][j]; - if (cpos < chainpos_min[i][cid]) chainpos_min[i][cid] = cpos; - if (cpos > chainpos_max[i][cid]) chainpos_max[i][cid] = cpos; + if (cid < selfid[i]) { + int cpos = chainpos[i][j]; + if (cpos < chainpos_min[i][cid]) chainpos_min[i][cid] = cpos; + if (cpos > chainpos_max[i][cid]) chainpos_max[i][cid] = cpos; + } + else if (cid > selfid[i]) { + int cpos = chainpos[i][j]; + if (cpos < chainpos_min[i][cid - 1]) chainpos_min[i][cid - 1] = cpos; + if (cpos > chainpos_max[i][cid - 1]) chainpos_max[i][cid - 1] = cpos; + } } for (int j = 0; j < numchainlist[i]; j++) { @@ -745,8 +754,14 @@ void PairMesoCNT::bond_neigh() for (int j = 0; j < reduced_nlist[i]; j++) { int cid = chainid[i][j]; - int cpos = chainpos[i][j] - chainpos_min[i][cid]; - chainlist[i][cid][cpos] = reduced_neighlist[i][j]; + if (cid < selfid[i]) { + int cpos = chainpos[i][j] - chainpos_min[i][cid]; + chainlist[i][cid][cpos] = reduced_neighlist[i][j]; + } + else if (cid > selfid[i]){ + int cpos = chainpos[i][j] - chainpos_min[i][cid - 1]; + chainlist[i][cid - 1][cpos] = reduced_neighlist[i][j]; + } } // check for ends @@ -762,6 +777,7 @@ void PairMesoCNT::bond_neigh() } } + /* for (int i = 0; i < nbondlist; i++) { printf("bond: %d\n", i + 1); for (int j = 0; j < reduced_nlist[i]; j++) @@ -774,6 +790,7 @@ void PairMesoCNT::bond_neigh() printf("\n"); } } + */ // destroy remaining temporary arrays for chain creation From f15c4852c93700d38ccd257fbf21698f99be5576 Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 11 May 2022 20:29:16 +0100 Subject: [PATCH 040/443] added forward comm case for less than two 1-2 neighbors (for cnt ends) --- src/MESONT/pair_mesocnt.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 01781803bc..33fd88b32c 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -60,7 +60,7 @@ PairMesoCNT::PairMesoCNT(LAMMPS *lmp) : Pair(lmp) writedata = 0; ghostneigh = 0; - comm_forward = 2; + comm_forward = 3; } /* ---------------------------------------------------------------------- @@ -880,8 +880,12 @@ int PairMesoCNT::pack_forward_comm(int n, int *list, double *buf, m = 0; for (i = 0; i < n; i++) { j = list[i]; + buf[m++] = ubuf(atom->nspecial[j][0]).d; buf[m++] = ubuf(atom->special[j][0]).d; - buf[m++] = ubuf(atom->special[j][1]).d; + if (atom->nspecial[j][0] == 1) + buf[m++] = ubuf(-1).d; + else + buf[m++] = ubuf(atom->special[j][1]).d; } return m; } @@ -895,8 +899,12 @@ void PairMesoCNT::unpack_forward_comm(int n, int first, double *buf) m = 0; last = first + n; for (i = first; i < last; i++) { + atom->nspecial[i][0] = (int) ubuf(buf[m++]).i; atom->special[i][0] = (tagint) ubuf(buf[m++]).i; - atom->special[i][1] = (tagint) ubuf(buf[m++]).i; + if (atom->nspecial[i][0] == 1) + atom->special[i][1] = -1; + else + atom->special[i][1] = (tagint) ubuf(buf[m++]).i; } } From ad25fd78e05a428cc6fad87a80cc5c0fc27f126a Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 12 May 2022 14:31:15 +0100 Subject: [PATCH 041/443] fixed forward comm bug for tube ends --- src/MESONT/pair_mesocnt.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 33fd88b32c..3a91fb1d26 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -560,6 +560,7 @@ void PairMesoCNT::bond_neigh() int nbondlist = neighbor->nbondlist; int *type = atom->type; + int **nspecial = atom->nspecial; tagint **special = atom->special; comm->forward_comm(this); @@ -572,9 +573,14 @@ void PairMesoCNT::bond_neigh() for (int i = 0; i < nlocal+nghost; i++) { atom1 = atom->map(special[i][0]); - atom2 = atom->map(special[i][1]); special_local[i][0] = domain->closest_image(i, atom1); - special_local[i][1] = domain->closest_image(i, atom2); + if (nspecial[i][0] == 1) + special_local[i][1] = -1; + else { + atom2 = atom->map(special[i][1]); + special_local[i][1] = domain->closest_image(i, atom2); + } + // printf("%d %d %d (%d) %d (%d)\n", atom->tag[i], nspecial[i][0], atom->tag[atom1], atom1, atom->tag[atom2], atom2); } int *numneigh = list->numneigh; @@ -791,7 +797,7 @@ void PairMesoCNT::bond_neigh() } } */ - + // destroy remaining temporary arrays for chain creation memory->destroy(reduced_neighlist); @@ -901,10 +907,9 @@ void PairMesoCNT::unpack_forward_comm(int n, int first, double *buf) for (i = first; i < last; i++) { atom->nspecial[i][0] = (int) ubuf(buf[m++]).i; atom->special[i][0] = (tagint) ubuf(buf[m++]).i; - if (atom->nspecial[i][0] == 1) - atom->special[i][1] = -1; - else - atom->special[i][1] = (tagint) ubuf(buf[m++]).i; + if (atom->nspecial[i][0] > 1) + atom->special[i][1] = (tagint) ubuf(buf[m]).i; + m++; } } From e8493a08b478da9fd10bce9cdc9edba20dbcedde Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 12 May 2022 15:46:23 +0100 Subject: [PATCH 042/443] destroying selfid --- src/MESONT/pair_mesocnt.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 3a91fb1d26..20011b806e 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -809,6 +809,7 @@ void PairMesoCNT::bond_neigh() memory->destroy(chainpos); memory->destroy(numneigh_max); + memory->destroy(selfid); // resize potential arrays From d37df9350ca33252b7e01e5234f3779d18445a70 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 27 May 2022 15:13:27 +0100 Subject: [PATCH 043/443] added buckled flag as custom atom property to angle_mesocnt, used by pair_mesocnt to determine if substitute chain heuristic can be used --- src/MESONT/angle_mesocnt.cpp | 16 ++++++++++++++++ src/MESONT/angle_mesocnt.h | 1 + src/MESONT/pair_mesocnt.cpp | 24 ++++++++++++++++++++++-- src/MESONT/pair_mesocnt.h | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp index 85a45b5c7e..ede39d8e3c 100644 --- a/src/MESONT/angle_mesocnt.cpp +++ b/src/MESONT/angle_mesocnt.cpp @@ -20,6 +20,7 @@ #include "force.h" #include "math_const.h" #include "memory.h" +#include "modify.h" #include "neighbor.h" #include @@ -72,6 +73,10 @@ void AngleMesoCNT::compute(int eflag, int vflag) int nlocal = atom->nlocal; int newton_bond = force->newton_bond; + int flag, cols; + int index = atom->find_custom("buckled", flag, cols); + int *buckled = atom->ivector[index]; + for (n = 0; n < nanglelist; n++) { i1 = anglelist[n][0]; i2 = anglelist[n][1]; @@ -117,12 +122,16 @@ void AngleMesoCNT::compute(int eflag, int vflag) tk = kh[type] * dtheta; if (eflag) eangle = tk * dtheta; a = -2.0 * tk * s; + + buckled[i2] = 0; } // bending buckling else { if (eflag) eangle = kb[type] * fabs(dtheta) + thetab[type] * (kh[type] * thetab[type] - kb[type]); if (dtheta < 0) a = kb[type] * s; else a = -kb[type] * s; + + buckled[i2] = 1; } a11 = a * c / rsq1; a12 = -a / (r1 * r2); @@ -208,6 +217,13 @@ void AngleMesoCNT::coeff(int narg, char **arg) if (count == 0) error->all(FLERR, "Incorrect args for angle coefficients"); } +void AngleMesoCNT::init_style() +{ + char *id_fix = utils::strdup("angle_mesocnt_buckled"); + if (modify->find_fix(id_fix) < 0) + modify->add_fix(std::string(id_fix)+" all property/atom i_buckled ghost yes"); +} + /* ---------------------------------------------------------------------- */ double AngleMesoCNT::equilibrium_angle(int i) diff --git a/src/MESONT/angle_mesocnt.h b/src/MESONT/angle_mesocnt.h index 34960e4de8..faec85f1c2 100644 --- a/src/MESONT/angle_mesocnt.h +++ b/src/MESONT/angle_mesocnt.h @@ -28,6 +28,7 @@ class AngleMesoCNT : public Angle { ~AngleMesoCNT() override; void compute(int, int) override; void coeff(int, char **) override; + void init_style() override; double equilibrium_angle(int) override; void write_restart(FILE *) override; void read_restart(FILE *) override; diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 20011b806e..6b5946783e 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -33,6 +33,7 @@ #include #include +#include #include using namespace LAMMPS_NS; @@ -83,6 +84,7 @@ PairMesoCNT::~PairMesoCNT() memory->destroy(numchainlist); memory->destroy(nchainlist); memory->destroy(endlist); + memory->destroy(modelist); memory->destroy(chainlist); memory->destroy(w); @@ -134,6 +136,7 @@ void PairMesoCNT::allocate() memory->create(numchainlist, init_size, "pair:numchainlist"); memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); memory->create(endlist, init_size, init_size, "pair:endlist"); + memory->create(modelist, init_size, init_size, "pair:modelist"); memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); memory->create(w, init_size, "pair:w"); @@ -563,6 +566,9 @@ void PairMesoCNT::bond_neigh() int **nspecial = atom->nspecial; tagint **special = atom->special; + int flag, cols; + int buckled_index = atom->find_custom("buckled", flag, cols); + comm->forward_comm(this); // create version of atom->special with local ids and correct images @@ -623,6 +629,7 @@ void PairMesoCNT::bond_neigh() memory->destroy(numchainlist); memory->destroy(nchainlist); memory->destroy(endlist); + memory->destroy(modelist); memory->destroy(chainlist); // split neighbor list into neighbor chains based on bond topology @@ -749,6 +756,7 @@ void PairMesoCNT::bond_neigh() // MEMORY: prevent zero-size array creation for chainlist memory->create_ragged(endlist, nbondlist, numchainlist, "pair:endlist"); + memory->create_ragged(modelist, nbondlist, numchainlist, "pair:modelist"); if (empty_neigh) memory->create(chainlist, 1, 1, 1, "pair:chainlist"); else @@ -777,9 +785,21 @@ void PairMesoCNT::bond_neigh() int cstart = chainlist[i][j][0]; int cend = chainlist[i][j][clen-1]; - if (match_end(type[cstart])) endlist[i][j] = 1; - else if (match_end(type[cend])) endlist[i][j] = 2; + modelist[i][j] = 0; + + if (nspecial[cstart][0] == 1 && nspecial[cend][0] == 1) modelist[i][j] = 1; + else if (nspecial[cstart][0] == 1) endlist[i][j] = 1; + else if (nspecial[cend][0] == 1) endlist[i][j] = 2; else endlist[i][j] = 0; + + if (buckled_index != -1) { + for (int k = 0; k < nchainlist[i][j]; k++) { + if (atom->ivector[buckled_index][chainlist[i][j][k]]) { + modelist[i][j] = 1; + break; + } + } + } } } diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index 4933edeb5c..c58e7439ff 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -39,7 +39,7 @@ class PairMesoCNT : public Pair { int nend_types; int uinf_points, gamma_points, phi_points, usemi_points; int *end_types, *reduced_nlist, *numchainlist; - int **reduced_neighlist, **nchainlist, **endlist; + int **reduced_neighlist, **nchainlist, **endlist, **modelist; int ***chainlist; double ang, ang_inv, eunit, funit; From 57115f1769531e0a9589b6effc5abd8e1ecc3cd6 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 27 May 2022 17:35:50 +0100 Subject: [PATCH 044/443] reverted end identification to type comparison + added if statement for segment-segment mode --- src/MESONT/pair_mesocnt.cpp | 389 ++++++++++++++++++------------------ 1 file changed, 199 insertions(+), 190 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 6b5946783e..703cb4f9cd 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -309,241 +309,246 @@ void PairMesoCNT::mesolj() clen = nchain[j]; if (clen < 2) continue; - // assign end position + if (modelist[i][j]) { - endflag = end[j]; - if (endflag == 1) { - endindex = chain[j][0]; - qe = x[endindex]; - } else if (endflag == 2) { - endindex = chain[j][clen - 1]; - qe = x[endindex]; } + else { + // assign end position - // compute substitute straight (semi-)infinite CNT - - zero3(p1); - zero3(p2); - zero3(dr1_sumw); - zero3(dr2_sumw); - zeromat3(q1_dr1_w); - zeromat3(q2_dr1_w); - zeromat3(q1_dr2_w); - zeromat3(q2_dr2_w); - for (k = 0; k < clen; k++) { - wnode[k] = 0.0; - zero3(dq_w[k]); - zeromat3(q1_dq_w[k]); - zeromat3(q2_dq_w[k]); - } - sumw = 0.0; - - for (k = 0; k < clen - 1; k++) { - j1 = chain[j][k]; - j2 = chain[j][k + 1]; - j1 &= NEIGHMASK; - j2 &= NEIGHMASK; - q1 = x[j1]; - q2 = x[j2]; - - weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); - - if (w[k] == 0.0) { - if (endflag == 1 && k == 0) - endflag = 0; - else if (endflag == 2 && k == clen - 2) - endflag = 0; - continue; + endflag = end[j]; + if (endflag == 1) { + endindex = chain[j][0]; + qe = x[endindex]; + } else if (endflag == 2) { + endindex = chain[j][clen - 1]; + qe = x[endindex]; } - sumw += w[k]; - wnode[k] += w[k]; - wnode[k + 1] += w[k]; + // compute substitute straight (semi-)infinite CNT - scaleadd3(w[k], q1, p1, p1); - scaleadd3(w[k], q2, p2, p2); + zero3(p1); + zero3(p2); + zero3(dr1_sumw); + zero3(dr2_sumw); + zeromat3(q1_dr1_w); + zeromat3(q2_dr1_w); + zeromat3(q1_dr2_w); + zeromat3(q2_dr2_w); + for (k = 0; k < clen; k++) { + wnode[k] = 0.0; + zero3(dq_w[k]); + zeromat3(q1_dq_w[k]); + zeromat3(q2_dq_w[k]); + } + sumw = 0.0; - // weight gradient terms + for (k = 0; k < clen - 1; k++) { + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + q1 = x[j1]; + q2 = x[j2]; - add3(dr1_w, dr1_sumw, dr1_sumw); - add3(dr2_w, dr2_sumw, dr2_sumw); + weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); - outer3(q1, dr1_w, temp); - plus3(temp, q1_dr1_w, q1_dr1_w); - outer3(q2, dr1_w, temp); - plus3(temp, q2_dr1_w, q2_dr1_w); - outer3(q1, dr2_w, temp); - plus3(temp, q1_dr2_w, q1_dr2_w); - outer3(q2, dr2_w, temp); - plus3(temp, q2_dr2_w, q2_dr2_w); + if (w[k] == 0.0) { + if (endflag == 1 && k == 0) + endflag = 0; + else if (endflag == 2 && k == clen - 2) + endflag = 0; + continue; + } - add3(dq1_w, dq_w[k], dq_w[k]); - add3(dq2_w, dq_w[k + 1], dq_w[k + 1]); + sumw += w[k]; + wnode[k] += w[k]; + wnode[k + 1] += w[k]; - outer3(q1, dq1_w, temp); - plus3(temp, q1_dq_w[k], q1_dq_w[k]); - outer3(q1, dq2_w, temp); - plus3(temp, q1_dq_w[k + 1], q1_dq_w[k + 1]); - outer3(q2, dq1_w, temp); - plus3(temp, q2_dq_w[k], q2_dq_w[k]); - outer3(q2, dq2_w, temp); - plus3(temp, q2_dq_w[k + 1], q2_dq_w[k + 1]); - } + scaleadd3(w[k], q1, p1, p1); + scaleadd3(w[k], q2, p2, p2); - if (sumw == 0.0) continue; + // weight gradient terms - sumw_inv = 1.0 / sumw; - scale3(sumw_inv, p1); - scale3(sumw_inv, p2); + add3(dr1_w, dr1_sumw, dr1_sumw); + add3(dr2_w, dr2_sumw, dr2_sumw); - // compute geometry and forces + outer3(q1, dr1_w, temp); + plus3(temp, q1_dr1_w, q1_dr1_w); + outer3(q2, dr1_w, temp); + plus3(temp, q2_dr1_w, q2_dr1_w); + outer3(q1, dr2_w, temp); + plus3(temp, q1_dr2_w, q1_dr2_w); + outer3(q2, dr2_w, temp); + plus3(temp, q2_dr2_w, q2_dr2_w); - // infinite CNT case + add3(dq1_w, dq_w[k], dq_w[k]); + add3(dq2_w, dq_w[k + 1], dq_w[k + 1]); - if (endflag == 0) { - geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); - if (param[0] > cutoff) continue; - finf(param, evdwl, flocal); + outer3(q1, dq1_w, temp); + plus3(temp, q1_dq_w[k], q1_dq_w[k]); + outer3(q1, dq2_w, temp); + plus3(temp, q1_dq_w[k + 1], q1_dq_w[k + 1]); + outer3(q2, dq1_w, temp); + plus3(temp, q2_dq_w[k], q2_dq_w[k]); + outer3(q2, dq2_w, temp); + plus3(temp, q2_dq_w[k + 1], q2_dq_w[k + 1]); + } - // semi-infinite CNT case with end at start of chain + if (sumw == 0.0) continue; - } else if (endflag == 1) { - geometry(r1, r2, p1, p2, qe, p, m, param, basis); - if (param[0] > cutoff) continue; - fsemi(param, evdwl, fend, flocal); + sumw_inv = 1.0 / sumw; + scale3(sumw_inv, p1); + scale3(sumw_inv, p2); - // semi-infinite CNT case with end at end of chain + // compute geometry and forces - } else { - geometry(r1, r2, p2, p1, qe, p, m, param, basis); - if (param[0] > cutoff) continue; - fsemi(param, evdwl, fend, flocal); - } + // infinite CNT case - evdwl *= 0.5; + if (endflag == 0) { + geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); + if (param[0] > cutoff) continue; + finf(param, evdwl, flocal); - // transform to global coordinate system + // semi-infinite CNT case with end at start of chain - matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); - matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + } else if (endflag == 1) { + geometry(r1, r2, p1, p2, qe, p, m, param, basis); + if (param[0] > cutoff) continue; + fsemi(param, evdwl, fend, flocal); - // forces acting on approximate chain + // semi-infinite CNT case with end at end of chain - add3(fglobal[0], fglobal[1], ftotal); - if (endflag) scaleadd3(fend, m, ftotal, ftotal); - scale3(-0.5, ftotal); + } else { + geometry(r1, r2, p2, p1, qe, p, m, param, basis); + if (param[0] > cutoff) continue; + fsemi(param, evdwl, fend, flocal); + } - sub3(r1, p, delr1); - sub3(r2, p, delr2); - cross3(delr1, fglobal[0], t1); - cross3(delr2, fglobal[1], t2); - add3(t1, t2, torque); + evdwl *= 0.5; - // additional torque contribution from chain end + // transform to global coordinate system - if (endflag) { - sub3(qe, p, delqe); - cross3(delqe, m, t3); - scale3(fend, t3); - add3(t3, torque, torque); - } + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); - cross3(torque, m, ftorque); - lp = param[5] - param[4]; - scale3(1.0 / lp, ftorque); + // forces acting on approximate chain - if (endflag == 2) { - add3(ftotal, ftorque, fglobal[3]); - sub3(ftotal, ftorque, fglobal[2]); - } else { - add3(ftotal, ftorque, fglobal[2]); - sub3(ftotal, ftorque, fglobal[3]); - } + add3(fglobal[0], fglobal[1], ftotal); + if (endflag) scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); - scale3(0.5, fglobal[0]); - scale3(0.5, fglobal[1]); - scale3(0.5, fglobal[2]); - scale3(0.5, fglobal[3]); + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); - // weight gradient terms acting on current segment + // additional torque contribution from chain end - outer3(p1, dr1_sumw, temp); - minus3(q1_dr1_w, temp, dr1_p1); - outer3(p2, dr1_sumw, temp); - minus3(q2_dr1_w, temp, dr1_p2); - outer3(p1, dr2_sumw, temp); - minus3(q1_dr2_w, temp, dr2_p1); - outer3(p2, dr2_sumw, temp); - minus3(q2_dr2_w, temp, dr2_p2); + if (endflag) { + sub3(qe, p, delqe); + cross3(delqe, m, t3); + scale3(fend, t3); + add3(t3, torque, torque); + } - transpose_matvec(dr1_p1, fglobal[2], fgrad_r1_p1); - transpose_matvec(dr1_p2, fglobal[3], fgrad_r1_p2); - transpose_matvec(dr2_p1, fglobal[2], fgrad_r2_p1); - transpose_matvec(dr2_p2, fglobal[3], fgrad_r2_p2); + cross3(torque, m, ftorque); + lp = param[5] - param[4]; + scale3(1.0 / lp, ftorque); - // add forces to nodes in current segment + if (endflag == 2) { + add3(ftotal, ftorque, fglobal[3]); + sub3(ftotal, ftorque, fglobal[2]); + } else { + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + } - add3(fglobal[0], f[i1], f[i1]); - add3(fglobal[1], f[i2], f[i2]); + scale3(0.5, fglobal[0]); + scale3(0.5, fglobal[1]); + scale3(0.5, fglobal[2]); + scale3(0.5, fglobal[3]); - scaleadd3(sumw_inv, fgrad_r1_p1, f[i1], f[i1]); - scaleadd3(sumw_inv, fgrad_r1_p2, f[i1], f[i1]); - scaleadd3(sumw_inv, fgrad_r2_p1, f[i2], f[i2]); - scaleadd3(sumw_inv, fgrad_r2_p2, f[i2], f[i2]); + // weight gradient terms acting on current segment - // add forces in approximate chain + outer3(p1, dr1_sumw, temp); + minus3(q1_dr1_w, temp, dr1_p1); + outer3(p2, dr1_sumw, temp); + minus3(q2_dr1_w, temp, dr1_p2); + outer3(p1, dr2_sumw, temp); + minus3(q1_dr2_w, temp, dr2_p1); + outer3(p2, dr2_sumw, temp); + minus3(q2_dr2_w, temp, dr2_p2); - for (k = 0; k < clen - 1; k++) { - if (w[k] == 0.0) continue; - j1 = chain[j][k]; - j2 = chain[j][k + 1]; - j1 &= NEIGHMASK; - j2 &= NEIGHMASK; - scale = w[k] * sumw_inv; - scaleadd3(scale, fglobal[2], f[j1], f[j1]); - scaleadd3(scale, fglobal[3], f[j2], f[j2]); - } + transpose_matvec(dr1_p1, fglobal[2], fgrad_r1_p1); + transpose_matvec(dr1_p2, fglobal[3], fgrad_r1_p2); + transpose_matvec(dr2_p1, fglobal[2], fgrad_r2_p1); + transpose_matvec(dr2_p2, fglobal[3], fgrad_r2_p2); - // weight gradient terms acting on approximate chain - // iterate over nodes instead of segments + // add forces to nodes in current segment - for (k = 0; k < clen; k++) { - if (wnode[k] == 0.0) continue; - j1 = chain[j][k]; - j1 &= NEIGHMASK; + add3(fglobal[0], f[i1], f[i1]); + add3(fglobal[1], f[i2], f[i2]); - outer3(p1, dq_w[k], temp); - minus3(q1_dq_w[k], temp, dq_p1); - outer3(p2, dq_w[k], temp); - minus3(q2_dq_w[k], temp, dq_p2); + scaleadd3(sumw_inv, fgrad_r1_p1, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r1_p2, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r2_p1, f[i2], f[i2]); + scaleadd3(sumw_inv, fgrad_r2_p2, f[i2], f[i2]); - transpose_matvec(dq_p1, fglobal[2], fgrad_q_p1); - transpose_matvec(dq_p2, fglobal[3], fgrad_q_p2); + // add forces in approximate chain - scaleadd3(sumw_inv, fgrad_q_p1, f[j1], f[j1]); - scaleadd3(sumw_inv, fgrad_q_p2, f[j1], f[j1]); - } + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + scale = w[k] * sumw_inv; + scaleadd3(scale, fglobal[2], f[j1], f[j1]); + scaleadd3(scale, fglobal[3], f[j2], f[j2]); + } - // force on node at CNT end + // weight gradient terms acting on approximate chain + // iterate over nodes instead of segments - if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); + for (k = 0; k < clen; k++) { + if (wnode[k] == 0.0) continue; + j1 = chain[j][k]; + j1 &= NEIGHMASK; - // compute energy + outer3(p1, dq_w[k], temp); + minus3(q1_dq_w[k], temp, dq_p1); + outer3(p2, dq_w[k], temp); + minus3(q2_dq_w[k], temp, dq_p2); - if (eflag_either) { - if (eflag_global) eng_vdwl += evdwl; - if (eflag_atom) { - eatom[i1] += 0.25 * evdwl; - eatom[i2] += 0.25 * evdwl; - for (k = 0; k < clen - 1; k++) { - if (w[k] == 0.0) continue; - j1 = chain[j][k]; - j2 = chain[j][k + 1]; - j1 &= NEIGHMASK; - j2 &= NEIGHMASK; - evdwl_chain = 0.5 * w[k] * sumw_inv * evdwl; - eatom[j1] += evdwl_chain; - eatom[j2] += evdwl_chain; + transpose_matvec(dq_p1, fglobal[2], fgrad_q_p1); + transpose_matvec(dq_p2, fglobal[3], fgrad_q_p2); + + scaleadd3(sumw_inv, fgrad_q_p1, f[j1], f[j1]); + scaleadd3(sumw_inv, fgrad_q_p2, f[j1], f[j1]); + } + + // force on node at CNT end + + if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); + + // compute energy + + if (eflag_either) { + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += 0.25 * evdwl; + eatom[i2] += 0.25 * evdwl; + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + evdwl_chain = 0.5 * w[k] * sumw_inv * evdwl; + eatom[j1] += evdwl_chain; + eatom[j2] += evdwl_chain; + } } } } @@ -586,6 +591,7 @@ void PairMesoCNT::bond_neigh() atom2 = atom->map(special[i][1]); special_local[i][1] = domain->closest_image(i, atom2); } + // printf("%d %d %d (%d) %d (%d)\n", atom->tag[i], nspecial[i][0], atom->tag[atom1], atom1, atom->tag[atom2], atom2); } @@ -787,9 +793,12 @@ void PairMesoCNT::bond_neigh() modelist[i][j] = 0; - if (nspecial[cstart][0] == 1 && nspecial[cend][0] == 1) modelist[i][j] = 1; - else if (nspecial[cstart][0] == 1) endlist[i][j] = 1; - else if (nspecial[cend][0] == 1) endlist[i][j] = 2; + bool estart = match_end(type[cstart]); + bool eend = match_end(type[cend]); + + if (estart && eend) modelist[i][j] = 1; + else if (estart) endlist[i][j] = 1; + else if (eend) endlist[i][j] = 2; else endlist[i][j] = 0; if (buckled_index != -1) { From d8f8a3a36ab2fafdb63447fb2ffb841175fcc4b6 Mon Sep 17 00:00:00 2001 From: Vsevak Date: Sat, 28 May 2022 00:24:24 +0300 Subject: [PATCH 045/443] Handle inconsistent J molecules in tip4p/gpu --- lib/gpu/geryon/hip_device.h | 2 +- lib/gpu/lal_lj_tip4p_long.cu | 42 ++++++++++++++++++++------ src/GPU/pair_lj_cut_tip4p_long_gpu.cpp | 7 +++-- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/lib/gpu/geryon/hip_device.h b/lib/gpu/geryon/hip_device.h index fadeec8711..f809323ee7 100644 --- a/lib/gpu/geryon/hip_device.h +++ b/lib/gpu/geryon/hip_device.h @@ -394,7 +394,7 @@ UCL_Device::~UCL_Device() { clear(); } -int UCL_Device::set_platform(const int) { +int UCL_Device::set_platform(const int pid) { clear(); #ifdef UCL_DEBUG assert(pid=0 && iH2>=0) { + compute_newsite(iO,iH1,iH2, &m[iO], qO, alpha, x_); + } else { + m[iO] = ix; + m[iO].w = qO; + hneigh[i*4] = iO; + hneigh[i*4+1] = iO; + } } } } diff --git a/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp b/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp index 5c2c391136..f6e528676d 100644 --- a/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp +++ b/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp @@ -186,8 +186,9 @@ void PairLJCutTIP4PLongGPU::init_style() alpha = qdist / (cos(0.5 * theta) * blen); cut_coulsq = cut_coul * cut_coul; - double cut_coulsqplus = (cut_coul + qdist + blen) * (cut_coul + qdist + blen); - if (maxcut < cut_coulsqplus) { cell_size = (cut_coul + qdist + blen) + neighbor->skin; } + double cut_coulplus = cut_coul + qdist + blen; + double cut_coulsqplus = cut_coulplus*cut_coulplus; + if (sqrt(maxcut) < cut_coulplus+blen) { cell_size = (cut_coulplus + blen) + neighbor->skin; } if (comm->cutghostuser < cell_size) { if (comm->me == 0) error->warning(FLERR, @@ -205,7 +206,7 @@ void PairLJCutTIP4PLongGPU::init_style() GPU_EXTRA::check_flag(success, error, world); if (gpu_mode == GPU_FORCE) { auto req = neighbor->add_request(this, NeighConst::REQ_FULL); - req->set_cutoff(cut_coul + qdist + blen + neighbor->skin); + req->set_cutoff(cut_coulplus + neighbor->skin); } } From e9051620a510a69bd2eddaa76903f801b7a79de1 Mon Sep 17 00:00:00 2001 From: Vsevak Date: Sat, 28 May 2022 00:39:07 +0300 Subject: [PATCH 046/443] Cleanup --- lib/gpu/lal_lj_tip4p_long.cu | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/lib/gpu/lal_lj_tip4p_long.cu b/lib/gpu/lal_lj_tip4p_long.cu index 21fb1a91c8..74ee7a9036 100644 --- a/lib/gpu/lal_lj_tip4p_long.cu +++ b/lib/gpu/lal_lj_tip4p_long.cu @@ -218,15 +218,6 @@ __kernel void k_lj_tip4p_reneigh(const __global numtyp4 *restrict x_, iH1 = closest_image(i, iH1, sametag, x_); iH2 = closest_image(i, iH2, sametag, x_); - //printf("%d %f %f %f\n", (iH1 < 0 || iH2 < 0) ? 0:1, ix.x, ix.y, ix.z ); - /* - if (iH1 < 0) { - printf("i=%d\ttag[i]=%d\tmap[tag[i]-1]=%d\tmap[tag[i]-2]=%d\n", i, tag[i], map[tag[i]+1], map[tag[i]+2]); - } - if (iH2 < 0) { - printf("i=%d\ttag[i]=%d\tmap[tag[i]-1]=%d\tmap[tag[i]-2]=%d\n", i, tag[i], map[tag[i]+1], map[tag[i]+2]); - }*/ - hneigh[i*4 ] = iH1; hneigh[i*4+1] = iH2; hneigh[i*4+2] = -1; @@ -237,25 +228,12 @@ __kernel void k_lj_tip4p_reneigh(const __global numtyp4 *restrict x_, int iI, iH; iI = atom_mapping(map,tag[i] - 1); iO = closest_image(i,iI,sametag, x_); - //printf("%d %f %f %f\n", (iI < 0) ? 2:3, ix.x, ix.y, ix.z ); - /* - // printf("iI = %d iO closest = %d\n",iI, iO); - if (iI < 0) { - printf("i=%d\ttag[i]=%d\tmap[tag[i]-1]=%d\tmap[tag[i]-2]=%d\n", i, tag[i], map[tag[i]-1],map[tag[i]-2]); - }*/ numtyp4 iIx; fetch4(iIx,iO,pos_tex); //x_[iI]; if ((int)iIx.w == typeH) { iO = atom_mapping(map,tag[i] - 2); iO = closest_image(i, iO, sametag, x_); - //iH1 = closest_image(i, iI, sametag, x_); - //iH2 = i; - } else { //if ((int)iIx.w == typeO) - //iH = atom_mapping(map, tag[i] + 1); - //iO = closest_image(i,iI,sametag, x_); - //iH1 = i; - //iH2 = closest_image(i,iH,sametag, x_); - } - hneigh[i*4+0] = iO; + } + hneigh[i*4+0] = iO; hneigh[i*4+1] += -1; hneigh[i*4+2] = -1; } From 763b323f7c1a72d3d9302cf231fac21db0019f8c Mon Sep 17 00:00:00 2001 From: phankl Date: Sun, 29 May 2022 10:55:36 +0100 Subject: [PATCH 047/443] added exact segment-segment calculation, energy works, forces don't and no optimisation --- src/MESONT/pair_mesocnt.cpp | 129 +++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 703cb4f9cd..71c37cabae 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -309,8 +309,135 @@ void PairMesoCNT::mesolj() clen = nchain[j]; if (clen < 2) continue; - if (modelist[i][j]) { + if (modelist[i][j] || true) { + for (k = 0; k < clen - 1; k++) { + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + q1 = x[j1]; + q2 = x[j2]; + double l[3], delp1r1[3], delp2r1[3]; + sub3(r2, r1, l); + norm3(l); + sub3(q1, r1, delp1r1); + sub3(q2, r1, delp2r1); + + double cr1[3], cr2[3]; + cross3(delp1r1, l, cr1); + cross3(delp2r1, l, cr2); + + double d1 = len3(cr1); + double d2 = len3(cr2); + + int jj1, jj2; + if (d1 < d2) { + jj1 = j1; + jj2 = j2; + } + else { + jj1 = j2; + jj2 = j1; + } + + q1 = x[jj1]; + q2 = x[jj2]; + + geometry(r1, r2, q1, q2, q1, p, m, param, basis); + if (param[0] > cutoff) continue; + + double evdwl1 = 0.0; + double evdwl2 = 0.0; + + // first force contribution + + fsemi(param, evdwl1, fend, flocal); + + // transform to global coordinate system + + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + + // forces acting on segment 2 + + add3(fglobal[0], fglobal[1], ftotal); + scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); + + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); + + cross3(torque, m, ftorque); + lp = param[5] - param[4]; + scale3(1.0 / lp, ftorque); + + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + + // add forces to nodes + + scaleadd3(0.5, fglobal[0], f[i1], f[i1]); + scaleadd3(0.5, fglobal[1], f[i2], f[i2]); + scaleadd3(0.5, fglobal[2], f[jj1], f[jj1]); + scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); + scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); + + // second force contribution + + param[6] += lp; + + fsemi(param, evdwl2, fend, flocal); + + // transform to global coordinate system + + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + + // forces acting on segment 2 + + add3(fglobal[0], fglobal[1], ftotal); + scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); + + scaleadd3(lp, m, p, p); + + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); + + cross3(torque, m, ftorque); + scale3(1.0 / lp, ftorque); + + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + + // add forces to nodes + + scaleadd3(-0.5, fglobal[0], f[i1], f[i1]); + scaleadd3(-0.5, fglobal[1], f[i2], f[i2]); + scaleadd3(-0.5, fglobal[2], f[jj2], f[jj2]); + scaleadd3(0.5, fglobal[3], f[jj1], f[jj1]); + sub3(f[jj2], fglobal[3], f[jj2]); + scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); + + if (eflag_either) { + evdwl = 0.5 * (evdwl1 - evdwl2); + double evdwl_atom = 0.25 * evdwl; + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += evdwl_atom; + eatom[i2] += evdwl_atom; + eatom[jj1] += evdwl_atom; + eatom[jj2] += evdwl_atom; + } + } + } } else { // assign end position From 9b73c66ec6c2b4a3d76b69fad544e7929f45a9e9 Mon Sep 17 00:00:00 2001 From: Vsevak Date: Mon, 30 May 2022 18:44:53 +0300 Subject: [PATCH 048/443] Reduce increased comm cutoff --- src/GPU/pair_lj_cut_tip4p_long_gpu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp b/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp index f6e528676d..cad8f2c07c 100644 --- a/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp +++ b/src/GPU/pair_lj_cut_tip4p_long_gpu.cpp @@ -188,7 +188,7 @@ void PairLJCutTIP4PLongGPU::init_style() cut_coulsq = cut_coul * cut_coul; double cut_coulplus = cut_coul + qdist + blen; double cut_coulsqplus = cut_coulplus*cut_coulplus; - if (sqrt(maxcut) < cut_coulplus+blen) { cell_size = (cut_coulplus + blen) + neighbor->skin; } + if (sqrt(maxcut) < cut_coulplus) { cell_size = cut_coulplus + neighbor->skin; } if (comm->cutghostuser < cell_size) { if (comm->me == 0) error->warning(FLERR, From 59dc63d003d3a12b4983e8b8d735ee759c086987 Mon Sep 17 00:00:00 2001 From: Vsevak Date: Wed, 1 Jun 2022 01:29:18 +0300 Subject: [PATCH 049/443] Add typecasting for consts in tip4p GPU kernels --- lib/gpu/lal_lj_tip4p_long.cu | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/gpu/lal_lj_tip4p_long.cu b/lib/gpu/lal_lj_tip4p_long.cu index 74ee7a9036..e6c0022ca0 100644 --- a/lib/gpu/lal_lj_tip4p_long.cu +++ b/lib/gpu/lal_lj_tip4p_long.cu @@ -417,12 +417,12 @@ __kernel void k_lj_tip4p_long(const __global numtyp4 *restrict x_, fO.x += delx * force_coul; fO.y += dely * force_coul; fO.z += delz * force_coul; - fO.w += 0; + //fO.w += 0; } else { f.x += delx * force_coul; f.y += dely * force_coul; f.z += delz * force_coul; - f.w += 0; + //f.w += 0; } if (EVFLAG && eflag) { e_coul += prefactor*(_erfc-factor_coul); @@ -433,7 +433,7 @@ __kernel void k_lj_tip4p_long(const __global numtyp4 *restrict x_, fd.y = dely*force_coul; fd.z = delz*force_coul; if (itype == typeO) { - numtyp cO = 1 - alpha, cH = 0.5*alpha; + numtyp cO = (numtyp)1.0 - alpha, cH = (numtyp)0.5*alpha; numtyp4 vdi, vdj; numtyp4 xH1; fetch4(xH1,iH1,pos_tex); numtyp4 xH2; fetch4(xH2,iH2,pos_tex); @@ -451,15 +451,15 @@ __kernel void k_lj_tip4p_long(const __global numtyp4 *restrict x_, vdj.z = xjO.z*cO + xjH1.z*cH + xjH2.z*cH; //vdj.w = vdj.w; } else vdj = jx; - vO[0] += 0.5*(vdi.x - vdj.x)*fd.x; - vO[1] += 0.5*(vdi.y - vdj.y)*fd.y; - vO[2] += 0.5*(vdi.z - vdj.z)*fd.z; - vO[3] += 0.5*(vdi.x - vdj.x)*fd.y; - vO[4] += 0.5*(vdi.x - vdj.x)*fd.z; - vO[5] += 0.5*(vdi.y - vdj.y)*fd.z; + vO[0] += (numtyp)0.5*(vdi.x - vdj.x)*fd.x; + vO[1] += (numtyp)0.5*(vdi.y - vdj.y)*fd.y; + vO[2] += (numtyp)0.5*(vdi.z - vdj.z)*fd.z; + vO[3] += (numtyp)0.5*(vdi.x - vdj.x)*fd.y; + vO[4] += (numtyp)0.5*(vdi.x - vdj.x)*fd.z; + vO[5] += (numtyp)0.5*(vdi.y - vdj.y)*fd.z; } else { if (jtype == typeO) { - numtyp cO = 1 - alpha, cH = 0.5*alpha; + numtyp cO = (numtyp)1.0 - alpha, cH = (numtyp)0.5*alpha; numtyp4 vdj; numtyp4 xjH1; fetch4(xjH1,jH1,pos_tex); numtyp4 xjH2; fetch4(xjH2,jH2,pos_tex); @@ -507,7 +507,7 @@ __kernel void k_lj_tip4p_long(const __global numtyp4 *restrict x_, prefactor *= qqrd2e*x1m.w/r; numtyp force_coul = r2inv*prefactor * (_erfc + EWALD_F*grij*expm2 - factor_coul); - numtyp cO = 1 - alpha, cH = 0.5*alpha; + numtyp cO = (numtyp)1 - alpha, cH = (numtyp)0.5*alpha; numtyp4 fd; fd.x = delx * force_coul * cH; fd.y = dely * force_coul * cH; @@ -518,7 +518,7 @@ __kernel void k_lj_tip4p_long(const __global numtyp4 *restrict x_, f.z += fd.z; if (EVFLAG && eflag) { - e_coul += prefactor*(_erfc-factor_coul) * (acctyp)0.5 * alpha; + e_coul += prefactor*(_erfc-factor_coul) * (numtyp)0.5 * alpha; } if (EVFLAG && vflag) { numtyp4 xH1; fetch4(xH1,iH1,pos_tex); @@ -748,12 +748,12 @@ __kernel void k_lj_tip4p_long_fast(const __global numtyp4 *restrict x_, fO.x += delx * force_coul; fO.y += dely * force_coul; fO.z += delz * force_coul; - fO.w += 0; + //fO.w += 0; } else { f.x += delx * force_coul; f.y += dely * force_coul; f.z += delz * force_coul; - f.w += 0; + //f.w += 0; } if (EVFLAG && eflag) { e_coul += prefactor*(_erfc-factor_coul); @@ -764,7 +764,7 @@ __kernel void k_lj_tip4p_long_fast(const __global numtyp4 *restrict x_, fd.y = dely*force_coul; fd.z = delz*force_coul; if (itype == typeO) { - numtyp cO = 1 - alpha, cH = 0.5*alpha; + numtyp cO = (numtyp)1.0 - alpha, cH = (numtyp)0.5*alpha; numtyp4 vdi, vdj; numtyp4 xH1; fetch4(xH1,iH1,pos_tex); numtyp4 xH2; fetch4(xH2,iH2,pos_tex); @@ -782,15 +782,15 @@ __kernel void k_lj_tip4p_long_fast(const __global numtyp4 *restrict x_, vdj.z = xjO.z*cO + xjH1.z*cH + xjH2.z*cH; //vdj.w = vdj.w; } else vdj = jx; - vO[0] += 0.5*(vdi.x - vdj.x)*fd.x; - vO[1] += 0.5*(vdi.y - vdj.y)*fd.y; - vO[2] += 0.5*(vdi.z - vdj.z)*fd.z; - vO[3] += 0.5*(vdi.x - vdj.x)*fd.y; - vO[4] += 0.5*(vdi.x - vdj.x)*fd.z; - vO[5] += 0.5*(vdi.y - vdj.y)*fd.z; + vO[0] += (numtyp)0.5*(vdi.x - vdj.x)*fd.x; + vO[1] += (numtyp)0.5*(vdi.y - vdj.y)*fd.y; + vO[2] += (numtyp)0.5*(vdi.z - vdj.z)*fd.z; + vO[3] += (numtyp)0.5*(vdi.x - vdj.x)*fd.y; + vO[4] += (numtyp)0.5*(vdi.x - vdj.x)*fd.z; + vO[5] += (numtyp)0.5*(vdi.y - vdj.y)*fd.z; } else { if (jtype == typeO) { - numtyp cO = 1 - alpha, cH = 0.5*alpha; + numtyp cO = (numtyp)1.0 - alpha, cH = (numtyp)0.5*alpha; numtyp4 vdj; numtyp4 xjH1; fetch4(xjH1,jH1,pos_tex); numtyp4 xjH2; fetch4(xjH2,jH2,pos_tex); @@ -838,7 +838,7 @@ __kernel void k_lj_tip4p_long_fast(const __global numtyp4 *restrict x_, prefactor *= qqrd2e*x1m.w/r; numtyp force_coul = r2inv*prefactor * (_erfc + EWALD_F*grij*expm2 - factor_coul); - numtyp cO = 1 - alpha, cH = 0.5*alpha; + numtyp cO = (numtyp)1.0 - alpha, cH = (numtyp)0.5*alpha; numtyp4 fd; fd.x = delx * force_coul * cH; fd.y = dely * force_coul * cH; From b89acb15a6bd3a23683ea6c911ac9397cd857fd9 Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 1 Jun 2022 16:51:56 +0100 Subject: [PATCH 050/443] fixed segment orientation for exact segmeent-segment calculation --- src/MESONT/pair_mesocnt.cpp | 77 ++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 71c37cabae..83a0b290b8 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -318,35 +318,46 @@ void PairMesoCNT::mesolj() q1 = x[j1]; q2 = x[j2]; - double l[3], delp1r1[3], delp2r1[3]; - sub3(r2, r1, l); - norm3(l); - sub3(q1, r1, delp1r1); - sub3(q2, r1, delp2r1); + geometry(r1, r2, q1, q2, q1, p, m, param, basis); + if (param[0] > cutoff) continue; + + double calpha = cos(param[1]); + double salpha = sin(param[1]); + + double ceta = calpha * param[4]; + double seta = salpha * param[4]; + double dsq1 = seta * seta; + if (ceta < param[2]) dsq1 += pow(ceta - param[2], 2); + else if (ceta > param[3]) dsq1 += pow(ceta - param[3], 2); - double cr1[3], cr2[3]; - cross3(delp1r1, l, cr1); - cross3(delp2r1, l, cr2); - - double d1 = len3(cr1); - double d2 = len3(cr2); + ceta = calpha * param[5]; + seta = salpha * param[5]; + + double dsq2 = seta * seta; + if (ceta < param[2]) dsq2 += pow(ceta - param[2], 2); + else if (ceta > param[3]) dsq2 += pow(ceta - param[3], 2); int jj1, jj2; - if (d1 < d2) { + + if (dsq1 < dsq2) { jj1 = j1; jj2 = j2; } else { + if (param[1] > MY_PI) param[1] -= MY_PI; + else param[1] += MY_PI; + + double temp = -param[5]; + param[5] = -param[4]; + param[4] = temp; + param[6] = temp; + + negate3(m); + jj1 = j2; jj2 = j1; } - q1 = x[jj1]; - q2 = x[jj2]; - - geometry(r1, r2, q1, q2, q1, p, m, param, basis); - if (param[0] > cutoff) continue; - double evdwl1 = 0.0; double evdwl2 = 0.0; @@ -385,6 +396,26 @@ void PairMesoCNT::mesolj() scaleadd3(0.5, fglobal[2], f[jj1], f[jj1]); scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); + + bool seg1 = (atom->tag[i1] == 958412 && atom->tag[i2] == 958413) || (atom->tag[i1] == 958413 && atom->tag[i2] == 958412); + bool seg2 = (atom->tag[jj1] == 320636 && atom->tag[jj2] == 320637) || (atom->tag[jj1] == 320637 && atom->tag[jj2] == 320636); + + if (seg1 && seg2) { + printf("\n"); + printf("tags: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + printf("m: %f %f %f\n", m[0], m[1], m[2]); + printf("basis 1: %f %f %f\n", basis[0][0], basis[0][1], basis[0][2]); + printf("basis 2: %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); + printf("basis 3: %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); + + printf("fglobal 1: %f %f %f\n", fglobal[0][0], fglobal[0][1], fglobal[0][2]); + printf("fglobal 2: %f %f %f\n", fglobal[1][0], fglobal[1][1], fglobal[1][2]); + printf("fglobal 3: %f %f %f\n", fglobal[2][0], fglobal[2][1], fglobal[2][2]); + printf("fglobal 4: %f %f %f\n", fglobal[3][0], fglobal[3][1], fglobal[3][2]); + printf("fend: %f\n", fend); + printf("\n"); + } // second force contribution @@ -425,6 +456,15 @@ void PairMesoCNT::mesolj() scaleadd3(0.5, fglobal[3], f[jj1], f[jj1]); sub3(f[jj2], fglobal[3], f[jj2]); scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); + + if (seg1 && seg2) { + printf("fglobal 1: %f %f %f\n", fglobal[0][0], fglobal[0][1], fglobal[0][2]); + printf("fglobal 2: %f %f %f\n", fglobal[1][0], fglobal[1][1], fglobal[1][2]); + printf("fglobal 3: %f %f %f\n", fglobal[2][0], fglobal[2][1], fglobal[2][2]); + printf("fglobal 4: %f %f %f\n", fglobal[3][0], fglobal[3][1], fglobal[3][2]); + printf("fend: %f\n", fend); + printf("\n"); + } if (eflag_either) { evdwl = 0.5 * (evdwl1 - evdwl2); @@ -437,6 +477,7 @@ void PairMesoCNT::mesolj() eatom[jj2] += evdwl_atom; } } + } } else { From 59eadfecc4e8daf01c332050d2ec95d2fc3ff823 Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 1 Jun 2022 17:38:03 +0100 Subject: [PATCH 051/443] removed print statements --- src/MESONT/pair_mesocnt.cpp | 82 +++++++++++++------------------------ 1 file changed, 28 insertions(+), 54 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 83a0b290b8..fd3a1a9ae8 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -323,20 +323,23 @@ void PairMesoCNT::mesolj() double calpha = cos(param[1]); double salpha = sin(param[1]); - + double hsq = param[0] * param[0]; + double ceta = calpha * param[4]; double seta = salpha * param[4]; - double dsq1 = seta * seta; + double dsq1 = hsq + seta * seta; if (ceta < param[2]) dsq1 += pow(ceta - param[2], 2); else if (ceta > param[3]) dsq1 += pow(ceta - param[3], 2); ceta = calpha * param[5]; seta = salpha * param[5]; - double dsq2 = seta * seta; + double dsq2 = hsq + seta * seta; if (ceta < param[2]) dsq2 += pow(ceta - param[2], 2); else if (ceta > param[3]) dsq2 += pow(ceta - param[3], 2); + if (dsq1 > cutoffsq && dsq2 > cutoffsq) continue; + int jj1, jj2; if (dsq1 < dsq2) { @@ -358,12 +361,11 @@ void PairMesoCNT::mesolj() jj2 = j1; } - double evdwl1 = 0.0; - double evdwl2 = 0.0; - // first force contribution - fsemi(param, evdwl1, fend, flocal); + fsemi(param, evdwl, fend, flocal); + + if (evdwl == 0.0) continue; // transform to global coordinate system @@ -397,32 +399,28 @@ void PairMesoCNT::mesolj() scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); - bool seg1 = (atom->tag[i1] == 958412 && atom->tag[i2] == 958413) || (atom->tag[i1] == 958413 && atom->tag[i2] == 958412); - bool seg2 = (atom->tag[jj1] == 320636 && atom->tag[jj2] == 320637) || (atom->tag[jj1] == 320637 && atom->tag[jj2] == 320636); - - if (seg1 && seg2) { - printf("\n"); - printf("tags: %d %d\n", atom->tag[jj1], atom->tag[jj2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - printf("m: %f %f %f\n", m[0], m[1], m[2]); - printf("basis 1: %f %f %f\n", basis[0][0], basis[0][1], basis[0][2]); - printf("basis 2: %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); - printf("basis 3: %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); - - printf("fglobal 1: %f %f %f\n", fglobal[0][0], fglobal[0][1], fglobal[0][2]); - printf("fglobal 2: %f %f %f\n", fglobal[1][0], fglobal[1][1], fglobal[1][2]); - printf("fglobal 3: %f %f %f\n", fglobal[2][0], fglobal[2][1], fglobal[2][2]); - printf("fglobal 4: %f %f %f\n", fglobal[3][0], fglobal[3][1], fglobal[3][2]); - printf("fend: %f\n", fend); - printf("\n"); - } + // add energy + if (eflag_either) { + evdwl = 0.5 * evdwl; + double evdwl_atom = 0.25 * evdwl; + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += evdwl_atom; + eatom[i2] += evdwl_atom; + eatom[jj1] += evdwl_atom; + eatom[jj2] += evdwl_atom; + } + } + // second force contribution param[6] += lp; - fsemi(param, evdwl2, fend, flocal); + fsemi(param, evdwl, fend, flocal); + if (evdwl == 0.0) continue; + // transform to global coordinate system matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); @@ -456,18 +454,11 @@ void PairMesoCNT::mesolj() scaleadd3(0.5, fglobal[3], f[jj1], f[jj1]); sub3(f[jj2], fglobal[3], f[jj2]); scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); - - if (seg1 && seg2) { - printf("fglobal 1: %f %f %f\n", fglobal[0][0], fglobal[0][1], fglobal[0][2]); - printf("fglobal 2: %f %f %f\n", fglobal[1][0], fglobal[1][1], fglobal[1][2]); - printf("fglobal 3: %f %f %f\n", fglobal[2][0], fglobal[2][1], fglobal[2][2]); - printf("fglobal 4: %f %f %f\n", fglobal[3][0], fglobal[3][1], fglobal[3][2]); - printf("fend: %f\n", fend); - printf("\n"); - } + + // add energy if (eflag_either) { - evdwl = 0.5 * (evdwl1 - evdwl2); + evdwl = -0.5 * evdwl; double evdwl_atom = 0.25 * evdwl; if (eflag_global) eng_vdwl += evdwl; if (eflag_atom) { @@ -759,8 +750,6 @@ void PairMesoCNT::bond_neigh() atom2 = atom->map(special[i][1]); special_local[i][1] = domain->closest_image(i, atom2); } - - // printf("%d %d %d (%d) %d (%d)\n", atom->tag[i], nspecial[i][0], atom->tag[atom1], atom1, atom->tag[atom2], atom2); } int *numneigh = list->numneigh; @@ -980,21 +969,6 @@ void PairMesoCNT::bond_neigh() } } - /* - for (int i = 0; i < nbondlist; i++) { - printf("bond: %d\n", i + 1); - for (int j = 0; j < reduced_nlist[i]; j++) - printf("%d ", atom->tag[reduced_neighlist[i][j]]); - printf("\n"); - for (int j = 0; j < numchainlist[i]; j++) { - printf("chain %d: ", j + 1); - for (int k = 0; k < nchainlist[i][j]; k++) - printf("%d ", atom->tag[chainlist[i][j][k]]); - printf("\n"); - } - } - */ - // destroy remaining temporary arrays for chain creation memory->destroy(reduced_neighlist); From da1b5995898a7e54355ddd71804e1a68b6b4e840 Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 2 Jun 2022 15:45:00 +0100 Subject: [PATCH 052/443] added some optimisations to prevent unnecessary force calculations --- src/MESONT/pair_mesocnt.cpp | 60 +++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index fd3a1a9ae8..ecd46e1f17 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -309,7 +309,7 @@ void PairMesoCNT::mesolj() clen = nchain[j]; if (clen < 2) continue; - if (modelist[i][j] || true) { + if (modelist[i][j]) { for (k = 0; k < clen - 1; k++) { j1 = chain[j][k]; j2 = chain[j][k + 1]; @@ -561,28 +561,58 @@ void PairMesoCNT::mesolj() // compute geometry and forces - // infinite CNT case - if (endflag == 0) { + + // infinite CNT case + geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); + if (param[0] > cutoff) continue; + double salpha = sin(param[1]); + double sxi1 = salpha * param[2]; + double sxi2 = salpha * param[3]; + double hsq = param[0] * param[0]; + if (sxi1 * sxi1 + hsq > cutoffsq && sxi2 * sxi2 + hsq > cutoffsq) + continue; + finf(param, evdwl, flocal); - // semi-infinite CNT case with end at start of chain - - } else if (endflag == 1) { - geometry(r1, r2, p1, p2, qe, p, m, param, basis); - if (param[0] > cutoff) continue; - fsemi(param, evdwl, fend, flocal); - - // semi-infinite CNT case with end at end of chain - } else { - geometry(r1, r2, p2, p1, qe, p, m, param, basis); + + // semi-infinite CNT case + // endflag == 1: CNT end at start of chain + // endflag == 2: CNT end at end of chain + + if (endflag == 1) geometry(r1, r2, p1, p2, qe, p, m, param, basis); + else geometry(r1, r2, p2, p1, qe, p, m, param, basis); + if (param[0] > cutoff) continue; + double hsq = param[0] * param[0]; + double calpha = cos(param[1]); + double etamin = calpha * param[2]; + double dsq1; + if (etamin < param[6]) { + dsq1 = hsq + pow(sin(param[1]) * param[6], 2); + dsq1 += pow(param[2] - calpha * param[6], 2); + } + else + dsq1 = hsq + pow(sin(param[1]) * param[2], 2); + + etamin = calpha * param[3]; + double dsq2; + if (etamin < param[6]) { + dsq2 = hsq + pow(sin(param[1]) * param[6], 2); + dsq2 += pow(param[3] - calpha * param[6], 2); + } + else + dsq2 = hsq + pow(sin(param[1]) * param[3], 2); + + if (dsq1 > cutoffsq && dsq2 > cutoffsq) continue; + fsemi(param, evdwl, fend, flocal); } + if (evdwl == 0.0) continue; evdwl *= 0.5; // transform to global coordinate system @@ -1757,6 +1787,10 @@ void PairMesoCNT::geometry(const double *r1, const double *r2, const double *p1, sub3(pbar, rbar, delrbar); double h = len3(delrbar); + if (h > cutoff) { + param[0] = h; + return; + } if (h * ang_inv < SMALL) h = SMALL * ang; copy3(delrbar, ex); From dac00dde27ff51f2401fabaf8ea15c7ae5764156 Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 2 Jun 2022 16:10:08 +0100 Subject: [PATCH 053/443] removed mesolj function, moved contents back to compute + changed pair_mesocnt_viscous to prepare for segment-segment interactions with friction --- src/MESONT/pair_mesocnt.cpp | 295 ++++++------- src/MESONT/pair_mesocnt.h | 2 - src/MESONT/pair_mesocnt_viscous.cpp | 655 ++++++++++++++++++---------- 3 files changed, 565 insertions(+), 387 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index ecd46e1f17..6751083438 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -107,158 +107,6 @@ void PairMesoCNT::compute(int eflag, int vflag) { ev_init(eflag, vflag); - mesolj(); - - if (vflag_fdotr) virial_fdotr_compute(); -} - -/* ---------------------------------------------------------------------- */ - -void PairMesoCNT::allocate() -{ - allocated = 1; - int ntypes = atom->ntypes; - int np1 = ntypes + 1; - int init_size = 1; - - memory->create(cutsq, np1, np1, "pair:cutsq"); - memory->create(setflag, np1, np1, "pair:setflag"); - for (int i = 1; i <= ntypes; i++) - for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; - - memory->create(end_types, nend_types, "pair:end_types"); - - memory->create(uinf_coeff, uinf_points, 4, "pair:uinf_coeff"); - memory->create(gamma_coeff, gamma_points, 4, "pair:gamma_coeff"); - memory->create(phi_coeff, phi_points, phi_points, 4, 4, "pair:phi_coeff"); - memory->create(usemi_coeff, usemi_points, usemi_points, 4, 4, "pair:usemi_coeff"); - - memory->create(numchainlist, init_size, "pair:numchainlist"); - memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); - memory->create(endlist, init_size, init_size, "pair:endlist"); - memory->create(modelist, init_size, init_size, "pair:modelist"); - memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); - - memory->create(w, init_size, "pair:w"); - memory->create(wnode, init_size, "pair:wnode"); - memory->create(dq_w, init_size, 3, "pair:dq_w"); - memory->create(q1_dq_w, init_size, 3, 3, "pair:q1_dq_w"); - memory->create(q2_dq_w, init_size, 3, 3, "pair:q2_dq_w"); - - memory->create(param, 7, "pair:param"); - - memory->create(flocal, 2, 3, "pair:flocal"); - memory->create(fglobal, 4, 3, "pair:fglobal"); - memory->create(basis, 3, 3, "pair:basis"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairMesoCNT::settings(int narg, char ** /* arg */) -{ - if (narg != 0) error->all(FLERR, "Illegal pair_style command"); -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairMesoCNT::coeff(int narg, char **arg) -{ - if (narg < 4) error->all(FLERR, "Incorrect args for pair coefficients"); - read_file(arg[2]); - - nend_types = narg - 3; - - if (!allocated) allocate(); - - // end atom types - for (int i = 3; i < narg; i++) end_types[i - 3] = utils::inumeric(FLERR, arg[i], false, lmp); - - // units, eV to energy unit conversion - ang = force->angstrom; - ang_inv = 1.0 / ang; - if (strcmp(update->unit_style, "lj") == 0) - error->all(FLERR, "Pair style mesocnt does not support lj units"); - else if (strcmp(update->unit_style, "real") == 0) - eunit = 23.06054966; - else if (strcmp(update->unit_style, "metal") == 0) - eunit = 1.0; - else if (strcmp(update->unit_style, "si") == 0) - eunit = 1.6021765e-19; - else if (strcmp(update->unit_style, "cgs") == 0) - eunit = 1.6021765e-12; - else if (strcmp(update->unit_style, "electron") == 0) - eunit = 3.674932248e-2; - else if (strcmp(update->unit_style, "micro") == 0) - eunit = 1.6021765e-4; - else if (strcmp(update->unit_style, "nano") == 0) - eunit = 1.6021765e2; - else - error->all(FLERR, "Pair style mesocnt does not recognize this units style"); - funit = eunit * ang_inv; - - // potential variables - sig = sig_ang * ang; - r = r_ang * ang; - rsq = r * r; - d = 2.0 * r; - d_ang = 2.0 * r_ang; - rc = 3.0 * sig; - cutoff = rc + d; - cutoffsq = cutoff * cutoff; - cutoff_ang = cutoff * ang_inv; - cutoffsq_ang = cutoff_ang * cutoff_ang; - comega = 0.275 * (1.0 - 1.0 / (1.0 + 0.59 * r_ang)); - ctheta = 0.35 + 0.0226 * (r_ang - 6.785); - - // compute spline coefficients - spline_coeff(uinf_data, uinf_coeff, delh_uinf, uinf_points); - spline_coeff(gamma_data, gamma_coeff, delh_gamma, gamma_points); - spline_coeff(phi_data, phi_coeff, delh_phi, delpsi_phi, phi_points); - spline_coeff(usemi_data, usemi_coeff, delh_usemi, delxi_usemi, usemi_points); - - memory->destroy(uinf_data); - memory->destroy(gamma_data); - memory->destroy(phi_data); - memory->destroy(usemi_data); - - int ntypes = atom->ntypes; - for (int i = 1; i <= ntypes; i++) - for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairMesoCNT::init_style() -{ - if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt requires atom IDs"); - if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt requires newton pair on"); - - // need a full neighbor list - - neighbor->add_request(this, NeighConst::REQ_FULL); -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairMesoCNT::init_one(int /* i */, int /* j */) -{ - return cutoff; -} - -/* ---------------------------------------------------------------------- - calculate energy and forces due to mesoscopic LJ potential -------------------------------------------------------------------------- */ - -void PairMesoCNT::mesolj() -{ int i, j, k, i1, i2, j1, j2; int endflag, endindex; int clen, numchain; @@ -743,6 +591,149 @@ void PairMesoCNT::mesolj() } } } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- */ + +void PairMesoCNT::allocate() +{ + allocated = 1; + int ntypes = atom->ntypes; + int np1 = ntypes + 1; + int init_size = 1; + + memory->create(cutsq, np1, np1, "pair:cutsq"); + memory->create(setflag, np1, np1, "pair:setflag"); + for (int i = 1; i <= ntypes; i++) + for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; + + memory->create(end_types, nend_types, "pair:end_types"); + + memory->create(uinf_coeff, uinf_points, 4, "pair:uinf_coeff"); + memory->create(gamma_coeff, gamma_points, 4, "pair:gamma_coeff"); + memory->create(phi_coeff, phi_points, phi_points, 4, 4, "pair:phi_coeff"); + memory->create(usemi_coeff, usemi_points, usemi_points, 4, 4, "pair:usemi_coeff"); + + memory->create(numchainlist, init_size, "pair:numchainlist"); + memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); + memory->create(endlist, init_size, init_size, "pair:endlist"); + memory->create(modelist, init_size, init_size, "pair:modelist"); + memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); + + memory->create(w, init_size, "pair:w"); + memory->create(wnode, init_size, "pair:wnode"); + memory->create(dq_w, init_size, 3, "pair:dq_w"); + memory->create(q1_dq_w, init_size, 3, 3, "pair:q1_dq_w"); + memory->create(q2_dq_w, init_size, 3, 3, "pair:q2_dq_w"); + + memory->create(param, 7, "pair:param"); + + memory->create(flocal, 2, 3, "pair:flocal"); + memory->create(fglobal, 4, 3, "pair:fglobal"); + memory->create(basis, 3, 3, "pair:basis"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairMesoCNT::settings(int narg, char ** /* arg */) +{ + if (narg != 0) error->all(FLERR, "Illegal pair_style command"); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairMesoCNT::coeff(int narg, char **arg) +{ + if (narg < 4) error->all(FLERR, "Incorrect args for pair coefficients"); + read_file(arg[2]); + + nend_types = narg - 3; + + if (!allocated) allocate(); + + // end atom types + for (int i = 3; i < narg; i++) end_types[i - 3] = utils::inumeric(FLERR, arg[i], false, lmp); + + // units, eV to energy unit conversion + ang = force->angstrom; + ang_inv = 1.0 / ang; + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Pair style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Pair style mesocnt does not recognize this units style"); + funit = eunit * ang_inv; + + // potential variables + sig = sig_ang * ang; + r = r_ang * ang; + rsq = r * r; + d = 2.0 * r; + d_ang = 2.0 * r_ang; + rc = 3.0 * sig; + cutoff = rc + d; + cutoffsq = cutoff * cutoff; + cutoff_ang = cutoff * ang_inv; + cutoffsq_ang = cutoff_ang * cutoff_ang; + comega = 0.275 * (1.0 - 1.0 / (1.0 + 0.59 * r_ang)); + ctheta = 0.35 + 0.0226 * (r_ang - 6.785); + + // compute spline coefficients + spline_coeff(uinf_data, uinf_coeff, delh_uinf, uinf_points); + spline_coeff(gamma_data, gamma_coeff, delh_gamma, gamma_points); + spline_coeff(phi_data, phi_coeff, delh_phi, delpsi_phi, phi_points); + spline_coeff(usemi_data, usemi_coeff, delh_usemi, delxi_usemi, usemi_points); + + memory->destroy(uinf_data); + memory->destroy(gamma_data); + memory->destroy(phi_data); + memory->destroy(usemi_data); + + int ntypes = atom->ntypes; + for (int i = 1; i <= ntypes; i++) + for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairMesoCNT::init_style() +{ + if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt requires atom IDs"); + if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt requires newton pair on"); + + // need a full neighbor list + + neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairMesoCNT::init_one(int /* i */, int /* j */) +{ + return cutoff; } /* ---------------------------------------------------------------------- diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index c58e7439ff..c1100755c7 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -76,8 +76,6 @@ class PairMesoCNT : public Pair { void finf(const double *, double &, double **); void fsemi(const double *, double &, double &, double **); - void mesolj(); - // inlined functions for efficiency inline void weight(const double *, const double *, const double *, const double *, double &, diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 9d8e72b443..a288bb8933 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -40,7 +40,7 @@ using namespace MathExtra; void PairMesoCNTViscous::compute(int eflag, int vflag) { ev_init(eflag, vflag); - + int i, j, k, i1, i2, j1, j2; int endflag, endindex; int clen, numchain; @@ -48,7 +48,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) int **chain; double fend, lp, scale, sumw, sumw_inv; double evdwl, evdwl_chain; - double vtot, fvisc_tot; double *r1, *r2, *q1, *q2, *qe; double *vr1, *vr2, *vq1, *vq2; double vr[3], vp1[3], vp2[3], vp[3], vrel[3], fvisc[3]; @@ -83,7 +82,7 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) r1 = x[i1]; r2 = x[i2]; - + vr1 = v[i1]; vr2 = v[i2]; add3(vr1, vr2, vr); @@ -100,274 +99,464 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) clen = nchain[j]; if (clen < 2) continue; - // assign end position + if (modelist[i][j]) { + for (k = 0; k < clen - 1; k++) { + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + q1 = x[j1]; + q2 = x[j2]; - endflag = end[j]; - if (endflag == 1) { - endindex = chain[j][0]; - qe = x[endindex]; - } else if (endflag == 2) { - endindex = chain[j][clen - 1]; - qe = x[endindex]; + geometry(r1, r2, q1, q2, q1, p, m, param, basis); + if (param[0] > cutoff) continue; + + double calpha = cos(param[1]); + double salpha = sin(param[1]); + double hsq = param[0] * param[0]; + + double ceta = calpha * param[4]; + double seta = salpha * param[4]; + double dsq1 = hsq + seta * seta; + if (ceta < param[2]) dsq1 += pow(ceta - param[2], 2); + else if (ceta > param[3]) dsq1 += pow(ceta - param[3], 2); + + ceta = calpha * param[5]; + seta = salpha * param[5]; + + double dsq2 = hsq + seta * seta; + if (ceta < param[2]) dsq2 += pow(ceta - param[2], 2); + else if (ceta > param[3]) dsq2 += pow(ceta - param[3], 2); + + if (dsq1 > cutoffsq && dsq2 > cutoffsq) continue; + + int jj1, jj2; + + if (dsq1 < dsq2) { + jj1 = j1; + jj2 = j2; + } + else { + if (param[1] > MY_PI) param[1] -= MY_PI; + else param[1] += MY_PI; + + double temp = -param[5]; + param[5] = -param[4]; + param[4] = temp; + param[6] = temp; + + negate3(m); + + jj1 = j2; + jj2 = j1; + } + + // first force contribution + + fsemi(param, evdwl, fend, flocal); + + if (evdwl == 0.0) continue; + + // transform to global coordinate system + + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + + // forces acting on segment 2 + + add3(fglobal[0], fglobal[1], ftotal); + scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); + + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); + + cross3(torque, m, ftorque); + lp = param[5] - param[4]; + scale3(1.0 / lp, ftorque); + + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + + // add forces to nodes + + scaleadd3(0.5, fglobal[0], f[i1], f[i1]); + scaleadd3(0.5, fglobal[1], f[i2], f[i2]); + scaleadd3(0.5, fglobal[2], f[jj1], f[jj1]); + scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); + scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); + + // add energy + + if (eflag_either) { + evdwl = 0.5 * evdwl; + double evdwl_atom = 0.25 * evdwl; + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += evdwl_atom; + eatom[i2] += evdwl_atom; + eatom[jj1] += evdwl_atom; + eatom[jj2] += evdwl_atom; + } + } + + // second force contribution + + param[6] += lp; + + fsemi(param, evdwl, fend, flocal); + + if (evdwl == 0.0) continue; + + // transform to global coordinate system + + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + + // forces acting on segment 2 + + add3(fglobal[0], fglobal[1], ftotal); + scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); + + scaleadd3(lp, m, p, p); + + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); + + cross3(torque, m, ftorque); + scale3(1.0 / lp, ftorque); + + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + + // add forces to nodes + + scaleadd3(-0.5, fglobal[0], f[i1], f[i1]); + scaleadd3(-0.5, fglobal[1], f[i2], f[i2]); + scaleadd3(-0.5, fglobal[2], f[jj2], f[jj2]); + scaleadd3(0.5, fglobal[3], f[jj1], f[jj1]); + sub3(f[jj2], fglobal[3], f[jj2]); + scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); + + // add energy + + if (eflag_either) { + evdwl = -0.5 * evdwl; + double evdwl_atom = 0.25 * evdwl; + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += evdwl_atom; + eatom[i2] += evdwl_atom; + eatom[jj1] += evdwl_atom; + eatom[jj2] += evdwl_atom; + } + } + + } } + else { + // assign end position - // compute substitute straight (semi-)infinite CNT - - zero3(p1); - zero3(p2); - zero3(dr1_sumw); - zero3(dr2_sumw); - zero3(vp1); - zero3(vp2); - zeromat3(q1_dr1_w); - zeromat3(q2_dr1_w); - zeromat3(q1_dr2_w); - zeromat3(q2_dr2_w); - for (k = 0; k < clen; k++) { - wnode[k] = 0.0; - zero3(dq_w[k]); - zeromat3(q1_dq_w[k]); - zeromat3(q2_dq_w[k]); - } - sumw = 0.0; - - for (k = 0; k < clen - 1; k++) { - j1 = chain[j][k]; - j2 = chain[j][k + 1]; - j1 &= NEIGHMASK; - j2 &= NEIGHMASK; - q1 = x[j1]; - q2 = x[j2]; - vq1 = v[j1]; - vq2 = v[j2]; - - weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); - - if (w[k] == 0.0) { - if (endflag == 1 && k == 0) - endflag = 0; - else if (endflag == 2 && k == clen - 2) - endflag = 0; - continue; + endflag = end[j]; + if (endflag == 1) { + endindex = chain[j][0]; + qe = x[endindex]; + } else if (endflag == 2) { + endindex = chain[j][clen - 1]; + qe = x[endindex]; } - sumw += w[k]; - wnode[k] += w[k]; - wnode[k + 1] += w[k]; + // compute substitute straight (semi-)infinite CNT - scaleadd3(w[k], q1, p1, p1); - scaleadd3(w[k], q2, p2, p2); + zero3(p1); + zero3(p2); + zero3(dr1_sumw); + zero3(dr2_sumw); + zeromat3(q1_dr1_w); + zeromat3(q2_dr1_w); + zeromat3(q1_dr2_w); + zeromat3(q2_dr2_w); + for (k = 0; k < clen; k++) { + wnode[k] = 0.0; + zero3(dq_w[k]); + zeromat3(q1_dq_w[k]); + zeromat3(q2_dq_w[k]); + } + sumw = 0.0; + + for (k = 0; k < clen - 1; k++) { + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + q1 = x[j1]; + q2 = x[j2]; + + weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); + + if (w[k] == 0.0) { + if (endflag == 1 && k == 0) + endflag = 0; + else if (endflag == 2 && k == clen - 2) + endflag = 0; + continue; + } + + sumw += w[k]; + wnode[k] += w[k]; + wnode[k + 1] += w[k]; + + scaleadd3(w[k], q1, p1, p1); + scaleadd3(w[k], q2, p2, p2); - // weighted velocity for friction + // weighted velocity for friction - scaleadd3(w[k], vq1, vp1, vp1); - scaleadd3(w[k], vq2, vp2, vp2); + scaleadd3(w[k], vq1, vp1, vp1); + scaleadd3(w[k], vq2, vp2, vp2); - // weight gradient terms + // weight gradient terms - add3(dr1_w, dr1_sumw, dr1_sumw); - add3(dr2_w, dr2_sumw, dr2_sumw); + add3(dr1_w, dr1_sumw, dr1_sumw); + add3(dr2_w, dr2_sumw, dr2_sumw); - outer3(q1, dr1_w, temp); - plus3(temp, q1_dr1_w, q1_dr1_w); - outer3(q2, dr1_w, temp); - plus3(temp, q2_dr1_w, q2_dr1_w); - outer3(q1, dr2_w, temp); - plus3(temp, q1_dr2_w, q1_dr2_w); - outer3(q2, dr2_w, temp); - plus3(temp, q2_dr2_w, q2_dr2_w); + outer3(q1, dr1_w, temp); + plus3(temp, q1_dr1_w, q1_dr1_w); + outer3(q2, dr1_w, temp); + plus3(temp, q2_dr1_w, q2_dr1_w); + outer3(q1, dr2_w, temp); + plus3(temp, q1_dr2_w, q1_dr2_w); + outer3(q2, dr2_w, temp); + plus3(temp, q2_dr2_w, q2_dr2_w); - add3(dq1_w, dq_w[k], dq_w[k]); - add3(dq2_w, dq_w[k + 1], dq_w[k + 1]); + add3(dq1_w, dq_w[k], dq_w[k]); + add3(dq2_w, dq_w[k + 1], dq_w[k + 1]); - outer3(q1, dq1_w, temp); - plus3(temp, q1_dq_w[k], q1_dq_w[k]); - outer3(q1, dq2_w, temp); - plus3(temp, q1_dq_w[k + 1], q1_dq_w[k + 1]); - outer3(q2, dq1_w, temp); - plus3(temp, q2_dq_w[k], q2_dq_w[k]); - outer3(q2, dq2_w, temp); - plus3(temp, q2_dq_w[k + 1], q2_dq_w[k + 1]); - } + outer3(q1, dq1_w, temp); + plus3(temp, q1_dq_w[k], q1_dq_w[k]); + outer3(q1, dq2_w, temp); + plus3(temp, q1_dq_w[k + 1], q1_dq_w[k + 1]); + outer3(q2, dq1_w, temp); + plus3(temp, q2_dq_w[k], q2_dq_w[k]); + outer3(q2, dq2_w, temp); + plus3(temp, q2_dq_w[k + 1], q2_dq_w[k + 1]); + } - if (sumw == 0.0) continue; + if (sumw == 0.0) continue; - sumw_inv = 1.0 / sumw; - scale3(sumw_inv, p1); - scale3(sumw_inv, p2); + sumw_inv = 1.0 / sumw; + scale3(sumw_inv, p1); + scale3(sumw_inv, p2); - // compute geometry and forces + // compute geometry and forces - // infinite CNT case + if (endflag == 0) { + + // infinite CNT case + + geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); + + if (param[0] > cutoff) continue; + double salpha = sin(param[1]); + double sxi1 = salpha * param[2]; + double sxi2 = salpha * param[3]; + double hsq = param[0] * param[0]; + if (sxi1 * sxi1 + hsq > cutoffsq && sxi2 * sxi2 + hsq > cutoffsq) + continue; - if (endflag == 0) { - geometry(r1, r2, p1, p2, nullptr, p, m, param, basis); - if (param[0] > cutoff) continue; - finf(param, evdwl, flocal); + finf(param, evdwl, flocal); - // semi-infinite CNT case with end at start of chain + } else { + + // semi-infinite CNT case + // endflag == 1: CNT end at start of chain + // endflag == 2: CNT end at end of chain + + if (endflag == 1) geometry(r1, r2, p1, p2, qe, p, m, param, basis); + else geometry(r1, r2, p2, p1, qe, p, m, param, basis); + + if (param[0] > cutoff) continue; + double hsq = param[0] * param[0]; + double calpha = cos(param[1]); + double etamin = calpha * param[2]; + double dsq1; + if (etamin < param[6]) { + dsq1 = hsq + pow(sin(param[1]) * param[6], 2); + dsq1 += pow(param[2] - calpha * param[6], 2); + } + else + dsq1 = hsq + pow(sin(param[1]) * param[2], 2); + + etamin = calpha * param[3]; + double dsq2; + if (etamin < param[6]) { + dsq2 = hsq + pow(sin(param[1]) * param[6], 2); + dsq2 += pow(param[3] - calpha * param[6], 2); + } + else + dsq2 = hsq + pow(sin(param[1]) * param[3], 2); - } else if (endflag == 1) { - geometry(r1, r2, p1, p2, qe, p, m, param, basis); - if (param[0] > cutoff) continue; - fsemi(param, evdwl, fend, flocal); + if (dsq1 > cutoffsq && dsq2 > cutoffsq) continue; - // semi-infinite CNT case with end at end of chain + fsemi(param, evdwl, fend, flocal); + } - } else { - geometry(r1, r2, p2, p1, qe, p, m, param, basis); - if (param[0] > cutoff) continue; - fsemi(param, evdwl, fend, flocal); - } + if (evdwl == 0.0) continue; + evdwl *= 0.5; - evdwl *= 0.5; + // transform to global coordinate system - // transform to global coordinate system - - matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); - matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); + matvec(basis[0], basis[1], basis[2], flocal[0], fglobal[0]); + matvec(basis[0], basis[1], basis[2], flocal[1], fglobal[1]); - // mean chain velocity and relative velocity + // mean chain velocity and relative velocity - add3(vp1, vp2, vp); - scale3(0.5*sumw_inv, vp); - sub3(vp, vr, vrel); + add3(vp1, vp2, vp); + scale3(0.5*sumw_inv, vp); + sub3(vp, vr, vrel); - // friction forces - - vtot = len3(vrel); - if (vtot < vswitch) scale3(0.25*a1, vrel, fvisc); - else { - fvisc_tot = b2 / vtot - a2; - if (fvisc_tot < 0.0) zero3(fvisc); - else scale3(0.25*fvisc_tot, vrel, fvisc); - } - - add3(fvisc, f[i1], f[i1]); - add3(fvisc, f[i2], f[i2]); - - // forces acting on approximate chain - - add3(fglobal[0], fglobal[1], ftotal); - if (endflag) scaleadd3(fend, m, ftotal, ftotal); - scale3(-0.5, ftotal); - - sub3(r1, p, delr1); - sub3(r2, p, delr2); - cross3(delr1, fglobal[0], t1); - cross3(delr2, fglobal[1], t2); - add3(t1, t2, torque); - - // additional torque contribution from chain end - - if (endflag) { - sub3(qe, p, delqe); - cross3(delqe, m, t3); - scale3(fend, t3); - add3(t3, torque, torque); - } - - cross3(torque, m, ftorque); - lp = param[5] - param[4]; - scale3(1.0 / lp, ftorque); - - if (endflag == 2) { - add3(ftotal, ftorque, fglobal[3]); - sub3(ftotal, ftorque, fglobal[2]); - } else { - add3(ftotal, ftorque, fglobal[2]); - sub3(ftotal, ftorque, fglobal[3]); - } - - scale3(0.5, fglobal[0]); - scale3(0.5, fglobal[1]); - scale3(0.5, fglobal[2]); - scale3(0.5, fglobal[3]); - - // weight gradient terms acting on current segment - - outer3(p1, dr1_sumw, temp); - minus3(q1_dr1_w, temp, dr1_p1); - outer3(p2, dr1_sumw, temp); - minus3(q2_dr1_w, temp, dr1_p2); - outer3(p1, dr2_sumw, temp); - minus3(q1_dr2_w, temp, dr2_p1); - outer3(p2, dr2_sumw, temp); - minus3(q2_dr2_w, temp, dr2_p2); - - transpose_matvec(dr1_p1, fglobal[2], fgrad_r1_p1); - transpose_matvec(dr1_p2, fglobal[3], fgrad_r1_p2); - transpose_matvec(dr2_p1, fglobal[2], fgrad_r2_p1); - transpose_matvec(dr2_p2, fglobal[3], fgrad_r2_p2); - - // add forces to nodes in current segment - - add3(fglobal[0], f[i1], f[i1]); - add3(fglobal[1], f[i2], f[i2]); - - scaleadd3(sumw_inv, fgrad_r1_p1, f[i1], f[i1]); - scaleadd3(sumw_inv, fgrad_r1_p2, f[i1], f[i1]); - scaleadd3(sumw_inv, fgrad_r2_p1, f[i2], f[i2]); - scaleadd3(sumw_inv, fgrad_r2_p2, f[i2], f[i2]); - - // add forces in approximate chain - - for (k = 0; k < clen - 1; k++) { - if (w[k] == 0.0) continue; - j1 = chain[j][k]; - j2 = chain[j][k + 1]; - j1 &= NEIGHMASK; - j2 &= NEIGHMASK; - scale = w[k] * sumw_inv; - scaleadd3(scale, fglobal[2], f[j1], f[j1]); - scaleadd3(scale, fglobal[3], f[j2], f[j2]); - // friction forces + + vtot = len3(vrel); + if (vtot < vswitch) scale3(0.25*a1, vrel, fvisc); + else { + fvisc_tot = b2 / vtot - a2; + if (fvisc_tot < 0.0) zero3(fvisc); + else scale3(0.25*fvisc_tot, vrel, fvisc); + } + + add3(fvisc, f[i1], f[i1]); + add3(fvisc, f[i2], f[i2]); + + // forces acting on approximate chain + + add3(fglobal[0], fglobal[1], ftotal); + if (endflag) scaleadd3(fend, m, ftotal, ftotal); + scale3(-0.5, ftotal); + + sub3(r1, p, delr1); + sub3(r2, p, delr2); + cross3(delr1, fglobal[0], t1); + cross3(delr2, fglobal[1], t2); + add3(t1, t2, torque); + + // additional torque contribution from chain end + + if (endflag) { + sub3(qe, p, delqe); + cross3(delqe, m, t3); + scale3(fend, t3); + add3(t3, torque, torque); + } + + cross3(torque, m, ftorque); + lp = param[5] - param[4]; + scale3(1.0 / lp, ftorque); + + if (endflag == 2) { + add3(ftotal, ftorque, fglobal[3]); + sub3(ftotal, ftorque, fglobal[2]); + } else { + add3(ftotal, ftorque, fglobal[2]); + sub3(ftotal, ftorque, fglobal[3]); + } + + scale3(0.5, fglobal[0]); + scale3(0.5, fglobal[1]); + scale3(0.5, fglobal[2]); + scale3(0.5, fglobal[3]); + + // weight gradient terms acting on current segment + + outer3(p1, dr1_sumw, temp); + minus3(q1_dr1_w, temp, dr1_p1); + outer3(p2, dr1_sumw, temp); + minus3(q2_dr1_w, temp, dr1_p2); + outer3(p1, dr2_sumw, temp); + minus3(q1_dr2_w, temp, dr2_p1); + outer3(p2, dr2_sumw, temp); + minus3(q2_dr2_w, temp, dr2_p2); + + transpose_matvec(dr1_p1, fglobal[2], fgrad_r1_p1); + transpose_matvec(dr1_p2, fglobal[3], fgrad_r1_p2); + transpose_matvec(dr2_p1, fglobal[2], fgrad_r2_p1); + transpose_matvec(dr2_p2, fglobal[3], fgrad_r2_p2); + + // add forces to nodes in current segment + + add3(fglobal[0], f[i1], f[i1]); + add3(fglobal[1], f[i2], f[i2]); + + scaleadd3(sumw_inv, fgrad_r1_p1, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r1_p2, f[i1], f[i1]); + scaleadd3(sumw_inv, fgrad_r2_p1, f[i2], f[i2]); + scaleadd3(sumw_inv, fgrad_r2_p2, f[i2], f[i2]); + + // add forces in approximate chain + + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + scale = w[k] * sumw_inv; + scaleadd3(scale, fglobal[2], f[j1], f[j1]); + scaleadd3(scale, fglobal[3], f[j2], f[j2]); - scaleadd3(-scale, fvisc, f[j1], f[j1]); - scaleadd3(-scale, fvisc, f[j2], f[j2]); - } + // friction forces + + scaleadd3(-scale, fvisc, f[j1], f[j1]); + scaleadd3(-scale, fvisc, f[j2], f[j2]); + } - // weight gradient terms acting on approximate chain - // iterate over nodes instead of segments + // weight gradient terms acting on approximate chain + // iterate over nodes instead of segments - for (k = 0; k < clen; k++) { - if (wnode[k] == 0.0) continue; - j1 = chain[j][k]; - j1 &= NEIGHMASK; + for (k = 0; k < clen; k++) { + if (wnode[k] == 0.0) continue; + j1 = chain[j][k]; + j1 &= NEIGHMASK; - outer3(p1, dq_w[k], temp); - minus3(q1_dq_w[k], temp, dq_p1); - outer3(p2, dq_w[k], temp); - minus3(q2_dq_w[k], temp, dq_p2); + outer3(p1, dq_w[k], temp); + minus3(q1_dq_w[k], temp, dq_p1); + outer3(p2, dq_w[k], temp); + minus3(q2_dq_w[k], temp, dq_p2); - transpose_matvec(dq_p1, fglobal[2], fgrad_q_p1); - transpose_matvec(dq_p2, fglobal[3], fgrad_q_p2); + transpose_matvec(dq_p1, fglobal[2], fgrad_q_p1); + transpose_matvec(dq_p2, fglobal[3], fgrad_q_p2); - scaleadd3(sumw_inv, fgrad_q_p1, f[j1], f[j1]); - scaleadd3(sumw_inv, fgrad_q_p2, f[j1], f[j1]); - } + scaleadd3(sumw_inv, fgrad_q_p1, f[j1], f[j1]); + scaleadd3(sumw_inv, fgrad_q_p2, f[j1], f[j1]); + } - // force on node at CNT end + // force on node at CNT end - if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); + if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); - // compute energy + // compute energy - if (eflag_either) { - if (eflag_global) eng_vdwl += evdwl; - if (eflag_atom) { - eatom[i1] += 0.25 * evdwl; - eatom[i2] += 0.25 * evdwl; - for (k = 0; k < clen - 1; k++) { - if (w[k] == 0.0) continue; - j1 = chain[j][k]; - j2 = chain[j][k + 1]; - j1 &= NEIGHMASK; - j2 &= NEIGHMASK; - evdwl_chain = 0.5 * w[k] * sumw_inv * evdwl; - eatom[j1] += evdwl_chain; - eatom[j2] += evdwl_chain; + if (eflag_either) { + if (eflag_global) eng_vdwl += evdwl; + if (eflag_atom) { + eatom[i1] += 0.25 * evdwl; + eatom[i2] += 0.25 * evdwl; + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + evdwl_chain = 0.5 * w[k] * sumw_inv * evdwl; + eatom[j1] += evdwl_chain; + eatom[j2] += evdwl_chain; + } } } } From 9bbd252cc0d096462126c7682de33686d228461e Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 2 Jun 2022 16:18:49 +0100 Subject: [PATCH 054/443] fixed missing header files + variable declarations --- src/MESONT/pair_mesocnt_viscous.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index a288bb8933..c1293e8035 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -21,6 +21,7 @@ #include "atom.h" #include "error.h" #include "force.h" +#include "math_const.h" #include "math_extra.h" #include "memory.h" #include "neigh_list.h" @@ -31,6 +32,7 @@ #include using namespace LAMMPS_NS; +using namespace MathConst; using namespace MathExtra; #define RHOMIN 10.0 @@ -48,6 +50,7 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) int **chain; double fend, lp, scale, sumw, sumw_inv; double evdwl, evdwl_chain; + double vtot, fvisc_tot; double *r1, *r2, *q1, *q2, *qe; double *vr1, *vr2, *vq1, *vq2; double vr[3], vp1[3], vp2[3], vp[3], vrel[3], fvisc[3]; From 8842a35c3a62692d78a9aa29c30bd408543d10ff Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 2 Jun 2022 16:39:24 +0100 Subject: [PATCH 055/443] added smooth cutoff to friction force based on sumw --- src/MESONT/pair_mesocnt_viscous.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index c1293e8035..397ce6a0b5 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -301,6 +301,8 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) j2 &= NEIGHMASK; q1 = x[j1]; q2 = x[j2]; + vq1 = v[j1]; + vq2 = v[j2]; weight(r1, r2, q1, q2, w[k], dr1_w, dr2_w, dq1_w, dq2_w); @@ -427,11 +429,11 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) // friction forces vtot = len3(vrel); - if (vtot < vswitch) scale3(0.25*a1, vrel, fvisc); + if (vtot < vswitch) scale3(0.25 * (1 - s(sumw)) * a1, vrel, fvisc); else { fvisc_tot = b2 / vtot - a2; if (fvisc_tot < 0.0) zero3(fvisc); - else scale3(0.25*fvisc_tot, vrel, fvisc); + else scale3(0.25 * (1 - s(sumw)) * fvisc_tot, vrel, fvisc); } add3(fvisc, f[i1], f[i1]); From 1465b75f55880dc30db1f2c1f9cbd6edc794921a Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 2 Jun 2022 17:20:34 +0100 Subject: [PATCH 056/443] added weight function without gradients + weighted viscous friction for segment-segment interactions --- src/MESONT/pair_mesocnt_viscous.cpp | 79 ++++++++++++++++++++++++++++- src/MESONT/pair_mesocnt_viscous.h | 4 ++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 397ce6a0b5..72a3fd6c7c 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -102,7 +102,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) clen = nchain[j]; if (clen < 2) continue; - if (modelist[i][j]) { + if (modelist[i][j] || true) { + + zero3(vp1); + zero3(vp2); + sumw = 0.0; + for (k = 0; k < clen - 1; k++) { j1 = chain[j][k]; j2 = chain[j][k + 1]; @@ -110,6 +115,18 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) j2 &= NEIGHMASK; q1 = x[j1]; q2 = x[j2]; + vq1 = v[j1]; + vq2 = v[j2]; + + // weighted velocity for friction + + w[k] = weight(r1, r2, q1, q2); + if (w[k] == 0.0) continue; + sumw += w[k]; + scaleadd3(w[k], vq1, vp1, vp1); + scaleadd3(w[k], vq2, vp2, vp2); + + // check if orientation of segment needs to be flipped to prevent overlap geometry(r1, r2, q1, q2, q1, p, m, param, basis); if (param[0] > cutoff) continue; @@ -135,6 +152,8 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) int jj1, jj2; + // do flip if necessary + if (dsq1 < dsq2) { jj1 = j1; jj2 = j2; @@ -261,7 +280,38 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) eatom[jj2] += evdwl_atom; } } + } + if (sumw == 0.0) continue; + sumw_inv = 1.0 / sumw; + + // friction forces + + vtot = len3(vrel); + if (vtot < vswitch) scale3(0.25 * (1 - s(sumw)) * a1, vrel, fvisc); + else { + fvisc_tot = b2 / vtot - a2; + if (fvisc_tot < 0.0) zero3(fvisc); + else scale3(0.25 * (1 - s(sumw)) * fvisc_tot, vrel, fvisc); + } + + // add friction forces to current segment + + add3(fvisc, f[i1], f[i1]); + add3(fvisc, f[i2], f[i2]); + + // add friction forces to neighbor chain + + for (k = 0; k < clen - 1; k++) { + if (w[k] == 0.0) continue; + j1 = chain[j][k]; + j2 = chain[j][k + 1]; + j1 &= NEIGHMASK; + j2 &= NEIGHMASK; + scale = w[k] * sumw_inv; + + scaleadd3(-scale, fvisc, f[j1], f[j1]); + scaleadd3(-scale, fvisc, f[j2], f[j2]); } } else { @@ -282,6 +332,8 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) zero3(p2); zero3(dr1_sumw); zero3(dr2_sumw); + zero3(vp1); + zero3(vp2); zeromat3(q1_dr1_w); zeromat3(q2_dr1_w); zeromat3(q1_dr2_w); @@ -646,12 +698,35 @@ void PairMesoCNTViscous::coeff(int narg, char **arg) for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; } +/* ---------------------------------------------------------------------- + weight for averaged friction from CNT chain +------------------------------------------------------------------------- */ + +inline double PairMesoCNTViscous::weight(const double *r1, const double *r2, const double *p1, + const double *p2) +{ + double dr, dp, rhoc, rhomin, rho, frac, arg; + double r[3], p[3]; + + add3(r1, r2, r); + add3(p1, p2, p); + + dr = sqrt(0.25 * distsq3(r1, r2) + rsq); + dp = sqrt(0.25 * distsq3(p1, p2) + rsq); + rhoc = dr + dp + rc; + rhomin = RHOMIN * ang; + rho = 0.5 * sqrt(distsq3(r, p)); + + return s((rho - rhomin) / (rhoc - rhomin)); +} + /* ---------------------------------------------------------------------- weight for substitute CNT chain + computes gradients with respect to positions ------------------------------------------------------------------------- */ -inline void PairMesoCNT::weight(const double *r1, const double *r2, const double *p1, +inline void PairMesoCNTViscous::weight(const double *r1, const double *r2, const double *p1, const double *p2, double &w, double *dr1_w, double *dr2_w, double *dp1_w, double *dp2_w) { diff --git a/src/MESONT/pair_mesocnt_viscous.h b/src/MESONT/pair_mesocnt_viscous.h index 3c86329479..2027435da3 100644 --- a/src/MESONT/pair_mesocnt_viscous.h +++ b/src/MESONT/pair_mesocnt_viscous.h @@ -30,6 +30,10 @@ class PairMesoCNTViscous : public PairMesoCNT { protected: double a1, a2, b2, vswitch; + + inline double weight(const double *, const double *, const double *, const double*); + inline void weight(const double *, const double *, const double *, const double *, double &, + double *, double *, double *, double *); }; } // namespace LAMMPS_NS From 79b850fc870a859488f2924ae2841d98da0867df Mon Sep 17 00:00:00 2001 From: phankl Date: Thu, 2 Jun 2022 17:46:21 +0100 Subject: [PATCH 057/443] removed true statement to trigger segment-segment evaluation --- src/MESONT/pair_mesocnt_viscous.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 72a3fd6c7c..6f69da1c45 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -102,7 +102,7 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) clen = nchain[j]; if (clen < 2) continue; - if (modelist[i][j] || true) { + if (modelist[i][j]) { zero3(vp1); zero3(vp2); From dba18c1c8d0be3fb6f3a3566362e7de718cc6e3e Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 3 Jun 2022 19:15:30 +0100 Subject: [PATCH 058/443] moved mode check to compute loop rather than neighbor list creation --- src/MESONT/pair_mesocnt.cpp | 39 +++++++-------- src/MESONT/pair_mesocnt_viscous.cpp | 76 ++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 6751083438..918dc9e088 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -84,7 +84,6 @@ PairMesoCNT::~PairMesoCNT() memory->destroy(numchainlist); memory->destroy(nchainlist); memory->destroy(endlist); - memory->destroy(modelist); memory->destroy(chainlist); memory->destroy(w); @@ -133,6 +132,9 @@ void PairMesoCNT::compute(int eflag, int vflag) int **bondlist = neighbor->bondlist; int nbondlist = neighbor->nbondlist; + int flag, cols; + int buckled_index = atom->find_custom("buckled", flag, cols); + // update bond neighbor list when necessary if (update->ntimestep == neighbor->lastcall) bond_neigh(); @@ -156,8 +158,21 @@ void PairMesoCNT::compute(int eflag, int vflag) for (j = 0; j < numchain; j++) { clen = nchain[j]; if (clen < 2) continue; + + // check if segment-segment interactions are necessary - if (modelist[i][j]) { + endflag = end[j]; + int buckled = 0; + if (buckled_index != -1) { + for (k = 0; k < clen; k++) { + if (atom->ivector[buckled_index][chain[j][k]]) { + buckled = 1; + break; + } + } + } + + if (buckled || endflag == 3) { for (k = 0; k < clen - 1; k++) { j1 = chain[j][k]; j2 = chain[j][k + 1]; @@ -322,7 +337,6 @@ void PairMesoCNT::compute(int eflag, int vflag) else { // assign end position - endflag = end[j]; if (endflag == 1) { endindex = chain[j][0]; qe = x[endindex]; @@ -619,7 +633,6 @@ void PairMesoCNT::allocate() memory->create(numchainlist, init_size, "pair:numchainlist"); memory->create(nchainlist, init_size, init_size, "pair:nchainlist"); memory->create(endlist, init_size, init_size, "pair:endlist"); - memory->create(modelist, init_size, init_size, "pair:modelist"); memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); memory->create(w, init_size, "pair:w"); @@ -751,9 +764,6 @@ void PairMesoCNT::bond_neigh() int **nspecial = atom->nspecial; tagint **special = atom->special; - int flag, cols; - int buckled_index = atom->find_custom("buckled", flag, cols); - comm->forward_comm(this); // create version of atom->special with local ids and correct images @@ -813,7 +823,6 @@ void PairMesoCNT::bond_neigh() memory->destroy(numchainlist); memory->destroy(nchainlist); memory->destroy(endlist); - memory->destroy(modelist); memory->destroy(chainlist); // split neighbor list into neighbor chains based on bond topology @@ -940,7 +949,6 @@ void PairMesoCNT::bond_neigh() // MEMORY: prevent zero-size array creation for chainlist memory->create_ragged(endlist, nbondlist, numchainlist, "pair:endlist"); - memory->create_ragged(modelist, nbondlist, numchainlist, "pair:modelist"); if (empty_neigh) memory->create(chainlist, 1, 1, 1, "pair:chainlist"); else @@ -969,24 +977,13 @@ void PairMesoCNT::bond_neigh() int cstart = chainlist[i][j][0]; int cend = chainlist[i][j][clen-1]; - modelist[i][j] = 0; - bool estart = match_end(type[cstart]); bool eend = match_end(type[cend]); - if (estart && eend) modelist[i][j] = 1; + if (estart && eend) endlist[i][j] = 3; else if (estart) endlist[i][j] = 1; else if (eend) endlist[i][j] = 2; else endlist[i][j] = 0; - - if (buckled_index != -1) { - for (int k = 0; k < nchainlist[i][j]; k++) { - if (atom->ivector[buckled_index][chainlist[i][j][k]]) { - modelist[i][j] = 1; - break; - } - } - } } } diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 6f69da1c45..952f6352cf 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -72,6 +72,9 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) double **f = atom->f; int **bondlist = neighbor->bondlist; int nbondlist = neighbor->nbondlist; + + int flag, cols; + int buckled_index = atom->find_custom("buckled", flag, cols); // update bond neighbor list when necessary @@ -101,8 +104,21 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) for (j = 0; j < numchain; j++) { clen = nchain[j]; if (clen < 2) continue; + + // check if segment-segment interactions are necessary - if (modelist[i][j]) { + endflag = end[j]; + int buckled = 0; + if (buckled_index != -1) { + for (k = 0; k < clen; k++) { + if (atom->ivector[buckled_index][chain[j][k]]) { + buckled = 1; + break; + } + } + } + + if (buckled || endflag == 3) { zero3(vp1); zero3(vp2); @@ -176,6 +192,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) // first force contribution fsemi(param, evdwl, fend, flocal); + if (evdwl > 1.0e1) { + printf("high energy detected in first contribution (%f eV)\n", evdwl); + printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("segment2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + } if (evdwl == 0.0) continue; @@ -211,6 +233,18 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); + bool nan0 = fglobal[0][0] == fglobal[0][0]; + bool nan1 = fglobal[1][0] == fglobal[1][0]; + bool nan2 = fglobal[2][0] == fglobal[2][0]; + bool nan3 = fglobal[3][0] == fglobal[3][0]; + + if (!(nan0 || nan1 || nan2 || nan3)) { + printf("nan in segment-segment 1\n"); + printf("segment 1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("segment 2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + } + // add energy if (eflag_either) { @@ -230,6 +264,13 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) param[6] += lp; fsemi(param, evdwl, fend, flocal); + if (evdwl > 1.0e1) { + printf("high energy detected in second contribution (%f eV)\n", evdwl); + printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("segment2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + } + if (evdwl == 0.0) continue; @@ -266,6 +307,18 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) scaleadd3(0.5, fglobal[3], f[jj1], f[jj1]); sub3(f[jj2], fglobal[3], f[jj2]); scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); + + nan0 = fglobal[0][0] == fglobal[0][0]; + nan1 = fglobal[1][0] == fglobal[1][0]; + nan2 = fglobal[2][0] == fglobal[2][0]; + nan3 = fglobal[3][0] == fglobal[3][0]; + + if (!(nan0 || nan1 || nan2 || nan3)) { + printf("nan in segment-segment 2\n"); + printf("segment 1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("segment 2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + } // add energy @@ -464,6 +517,16 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fsemi(param, evdwl, fend, flocal); } + if (evdwl > 1.0e1) { + printf("high energy detected in segment-chain interaction (%f eV)\n", evdwl); + printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("chain: "); + for (k = 0; k < clen; k++) + printf("%d ", atom->tag[chain[j][k]]); + printf("\n"); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + } + if (evdwl == 0.0) continue; evdwl *= 0.5; @@ -597,6 +660,17 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); + bool nan0 = fglobal[0][0] == fglobal[0][0]; + bool nan1 = fglobal[1][0] == fglobal[1][0]; + bool nan2 = fglobal[2][0] == fglobal[2][0]; + bool nan3 = fglobal[3][0] == fglobal[3][0]; + + if (!(nan0 || nan1 || nan2 || nan3)) { + printf("nan in segment-chain\n"); + printf("tags: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + } + // compute energy if (eflag_either) { From 515b4d196e412b59a88bd3d3451c68c714b48054 Mon Sep 17 00:00:00 2001 From: phankl Date: Sat, 4 Jun 2022 14:39:22 +0100 Subject: [PATCH 059/443] fixed nan issue in segment-segment friction --- src/MESONT/pair_mesocnt_viscous.cpp | 58 ++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 952f6352cf..d12e1e6e2f 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -178,10 +178,10 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (param[1] > MY_PI) param[1] -= MY_PI; else param[1] += MY_PI; - double temp = -param[5]; + double eta2 = -param[5]; param[5] = -param[4]; - param[4] = temp; - param[6] = temp; + param[4] = eta2; + param[6] = eta2; negate3(m); @@ -195,7 +195,11 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (evdwl > 1.0e1) { printf("high energy detected in first contribution (%f eV)\n", evdwl); printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("%f %f %f\n", r1[0], r1[1], r1[2]); + printf("%f %f %f\n", r2[0], r2[1], r2[2]); printf("segment2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("%f %f %f\n", q1[0], q1[1], q1[2]); + printf("%f %f %f\n", q2[0], q2[1], q2[2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } @@ -241,7 +245,11 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (!(nan0 || nan1 || nan2 || nan3)) { printf("nan in segment-segment 1\n"); printf("segment 1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("%f %f %f\n", r1[0], r1[1], r1[2]); + printf("%f %f %f\n", r2[0], r2[1], r2[2]); printf("segment 2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("%f %f %f\n", q1[0], q1[1], q1[2]); + printf("%f %f %f\n", q2[0], q2[1], q2[2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } @@ -267,7 +275,11 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (evdwl > 1.0e1) { printf("high energy detected in second contribution (%f eV)\n", evdwl); printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("%f %f %f\n", r1[0], r1[1], r1[2]); + printf("%f %f %f\n", r2[0], r2[1], r2[2]); printf("segment2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("%f %f %f\n", q1[0], q1[1], q1[2]); + printf("%f %f %f\n", q2[0], q2[1], q2[2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } @@ -316,7 +328,11 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (!(nan0 || nan1 || nan2 || nan3)) { printf("nan in segment-segment 2\n"); printf("segment 1: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("%f %f %f\n", r1[0], r1[1], r1[2]); + printf("%f %f %f\n", r2[0], r2[1], r2[2]); printf("segment 2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); + printf("%f %f %f\n", q1[0], q1[1], q1[2]); + printf("%f %f %f\n", q2[0], q2[1], q2[2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } @@ -337,6 +353,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (sumw == 0.0) continue; sumw_inv = 1.0 / sumw; + + // mean chain velocity and relative velocity + + add3(vp1, vp2, vp); + scale3(0.5*sumw_inv, vp); + sub3(vp, vr, vrel); // friction forces @@ -346,8 +368,13 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fvisc_tot = b2 / vtot - a2; if (fvisc_tot < 0.0) zero3(fvisc); else scale3(0.25 * (1 - s(sumw)) * fvisc_tot, vrel, fvisc); + if (std::isnan(fvisc_tot)) { + printf("nan in segment-segment friction\n"); + printf("fvisc: %f %f %f\n", fvisc[0], fvisc[1], fvisc[2]); + printf("vrel: %f %f %f\n", vrel[0], vrel[1], vrel[2]); + } } - + // add friction forces to current segment add3(fvisc, f[i1], f[i1]); @@ -519,11 +546,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (evdwl > 1.0e1) { printf("high energy detected in segment-chain interaction (%f eV)\n", evdwl); - printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("chain: "); + printf("segment: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("%f %f %f\n", r1[0], r1[1], r1[2]); + printf("%f %f %f\n", r2[0], r2[1], r2[2]); + printf("chain: \n"); for (k = 0; k < clen; k++) - printf("%d ", atom->tag[chain[j][k]]); - printf("\n"); + printf("%d %f %f %f\n", atom->tag[chain[j][k]], x[chain[j][k]][0], x[chain[j][k]][1], x[chain[j][k]][2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } @@ -549,8 +577,13 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fvisc_tot = b2 / vtot - a2; if (fvisc_tot < 0.0) zero3(fvisc); else scale3(0.25 * (1 - s(sumw)) * fvisc_tot, vrel, fvisc); + if (std::isnan(fvisc_tot)) { + printf("nan in segment-chain friction\n"); + printf("fvisc: %f %f %f\n", fvisc[0], fvisc[1], fvisc[2]); + printf("vrel: %f %f %f\n", vrel[0], vrel[1], vrel[2]); + } } - + add3(fvisc, f[i1], f[i1]); add3(fvisc, f[i2], f[i2]); @@ -667,7 +700,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (!(nan0 || nan1 || nan2 || nan3)) { printf("nan in segment-chain\n"); - printf("tags: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("segment: %d %d\n", atom->tag[i1], atom->tag[i2]); + printf("%f %f %f\n", r1[0], r1[1], r1[2]); + printf("%f %f %f\n", r2[0], r2[1], r2[2]); + printf("chain: \n"); + for (k = 0; k < clen; k++) + printf("%d %f %f %f\n", atom->tag[chain[j][k]], x[chain[j][k]][0], x[chain[j][k]][1], x[chain[j][k]][2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } From c3d57760feaf189a821576ff574a783c8eda7dc3 Mon Sep 17 00:00:00 2001 From: phankl Date: Sat, 4 Jun 2022 20:35:06 +0100 Subject: [PATCH 060/443] fixed zero-size memory allocation for empty chainlist --- src/MESONT/pair_mesocnt.cpp | 43 +++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 918dc9e088..4e5d06e732 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -783,6 +783,11 @@ void PairMesoCNT::bond_neigh() } } + if (comm->me == 379) { + printf("rank %d created special_local\n", comm->me); + fflush(stdout); + } + int *numneigh = list->numneigh; int *numneigh_max; memory->create(numneigh_max, nbondlist, "pair:numneigh_max"); @@ -817,6 +822,11 @@ void PairMesoCNT::bond_neigh() int i2 = bondlist[i][1]; neigh_common(i1, i2, reduced_nlist[i], reduced_neighlist[i]); } + + if (comm->me == 379) { + printf("rank %d created common neighbor list\n", comm->me); + fflush(stdout); + } // resize chain arrays @@ -836,12 +846,16 @@ void PairMesoCNT::bond_neigh() bool empty_neigh = true; for (int i = 0; i < nbondlist; i++) { + + if (comm->me == 379) { + printf("rank %d, splitting chains for bond %d (%d %d)\n", comm->me, i, atom->tag[bondlist[i][0]], atom->tag[bondlist[i][1]]); + printf("reduced_nlist: %d\n", reduced_nlist[i]); + fflush(stdout); + } numchainlist[i] = 0; if (reduced_nlist[i] == 0) continue; - empty_neigh = false; - // map local ids to reduced neighbor list ids std::unordered_map reduced_map; @@ -849,6 +863,11 @@ void PairMesoCNT::bond_neigh() reduced_map[reduced_neighlist[i][j]] = j; chainid[i][j] = -1; } + + if (comm->me == 379) { + printf("reduced map created\n"); + fflush(stdout); + } // assign chain ids and positions @@ -906,8 +925,14 @@ void PairMesoCNT::bond_neigh() numchainlist[i]++; } numchainlist[i]--; + if (numchainlist[i]) empty_neigh = false; } - + + if (comm->me == 379) { + printf("rank %d split chains\n", comm->me); + fflush(stdout); + } + memory->destroy(special_local); // count neighbor chain lengths per bond @@ -944,7 +969,12 @@ void PairMesoCNT::bond_neigh() if (clen > nchain_max) nchain_max = clen; } } - + + if (comm->me == 379) { + printf("rank %d counted neighbor chain lengths\n", comm->me); + fflush(stdout); + } + // create connected neighbor chains and check for ends // MEMORY: prevent zero-size array creation for chainlist @@ -986,6 +1016,11 @@ void PairMesoCNT::bond_neigh() else endlist[i][j] = 0; } } + + if (comm->me == 379) { + printf("rank %d created chain and end list\n", comm->me); + fflush(stdout); + } // destroy remaining temporary arrays for chain creation From 786ca53e84f7e964b56d8e05fbb870866fa21fdb Mon Sep 17 00:00:00 2001 From: phankl Date: Sun, 5 Jun 2022 13:29:33 +0100 Subject: [PATCH 061/443] added lots of debug messages --- src/MESONT/pair_mesocnt_viscous.cpp | 122 +++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index d12e1e6e2f..04e162fc31 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -170,9 +170,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) // do flip if necessary + bool flip; if (dsq1 < dsq2) { jj1 = j1; jj2 = j2; + + flip = false; } else { if (param[1] > MY_PI) param[1] -= MY_PI; @@ -187,11 +190,13 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) jj1 = j2; jj2 = j1; + + flip = true; } // first force contribution - fsemi(param, evdwl, fend, flocal); + fsemi(param, evdwl, fend, flocal); if (evdwl > 1.0e1) { printf("high energy detected in first contribution (%f eV)\n", evdwl); printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); @@ -236,7 +241,66 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) scaleadd3(0.5, fglobal[2], f[jj1], f[jj1]); scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); + + double fnum[4][3]; + double rnum[4][3], rcopy[4][3]; + double mtemp[3]; + q1 = x[jj1]; + q2 = x[jj2]; + + copy3(r1, rnum[0]); + copy3(r2, rnum[1]); + copy3(q1, rnum[2]); + copy3(q2, rnum[3]); + + copy3(r1, rcopy[0]); + copy3(r2, rcopy[1]); + copy3(q1, rcopy[2]); + copy3(q2, rcopy[3]); + + if (flip) { + printf("flipped param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + printf("flipped p %f %f %f\n", p[0], p[1], p[2]); + printf("flipped m %f %f %f\n", m[0], m[1], m[2]); + printf("flipped basis 1 %f %f %f\n", basis[0][0], basis[0][1], basis[0][2]); + printf("flipped basis 2 %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); + printf("flipped basis 3 %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); + + geometry(r1, r2, q1, q2, q1, p, m, param, basis); + printf("true param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + printf("true p %f %f %f\n", p[0], p[1], p[2]); + printf("true m %f %f %f\n", m[0], m[1], m[2]); + printf("true basis 1 %f %f %f\n", basis[0][0], basis[0][1], basis[0][2]); + printf("true basis 2 %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); + printf("true basis 3 %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); + } + + double dx = 1.0e-8; + printf("First contribution:\n"); + for (int k1 = 0; k1 < 4; k1++) { + for (int k2 = 0; k2 < 3; k2++) { + double ehi, elo; + rnum[k1][k2] = rcopy[k1][k2] + dx; + geometry(rnum[0], rnum[1], rnum[2], rnum[3], rnum[2], p, mtemp, param, basis); + fsemi(param, ehi, fend, flocal); + rnum[k1][k2] = rcopy[k1][k2] - dx; + geometry(rnum[0], rnum[1], rnum[2], rnum[3], rnum[2], p, mtemp, param, basis); + fsemi(param, elo, fend, flocal); + + fnum[k1][k2] = 0.5 * (elo - ehi) / dx; + } + if (k1 == 2) + printf("fglobal %d: %f %f %f\n", k1, fglobal[k1][0]+fend*m[0], fglobal[k1][1]+fend*m[1], fglobal[k1][2]+fend*m[2]); + else + printf("fglobal %d: %f %f %f\n", k1, fglobal[k1][0], fglobal[k1][1], fglobal[k1][2]); + printf("fnum %d: %f %f %f\n", k1, fnum[k1][0], fnum[k1][1], fnum[k1][2]); + } + if (flip) + printf("flip: true\n\n"); + else + printf("flip: false\n\n"); + bool nan0 = fglobal[0][0] == fglobal[0][0]; bool nan1 = fglobal[1][0] == fglobal[1][0]; bool nan2 = fglobal[2][0] == fglobal[2][0]; @@ -319,6 +383,62 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) scaleadd3(0.5, fglobal[3], f[jj1], f[jj1]); sub3(f[jj2], fglobal[3], f[jj2]); scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); + + double pnum1[3], pnum2[3]; + + copy3(r1, rnum[0]); + copy3(r2, rnum[1]); + copy3(q1, rnum[2]); + copy3(q2, rnum[3]); + + copy3(r1, rcopy[0]); + copy3(r2, rcopy[1]); + copy3(q1, rcopy[2]); + copy3(q2, rcopy[3]); + + double ftemp[4][3]; + copy3(fglobal[0], ftemp[0]); + copy3(fglobal[1], ftemp[1]); + copy3(fglobal[2], ftemp[3]); + copy3(fglobal[3], ftemp[2]); + negate3(ftemp[2]); + scaleadd3(2, fglobal[3], ftemp[3], ftemp[3]); + scaleadd3(fend, m, ftemp[3], ftemp[3]); + + printf("Second contribution:\n"); + for (int k1 = 0; k1 < 4; k1++) { + for (int k2 = 0; k2 < 3; k2++) { + double ehi, elo; + rnum[k1][k2] = rcopy[k1][k2] + dx; + + pnum1[0] = rnum[3][0]; + pnum1[1] = rnum[3][1]; + pnum1[2] = rnum[3][2]; + pnum2[0] = 2*rnum[3][0] - rnum[2][0]; + pnum2[1] = 2*rnum[3][1] - rnum[2][1]; + pnum2[2] = 2*rnum[3][2] - rnum[2][2]; + geometry(rnum[0], rnum[1], pnum1, pnum2, pnum1, p, mtemp, param, basis); + fsemi(param, ehi, fend, flocal); + + rnum[k1][k2] = rcopy[k1][k2] - dx; + pnum1[0] = rnum[3][0]; + pnum1[1] = rnum[3][1]; + pnum1[2] = rnum[3][2]; + pnum2[0] = 2*rnum[3][0] - rnum[2][0]; + pnum2[1] = 2*rnum[3][1] - rnum[2][1]; + pnum2[2] = 2*rnum[3][2] - rnum[2][2]; + geometry(rnum[0], rnum[1], pnum1, pnum2, pnum1, p, mtemp, param, basis); + fsemi(param, elo, fend, flocal); + + fnum[k1][k2] = 0.5 * (elo - ehi) / dx; + } + printf("fglobal %d: %f %f %f\n", k1, ftemp[k1][0], ftemp[k1][1], ftemp[k1][2]); + printf("fnum %d: %f %f %f\n", k1, fnum[k1][0], fnum[k1][1], fnum[k1][2]); + } + if (flip) + printf("flip: true\n\n"); + else + printf("flip: false\n\n"); nan0 = fglobal[0][0] == fglobal[0][0]; nan1 = fglobal[1][0] == fglobal[1][0]; From 322bf1ef477e928a49796eacdfe686e897a3a4c1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 9 Jun 2022 22:34:35 -0400 Subject: [PATCH 062/443] compute energy due to restraint forces during minimization. output stats. --- doc/src/fix_shake.rst | 31 ++++++++++++++--------- src/RIGID/fix_shake.cpp | 54 ++++++++++++++++++++++++++--------------- src/RIGID/fix_shake.h | 3 +++ 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/doc/src/fix_shake.rst b/doc/src/fix_shake.rst index d723f28fc0..137cb1aedb 100644 --- a/doc/src/fix_shake.rst +++ b/doc/src/fix_shake.rst @@ -58,7 +58,9 @@ Description Apply bond and angle constraints to specified bonds and angles in the simulation by either the SHAKE or RATTLE algorithms. This typically -enables a longer timestep. +enables a longer timestep. This SHAKE or RATTLE algorithms can *only* +be applied during molecular dynamics runs. When this fix is used during +a minimization, the constraints are replaced by strong harmonic restraints. **SHAKE vs RATTLE:** @@ -166,10 +168,13 @@ See the :doc:`molecule ` command for details. The only settings required to be in this file (by this command) are the SHAKE info of atoms in the molecule. -The *kbond* keyword allows to set the restraint force constant when -fix shake or fix rattle are used during minimization. In that case -the constraint algorithms are **not** applied and restraint -forces are used instead to help maintaining the geometries. +The *kbond* keyword allows to set the restraint force constant when fix +shake or fix rattle are used during minimization. In that case the +constraint algorithms are *not* applied and restraint forces are used +instead to help maintaining the geometries. How well the geometries +are maintained and how quickly a minimization will converge depends on +the magnitude of the force constant (kbond). If it is chosen too large +the minimization may converge slowly. The default is 1.0e6*k_B. ---------- @@ -202,6 +207,9 @@ Restart, fix_modify, output, run start/stop, minimize info No information about these fixes is written to :doc:`binary restart files `. +When used during minimization, the SHAKE or RATTLE algorithms are **not** +applied. Strong restraint forces are applied instead. + The :doc:`fix_modify ` *virial* option is supported by these fixes to add the contribution due to the added forces on atoms to both the global pressure and per-atom stress of the system via the @@ -209,14 +217,15 @@ to both the global pressure and per-atom stress of the system via the stress/atom ` commands. The former can be accessed by :doc:`thermodynamic output `. The default setting for this fix is :doc:`fix_modify virial yes `. +During minimization, the virial contribution is *NOT* available. -No global or per-atom quantities are stored by these fixes for access -by various :doc:`output commands `. No parameter of -these fixes can be used with the *start/stop* keywords of the +No global or per-atom quantities are stored by these fixes for access by +various :doc:`output commands ` during a run. During +minimization, this fix computes a global scalar which is the energy of +the restraint forces applied insteat of the constraints. No parameter +of these fixes can be used with the *start/stop* keywords of the :doc:`run ` command. -When used during minimization, the SHAKE or RATTLE algorithms are **not** -applied. Strong restraint forces are applied instead. Restrictions """""""""""" @@ -249,7 +258,7 @@ Related commands Default """"""" -kbond = 1.0e6 +kbond = 1.0e9*k_B ---------- diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 41d8c1599c..99836483dd 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -52,16 +52,17 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : loop_respa(nullptr), step_respa(nullptr), x(nullptr), v(nullptr), f(nullptr), ftmp(nullptr), vtmp(nullptr), mass(nullptr), rmass(nullptr), type(nullptr), shake_flag(nullptr), shake_atom(nullptr), shake_type(nullptr), xshake(nullptr), nshake(nullptr), list(nullptr), - b_count(nullptr), b_count_all(nullptr), b_atom(nullptr), b_atom_all(nullptr), b_ave(nullptr), b_max(nullptr), - b_min(nullptr), b_ave_all(nullptr), b_max_all(nullptr), b_min_all(nullptr), a_count(nullptr), - a_count_all(nullptr), a_ave(nullptr), a_max(nullptr), a_min(nullptr), a_ave_all(nullptr), - a_max_all(nullptr), a_min_all(nullptr), atommols(nullptr), onemols(nullptr) + b_count(nullptr), b_count_all(nullptr), b_atom(nullptr), b_atom_all(nullptr), b_ave(nullptr), + b_max(nullptr), b_min(nullptr), b_ave_all(nullptr), b_max_all(nullptr), b_min_all(nullptr), + a_count(nullptr), a_count_all(nullptr), a_ave(nullptr), a_max(nullptr), a_min(nullptr), + a_ave_all(nullptr), a_max_all(nullptr), a_min_all(nullptr), atommols(nullptr), onemols(nullptr) { energy_global_flag = energy_peratom_flag = 1; virial_global_flag = virial_peratom_flag = 1; thermo_energy = thermo_virial = 1; create_attribute = 1; dof_flag = 1; + scalar_flag = 1; stores_ids = 1; centroidstressflag = CENTROID_AVAIL; next_output = -1; @@ -162,7 +163,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : // parse optional args onemols = nullptr; - kbond = 1.0e6; + kbond = 1.0e6*force->boltz; int iarg = next; while (iarg < narg) { @@ -328,6 +329,7 @@ int FixShake::setmask() mask |= POST_FORCE; mask |= POST_FORCE_RESPA; mask |= MIN_POST_FORCE; + mask |= POST_RUN; return mask; } @@ -351,8 +353,8 @@ void FixShake::init() // that should contribute to potential energy if ((comm->me == 0) && (update->whichflag == 2)) - error->warning(FLERR,"Using fix {} with minimization. Substituting constraints with " - "restraint forces using k={:.4g}", style, kbond); + error->warning(FLERR,"Using fix {} with minimization.\n Substituting constraints with " + "harmonic restraint forces using kbond={:.4g}", style, kbond); // error if a fix changing the box comes before shake fix bool boxflag = false; @@ -590,6 +592,7 @@ void FixShake::post_force(int vflag) // virial setup v_init(vflag); + ebond = 0.0; // loop over clusters to add constraint forces @@ -669,13 +672,12 @@ void FixShake::min_post_force(int vflag) next_output = (ntimestep/output_every)*output_every + output_every; } else next_output = -1; - v_init(vflag); - x = atom->x; f = atom->f; nlocal = atom->nlocal; + ebond = 0.0; - // loop over clusters to add strong restraint forces + // loop over shake clusters to add restraint forces for (int i = 0; i < nlist; i++) { int m = list[i]; @@ -2506,7 +2508,6 @@ void FixShake::shake3angle(int m) void FixShake::bond_force(tagint id1, tagint id2, double length) { - int i1 = atom->map(id1); int i2 = atom->map(id2); @@ -2525,25 +2526,18 @@ void FixShake::bond_force(tagint id1, tagint id2, double length) const double dr = r - length; const double rk = kbond * dr; const double fbond = (r > 0.0) ? -2.0 * rk / r : 0.0; - double v[6]; - v[0] = 0.5 * delx * delx * fbond; - v[1] = 0.5 * dely * dely * fbond; - v[2] = 0.5 * delz * delz * fbond; - v[3] = 0.5 * delx * dely * fbond; - v[4] = 0.5 * delx * delz * fbond; - v[5] = 0.5 * dely * delz * fbond; if (i1 < nlocal) { f[i1][0] += delx * fbond; f[i1][1] += dely * fbond; f[i1][2] += delz * fbond; - if (evflag) v_tally(i1, v); + ebond += 0.5*rk*dr; } if (i2 < nlocal) { f[i2][0] -= delx * fbond; f[i2][1] -= dely * fbond; f[i2][2] -= delz * fbond; - if (evflag) v_tally(i2, v); + ebond += 0.5*rk*dr; } } @@ -3102,6 +3096,26 @@ void *FixShake::extract(const char *str, int &dim) return nullptr; } +/* ---------------------------------------------------------------------- + energy due to restraint forces +------------------------------------------------------------------------- */ + +double FixShake::compute_scalar() +{ + double all; + MPI_Allreduce(&ebond, &all, 1, MPI_DOUBLE, MPI_SUM, world); + return all; +} + +/* ---------------------------------------------------------------------- + print shake stats at the end of a minimization +------------------------------------------------------------------------- */ +void FixShake::post_run() +{ + if ((update->whichflag == 2) && (output_every > 0)) stats(); +} + + /* ---------------------------------------------------------------------- add coordinate constraining forces this method is called at the end of a timestep diff --git a/src/RIGID/fix_shake.h b/src/RIGID/fix_shake.h index a0f743d7d2..d6f9a8f5d6 100644 --- a/src/RIGID/fix_shake.h +++ b/src/RIGID/fix_shake.h @@ -39,6 +39,7 @@ class FixShake : public Fix { void post_force(int) override; void post_force_respa(int, int, int) override; void min_post_force(int) override; + void post_run() override; double memory_usage() override; void grow_arrays(int) override; @@ -59,6 +60,7 @@ class FixShake : public Fix { int dof(int) override; void reset_dt() override; void *extract(const char *, int &) override; + double compute_scalar() override; protected: int vflag_post_force; // store the vflag of last post_force call @@ -78,6 +80,7 @@ class FixShake : public Fix { int molecular; // copy of atom->molecular double *bond_distance, *angle_distance; // constraint distances double kbond; // force constant for restraint + double ebond; // energy of bond restraints class FixRespa *fix_respa; // rRESPA fix needed by SHAKE int nlevels_respa; // copies of needed rRESPA variables From 1ee35bea6117c0df955326d4857a7a4475ff696e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 10 Jun 2022 01:41:14 -0400 Subject: [PATCH 063/443] fix shake stats (again) --- src/RIGID/fix_shake.cpp | 60 ++++++++++++++++++++--------------------- src/RIGID/fix_shake.h | 3 +-- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 99836483dd..c284d99011 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -52,10 +52,10 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : loop_respa(nullptr), step_respa(nullptr), x(nullptr), v(nullptr), f(nullptr), ftmp(nullptr), vtmp(nullptr), mass(nullptr), rmass(nullptr), type(nullptr), shake_flag(nullptr), shake_atom(nullptr), shake_type(nullptr), xshake(nullptr), nshake(nullptr), list(nullptr), - b_count(nullptr), b_count_all(nullptr), b_atom(nullptr), b_atom_all(nullptr), b_ave(nullptr), - b_max(nullptr), b_min(nullptr), b_ave_all(nullptr), b_max_all(nullptr), b_min_all(nullptr), - a_count(nullptr), a_count_all(nullptr), a_ave(nullptr), a_max(nullptr), a_min(nullptr), - a_ave_all(nullptr), a_max_all(nullptr), a_min_all(nullptr), atommols(nullptr), onemols(nullptr) + b_count(nullptr), b_count_all(nullptr), b_ave(nullptr), b_max(nullptr), b_min(nullptr), + b_ave_all(nullptr), b_max_all(nullptr), b_min_all(nullptr), a_count(nullptr), + a_count_all(nullptr), a_ave(nullptr), a_max(nullptr), a_min(nullptr), a_ave_all(nullptr), + a_max_all(nullptr), a_min_all(nullptr), atommols(nullptr), onemols(nullptr) { energy_global_flag = energy_peratom_flag = 1; virial_global_flag = virial_peratom_flag = 1; @@ -204,8 +204,6 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : int nb = atom->nbondtypes + 1; b_count = new int[nb]; b_count_all = new int[nb]; - b_atom = new int[nb]; - b_atom_all = new int[nb]; b_ave = new double[nb]; b_ave_all = new double[nb]; b_max = new double[nb]; @@ -298,8 +296,6 @@ FixShake::~FixShake() if (output_every) { delete[] b_count; delete[] b_count_all; - delete[] b_atom; - delete[] b_atom_all; delete[] b_ave; delete[] b_ave_all; delete[] b_max; @@ -2547,7 +2543,6 @@ void FixShake::bond_force(tagint id1, tagint id2, double length) void FixShake::stats() { - int i,j,m,n,iatom,jatom,katom; double delx,dely,delz; double r,r1,r2,r3,angle; @@ -2556,13 +2551,12 @@ void FixShake::stats() int nb = atom->nbondtypes + 1; int na = atom->nangletypes + 1; - for (i = 0; i < nb; i++) { + for (int i = 0; i < nb; i++) { b_count[i] = 0; b_ave[i] = b_max[i] = 0.0; b_min[i] = BIG; - b_atom[i] = -1; } - for (i = 0; i < na; i++) { + for (int i = 0; i < na; i++) { a_count[i] = 0; a_ave[i] = a_max[i] = 0.0; a_min[i] = BIG; @@ -2574,25 +2568,26 @@ void FixShake::stats() double **x = atom->x; int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) { - if (shake_flag[i] == 0) continue; + for (int ii = 0; ii < nlist; ++ii) { + int i = list[ii]; + int n = shake_flag[i]; + if (n == 0) continue; // bond stats - n = shake_flag[i]; if (n == 1) n = 3; - iatom = atom->map(shake_atom[i][0]); - for (j = 1; j < n; j++) { - jatom = atom->map(shake_atom[i][j]); + int iatom = atom->map(shake_atom[i][0]); + for (int j = 1; j < n; j++) { + int jatom = atom->map(shake_atom[i][j]); + if (jatom >= nlocal) continue; delx = x[iatom][0] - x[jatom][0]; dely = x[iatom][1] - x[jatom][1]; delz = x[iatom][2] - x[jatom][2]; domain->minimum_image(delx,dely,delz); - r = sqrt(delx*delx + dely*dely + delz*delz); - m = shake_type[i][j-1]; + r = sqrt(delx*delx + dely*dely + delz*delz); + int m = shake_type[i][j-1]; b_count[m]++; - b_atom[m] = n; b_ave[m] += r; b_max[m] = MAX(b_max[m],r); b_min[m] = MIN(b_min[m],r); @@ -2601,9 +2596,13 @@ void FixShake::stats() // angle stats if (shake_flag[i] == 1) { - iatom = atom->map(shake_atom[i][0]); - jatom = atom->map(shake_atom[i][1]); - katom = atom->map(shake_atom[i][2]); + int iatom = atom->map(shake_atom[i][0]); + int jatom = atom->map(shake_atom[i][1]); + int katom = atom->map(shake_atom[i][2]); + int n = 0; + if (iatom < nlocal) ++n; + if (jatom < nlocal) ++n; + if (katom < nlocal) ++n; delx = x[iatom][0] - x[jatom][0]; dely = x[iatom][1] - x[jatom][1]; @@ -2625,9 +2624,9 @@ void FixShake::stats() angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2)); angle *= 180.0/MY_PI; - m = shake_type[i][2]; - a_count[m]++; - a_ave[m] += angle; + int m = shake_type[i][2]; + a_count[m] += n; + a_ave[m] += n*angle; a_max[m] = MAX(a_max[m],angle); a_min[m] = MIN(a_min[m],angle); } @@ -2636,7 +2635,6 @@ void FixShake::stats() // sum across all procs MPI_Allreduce(b_count,b_count_all,nb,MPI_INT,MPI_SUM,world); - MPI_Allreduce(b_atom,b_atom_all,nb,MPI_INT,MPI_MAX,world); MPI_Allreduce(b_ave,b_ave_all,nb,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(b_max,b_max_all,nb,MPI_DOUBLE,MPI_MAX,world); MPI_Allreduce(b_min,b_min_all,nb,MPI_DOUBLE,MPI_MIN,world); @@ -2652,13 +2650,13 @@ void FixShake::stats() const int width = log10((MAX(MAX(1,nb),na)))+2; auto mesg = fmt::format("{} stats (type/ave/delta/count) on step {}\n", utils::uppercase(style), update->ntimestep); - for (i = 1; i < nb; i++) { + for (int i = 1; i < nb; i++) { const auto bcnt = b_count_all[i]; if (bcnt) mesg += fmt::format("Bond: {:>{}d} {:<9.6} {:<11.6} {:>8d}\n",i,width, - b_ave_all[i]/bcnt,b_max_all[i]-b_min_all[i],bcnt/b_atom_all[i]); + b_ave_all[i]/bcnt,b_max_all[i]-b_min_all[i],bcnt); } - for (i = 1; i < na; i++) { + for (int i = 1; i < na; i++) { const auto acnt = a_count_all[i]; if (acnt) mesg += fmt::format("Angle: {:>{}d} {:<9.6} {:<11.6} {:>8d}\n",i,width, diff --git a/src/RIGID/fix_shake.h b/src/RIGID/fix_shake.h index d6f9a8f5d6..820d68ebe7 100644 --- a/src/RIGID/fix_shake.h +++ b/src/RIGID/fix_shake.h @@ -113,8 +113,7 @@ class FixShake : public Fix { int nlist, maxlist; // size and max-size of list // stat quantities - int *b_count, *b_count_all, *b_atom, - *b_atom_all; // counts for each bond type, atoms in bond cluster + int *b_count, *b_count_all; // counts for each bond type, atoms in bond cluster double *b_ave, *b_max, *b_min; // ave/max/min dist for each bond type double *b_ave_all, *b_max_all, *b_min_all; // MPI summing arrays int *a_count, *a_count_all; // ditto for angle types From c4a76103667823d30ce4ce1b4d89ff90889270a0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 10 Jun 2022 11:07:50 -0400 Subject: [PATCH 064/443] update docs and include suggestions --- doc/src/fix_shake.rst | 56 ++++++++++++--------- doc/utils/sphinx-config/false_positives.txt | 1 + 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/doc/src/fix_shake.rst b/doc/src/fix_shake.rst index 137cb1aedb..4ba2eb7f4d 100644 --- a/doc/src/fix_shake.rst +++ b/doc/src/fix_shake.rst @@ -168,13 +168,17 @@ See the :doc:`molecule ` command for details. The only settings required to be in this file (by this command) are the SHAKE info of atoms in the molecule. -The *kbond* keyword allows to set the restraint force constant when fix -shake or fix rattle are used during minimization. In that case the -constraint algorithms are *not* applied and restraint forces are used -instead to help maintaining the geometries. How well the geometries -are maintained and how quickly a minimization will converge depends on -the magnitude of the force constant (kbond). If it is chosen too large -the minimization may converge slowly. The default is 1.0e6*k_B. +The *kbond* keyword sets the restraint force constant when fix shake or +fix rattle are used during minimization. In that case the constraint +algorithms are *not* applied and restraint forces are used instead to +maintain the geometries similar to the constraints. How well the +geometries are maintained and how quickly a minimization converges, +depends on the force constant *kbond*: larger values will reduce the +deviation from the desired geometry, but can also lead to slower +convergence of the minimization or lead to instabilities depending on +the minimization algorithm requiring to reduce the value of +:doc:`timestep `. The default value for *kbond* depends on +the :doc:`units ` setting and is 1.0e6*k_B. ---------- @@ -190,7 +194,7 @@ LAMMPS closely follows (:ref:`Andersen (1983) `). .. note:: - The fix rattle command modifies forces and velocities and thus + The *fix rattle* command modifies forces and velocities and thus should be defined after all other integration fixes in your input script. If you define other fixes that modify velocities or forces after fix rattle operates, then fix rattle will not take them into @@ -207,24 +211,28 @@ Restart, fix_modify, output, run start/stop, minimize info No information about these fixes is written to :doc:`binary restart files `. -When used during minimization, the SHAKE or RATTLE algorithms are **not** -applied. Strong restraint forces are applied instead. +Fix *shake* and *rattle* behave differently during minimization and +during a molecular dynamics run. -The :doc:`fix_modify ` *virial* option is supported by -these fixes to add the contribution due to the added forces on atoms -to both the global pressure and per-atom stress of the system via the -:doc:`compute pressure ` and :doc:`compute -stress/atom ` commands. The former can be -accessed by :doc:`thermodynamic output `. The default -setting for this fix is :doc:`fix_modify virial yes `. -During minimization, the virial contribution is *NOT* available. +When used during minimization, the SHAKE or RATTLE algorithms are +**not** applied. The constraints are replaced by restraint forces +instead. The energy due to restraint forces is included in the global +potential energy, but virial contributions from them are not included in +the global pressure. The restraint energy is also accessible as a +global scalar property of the fix. -No global or per-atom quantities are stored by these fixes for access by -various :doc:`output commands ` during a run. During -minimization, this fix computes a global scalar which is the energy of -the restraint forces applied insteat of the constraints. No parameter -of these fixes can be used with the *start/stop* keywords of the -:doc:`run ` command. +During molecular dynamics runs, the fixes apply the requested +constraints. The :doc:`fix_modify ` *virial* option is in +this case supported by these fixes to add the contribution due to the +added constraint forces on atoms to both the global pressure and +per-atom stress of the system via the :doc:`compute pressure +` and :doc:`compute stress/atom ` +commands. The former can be accessed by :doc:`thermodynamic output +`. The default setting for this fix is :doc:`fix_modify +virial yes `. No global or per-atom quantities are stored by +these fixes for access by various :doc:`output commands ` +during a run. No parameter of these fixes can be used with the +*start/stop* keywords of the :doc:`run ` command. Restrictions diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index b42cff262a..ff1d17ee07 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1609,6 +1609,7 @@ kb kB kbit kbits +kbond kcal kcl Kd From f05fcaf0d5f8b086a0deaf07839bd8c1686ba68e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 17 Jun 2022 05:31:42 -0400 Subject: [PATCH 065/443] change energy tally during minimize --- src/RIGID/fix_shake.cpp | 45 ++++++++++++++++++++++++++-- src/RIGID/fix_shake.h | 3 ++ src/compute_pe_atom.cpp | 66 ++++++++++++++++++++++------------------- 3 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index c284d99011..5b2cc7a33a 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -67,6 +67,11 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : centroidstressflag = CENTROID_AVAIL; next_output = -1; + // to avoid uninitialized access + vflag_post_force = 0; + eflag_pre_reverse = 0; + ebond = 0.0; + // error check molecular = atom->molecular; @@ -324,6 +329,7 @@ int FixShake::setmask() mask |= PRE_NEIGHBOR; mask |= POST_FORCE; mask |= POST_FORCE_RESPA; + mask |= MIN_PRE_REVERSE; mask |= MIN_POST_FORCE; mask |= POST_RUN; return mask; @@ -505,6 +511,13 @@ void FixShake::min_setup(int vflag) min_post_force(vflag); } +/* --------------------------------------------------------------------- */ + +void FixShake::setup_pre_reverse(int eflag, int vflag) +{ + min_pre_reverse(eflag,vflag); +} + /* ---------------------------------------------------------------------- build list of SHAKE clusters to constrain if one or more atoms in cluster are on this proc, @@ -513,6 +526,7 @@ void FixShake::min_setup(int vflag) void FixShake::pre_neighbor() { + ebond = 0.0; int atom1,atom2,atom3,atom4; // local copies of atom quantities @@ -653,6 +667,15 @@ void FixShake::post_force_respa(int vflag, int ilevel, int iloop) vflag_post_force = vflag; } +/* ---------------------------------------------------------------------- + store eflag so it can be used in min_post_force +------------------------------------------------------------------------- */ + +void FixShake::min_pre_reverse(int eflag, int /*vflag*/) +{ + eflag_pre_reverse = eflag; +} + /* ---------------------------------------------------------------------- substitute shake constraints with very strong bonds ------------------------------------------------------------------------- */ @@ -668,6 +691,9 @@ void FixShake::min_post_force(int vflag) next_output = (ntimestep/output_every)*output_every + output_every; } else next_output = -1; + int eflag = eflag_pre_reverse; + ev_init(eflag, vflag); + x = atom->x; f = atom->f; nlocal = atom->nlocal; @@ -2522,18 +2548,33 @@ void FixShake::bond_force(tagint id1, tagint id2, double length) const double dr = r - length; const double rk = kbond * dr; const double fbond = (r > 0.0) ? -2.0 * rk / r : 0.0; + const double eb = rk*dr; + int list[2]; + int nlist = 0; if (i1 < nlocal) { f[i1][0] += delx * fbond; f[i1][1] += dely * fbond; f[i1][2] += delz * fbond; - ebond += 0.5*rk*dr; + list[nlist++] = i1; + ebond += 0.5*eb; } if (i2 < nlocal) { f[i2][0] -= delx * fbond; f[i2][1] -= dely * fbond; f[i2][2] -= delz * fbond; - ebond += 0.5*rk*dr; + list[nlist++] = i2; + ebond += 0.5*eb; + } + if (evflag) { + double v[6]; + v[0] = 0.5 * delx * delx * fbond; + v[1] = 0.5 * dely * dely * fbond; + v[2] = 0.5 * delz * delz * fbond; + v[3] = 0.5 * delx * dely * fbond; + v[4] = 0.5 * delx * delz * fbond; + v[5] = 0.5 * dely * delz * fbond; + ev_tally(nlist, list, 2.0, eb, v); } } diff --git a/src/RIGID/fix_shake.h b/src/RIGID/fix_shake.h index 820d68ebe7..914b73ea34 100644 --- a/src/RIGID/fix_shake.h +++ b/src/RIGID/fix_shake.h @@ -34,10 +34,12 @@ class FixShake : public Fix { int setmask() override; void init() override; void setup(int) override; + void setup_pre_reverse(int, int) override; void min_setup(int) override; void pre_neighbor() override; void post_force(int) override; void post_force_respa(int, int, int) override; + void min_pre_reverse(int, int) override; void min_post_force(int) override; void post_run() override; @@ -64,6 +66,7 @@ class FixShake : public Fix { protected: int vflag_post_force; // store the vflag of last post_force call + int eflag_pre_reverse; // store the eflag of last pre_reverse call int respa; // 0 = vel. Verlet, 1 = respa int rattle; // 0 = SHAKE, 1 = RATTLE double tolerance; // SHAKE tolerance diff --git a/src/compute_pe_atom.cpp b/src/compute_pe_atom.cpp index a627e133e5..b1b62ec16d 100644 --- a/src/compute_pe_atom.cpp +++ b/src/compute_pe_atom.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -13,30 +12,31 @@ ------------------------------------------------------------------------- */ #include "compute_pe_atom.h" -#include -#include "atom.h" -#include "update.h" -#include "comm.h" -#include "force.h" -#include "pair.h" -#include "bond.h" + #include "angle.h" +#include "atom.h" +#include "bond.h" +#include "comm.h" #include "dihedral.h" +#include "error.h" +#include "force.h" #include "improper.h" #include "kspace.h" -#include "modify.h" #include "memory.h" -#include "error.h" +#include "modify.h" +#include "pair.h" +#include "update.h" + +#include using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputePEAtom::ComputePEAtom(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - energy(nullptr) + Compute(lmp, narg, arg), energy(nullptr) { - if (narg < 3) error->all(FLERR,"Illegal compute pe/atom command"); + if (narg < 3) error->all(FLERR, "Illegal compute pe/atom command"); peratom_flag = 1; size_peratom_cols = 0; @@ -56,14 +56,22 @@ ComputePEAtom::ComputePEAtom(LAMMPS *lmp, int narg, char **arg) : fixflag = 0; int iarg = 3; while (iarg < narg) { - if (strcmp(arg[iarg],"pair") == 0) pairflag = 1; - else if (strcmp(arg[iarg],"bond") == 0) bondflag = 1; - else if (strcmp(arg[iarg],"angle") == 0) angleflag = 1; - else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1; - else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1; - else if (strcmp(arg[iarg],"kspace") == 0) kspaceflag = 1; - else if (strcmp(arg[iarg],"fix") == 0) fixflag = 1; - else error->all(FLERR,"Illegal compute pe/atom command"); + if (strcmp(arg[iarg], "pair") == 0) + pairflag = 1; + else if (strcmp(arg[iarg], "bond") == 0) + bondflag = 1; + else if (strcmp(arg[iarg], "angle") == 0) + angleflag = 1; + else if (strcmp(arg[iarg], "dihedral") == 0) + dihedralflag = 1; + else if (strcmp(arg[iarg], "improper") == 0) + improperflag = 1; + else if (strcmp(arg[iarg], "kspace") == 0) + kspaceflag = 1; + else if (strcmp(arg[iarg], "fix") == 0) + fixflag = 1; + else + error->all(FLERR, "Illegal compute pe/atom command"); iarg++; } } @@ -86,7 +94,7 @@ void ComputePEAtom::compute_peratom() invoked_peratom = update->ntimestep; if (update->eflag_atom != invoked_peratom) - error->all(FLERR,"Per-atom energy was not tallied on needed timestep"); + error->all(FLERR, "Per-atom energy was not tallied on needed timestep"); // grow local energy array if necessary // needs to be atom->nmax in length @@ -94,7 +102,7 @@ void ComputePEAtom::compute_peratom() if (atom->nmax > nmax) { memory->destroy(energy); nmax = atom->nmax; - memory->create(energy,nmax,"pe/atom:energy"); + memory->create(energy, nmax, "pe/atom:energy"); vector_atom = energy; } @@ -153,13 +161,11 @@ void ComputePEAtom::compute_peratom() // add in per-atom contributions from relevant fixes // always only for owned atoms, not ghost - if (fixflag && modify->n_energy_atom) - modify->energy_atom(nlocal,energy); + if (fixflag && modify->n_energy_atom) modify->energy_atom(nlocal, energy); // communicate ghost energy between neighbor procs - if (force->newton || (force->kspace && force->kspace->tip4pflag)) - comm->reverse_comm(this); + if (force->newton || (force->kspace && force->kspace->tip4pflag)) comm->reverse_comm(this); // zero energy of atoms not in group // only do this after comm since ghost contributions must be included @@ -174,7 +180,7 @@ void ComputePEAtom::compute_peratom() int ComputePEAtom::pack_reverse_comm(int n, int first, double *buf) { - int i,m,last; + int i, m, last; m = 0; last = first + n; @@ -186,7 +192,7 @@ int ComputePEAtom::pack_reverse_comm(int n, int first, double *buf) void ComputePEAtom::unpack_reverse_comm(int n, int *list, double *buf) { - int i,j,m; + int i, j, m; m = 0; for (i = 0; i < n; i++) { @@ -201,6 +207,6 @@ void ComputePEAtom::unpack_reverse_comm(int n, int *list, double *buf) double ComputePEAtom::memory_usage() { - double bytes = (double)nmax * sizeof(double); + double bytes = (double) nmax * sizeof(double); return bytes; } From 0ad45a02249d6c60e2c80a34330fb76f08f6f620 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 17 Jun 2022 05:53:34 -0400 Subject: [PATCH 066/443] correctly produce eatom (=0) for MD runs --- src/RIGID/fix_shake.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 5b2cc7a33a..6673472458 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -601,7 +601,8 @@ void FixShake::post_force(int vflag) // virial setup - v_init(vflag); + int eflag = eflag_pre_reverse; + ev_init(eflag, vflag); ebond = 0.0; // loop over clusters to add constraint forces From e66229dadb61f60c784c7f1863331a6afefcf4de Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 17 Jun 2022 06:19:57 -0400 Subject: [PATCH 067/443] update docs --- doc/src/fix_shake.rst | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/doc/src/fix_shake.rst b/doc/src/fix_shake.rst index 4ba2eb7f4d..b53f8602ec 100644 --- a/doc/src/fix_shake.rst +++ b/doc/src/fix_shake.rst @@ -216,23 +216,25 @@ during a molecular dynamics run. When used during minimization, the SHAKE or RATTLE algorithms are **not** applied. The constraints are replaced by restraint forces -instead. The energy due to restraint forces is included in the global -potential energy, but virial contributions from them are not included in -the global pressure. The restraint energy is also accessible as a -global scalar property of the fix. +instead. The energy and virial contributions due to the restraint +forces are tallied into global and per-atom accumulators. The total +restraint energy is also accessible as a global scalar property of the +fix. During molecular dynamics runs, the fixes apply the requested -constraints. The :doc:`fix_modify ` *virial* option is in -this case supported by these fixes to add the contribution due to the -added constraint forces on atoms to both the global pressure and -per-atom stress of the system via the :doc:`compute pressure -` and :doc:`compute stress/atom ` -commands. The former can be accessed by :doc:`thermodynamic output -`. The default setting for this fix is :doc:`fix_modify -virial yes `. No global or per-atom quantities are stored by -these fixes for access by various :doc:`output commands ` -during a run. No parameter of these fixes can be used with the -*start/stop* keywords of the :doc:`run ` command. +constraints. + +The :doc:`fix_modify ` *virial* option is supported by these +fixes to add the contribution due to the added constraint forces on +atoms to both the global pressure and per-atom stress of the system via +the :doc:`compute pressure ` and :doc:`compute +stress/atom ` commands. The former can be accessed +by :doc:`thermodynamic output `. The default setting for +this fix is :doc:`fix_modify virial yes `. No global or +per-atom quantities are stored by these fixes for access by various +:doc:`output commands ` during an MD run. No parameter of +these fixes can be used with the *start/stop* keywords of the :doc:`run +` command. Restrictions @@ -256,6 +258,11 @@ degrees (e.g. linear CO2 molecule). This causes numeric difficulties. You can use :doc:`fix rigid or fix rigid/small ` instead to make a linear molecule rigid. +When used during minimization choosing a too large value of the *kbond* +can make minimization very inefficent and also cause stability problems +with some minimization algorithms. Sometimes those can be avoided by +reducing the :doc:`timestep `. + Related commands """""""""""""""" From 114b19f620b3d7904cfe9bb5cbf1a1621767bd40 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 23 Jun 2022 06:51:13 -0400 Subject: [PATCH 068/443] make certain that the fix energy is properly reset to zero --- src/KOKKOS/fix_shake_kokkos.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index 5ed8cfccb3..40f641780a 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -192,6 +192,7 @@ void FixShakeKokkos::pre_neighbor() // local copies of atom quantities // used by SHAKE until next re-neighboring + ebond = 0.0; x = atom->x; v = atom->v; f = atom->f; @@ -302,6 +303,7 @@ void FixShakeKokkos::pre_neighbor() template void FixShakeKokkos::post_force(int vflag) { + ebond = 0.0; copymode = 1; d_x = atomKK->k_x.view(); From 6ecf738b08b04bb5817d9ca3f2180ca9d27a9baa Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Tue, 12 Jul 2022 11:32:32 +0100 Subject: [PATCH 069/443] self-chain interactions added with cutoff --- src/MESONT/pair_mesocnt.cpp | 117 +++++++++++------------- src/MESONT/pair_mesocnt.h | 4 +- src/MESONT/pair_mesocnt_viscous.cpp | 134 +++++++++++++++------------- 3 files changed, 128 insertions(+), 127 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 4e5d06e732..6951a135ad 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -41,10 +41,10 @@ using namespace MathConst; using namespace MathExtra; #define MAXLINE 1024 -#define SELF_CUTOFF 20 +#define SELF_CUTOFF 3 #define SMALL 1.0e-6 #define SWITCH 1.0e-6 -#define QUADRATURE 10 +#define QUADRATURE 1000 #define RHOMIN 10.0 /* ---------------------------------------------------------------------- */ @@ -86,6 +86,9 @@ PairMesoCNT::~PairMesoCNT() memory->destroy(endlist); memory->destroy(chainlist); + memory->destroy(selfid); + memory->destroy(selfpos); + memory->destroy(w); memory->destroy(wnode); memory->destroy(dq_w); @@ -172,8 +175,22 @@ void PairMesoCNT::compute(int eflag, int vflag) } } - if (buckled || endflag == 3) { + if (buckled || j == selfid[i] || endflag == 3) { for (k = 0; k < clen - 1; k++) { + + // exclude SELF_CUTOFF neighbors in self-chain + + int min11 = abs(k - selfpos[i][0]); + int min12 = abs(k - selfpos[i][1]); + int min21 = abs(k + 1 - selfpos[i][0]); + int min22 = abs(k + 1 - selfpos[i][1]); + int min = min11; + if (min12 < min) min = min12; + if (min21 < min) min = min21; + if (min22 < min) min = min22; + + if (min < SELF_CUTOFF) continue; + j1 = chain[j][k]; j2 = chain[j][k + 1]; j1 &= NEIGHMASK; @@ -635,6 +652,9 @@ void PairMesoCNT::allocate() memory->create(endlist, init_size, init_size, "pair:endlist"); memory->create(chainlist, init_size, init_size, init_size, "pair:chainlist"); + memory->create(selfid, init_size, "pair:selfid"); + memory->create(selfpos, init_size, 2, "pair:selfpos"); + memory->create(w, init_size, "pair:w"); memory->create(wnode, init_size, "pair:wnode"); memory->create(dq_w, init_size, 3, "pair:dq_w"); @@ -783,11 +803,6 @@ void PairMesoCNT::bond_neigh() } } - if (comm->me == 379) { - printf("rank %d created special_local\n", comm->me); - fflush(stdout); - } - int *numneigh = list->numneigh; int *numneigh_max; memory->create(numneigh_max, nbondlist, "pair:numneigh_max"); @@ -822,11 +837,6 @@ void PairMesoCNT::bond_neigh() int i2 = bondlist[i][1]; neigh_common(i1, i2, reduced_nlist[i], reduced_neighlist[i]); } - - if (comm->me == 379) { - printf("rank %d created common neighbor list\n", comm->me); - fflush(stdout); - } // resize chain arrays @@ -835,24 +845,19 @@ void PairMesoCNT::bond_neigh() memory->destroy(endlist); memory->destroy(chainlist); + memory->grow(selfid, nbondlist, "pair:selfid"); + memory->grow(selfpos, nbondlist, 2, "pair:selfpos"); + // split neighbor list into neighbor chains based on bond topology - int *selfid; int **chainid, **chainpos; memory->create_ragged(chainid, nbondlist, reduced_nlist, "pair:chainid"); memory->create_ragged(chainpos, nbondlist, reduced_nlist, "pair:chainpos"); - memory->create(selfid, nbondlist, "pair:selfid"); memory->create(numchainlist, nbondlist, "pair:numchainlist"); bool empty_neigh = true; for (int i = 0; i < nbondlist; i++) { - if (comm->me == 379) { - printf("rank %d, splitting chains for bond %d (%d %d)\n", comm->me, i, atom->tag[bondlist[i][0]], atom->tag[bondlist[i][1]]); - printf("reduced_nlist: %d\n", reduced_nlist[i]); - fflush(stdout); - } - numchainlist[i] = 0; if (reduced_nlist[i] == 0) continue; @@ -863,11 +868,6 @@ void PairMesoCNT::bond_neigh() reduced_map[reduced_neighlist[i][j]] = j; chainid[i][j] = -1; } - - if (comm->me == 379) { - printf("reduced map created\n"); - fflush(stdout); - } // assign chain ids and positions @@ -882,8 +882,14 @@ void PairMesoCNT::bond_neigh() chainid[i][j] = numchainlist[i]; chainpos[i][j] = 0; - if (reduced_neighlist[i][j] == bondlist[i][0]) + if (reduced_neighlist[i][j] == bondlist[i][0]) { selfid[i] = numchainlist[i]; + selfpos[i][0] = 0; + } + else if (reduced_neighlist[i][j] == bondlist[i][1]) { + selfid[i] = numchainlist[i]; + selfpos[i][1] = 0; + } int curr_local, next_local; int curr_reduced, next_reduced; @@ -917,22 +923,21 @@ void PairMesoCNT::bond_neigh() next_local = special_local[next_local][1]; } - if (curr_local == bondlist[i][0]) + if (curr_local == bondlist[i][0]) { selfid[i] = numchainlist[i]; + selfpos[i][0] = chainpos[i][next_reduced]; + } + else if (curr_local == bondlist[i][1]) { + selfid[i] = numchainlist[i]; + selfpos[i][1] = chainpos[i][next_reduced]; + } } } - numchainlist[i]++; } - numchainlist[i]--; if (numchainlist[i]) empty_neigh = false; } - if (comm->me == 379) { - printf("rank %d split chains\n", comm->me); - fflush(stdout); - } - memory->destroy(special_local); // count neighbor chain lengths per bond @@ -951,16 +956,9 @@ void PairMesoCNT::bond_neigh() for (int j = 0; j < reduced_nlist[i]; j++) { int cid = chainid[i][j]; - if (cid < selfid[i]) { - int cpos = chainpos[i][j]; - if (cpos < chainpos_min[i][cid]) chainpos_min[i][cid] = cpos; - if (cpos > chainpos_max[i][cid]) chainpos_max[i][cid] = cpos; - } - else if (cid > selfid[i]) { - int cpos = chainpos[i][j]; - if (cpos < chainpos_min[i][cid - 1]) chainpos_min[i][cid - 1] = cpos; - if (cpos > chainpos_max[i][cid - 1]) chainpos_max[i][cid - 1] = cpos; - } + int cpos = chainpos[i][j]; + if (cpos < chainpos_min[i][cid]) chainpos_min[i][cid] = cpos; + if (cpos > chainpos_max[i][cid]) chainpos_max[i][cid] = cpos; } for (int j = 0; j < numchainlist[i]; j++) { @@ -969,11 +967,6 @@ void PairMesoCNT::bond_neigh() if (clen > nchain_max) nchain_max = clen; } } - - if (comm->me == 379) { - printf("rank %d counted neighbor chain lengths\n", comm->me); - fflush(stdout); - } // create connected neighbor chains and check for ends // MEMORY: prevent zero-size array creation for chainlist @@ -986,18 +979,17 @@ void PairMesoCNT::bond_neigh() for (int i = 0; i < nbondlist; i++) { + // shift selfpos + + selfpos[i][0] -= chainpos_min[i][selfid[i]]; + selfpos[i][1] -= chainpos_min[i][selfid[i]]; + // sort atoms into chain lists for (int j = 0; j < reduced_nlist[i]; j++) { int cid = chainid[i][j]; - if (cid < selfid[i]) { - int cpos = chainpos[i][j] - chainpos_min[i][cid]; - chainlist[i][cid][cpos] = reduced_neighlist[i][j]; - } - else if (cid > selfid[i]){ - int cpos = chainpos[i][j] - chainpos_min[i][cid - 1]; - chainlist[i][cid - 1][cpos] = reduced_neighlist[i][j]; - } + int cpos = chainpos[i][j] - chainpos_min[i][cid]; + chainlist[i][cid][cpos] = reduced_neighlist[i][j]; } // check for ends @@ -1016,11 +1008,6 @@ void PairMesoCNT::bond_neigh() else endlist[i][j] = 0; } } - - if (comm->me == 379) { - printf("rank %d created chain and end list\n", comm->me); - fflush(stdout); - } // destroy remaining temporary arrays for chain creation @@ -1033,7 +1020,6 @@ void PairMesoCNT::bond_neigh() memory->destroy(chainpos); memory->destroy(numneigh_max); - memory->destroy(selfid); // resize potential arrays @@ -1988,6 +1974,9 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) double dpsi_phibar2 = dyspline(h, psi2, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + if (psi1 < 0 || psi2 < 0) + printf("outside interpolation range!\n"); + double dzeta_range = dzetamax - dzetamin; double dh_psi1 = -zeta_range_inv * (dzetamin + dzeta_range * psi1); double dh_psi2 = -zeta_range_inv * (dzetamin + dzeta_range * psi2); diff --git a/src/MESONT/pair_mesocnt.h b/src/MESONT/pair_mesocnt.h index b1031ba85a..e4e182283d 100644 --- a/src/MESONT/pair_mesocnt.h +++ b/src/MESONT/pair_mesocnt.h @@ -38,8 +38,8 @@ class PairMesoCNT : public Pair { protected: int nend_types; int uinf_points, gamma_points, phi_points, usemi_points; - int *end_types, *reduced_nlist, *numchainlist; - int **reduced_neighlist, **nchainlist, **endlist, **modelist; + int *end_types, *reduced_nlist, *numchainlist, *selfid; + int **reduced_neighlist, **nchainlist, **endlist, **selfpos; int ***chainlist; double ang, ang_inv, eunit, funit; diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 04e162fc31..0adf5f7075 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -31,10 +31,13 @@ #include #include +#include + using namespace LAMMPS_NS; using namespace MathConst; using namespace MathExtra; +#define SELF_CUTOFF 3 #define RHOMIN 10.0 /* ---------------------------------------------------------------------- */ @@ -118,13 +121,27 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) } } - if (buckled || endflag == 3) { + if (buckled || j == selfid[i] || endflag == 3) { zero3(vp1); zero3(vp2); sumw = 0.0; for (k = 0; k < clen - 1; k++) { + + // exclude SELF_CUTOFF neighbors in self-chain + + int min11 = abs(k - selfpos[i][0]); + int min12 = abs(k - selfpos[i][1]); + int min21 = abs(k + 1 - selfpos[i][0]); + int min22 = abs(k + 1 - selfpos[i][1]); + int min = min11; + if (min12 < min) min = min12; + if (min21 < min) min = min21; + if (min22 < min) min = min22; + + if (min < SELF_CUTOFF) continue; + j1 = chain[j][k]; j2 = chain[j][k + 1]; j1 &= NEIGHMASK; @@ -206,6 +223,10 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) printf("%f %f %f\n", q1[0], q1[1], q1[2]); printf("%f %f %f\n", q2[0], q2[1], q2[2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); + + finf(param, evdwl, flocal); + printf("finf equivalent energy: %f\n", evdwl); + fsemi(param, evdwl, fend, flocal); } if (evdwl == 0.0) continue; @@ -259,6 +280,7 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) copy3(q1, rcopy[2]); copy3(q2, rcopy[3]); + /* if (flip) { printf("flipped param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); printf("flipped p %f %f %f\n", p[0], p[1], p[2]); @@ -275,9 +297,10 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) printf("true basis 2 %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); printf("true basis 3 %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); } + */ double dx = 1.0e-8; - printf("First contribution:\n"); + printf("First contribution (flip = %d):\n", flip); for (int k1 = 0; k1 < 4; k1++) { for (int k2 = 0; k2 < 3; k2++) { double ehi, elo; @@ -296,26 +319,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) printf("fglobal %d: %f %f %f\n", k1, fglobal[k1][0], fglobal[k1][1], fglobal[k1][2]); printf("fnum %d: %f %f %f\n", k1, fnum[k1][0], fnum[k1][1], fnum[k1][2]); } + /* if (flip) printf("flip: true\n\n"); else printf("flip: false\n\n"); - - bool nan0 = fglobal[0][0] == fglobal[0][0]; - bool nan1 = fglobal[1][0] == fglobal[1][0]; - bool nan2 = fglobal[2][0] == fglobal[2][0]; - bool nan3 = fglobal[3][0] == fglobal[3][0]; - - if (!(nan0 || nan1 || nan2 || nan3)) { - printf("nan in segment-segment 1\n"); - printf("segment 1: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("%f %f %f\n", r1[0], r1[1], r1[2]); - printf("%f %f %f\n", r2[0], r2[1], r2[2]); - printf("segment 2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); - printf("%f %f %f\n", q1[0], q1[1], q1[2]); - printf("%f %f %f\n", q2[0], q2[1], q2[2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - } + */ // add energy @@ -336,6 +345,7 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) param[6] += lp; fsemi(param, evdwl, fend, flocal); + if (evdwl > 1.0e1) { printf("high energy detected in second contribution (%f eV)\n", evdwl); printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); @@ -346,7 +356,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) printf("%f %f %f\n", q2[0], q2[1], q2[2]); printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); } - if (evdwl == 0.0) continue; @@ -435,26 +444,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) printf("fglobal %d: %f %f %f\n", k1, ftemp[k1][0], ftemp[k1][1], ftemp[k1][2]); printf("fnum %d: %f %f %f\n", k1, fnum[k1][0], fnum[k1][1], fnum[k1][2]); } + /* if (flip) printf("flip: true\n\n"); else printf("flip: false\n\n"); - - nan0 = fglobal[0][0] == fglobal[0][0]; - nan1 = fglobal[1][0] == fglobal[1][0]; - nan2 = fglobal[2][0] == fglobal[2][0]; - nan3 = fglobal[3][0] == fglobal[3][0]; - - if (!(nan0 || nan1 || nan2 || nan3)) { - printf("nan in segment-segment 2\n"); - printf("segment 1: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("%f %f %f\n", r1[0], r1[1], r1[2]); - printf("%f %f %f\n", r2[0], r2[1], r2[2]); - printf("segment 2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); - printf("%f %f %f\n", q1[0], q1[1], q1[2]); - printf("%f %f %f\n", q2[0], q2[1], q2[2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - } + */ // add energy @@ -488,11 +483,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fvisc_tot = b2 / vtot - a2; if (fvisc_tot < 0.0) zero3(fvisc); else scale3(0.25 * (1 - s(sumw)) * fvisc_tot, vrel, fvisc); - if (std::isnan(fvisc_tot)) { - printf("nan in segment-segment friction\n"); - printf("fvisc: %f %f %f\n", fvisc[0], fvisc[1], fvisc[2]); - printf("vrel: %f %f %f\n", vrel[0], vrel[1], vrel[2]); - } } // add friction forces to current segment @@ -666,6 +656,7 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (evdwl > 1.0e1) { printf("high energy detected in segment-chain interaction (%f eV)\n", evdwl); + printf("endflag: %d\n", endflag); printf("segment: %d %d\n", atom->tag[i1], atom->tag[i2]); printf("%f %f %f\n", r1[0], r1[1], r1[2]); printf("%f %f %f\n", r2[0], r2[1], r2[2]); @@ -697,11 +688,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fvisc_tot = b2 / vtot - a2; if (fvisc_tot < 0.0) zero3(fvisc); else scale3(0.25 * (1 - s(sumw)) * fvisc_tot, vrel, fvisc); - if (std::isnan(fvisc_tot)) { - printf("nan in segment-chain friction\n"); - printf("fvisc: %f %f %f\n", fvisc[0], fvisc[1], fvisc[2]); - printf("vrel: %f %f %f\n", vrel[0], vrel[1], vrel[2]); - } } add3(fvisc, f[i1], f[i1]); @@ -813,22 +799,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (endflag) scaleadd3(0.5 * fend, m, f[endindex], f[endindex]); - bool nan0 = fglobal[0][0] == fglobal[0][0]; - bool nan1 = fglobal[1][0] == fglobal[1][0]; - bool nan2 = fglobal[2][0] == fglobal[2][0]; - bool nan3 = fglobal[3][0] == fglobal[3][0]; - - if (!(nan0 || nan1 || nan2 || nan3)) { - printf("nan in segment-chain\n"); - printf("segment: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("%f %f %f\n", r1[0], r1[1], r1[2]); - printf("%f %f %f\n", r2[0], r2[1], r2[2]); - printf("chain: \n"); - for (k = 0; k < clen; k++) - printf("%d %f %f %f\n", atom->tag[chain[j][k]], x[chain[j][k]][0], x[chain[j][k]][1], x[chain[j][k]][2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - } - // compute energy if (eflag_either) { @@ -928,6 +898,48 @@ void PairMesoCNTViscous::coeff(int narg, char **arg) int ntypes = atom->ntypes; for (int i = 1; i <= ntypes; i++) for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; + + // debug output + + param[0] = 0; + param[1] = 0.5 * MY_PI; + param[4] = 0.0; + param[5] = 100.0; + param[6] = 0.0; + + int points = 1001; + double xStart = 9.0; + double xEnd = 14.0; + double xSpacing = (xEnd - xStart) / (points - 1); + double dx = 10.0; + + double evdwl, fend; + + std::ofstream finfFile("/Users/phankl/phd/tensile/finf.dat"); + std::ofstream fsemiFile("/Users/phankl/phd/tensile/fsemi.dat"); + + for (int i = 0; i < points; i++) { + double xi = xStart + i * xSpacing; + param[2] = xi; + param[3] = xi + dx; + + finf(param, evdwl, flocal); + finfFile << xi << " " << evdwl << " "; + for (int j = 0; j < 2; j++) + for (int k = 0; k < 3; k++) + finfFile << flocal[j][k] << " "; + finfFile << std::endl; + + fsemi(param, evdwl, fend, flocal); + fsemiFile << xi << " " << 2*evdwl << " "; + for (int j = 0; j < 2; j++) + for (int k = 0; k < 3; k++) + fsemiFile << 2*flocal[j][k] << " "; + fsemiFile << std::endl; + } + + finfFile.close(); + fsemiFile.close(); } /* ---------------------------------------------------------------------- From c5c565195d09500d830df8afaab04175438cd2f7 Mon Sep 17 00:00:00 2001 From: Philipp Kloza Date: Tue, 12 Jul 2022 11:34:23 +0100 Subject: [PATCH 070/443] removed unused case in angle_mesocnt --- src/MESONT/angle_mesocnt.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp index ede39d8e3c..706adcbaac 100644 --- a/src/MESONT/angle_mesocnt.cpp +++ b/src/MESONT/angle_mesocnt.cpp @@ -128,8 +128,7 @@ void AngleMesoCNT::compute(int eflag, int vflag) // bending buckling else { if (eflag) eangle = kb[type] * fabs(dtheta) + thetab[type] * (kh[type] * thetab[type] - kb[type]); - if (dtheta < 0) a = kb[type] * s; - else a = -kb[type] * s; + a = kb[type] * s; buckled[i2] = 1; } From 07c75021bba90846cc7b076febd1f54dde033652 Mon Sep 17 00:00:00 2001 From: phankl Date: Tue, 12 Jul 2022 19:54:25 +0100 Subject: [PATCH 071/443] removed numerical differentiation + flip messages, fixed bug in self skip --- src/MESONT/pair_mesocnt.cpp | 20 ++-- src/MESONT/pair_mesocnt_viscous.cpp | 163 +++++----------------------- 2 files changed, 38 insertions(+), 145 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 6951a135ad..4f06b4f3e1 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -180,16 +180,18 @@ void PairMesoCNT::compute(int eflag, int vflag) // exclude SELF_CUTOFF neighbors in self-chain - int min11 = abs(k - selfpos[i][0]); - int min12 = abs(k - selfpos[i][1]); - int min21 = abs(k + 1 - selfpos[i][0]); - int min22 = abs(k + 1 - selfpos[i][1]); - int min = min11; - if (min12 < min) min = min12; - if (min21 < min) min = min21; - if (min22 < min) min = min22; + if (j == selfid[i]) { + int min11 = abs(k - selfpos[i][0]); + int min12 = abs(k - selfpos[i][1]); + int min21 = abs(k + 1 - selfpos[i][0]); + int min22 = abs(k + 1 - selfpos[i][1]); + int min = min11; + if (min12 < min) min = min12; + if (min21 < min) min = min21; + if (min22 < min) min = min22; - if (min < SELF_CUTOFF) continue; + if (min < SELF_CUTOFF) continue; + } j1 = chain[j][k]; j2 = chain[j][k + 1]; diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 0adf5f7075..e9e50b047d 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -131,17 +131,19 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) // exclude SELF_CUTOFF neighbors in self-chain - int min11 = abs(k - selfpos[i][0]); - int min12 = abs(k - selfpos[i][1]); - int min21 = abs(k + 1 - selfpos[i][0]); - int min22 = abs(k + 1 - selfpos[i][1]); - int min = min11; - if (min12 < min) min = min12; - if (min21 < min) min = min21; - if (min22 < min) min = min22; + if (j == selfid[i]) { + int min11 = abs(k - selfpos[i][0]); + int min12 = abs(k - selfpos[i][1]); + int min21 = abs(k + 1 - selfpos[i][0]); + int min22 = abs(k + 1 - selfpos[i][1]); + int min = min11; + if (min12 < min) min = min12; + if (min21 < min) min = min21; + if (min22 < min) min = min22; + + if (min < SELF_CUTOFF) continue; + } - if (min < SELF_CUTOFF) continue; - j1 = chain[j][k]; j2 = chain[j][k + 1]; j1 &= NEIGHMASK; @@ -181,8 +183,9 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (ceta < param[2]) dsq2 += pow(ceta - param[2], 2); else if (ceta > param[3]) dsq2 += pow(ceta - param[3], 2); - if (dsq1 > cutoffsq && dsq2 > cutoffsq) continue; - + bool skip = false; + if (dsq1 > cutoffsq && dsq2 > cutoffsq) skip = true;// continue; + int jj1, jj2; // do flip if necessary @@ -213,7 +216,10 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) // first force contribution - fsemi(param, evdwl, fend, flocal); + fsemi(param, evdwl, fend, flocal); + + if (skip && fabs(evdwl) > 1.0e-3) printf("Incorrect skip in segment-segment: %f eV\n", evdwl); + if (evdwl > 1.0e1) { printf("high energy detected in first contribution (%f eV)\n", evdwl); printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); @@ -262,69 +268,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) scaleadd3(0.5, fglobal[2], f[jj1], f[jj1]); scaleadd3(0.5, fglobal[3], f[jj2], f[jj2]); scaleadd3(0.5 * fend, m, f[jj1], f[jj1]); - - double fnum[4][3]; - double rnum[4][3], rcopy[4][3]; - double mtemp[3]; - - q1 = x[jj1]; - q2 = x[jj2]; - - copy3(r1, rnum[0]); - copy3(r2, rnum[1]); - copy3(q1, rnum[2]); - copy3(q2, rnum[3]); - - copy3(r1, rcopy[0]); - copy3(r2, rcopy[1]); - copy3(q1, rcopy[2]); - copy3(q2, rcopy[3]); - - /* - if (flip) { - printf("flipped param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - printf("flipped p %f %f %f\n", p[0], p[1], p[2]); - printf("flipped m %f %f %f\n", m[0], m[1], m[2]); - printf("flipped basis 1 %f %f %f\n", basis[0][0], basis[0][1], basis[0][2]); - printf("flipped basis 2 %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); - printf("flipped basis 3 %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); - - geometry(r1, r2, q1, q2, q1, p, m, param, basis); - printf("true param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - printf("true p %f %f %f\n", p[0], p[1], p[2]); - printf("true m %f %f %f\n", m[0], m[1], m[2]); - printf("true basis 1 %f %f %f\n", basis[0][0], basis[0][1], basis[0][2]); - printf("true basis 2 %f %f %f\n", basis[1][0], basis[1][1], basis[1][2]); - printf("true basis 3 %f %f %f\n\n", basis[2][0], basis[2][1], basis[2][2]); - } - */ - - double dx = 1.0e-8; - printf("First contribution (flip = %d):\n", flip); - for (int k1 = 0; k1 < 4; k1++) { - for (int k2 = 0; k2 < 3; k2++) { - double ehi, elo; - rnum[k1][k2] = rcopy[k1][k2] + dx; - geometry(rnum[0], rnum[1], rnum[2], rnum[3], rnum[2], p, mtemp, param, basis); - fsemi(param, ehi, fend, flocal); - rnum[k1][k2] = rcopy[k1][k2] - dx; - geometry(rnum[0], rnum[1], rnum[2], rnum[3], rnum[2], p, mtemp, param, basis); - fsemi(param, elo, fend, flocal); - - fnum[k1][k2] = 0.5 * (elo - ehi) / dx; - } - if (k1 == 2) - printf("fglobal %d: %f %f %f\n", k1, fglobal[k1][0]+fend*m[0], fglobal[k1][1]+fend*m[1], fglobal[k1][2]+fend*m[2]); - else - printf("fglobal %d: %f %f %f\n", k1, fglobal[k1][0], fglobal[k1][1], fglobal[k1][2]); - printf("fnum %d: %f %f %f\n", k1, fnum[k1][0], fnum[k1][1], fnum[k1][2]); - } - /* - if (flip) - printf("flip: true\n\n"); - else - printf("flip: false\n\n"); - */ // add energy @@ -393,64 +336,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) sub3(f[jj2], fglobal[3], f[jj2]); scaleadd3(-0.5 * fend, m, f[jj2], f[jj2]); - double pnum1[3], pnum2[3]; - - copy3(r1, rnum[0]); - copy3(r2, rnum[1]); - copy3(q1, rnum[2]); - copy3(q2, rnum[3]); - - copy3(r1, rcopy[0]); - copy3(r2, rcopy[1]); - copy3(q1, rcopy[2]); - copy3(q2, rcopy[3]); - - double ftemp[4][3]; - copy3(fglobal[0], ftemp[0]); - copy3(fglobal[1], ftemp[1]); - copy3(fglobal[2], ftemp[3]); - copy3(fglobal[3], ftemp[2]); - negate3(ftemp[2]); - scaleadd3(2, fglobal[3], ftemp[3], ftemp[3]); - scaleadd3(fend, m, ftemp[3], ftemp[3]); - - printf("Second contribution:\n"); - for (int k1 = 0; k1 < 4; k1++) { - for (int k2 = 0; k2 < 3; k2++) { - double ehi, elo; - rnum[k1][k2] = rcopy[k1][k2] + dx; - - pnum1[0] = rnum[3][0]; - pnum1[1] = rnum[3][1]; - pnum1[2] = rnum[3][2]; - pnum2[0] = 2*rnum[3][0] - rnum[2][0]; - pnum2[1] = 2*rnum[3][1] - rnum[2][1]; - pnum2[2] = 2*rnum[3][2] - rnum[2][2]; - geometry(rnum[0], rnum[1], pnum1, pnum2, pnum1, p, mtemp, param, basis); - fsemi(param, ehi, fend, flocal); - - rnum[k1][k2] = rcopy[k1][k2] - dx; - pnum1[0] = rnum[3][0]; - pnum1[1] = rnum[3][1]; - pnum1[2] = rnum[3][2]; - pnum2[0] = 2*rnum[3][0] - rnum[2][0]; - pnum2[1] = 2*rnum[3][1] - rnum[2][1]; - pnum2[2] = 2*rnum[3][2] - rnum[2][2]; - geometry(rnum[0], rnum[1], pnum1, pnum2, pnum1, p, mtemp, param, basis); - fsemi(param, elo, fend, flocal); - - fnum[k1][k2] = 0.5 * (elo - ehi) / dx; - } - printf("fglobal %d: %f %f %f\n", k1, ftemp[k1][0], ftemp[k1][1], ftemp[k1][2]); - printf("fnum %d: %f %f %f\n", k1, fnum[k1][0], fnum[k1][1], fnum[k1][2]); - } - /* - if (flip) - printf("flip: true\n\n"); - else - printf("flip: false\n\n"); - */ - // add energy if (eflag_either) { @@ -614,11 +499,14 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) double sxi1 = salpha * param[2]; double sxi2 = salpha * param[3]; double hsq = param[0] * param[0]; + + bool skip = false; if (sxi1 * sxi1 + hsq > cutoffsq && sxi2 * sxi2 + hsq > cutoffsq) - continue; + skip = true; // continue; finf(param, evdwl, flocal); + if (skip && fabs(evdwl) > 1.0e-3) printf("incorrect skip in finf: %f eV\n", evdwl); } else { // semi-infinite CNT case @@ -649,9 +537,12 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) else dsq2 = hsq + pow(sin(param[1]) * param[3], 2); - if (dsq1 > cutoffsq && dsq2 > cutoffsq) continue; + bool skip = false; + if (dsq1 > cutoffsq && dsq2 > cutoffsq) + skip = true; // continue; fsemi(param, evdwl, fend, flocal); + if (skip && fabs(evdwl) > 1.0e-3) printf("incorrect skip in fsemi: %f eV\n", evdwl); } if (evdwl > 1.0e1) { From c73770da0915c7c74c475ba659ca761594f244fa Mon Sep 17 00:00:00 2001 From: phankl Date: Wed, 13 Jul 2022 06:55:32 +0100 Subject: [PATCH 072/443] skip zero-energy calculations and removed debug message in coeff --- src/MESONT/pair_mesocnt_viscous.cpp | 56 +++-------------------------- 1 file changed, 4 insertions(+), 52 deletions(-) diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index e9e50b047d..8bf776c942 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -183,8 +183,8 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) if (ceta < param[2]) dsq2 += pow(ceta - param[2], 2); else if (ceta > param[3]) dsq2 += pow(ceta - param[3], 2); - bool skip = false; - if (dsq1 > cutoffsq && dsq2 > cutoffsq) skip = true;// continue; + if (dsq1 > cutoffsq && dsq2 > cutoffsq) + continue; int jj1, jj2; @@ -218,8 +218,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fsemi(param, evdwl, fend, flocal); - if (skip && fabs(evdwl) > 1.0e-3) printf("Incorrect skip in segment-segment: %f eV\n", evdwl); - if (evdwl > 1.0e1) { printf("high energy detected in first contribution (%f eV)\n", evdwl); printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); @@ -500,13 +498,11 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) double sxi2 = salpha * param[3]; double hsq = param[0] * param[0]; - bool skip = false; if (sxi1 * sxi1 + hsq > cutoffsq && sxi2 * sxi2 + hsq > cutoffsq) - skip = true; // continue; + continue; finf(param, evdwl, flocal); - if (skip && fabs(evdwl) > 1.0e-3) printf("incorrect skip in finf: %f eV\n", evdwl); } else { // semi-infinite CNT case @@ -537,12 +533,10 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) else dsq2 = hsq + pow(sin(param[1]) * param[3], 2); - bool skip = false; if (dsq1 > cutoffsq && dsq2 > cutoffsq) - skip = true; // continue; + continue; fsemi(param, evdwl, fend, flocal); - if (skip && fabs(evdwl) > 1.0e-3) printf("incorrect skip in fsemi: %f eV\n", evdwl); } if (evdwl > 1.0e1) { @@ -789,48 +783,6 @@ void PairMesoCNTViscous::coeff(int narg, char **arg) int ntypes = atom->ntypes; for (int i = 1; i <= ntypes; i++) for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; - - // debug output - - param[0] = 0; - param[1] = 0.5 * MY_PI; - param[4] = 0.0; - param[5] = 100.0; - param[6] = 0.0; - - int points = 1001; - double xStart = 9.0; - double xEnd = 14.0; - double xSpacing = (xEnd - xStart) / (points - 1); - double dx = 10.0; - - double evdwl, fend; - - std::ofstream finfFile("/Users/phankl/phd/tensile/finf.dat"); - std::ofstream fsemiFile("/Users/phankl/phd/tensile/fsemi.dat"); - - for (int i = 0; i < points; i++) { - double xi = xStart + i * xSpacing; - param[2] = xi; - param[3] = xi + dx; - - finf(param, evdwl, flocal); - finfFile << xi << " " << evdwl << " "; - for (int j = 0; j < 2; j++) - for (int k = 0; k < 3; k++) - finfFile << flocal[j][k] << " "; - finfFile << std::endl; - - fsemi(param, evdwl, fend, flocal); - fsemiFile << xi << " " << 2*evdwl << " "; - for (int j = 0; j < 2; j++) - for (int k = 0; k < 3; k++) - fsemiFile << 2*flocal[j][k] << " "; - fsemiFile << std::endl; - } - - finfFile.close(); - fsemiFile.close(); } /* ---------------------------------------------------------------------- From 7c31772582f52b1864a9fdf9c86971cfc4ceb691 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 15 Jul 2022 09:22:34 +0100 Subject: [PATCH 073/443] checkpoint commit, potential seems to be stable --- src/MESONT/pair_mesocnt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 4f06b4f3e1..866cfe6469 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -44,7 +44,7 @@ using namespace MathExtra; #define SELF_CUTOFF 3 #define SMALL 1.0e-6 #define SWITCH 1.0e-6 -#define QUADRATURE 1000 +#define QUADRATURE 10 #define RHOMIN 10.0 /* ---------------------------------------------------------------------- */ From d0ca31e8f1b0fd008a2b4205f75f9d8e636b5951 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 15 Jul 2022 09:37:54 +0100 Subject: [PATCH 074/443] removed print statements and added proper warning for interpolation range in phi --- src/MESONT/pair_mesocnt.cpp | 4 ++- src/MESONT/pair_mesocnt_viscous.cpp | 38 ----------------------------- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 866cfe6469..2251073b18 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -1976,8 +1976,10 @@ void PairMesoCNT::finf(const double *param, double &evdwl, double **f) double dpsi_phibar2 = dyspline(h, psi2, hstart_phi, psistart_phi, delh_phi, delpsi_phi, phi_coeff, phi_points); + // warn if psi outside of interpolation range if (psi1 < 0 || psi2 < 0) - printf("outside interpolation range!\n"); + error->warning(FLERR, "Segment - infinite chain interaction outside of interpolation range." + " Use potential file with lower delta1 and delta2 values."); double dzeta_range = dzetamax - dzetamin; double dh_psi1 = -zeta_range_inv * (dzetamin + dzeta_range * psi1); diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 8bf776c942..06c2b38046 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -218,21 +218,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fsemi(param, evdwl, fend, flocal); - if (evdwl > 1.0e1) { - printf("high energy detected in first contribution (%f eV)\n", evdwl); - printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("%f %f %f\n", r1[0], r1[1], r1[2]); - printf("%f %f %f\n", r2[0], r2[1], r2[2]); - printf("segment2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); - printf("%f %f %f\n", q1[0], q1[1], q1[2]); - printf("%f %f %f\n", q2[0], q2[1], q2[2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - - finf(param, evdwl, flocal); - printf("finf equivalent energy: %f\n", evdwl); - fsemi(param, evdwl, fend, flocal); - } - if (evdwl == 0.0) continue; // transform to global coordinate system @@ -287,17 +272,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fsemi(param, evdwl, fend, flocal); - if (evdwl > 1.0e1) { - printf("high energy detected in second contribution (%f eV)\n", evdwl); - printf("segment1: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("%f %f %f\n", r1[0], r1[1], r1[2]); - printf("%f %f %f\n", r2[0], r2[1], r2[2]); - printf("segment2: %d %d\n", atom->tag[jj1], atom->tag[jj2]); - printf("%f %f %f\n", q1[0], q1[1], q1[2]); - printf("%f %f %f\n", q2[0], q2[1], q2[2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - } - if (evdwl == 0.0) continue; // transform to global coordinate system @@ -539,18 +513,6 @@ void PairMesoCNTViscous::compute(int eflag, int vflag) fsemi(param, evdwl, fend, flocal); } - if (evdwl > 1.0e1) { - printf("high energy detected in segment-chain interaction (%f eV)\n", evdwl); - printf("endflag: %d\n", endflag); - printf("segment: %d %d\n", atom->tag[i1], atom->tag[i2]); - printf("%f %f %f\n", r1[0], r1[1], r1[2]); - printf("%f %f %f\n", r2[0], r2[1], r2[2]); - printf("chain: \n"); - for (k = 0; k < clen; k++) - printf("%d %f %f %f\n", atom->tag[chain[j][k]], x[chain[j][k]][0], x[chain[j][k]][1], x[chain[j][k]][2]); - printf("param: %f %f %f %f %f %f %f\n", param[0], param[1], param[2], param[3], param[4], param[5], param[6]); - } - if (evdwl == 0.0) continue; evdwl *= 0.5; From 5871fcf692310526e822b95723e538dd42b3ac59 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 15 Jul 2022 15:22:31 +0200 Subject: [PATCH 075/443] added automatic angle parametrisation & buckling/harmonic toggle --- src/MESONT/angle_mesocnt.cpp | 87 ++++++++++++++++++++++++++++++++---- src/MESONT/angle_mesocnt.h | 3 ++ 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp index 706adcbaac..327a9aac69 100644 --- a/src/MESONT/angle_mesocnt.cpp +++ b/src/MESONT/angle_mesocnt.cpp @@ -22,14 +22,15 @@ #include "memory.h" #include "modify.h" #include "neighbor.h" +#include "update.h" #include using namespace LAMMPS_NS; -using MathConst::DEG2RAD; -using MathConst::RAD2DEG; +using namespace MathConst; static constexpr double SMALL = 0.001; +static constexpr double A_CC = 1.421; /* ---------------------------------------------------------------------- */ @@ -118,7 +119,7 @@ void AngleMesoCNT::compute(int eflag, int vflag) dtheta = acos(c) - theta0[type]; // harmonic bending - if (fabs(dtheta) < thetab[type]) { + if (!buckling || fabs(dtheta) < thetab[type]) { tk = kh[type] * dtheta; if (eflag) eangle = tk * dtheta; a = -2.0 * tk * s; @@ -185,22 +186,92 @@ void AngleMesoCNT::allocate() for (int i = 1; i < np1; i++) setflag[i] = 0; } +/* ---------------------------------------------------------------------- + set buckling parameter +------------------------------------------------------------------------- */ + +void AngleMesoCNT::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR, "Illegal angle_style command"); + + if (strcmp(arg[0], "buckling") == 0) + buckling = true; + else if (strcmp(arg[0], "harmonic") == 0) + buckling = false; + else + error->all(FLERR, "Unknown angle style in angle style mesocnt"); +} + + /* ---------------------------------------------------------------------- set coeffs for one or more types ------------------------------------------------------------------------- */ void AngleMesoCNT::coeff(int narg, char **arg) { - if (narg != 4) error->all(FLERR, "Incorrect args for angle coefficients"); + double kh_one, kb_one, thetab_one; + if (strcmp(arg[1], "custom") == 0) { + if (buckling) { + if (narg != 5) error->all(FLERR, "Incorrect args for custom angle coefficients"); + kb_one = utils::numeric(FLERR, arg[3], false, lmp); + thetab_one = utils::numeric(FLERR, arg[4], false, lmp); + } + else if (narg != 3) error->all(FLERR, "Incorrect args for custom angle coefficients"); + + kh_one = utils::numeric(FLERR, arg[2], false, lmp); + } + else if (strcmp(arg[1], "C") == 0) { + if (narg != 5) error->all(FLERR, "Incorrect args for 'C' preset in angle coefficients"); + int n = utils::inumeric(FLERR, arg[2], false, lmp); + int m = utils::inumeric(FLERR, arg[3], false, lmp); + double l = utils::numeric(FLERR, arg[4], false, lmp); + + double r_ang = sqrt(3.0 * (n*n + n*m + m*m)) * A_CC / MY_2PI; + + // units, eV to energy unit conversion + + double ang = force->angstrom; + double eunit; + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Angle style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Angle style mesocnt does not recognize this units style"); + + double k = 63.80 * pow(r_ang, 2.93) * eunit * ang; + kh_one = 0.5 * k / l; + + if (buckling) { + kb_one = 0.7 * k / (275.0 * ang); + thetab_one = 180.0 / MY_PI * atan(l / (275.0 * ang)); + } + } + + // set safe default values for buckling parameters if buckling is disabled + + if (!buckling) { + kb_one = 0.0; + thetab_one = 180.0; + } + if (!allocated) allocate(); int ilo, ihi; utils::bounds(FLERR, arg[0], 1, atom->nangletypes, ilo, ihi, error); - double kh_one = utils::numeric(FLERR, arg[1], false, lmp); - double kb_one = utils::numeric(FLERR, arg[2], false, lmp); - double thetab_one = utils::numeric(FLERR, arg[3], false, lmp); - // convert thetab from degrees to radians int count = 0; diff --git a/src/MESONT/angle_mesocnt.h b/src/MESONT/angle_mesocnt.h index faec85f1c2..0f8e5dde79 100644 --- a/src/MESONT/angle_mesocnt.h +++ b/src/MESONT/angle_mesocnt.h @@ -27,6 +27,7 @@ class AngleMesoCNT : public Angle { AngleMesoCNT(class LAMMPS *); ~AngleMesoCNT() override; void compute(int, int) override; + void settings(int, char **) override; void coeff(int, char **) override; void init_style() override; double equilibrium_angle(int) override; @@ -36,6 +37,8 @@ class AngleMesoCNT : public Angle { double single(int, int, int, int) override; protected: + bool buckling; + double *kh, *kb, *thetab, *theta0; virtual void allocate(); From 20e39b57d8b4863f1fe9f179789499ff03db13bd Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 15 Jul 2022 17:44:21 +0200 Subject: [PATCH 076/443] moved buckling/harmonic toggle to angle_coeff and added restart file support for buckling bool --- src/MESONT/angle_mesocnt.cpp | 122 +++++++++++++++++++---------------- src/MESONT/angle_mesocnt.h | 3 +- 2 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp index 327a9aac69..55eb991b28 100644 --- a/src/MESONT/angle_mesocnt.cpp +++ b/src/MESONT/angle_mesocnt.cpp @@ -47,6 +47,7 @@ AngleMesoCNT::~AngleMesoCNT() { if (allocated && !copymode) { memory->destroy(setflag); + memory->destroy(buckling); memory->destroy(kh); memory->destroy(kb); memory->destroy(thetab); @@ -119,7 +120,7 @@ void AngleMesoCNT::compute(int eflag, int vflag) dtheta = acos(c) - theta0[type]; // harmonic bending - if (!buckling || fabs(dtheta) < thetab[type]) { + if (!buckling[type] || fabs(dtheta) < thetab[type]) { tk = kh[type] * dtheta; if (eflag) eangle = tk * dtheta; a = -2.0 * tk * s; @@ -177,6 +178,7 @@ void AngleMesoCNT::allocate() allocated = 1; const int np1 = atom->nangletypes + 1; + memory->create(buckling, np1, "angle:buckling"); memory->create(kh, np1, "angle:kh"); memory->create(kb, np1, "angle:kb"); memory->create(thetab, np1, "angle:thetab"); @@ -186,22 +188,6 @@ void AngleMesoCNT::allocate() for (int i = 1; i < np1; i++) setflag[i] = 0; } -/* ---------------------------------------------------------------------- - set buckling parameter -------------------------------------------------------------------------- */ - -void AngleMesoCNT::settings(int narg, char **arg) -{ - if (narg != 1) error->all(FLERR, "Illegal angle_style command"); - - if (strcmp(arg[0], "buckling") == 0) - buckling = true; - else if (strcmp(arg[0], "harmonic") == 0) - buckling = false; - else - error->all(FLERR, "Unknown angle style in angle style mesocnt"); -} - /* ---------------------------------------------------------------------- set coeffs for one or more types @@ -209,64 +195,82 @@ void AngleMesoCNT::settings(int narg, char **arg) void AngleMesoCNT::coeff(int narg, char **arg) { - double kh_one, kb_one, thetab_one; - if (strcmp(arg[1], "custom") == 0) { - if (buckling) { - if (narg != 5) error->all(FLERR, "Incorrect args for custom angle coefficients"); - kb_one = utils::numeric(FLERR, arg[3], false, lmp); - thetab_one = utils::numeric(FLERR, arg[4], false, lmp); - } - else if (narg != 3) error->all(FLERR, "Incorrect args for custom angle coefficients"); + if (narg < 1) error->all(FLERR, "Incorrect args for angle coefficients"); + + bool buckling_one; + if (strcmp(arg[1], "buckling") == 0) + buckling_one = true; + else if (strcmp(arg[1], "harmonic") == 0) + buckling_one = false; + else + error->all(FLERR, "Unknown first argument for angle coefficients, must be 'buckling' or 'harmonic'"); - kh_one = utils::numeric(FLERR, arg[2], false, lmp); + // units, eV to energy unit conversion + + double ang = force->angstrom; + double eunit; + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Angle style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Angle style mesocnt does not recognize this units style"); + + // set parameters + + double kh_one, kb_one, thetab_one; + if (strcmp(arg[2], "custom") == 0) { + if (buckling_one) { + if (narg != 6) error->all(FLERR, "Incorrect args for custom angle coefficients"); + kb_one = utils::numeric(FLERR, arg[4], false, lmp); + thetab_one = utils::numeric(FLERR, arg[5], false, lmp); + } + else if (narg != 4) error->all(FLERR, "Incorrect args for custom angle coefficients"); + + kh_one = utils::numeric(FLERR, arg[3], false, lmp); } - else if (strcmp(arg[1], "C") == 0) { - if (narg != 5) error->all(FLERR, "Incorrect args for 'C' preset in angle coefficients"); - int n = utils::inumeric(FLERR, arg[2], false, lmp); - int m = utils::inumeric(FLERR, arg[3], false, lmp); - double l = utils::numeric(FLERR, arg[4], false, lmp); + else if (strcmp(arg[2], "C") == 0) { + if (narg != 6) error->all(FLERR, "Incorrect args for 'C' preset in angle coefficients"); + int n = utils::inumeric(FLERR, arg[3], false, lmp); + int m = utils::inumeric(FLERR, arg[4], false, lmp); + double l = utils::numeric(FLERR, arg[5], false, lmp); double r_ang = sqrt(3.0 * (n*n + n*m + m*m)) * A_CC / MY_2PI; - - // units, eV to energy unit conversion - double ang = force->angstrom; - double eunit; - if (strcmp(update->unit_style, "lj") == 0) - error->all(FLERR, "Angle style mesocnt does not support lj units"); - else if (strcmp(update->unit_style, "real") == 0) - eunit = 23.06054966; - else if (strcmp(update->unit_style, "metal") == 0) - eunit = 1.0; - else if (strcmp(update->unit_style, "si") == 0) - eunit = 1.6021765e-19; - else if (strcmp(update->unit_style, "cgs") == 0) - eunit = 1.6021765e-12; - else if (strcmp(update->unit_style, "electron") == 0) - eunit = 3.674932248e-2; - else if (strcmp(update->unit_style, "micro") == 0) - eunit = 1.6021765e-4; - else if (strcmp(update->unit_style, "nano") == 0) - eunit = 1.6021765e2; - else - error->all(FLERR, "Angle style mesocnt does not recognize this units style"); + // empirical parameters double k = 63.80 * pow(r_ang, 2.93) * eunit * ang; kh_one = 0.5 * k / l; - if (buckling) { + if (buckling_one) { kb_one = 0.7 * k / (275.0 * ang); thetab_one = 180.0 / MY_PI * atan(l / (275.0 * ang)); } } + else + error->all(FLERR, "Unknown preset in in angle coefficients"); // set safe default values for buckling parameters if buckling is disabled - if (!buckling) { + if (!buckling_one) { kb_one = 0.0; thetab_one = 180.0; } + printf("parameters: %d %f %f %f\n", buckling_one, kh_one, kb_one, thetab_one); + if (!allocated) allocate(); int ilo, ihi; @@ -276,6 +280,7 @@ void AngleMesoCNT::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { + buckling[i] = buckling_one; kh[i] = kh_one; kb[i] = kb_one; thetab[i] = DEG2RAD * thetab_one; @@ -307,6 +312,7 @@ double AngleMesoCNT::equilibrium_angle(int i) void AngleMesoCNT::write_restart(FILE *fp) { + fwrite(&buckling[1], sizeof(bool), atom->nangletypes, fp); fwrite(&kh[1], sizeof(double), atom->nangletypes, fp); fwrite(&kb[1], sizeof(double), atom->nangletypes, fp); fwrite(&thetab[1], sizeof(double), atom->nangletypes, fp); @@ -321,10 +327,12 @@ void AngleMesoCNT::read_restart(FILE *fp) allocate(); if (comm->me == 0) { + utils::sfread(FLERR, &buckling[1], sizeof(bool), atom->nangletypes, fp, nullptr, error); utils::sfread(FLERR, &kh[1], sizeof(double), atom->nangletypes, fp, nullptr, error); utils::sfread(FLERR, &kb[1], sizeof(double), atom->nangletypes, fp, nullptr, error); utils::sfread(FLERR, &thetab[1], sizeof(double), atom->nangletypes, fp, nullptr, error); } + MPI_Bcast(&buckling[1], atom->nangletypes, MPI_CXX_BOOL, 0, world); MPI_Bcast(&kh[1], atom->nangletypes, MPI_DOUBLE, 0, world); MPI_Bcast(&kb[1], atom->nangletypes, MPI_DOUBLE, 0, world); MPI_Bcast(&thetab[1], atom->nangletypes, MPI_DOUBLE, 0, world); @@ -342,7 +350,7 @@ void AngleMesoCNT::read_restart(FILE *fp) void AngleMesoCNT::write_data(FILE *fp) { for (int i = 1; i <= atom->nangletypes; i++) - fprintf(fp, "%d %g %g %g\n", i, kh[i], kb[i], RAD2DEG * thetab[i]); + fprintf(fp, "%d %d %g %g %g\n", i, buckling[i], kh[i], kb[i], RAD2DEG * thetab[i]); } /* ---------------------------------------------------------------------- */ @@ -371,7 +379,7 @@ double AngleMesoCNT::single(int type, int i1, int i2, int i3) double dtheta = acos(c) - theta0[type]; // harmonic bending - if (dtheta < thetab[type]) { + if (!buckling[type] || dtheta < thetab[type]) { double tk = kh[type] * dtheta; return tk * dtheta; } diff --git a/src/MESONT/angle_mesocnt.h b/src/MESONT/angle_mesocnt.h index 0f8e5dde79..0a9a6e93f8 100644 --- a/src/MESONT/angle_mesocnt.h +++ b/src/MESONT/angle_mesocnt.h @@ -27,7 +27,6 @@ class AngleMesoCNT : public Angle { AngleMesoCNT(class LAMMPS *); ~AngleMesoCNT() override; void compute(int, int) override; - void settings(int, char **) override; void coeff(int, char **) override; void init_style() override; double equilibrium_angle(int) override; @@ -37,8 +36,8 @@ class AngleMesoCNT : public Angle { double single(int, int, int, int) override; protected: - bool buckling; + bool *buckling; double *kh, *kb, *thetab, *theta0; virtual void allocate(); From a5a6f32aff01dd57b1078f85f62c244c790f3d5c Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 15 Jul 2022 17:45:19 +0200 Subject: [PATCH 077/443] removed print statement in angle_mesocnt --- src/MESONT/angle_mesocnt.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp index 55eb991b28..d57af9bd08 100644 --- a/src/MESONT/angle_mesocnt.cpp +++ b/src/MESONT/angle_mesocnt.cpp @@ -269,8 +269,6 @@ void AngleMesoCNT::coeff(int narg, char **arg) thetab_one = 180.0; } - printf("parameters: %d %f %f %f\n", buckling_one, kh_one, kb_one, thetab_one); - if (!allocated) allocate(); int ilo, ihi; From a0f3994ffa40540d20caaf543aaf0cd9b247a9b1 Mon Sep 17 00:00:00 2001 From: phankl Date: Fri, 15 Jul 2022 21:24:46 +0200 Subject: [PATCH 078/443] added mesocnt bond type as wrapper for harmonic bond with automatic parametrisation --- src/MESONT/angle_mesocnt.cpp | 3 +- src/MESONT/bond_mesocnt.cpp | 116 +++++++++++++++++++++++++++++++++++ src/MESONT/bond_mesocnt.h | 35 +++++++++++ 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/MESONT/bond_mesocnt.cpp create mode 100644 src/MESONT/bond_mesocnt.h diff --git a/src/MESONT/angle_mesocnt.cpp b/src/MESONT/angle_mesocnt.cpp index d57af9bd08..8dfe856942 100644 --- a/src/MESONT/angle_mesocnt.cpp +++ b/src/MESONT/angle_mesocnt.cpp @@ -36,6 +36,7 @@ static constexpr double A_CC = 1.421; AngleMesoCNT::AngleMesoCNT(LAMMPS *_lmp) : Angle(_lmp) { + buckling = nullptr; kh = nullptr; kb = nullptr; thetab = nullptr; @@ -260,7 +261,7 @@ void AngleMesoCNT::coeff(int narg, char **arg) } } else - error->all(FLERR, "Unknown preset in in angle coefficients"); + error->all(FLERR, "Unknown preset in angle coefficients"); // set safe default values for buckling parameters if buckling is disabled diff --git a/src/MESONT/bond_mesocnt.cpp b/src/MESONT/bond_mesocnt.cpp new file mode 100644 index 0000000000..ca889bfac7 --- /dev/null +++ b/src/MESONT/bond_mesocnt.cpp @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#include "bond_mesocnt.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "math_const.h" +#include "memory.h" +#include "neighbor.h" +#include "update.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace MathConst; + +static constexpr double A_CC = 1.421; + +/* ---------------------------------------------------------------------- */ + +BondMesoCNT::BondMesoCNT(LAMMPS *_lmp) : BondHarmonic(_lmp) +{ + born_matrix_enable = 1; +} + +/* ---------------------------------------------------------------------- */ + +BondMesoCNT::~BondMesoCNT() +{ + if (allocated && !copymode) { + memory->destroy(setflag); + memory->destroy(k); + memory->destroy(r0); + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more types +------------------------------------------------------------------------- */ + +void BondMesoCNT::coeff(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR, "Incorrect args for bond coefficients"); + + // units, eV to energy unit conversion + + double ang = force->angstrom; + double eunit; + if (strcmp(update->unit_style, "lj") == 0) + error->all(FLERR, "Angle style mesocnt does not support lj units"); + else if (strcmp(update->unit_style, "real") == 0) + eunit = 23.06054966; + else if (strcmp(update->unit_style, "metal") == 0) + eunit = 1.0; + else if (strcmp(update->unit_style, "si") == 0) + eunit = 1.6021765e-19; + else if (strcmp(update->unit_style, "cgs") == 0) + eunit = 1.6021765e-12; + else if (strcmp(update->unit_style, "electron") == 0) + eunit = 3.674932248e-2; + else if (strcmp(update->unit_style, "micro") == 0) + eunit = 1.6021765e-4; + else if (strcmp(update->unit_style, "nano") == 0) + eunit = 1.6021765e2; + else + error->all(FLERR, "Angle style mesocnt does not recognize this units style"); + + // set parameters + + double k_one, r0_one; + if (strcmp(arg[1], "custom") == 0) { + if (narg != 4) error->all(FLERR, "Incorrect args for custom bond coefficients"); + k_one = utils::numeric(FLERR, arg[2], false, lmp); + r0_one = utils::numeric(FLERR, arg[3], false, lmp); + } + else if (strcmp(arg[1], "C") == 0) { + if (narg != 5) error->all(FLERR, "Incorrect args for 'C' preset in bond coefficients"); + int n = utils::inumeric(FLERR, arg[2], false, lmp); + int m = utils::inumeric(FLERR, arg[3], false, lmp); + r0_one = utils::numeric(FLERR, arg[4], false, lmp); + + double r_ang = sqrt(3.0 * (n*n + n*m + m*m)) * A_CC / MY_2PI; + k_one = 0.5 * (86.64 + 100.56 * r_ang) * eunit / (ang * r0_one); + } + else + error->all(FLERR, "Unknown preset in bond coefficients"); + + if (!allocated) allocate(); + + int ilo, ihi; + utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + k[i] = k_one; + r0[i] = r0_one; + setflag[i] = 1; + count++; + } + + if (count == 0) error->all(FLERR, "Incorrect args for bond coefficients"); +} diff --git a/src/MESONT/bond_mesocnt.h b/src/MESONT/bond_mesocnt.h new file mode 100644 index 0000000000..6cd3f468af --- /dev/null +++ b/src/MESONT/bond_mesocnt.h @@ -0,0 +1,35 @@ +/* -*- 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 BOND_CLASS +BondStyle(mesocnt,BondMesoCNT); +#else + +#ifndef LMP_BOND_MESOCNT_H +#define LMP_BOND_MESOCNT_H + +#include "bond_harmonic.h" + +namespace LAMMPS_NS { + +class BondMesoCNT : public BondHarmonic { + public: + BondMesoCNT(class LAMMPS *); + ~BondMesoCNT() override; + void coeff(int, char **) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif From a99d0aa28e7c8037ad96ddee57f56f53989f4bf4 Mon Sep 17 00:00:00 2001 From: phankl Date: Mon, 18 Jul 2022 11:39:02 +0200 Subject: [PATCH 079/443] added error messages for special_lj and comm vel --- src/MESONT/pair_mesocnt.cpp | 2 ++ src/MESONT/pair_mesocnt_viscous.cpp | 19 +++++++++++++++++++ src/MESONT/pair_mesocnt_viscous.h | 1 + 3 files changed, 22 insertions(+) diff --git a/src/MESONT/pair_mesocnt.cpp b/src/MESONT/pair_mesocnt.cpp index 2251073b18..792f744339 100644 --- a/src/MESONT/pair_mesocnt.cpp +++ b/src/MESONT/pair_mesocnt.cpp @@ -756,6 +756,8 @@ void PairMesoCNT::init_style() { if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt requires atom IDs"); if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt requires newton pair on"); + if (force->special_lj[1] == 0.0 || force->special_lj[2] == 0.0 || force->special_lj[3] == 0.0) + error->all(FLERR,"Pair mesocnt requires special_bond lj x y z to have non-zero x, y and z"); // need a full neighbor list diff --git a/src/MESONT/pair_mesocnt_viscous.cpp b/src/MESONT/pair_mesocnt_viscous.cpp index 06c2b38046..c58d6a6774 100644 --- a/src/MESONT/pair_mesocnt_viscous.cpp +++ b/src/MESONT/pair_mesocnt_viscous.cpp @@ -19,6 +19,7 @@ #include "pair_mesocnt_viscous.h" #include "atom.h" +#include "comm.h" #include "error.h" #include "force.h" #include "math_const.h" @@ -747,6 +748,24 @@ void PairMesoCNTViscous::coeff(int narg, char **arg) for (int j = i; j <= ntypes; j++) setflag[i][j] = 1; } +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairMesoCNTViscous::init_style() +{ + if (atom->tag_enable == 0) error->all(FLERR, "Pair style mesocnt/viscous requires atom IDs"); + if (force->newton_pair == 0) error->all(FLERR, "Pair style mesocnt/viscous requires newton pair on"); + if (force->special_lj[1] == 0.0 || force->special_lj[2] == 0.0 || force->special_lj[3] == 0.0) + error->all(FLERR,"Pair mesocnt/viscous requires special_bond lj x y z to have non-zero x, y and z"); + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair mesocnt/viscous requires ghost atoms store velocity"); + + // need a full neighbor list + + neighbor->add_request(this, NeighConst::REQ_FULL); +} + /* ---------------------------------------------------------------------- weight for averaged friction from CNT chain ------------------------------------------------------------------------- */ diff --git a/src/MESONT/pair_mesocnt_viscous.h b/src/MESONT/pair_mesocnt_viscous.h index 2027435da3..dc5a701e0b 100644 --- a/src/MESONT/pair_mesocnt_viscous.h +++ b/src/MESONT/pair_mesocnt_viscous.h @@ -27,6 +27,7 @@ class PairMesoCNTViscous : public PairMesoCNT { void compute(int, int) override; void coeff(int, char **) override; + void init_style() override; protected: double a1, a2, b2, vswitch; From 00cecceab77989e57445a089b722c018302f4d69 Mon Sep 17 00:00:00 2001 From: Paulius Velesko Date: Thu, 21 Jul 2022 03:55:53 +0000 Subject: [PATCH 080/443] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bd2d0ea705..0cc211ab09 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ out/RelWithDebInfo out/Release out/x86 out/x64 +benchmark/* From 7901a317c0d6f90bd8f3130c53789bd6f5c6b0ee Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 20 Jul 2022 16:01:53 -0400 Subject: [PATCH 081/443] Initial version of an LAMMPS older version code update guide --- doc/src/Developer.rst | 1 + doc/src/Developer_updating.rst | 304 ++++++++++++++++++++ doc/utils/sphinx-config/false_positives.txt | 4 + 3 files changed, 309 insertions(+) create mode 100644 doc/src/Developer_updating.rst diff --git a/doc/src/Developer.rst b/doc/src/Developer.rst index bb10fcffd7..dc3fac94ce 100644 --- a/doc/src/Developer.rst +++ b/doc/src/Developer.rst @@ -17,6 +17,7 @@ of time and requests from the LAMMPS user community. Developer_flow Developer_write Developer_notes + Developer_updating Developer_plugins Developer_unittest Classes diff --git a/doc/src/Developer_updating.rst b/doc/src/Developer_updating.rst new file mode 100644 index 0000000000..13e1772589 --- /dev/null +++ b/doc/src/Developer_updating.rst @@ -0,0 +1,304 @@ +Notes for updating code written for older LAMMPS versions +--------------------------------------------------------- + +This section documents how C++ source files that were written for an +older version of LAMMPS need to be updated to be compatible with the +current and future version(s). Due to the active development of LAMMPS +it is likely to always be incomplete. Please contact developer@lammps.org +in case you run across an issue that is not (yet) listed here. Please +also review the latest information about the LAMMPS :doc:`programming style +conventions `. + +Available topics in chronological order are: + +- `Rename of pack/unpack_comm() to pack/unpack_forward_comm()`_ +- `Use ev_init() to initialize variables derived from eflag and vflag`_ +- `Use utils::numeric() functions instead of force->numeric()`_ +- `Use utils::open_potential() function to open potential files`_ +- `Simplify customized error messages`_ +- `Use of "override" instead of "virtual"`_ +- `Simplified and more compact neighbor list requests`_ + +---- + +Rename of pack/unpack_comm() to pack/unpack_forward_comm() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 8Aug2014 + +In this change set the functions to pack data into communication buffers +and to unpack data from communication buffers for :doc:`forward +communications ` were renamed from ``pack_comm()`` +and ``unpack_comm()`` to ``pack_forward_comm()`` and +``unpack_forward_comm()``, respectively. Also the meaning of the return +value of these functions was changed: rather than returning the number +of items per atom stored in the buffer, now the total number of items +added (or unpacked) needs to be returned. Here is an example from the +`PairEAM` class. Of course the member function declaration in corresponding +header file needs to be updated accordingly. + +Old: + +.. code-block:: C++ + + int PairEAM::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) + { + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; + buf[m++] = fp[j]; + } + return 1; + } + +New: + +.. code-block:: C++ + + int PairEAM::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) + { + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; + buf[m++] = fp[j]; + } + return m; + } + +.. note:: + + Because the various "pack" and "unpack" functions are defined in the + respective base classes as dummy functions doing nothing, and because + of the the name mismatch the custom versions in the derived class + will no longer be called, there will be no compilation error when + this change is not applied. Only calculations will suddenly produce + incorrect results because the required forward communication calls + will cease to function correctly. + +Use ev_init() to initialize variables derived from eflag and vflag +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 29Mar2019 + +There are several variables that need to be initialized based on +the values of the "eflag" and "vflag" variables and since sometimes +there are new bits added and new variables need to be set to 1 or 0. +To make this consistent, across all styles, there is now an inline +function ``ev_init(eflag, vflag)`` that makes those settings +consistently and calls either ``ev_setup()`` or ``ev_unset()``. +Example from a pair style: + +Old: + +.. code-block:: C++ + + if (eflag || vflag) ev_setup(eflag, vflag); + else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + +New: + +.. code-block:: C++ + + ev_init(eflag, vflag); + +Not applying this change will not cause a compilation error, but +can lead to inconsistent behavior and incorrect tallying of +energy or virial. + +Use utils::numeric() functions instead of force->numeric() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 18Sep2020 + +The "numeric()" conversion functions (including "inumeric()", +"bnumeric()", and "tnumeric()") have been moved from the Force class to +the utils namespace. Also they take an additional argument that selects +whether the ``Error::all()`` or ``Error::one()`` function should be +called in case of an error. The former should be used when *all* MPI +processes call the conversion function and the latter *must* be used +when they are called from only one or a subset of the MPI processes. + +Old: + +.. code-block:: C++ + + val = force->numeric(FLERR, arg[1]); + num = force->inumeric(FLERR, arg[2]); + +New: + +.. code-block:: C++ + + val = utils::numeric(FLERR, true, arg[1], lmp); + num = utils::inumeric(FLERR, false, arg[2], lmp); + +.. seealso:: + + :cpp:func:`utils::numeric() `, + :cpp:func:`utils::inumeric() `, + :cpp:func:`utils::bnumeric() `, + :cpp:func:`utils::tnumeric() ` + +Use utils::open_potential() function to open potential files +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 18Sep2020 + +The :cpp:func:`utils::open_potential() +` function must be used to replace +calls to ``force->open_potential()`` and should be used to replace +``fopen()`` for opening potential files for reading. The custom +function does three additional steps compared to ``fopen()``: 1) it will +try to parse the ``UNITS:`` and ``DATE:`` metadata will stop with an +error on a units mismatch and will print the date info, if present, in +the log file; 2) for pair styles that support it, it will set up +possible automatic unit conversions based on the embedded unit +information and LAMMPS' current units setting; 3) it will not only try +to open a potential file at the given path, but will also search in the +folders listed in the ``LAMMPS_POTENTIALS`` environment variable. This +allows to keep potential files in a common location instead of having to +copy them around for simulations. + +Old: + +.. code-block:: C++ + + fp = force->open_potential(filename); + fp = fopen(filename, "r"); + +New: + +.. code-block:: C++ + + fp = utils::open_potential(filename, lmp); + +Simplify customized error messages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 14May2021 + +Aided by features of the bundled {fmt} library, error messages now +can have a variable number of arguments and the string will be interpreted +as a {fmt} style format string so that custom error messages can be +easily customized without having to use temporary buffers and ``sprintf()``. +Example: + +Old: + +.. code-block:: C++ + + if (fptr == NULL) { + char str[128]; + sprintf(str,"Cannot open AEAM potential file %s",filename); + error->one(FLERR,str); + } + +New: + +.. code-block:: C++ + + if (fptr == nullptr) + error->one(FLERR, "Cannot open AEAM potential file {}: {}", filename, utils::getsyserror()); + +Use of "override" instead of "virtual" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 17Feb2022 + +Since LAMMPS requires C++11 we switched to use the "override" keyword +instead of "virtual" to indicate polymorphism in derived classes. This +allows the C++ compiler to better detect inconsistencies when an +override is intended or not. Please note that "override" has to be +added to **all** polymorph functions in derived classes and "virtual" +*only* to the function in the base class (or the destructor). Here is +an example from the ``FixWallReflect`` class: + +Old: + +.. code-block:: C++ + + FixWallReflect(class LAMMPS *, int, char **); + virtual ~FixWallReflect(); + int setmask(); + void init(); + void post_integrate(); + +New: + +.. code-block:: C++ + + FixWallReflect(class LAMMPS *, int, char **); + ~FixWallReflect() override; + int setmask() override; + void init() override; + void post_integrate() override; + +This change set will neither cause a compilation failure, nor will it +change functionality, but if you plan to submit the updated code for +inclusion into the LAMMPS distribution, it will be requested for achieve +a consistent :doc:`programming style `. + +Simplified function names for forward and reverse communication +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 24Mar2022 + +Rather then using the function name to distinguish between the different +forward and reverse communication functions for styles, LAMMPS now uses +the type of the "this" pointer argument. + +Old: + +.. code-block:: C++ + + comm->forward_comm_pair(this); + comm->forward_comm_fix(this); + comm->forward_comm_compute(this); + comm->forward_comm_dump(this); + comm->reverse_comm_pair(this); + comm->reverse_comm_fix(this); + comm->reverse_comm_compute(this); + comm->reverse_comm_dump(this); + +New: + +.. code-block:: C++ + + comm->forward_comm(this); + comm->reverse_comm(this); + +This change is required or else the code will not compile. + +Simplified and more compact neighbor list requests +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 24Mar2022 + +This change set reduces the amount of code required to request a +neighbor list. It enforces consistency and no longer requires to change +internal data of the request. More information on neighbor list +requests can be :doc:`found here `. Example from the +``ComputeRDF`` class: + +Old: + +.. code-block:: C++ + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; + if (cutflag) { + neighbor->requests[irequest]->cut = 1; + neighbor->requests[irequest]->cutoff = mycutneigh; + } + +New: + +.. code-block:: C++ + + auto req = neighbor->add_request(this, NeighConst::REQ_OCCASIONAL); + if (cutflag) req->set_cutoff(mycutneigh); + +Public access to the ``NeighRequest`` class data members has been +removed so this update is *required* to avoid compilation failure. diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 9f6edbec4c..9006f99e50 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -291,6 +291,7 @@ blocksize blueviolet bn bni +bnumeric bo Bochkarev Bochum @@ -1482,6 +1483,7 @@ intra intralayer intramolecular ints +inumeric inv invariants inversed @@ -2706,6 +2708,7 @@ polydispersity polyelectrolyte polyhedra Polym +polymorph polymorphism Ponder popen @@ -3463,6 +3466,7 @@ tmin Tmin tmp tN +tnumeric Tobias Toennies Tohoku From 57616478940b8cd7b77eef5cfcdd730779923ed6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Jul 2022 05:15:50 -0400 Subject: [PATCH 082/443] plug memory leak --- src/GRANULAR/compute_contact_atom.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/GRANULAR/compute_contact_atom.cpp b/src/GRANULAR/compute_contact_atom.cpp index 91511f57ec..b090fb8631 100644 --- a/src/GRANULAR/compute_contact_atom.cpp +++ b/src/GRANULAR/compute_contact_atom.cpp @@ -32,17 +32,16 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeContactAtom::ComputeContactAtom(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - contact(nullptr) + Compute(lmp, narg, arg), group2(nullptr), contact(nullptr) { - if (narg != 3 && narg != 4) error->all(FLERR,"Illegal compute contact/atom command"); + if ((narg != 3) && (narg != 4)) error->all(FLERR, "Illegal compute contact/atom command"); jgroup = group->find("all"); jgroupbit = group->bitmask[jgroup]; if (narg == 4) { group2 = utils::strdup(arg[3]); jgroup = group->find(group2); - if (jgroup == -1) error->all(FLERR, "Compute contact/atom group2 ID does not exist"); + if (jgroup == -1) error->all(FLERR, "Compute contact/atom group2 ID {} does not exist", group2); jgroupbit = group->bitmask[jgroup]; } @@ -54,8 +53,7 @@ ComputeContactAtom::ComputeContactAtom(LAMMPS *lmp, int narg, char **arg) : // error checks - if (!atom->sphere_flag) - error->all(FLERR,"Compute contact/atom requires atom style sphere"); + if (!atom->sphere_flag) error->all(FLERR, "Compute contact/atom requires atom style sphere"); } /* ---------------------------------------------------------------------- */ @@ -63,6 +61,7 @@ ComputeContactAtom::ComputeContactAtom(LAMMPS *lmp, int narg, char **arg) : ComputeContactAtom::~ComputeContactAtom() { memory->destroy(contact); + delete[] group2; } /* ---------------------------------------------------------------------- */ From c9c9139fd6fc2058b4b7ef78bfa528b0b111396f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Jul 2022 05:21:13 -0400 Subject: [PATCH 083/443] fix off-by-one error and resulting out-of-bounds write access. --- src/REACTION/fix_bond_react.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 0405971bdd..f487b8303f 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -1725,7 +1725,7 @@ void FixBondReact::inner_crosscheck_loop() int num_choices = 0; for (int i = 0; i < nfirst_neighs; i++) { if (type[(int)atom->map(xspecial[atom->map(glove[pion][1])][i])] == onemol->type[(int)onemol_xspecial[pion][neigh]-1]) { - if (num_choices > 5) { // here failed because too many identical first neighbors. but really no limit if situation arises + if (num_choices == 5) { // here failed because too many identical first neighbors. but really no limit if situation arises status = GUESSFAIL; return; } From 48ad917d9e27156c426ad9f542ff4ac4fa208a4a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Jul 2022 05:33:12 -0400 Subject: [PATCH 084/443] initialized pointers to null --- src/CG-SPICA/angle_spica.cpp | 17 +++++++++++------ src/CG-SPICA/pair_lj_spica.cpp | 16 +++++++++------- src/CG-SPICA/pair_lj_spica_coul_long.cpp | 9 ++++++--- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/CG-SPICA/angle_spica.cpp b/src/CG-SPICA/angle_spica.cpp index d25779d60c..ff19f29b75 100644 --- a/src/CG-SPICA/angle_spica.cpp +++ b/src/CG-SPICA/angle_spica.cpp @@ -21,17 +21,17 @@ #include "angle_spica.h" -#include #include "atom.h" -#include "neighbor.h" -#include "pair.h" -#include "domain.h" #include "comm.h" +#include "domain.h" +#include "error.h" #include "force.h" #include "math_const.h" #include "memory.h" -#include "error.h" +#include "neighbor.h" +#include "pair.h" +#include #include "lj_spica_common.h" @@ -43,7 +43,12 @@ using namespace LJSPICAParms; /* ---------------------------------------------------------------------- */ -AngleSPICA::AngleSPICA(LAMMPS *lmp) : Angle(lmp) { repflag = 0;} +AngleSPICA::AngleSPICA(LAMMPS *lmp) : + Angle(lmp), k(nullptr), theta0(nullptr), lj_type(nullptr), lj1(nullptr), lj2(nullptr), + lj3(nullptr), lj4(nullptr), rminsq(nullptr), emin(nullptr) +{ + repflag = 0; +} /* ---------------------------------------------------------------------- */ diff --git a/src/CG-SPICA/pair_lj_spica.cpp b/src/CG-SPICA/pair_lj_spica.cpp index 6a14d12146..32af30cd2b 100644 --- a/src/CG-SPICA/pair_lj_spica.cpp +++ b/src/CG-SPICA/pair_lj_spica.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -19,15 +18,15 @@ #include "pair_lj_spica.h" -#include -#include #include "atom.h" #include "comm.h" -#include "force.h" -#include "neigh_list.h" -#include "memory.h" #include "error.h" +#include "force.h" +#include "memory.h" +#include "neigh_list.h" +#include +#include #define LMP_NEED_SPICA_FIND_LJ_TYPE 1 #include "lj_spica_common.h" @@ -37,7 +36,9 @@ using namespace LJSPICAParms; /* ---------------------------------------------------------------------- */ -PairLJSPICA::PairLJSPICA(LAMMPS *lmp) : Pair(lmp) +PairLJSPICA::PairLJSPICA(LAMMPS *lmp) : + Pair(lmp), lj_type(nullptr), cut(nullptr), epsilon(nullptr), sigma(nullptr), lj1(nullptr), + lj2(nullptr), lj3(nullptr), lj4(nullptr), offset(nullptr), rminsq(nullptr), emin(nullptr) { respa_enable = 0; single_enable = 1; @@ -71,6 +72,7 @@ PairLJSPICA::~PairLJSPICA() } } +// clang-format off /* ---------------------------------------------------------------------- */ void PairLJSPICA::compute(int eflag, int vflag) diff --git a/src/CG-SPICA/pair_lj_spica_coul_long.cpp b/src/CG-SPICA/pair_lj_spica_coul_long.cpp index 416561c3a1..9b32f8eafb 100644 --- a/src/CG-SPICA/pair_lj_spica_coul_long.cpp +++ b/src/CG-SPICA/pair_lj_spica_coul_long.cpp @@ -46,7 +46,10 @@ using namespace LJSPICAParms; /* ---------------------------------------------------------------------- */ -PairLJSPICACoulLong::PairLJSPICACoulLong(LAMMPS *lmp) : Pair(lmp) +PairLJSPICACoulLong::PairLJSPICACoulLong(LAMMPS *lmp) : + Pair(lmp), lj_type(nullptr), cut_lj(nullptr), cut_ljsq(nullptr), + epsilon(nullptr), sigma(nullptr), lj1(nullptr), lj2(nullptr), lj3(nullptr), + lj4(nullptr), offset(nullptr), rminsq(nullptr), emin(nullptr) { ewaldflag = pppmflag = 1; respa_enable = 0; @@ -550,8 +553,8 @@ void PairLJSPICACoulLong::write_data_all(FILE *fp) /* ---------------------------------------------------------------------- */ -double PairLJSPICACoulLong::single(int i, int j, int itype, int jtype, double rsq, double factor_coul, - double factor_lj, double &fforce) +double PairLJSPICACoulLong::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_lj, double &fforce) { double r2inv, r, grij, expm2, t, erfc, prefactor; double fraction, table, forcecoul, forcelj, phicoul, philj; From 40920ac6e14e29477e779666f065e14c38c5bb4d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Jul 2022 12:41:43 -0400 Subject: [PATCH 085/443] improved error messages for duplicate or missing entries in manybody potential files --- src/INTERLAYER/pair_drip.cpp | 8 ++++++-- src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 8 ++++---- src/INTERLAYER/pair_kolmogorov_crespi_full.cpp | 8 ++++++-- src/INTERLAYER/pair_kolmogorov_crespi_z.cpp | 8 ++++++-- src/INTERLAYER/pair_lebedeva_z.cpp | 6 ++++-- src/KSPACE/pair_coul_streitz.cpp | 4 ++-- src/MANYBODY/pair_comb.cpp | 6 ++++-- src/MANYBODY/pair_comb3.cpp | 6 ++++-- src/MANYBODY/pair_edip.cpp | 8 ++++++-- src/MANYBODY/pair_edip_multi.cpp | 6 ++++-- src/MANYBODY/pair_extep.cpp | 6 ++++-- src/MANYBODY/pair_gw.cpp | 6 ++++-- src/MANYBODY/pair_nb3b_harmonic.cpp | 8 ++++++-- src/MANYBODY/pair_sw.cpp | 6 ++++-- src/MANYBODY/pair_tersoff.cpp | 6 ++++-- src/MANYBODY/pair_tersoff_mod.cpp | 6 ++++-- src/MANYBODY/pair_tersoff_table.cpp | 6 ++++-- src/MANYBODY/pair_threebody_table.cpp | 8 ++++++-- src/MANYBODY/pair_vashishta.cpp | 6 ++++-- src/MISC/pair_agni.cpp | 4 ++-- 20 files changed, 88 insertions(+), 42 deletions(-) diff --git a/src/INTERLAYER/pair_drip.cpp b/src/INTERLAYER/pair_drip.cpp index 2bd6a16e8c..e7b340c516 100644 --- a/src/INTERLAYER/pair_drip.cpp +++ b/src/INTERLAYER/pair_drip.cpp @@ -256,11 +256,15 @@ void PairDRIP::read_file(char *filename) int n = -1; for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR, "DRIP potential file has duplicate entry"); + if (n >= 0) + error->all(FLERR, "DRIP potential file has a duplicate entry for: {} {}", elements[i], + elements[j]); n = m; } } - if (n < 0) error->all(FLERR, "Potential file is missing an entry"); + if (n < 0) + error->all(FLERR, "Potential file is missing an entry for: {} {}", elements[i], + elements[j]); elem2param[i][j] = n; } } diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index 8e502a9f1f..49b2adbd33 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -313,14 +313,14 @@ void PairILPGrapheneHBN::read_file(char *filename) for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { if (n >= 0) - error->all(FLERR, "{} potential file {} has a duplicate entry", variant_map[variant], - filename); + error->all(FLERR, "{} potential file {} has a duplicate entry for: {} {}", + variant_map[variant], filename, elements[i], elements[j]); n = m; } } if (n < 0) - error->all(FLERR, "{} potential file {} is missing an entry", variant_map[variant], - filename); + error->all(FLERR, "{} potential file {} is missing an entry for: {} {}", + variant_map[variant], filename, elements[i], elements[j]); elem2param[i][j] = n; cutILPsq[i][j] = params[n].rcut * params[n].rcut; } diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp index 0c005d53a2..116018f18a 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp +++ b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp @@ -289,11 +289,15 @@ void PairKolmogorovCrespiFull::read_file(char *filename) int n = -1; for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR, "KC potential file has duplicate entry"); + if (n >= 0) + error->all(FLERR, "KC potential file has a duplicate entry for: {} {}", elements[i], + elements[j]); n = m; } } - if (n < 0) error->all(FLERR, "Potential file is missing an entry"); + if (n < 0) + error->all(FLERR, "Potential file is missing an entry for: {} {}", elements[i], + elements[j]); elem2param[i][j] = n; cutKCsq[i][j] = params[n].rcut * params[n].rcut; } diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp b/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp index 144e09cb50..a2abdc9a1c 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp +++ b/src/INTERLAYER/pair_kolmogorov_crespi_z.cpp @@ -379,11 +379,15 @@ void PairKolmogorovCrespiZ::read_file(char *filename) int n = -1; for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR, "Potential file has duplicate entry"); + if (n >= 0) + error->all(FLERR, "Potential file has a duplicate entry for: {} {}", elements[i], + elements[j]); n = m; } } - if (n < 0) error->all(FLERR, "Potential file is missing an entry"); + if (n < 0) + error->all(FLERR, "Potential file is missing an entry for: {} {}", elements[i], + elements[j]); elem2param[i][j] = n; } } diff --git a/src/INTERLAYER/pair_lebedeva_z.cpp b/src/INTERLAYER/pair_lebedeva_z.cpp index 95e23d3348..0c2c285504 100644 --- a/src/INTERLAYER/pair_lebedeva_z.cpp +++ b/src/INTERLAYER/pair_lebedeva_z.cpp @@ -376,11 +376,13 @@ void PairLebedevaZ::read_file(char *filename) int n = -1; for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {}", + elements[i], elements[j]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {}", + elements[i], elements[j]); elem2param[i][j] = n; } } diff --git a/src/KSPACE/pair_coul_streitz.cpp b/src/KSPACE/pair_coul_streitz.cpp index f388f4cc88..d0ad285f31 100644 --- a/src/KSPACE/pair_coul_streitz.cpp +++ b/src/KSPACE/pair_coul_streitz.cpp @@ -253,11 +253,11 @@ void PairCoulStreitz::setup_params() n = -1; for (m = 0; m < nparams; m++) { if (i == params[m].ielement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has duplicate entry for: {}", elements[i]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {}", elements[i]); elem1param[i] = n; } diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 90e2d72512..ddaf378445 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -687,11 +687,13 @@ void PairComb::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_comb3.cpp b/src/MANYBODY/pair_comb3.cpp index 7c126bf8ab..e5ea235363 100644 --- a/src/MANYBODY/pair_comb3.cpp +++ b/src/MANYBODY/pair_comb3.cpp @@ -642,11 +642,13 @@ void PairComb3::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_edip.cpp b/src/MANYBODY/pair_edip.cpp index 8becba670b..87ccf9b18a 100644 --- a/src/MANYBODY/pair_edip.cpp +++ b/src/MANYBODY/pair_edip.cpp @@ -871,11 +871,15 @@ void PairEDIP::setup_params() n = -1; for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR, "Potential file has duplicate entry"); + if (n >= 0) + error->all(FLERR, "Potential file has a duplicate entry for: {} {} {}", elements[i], + elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR, "Potential file is missing an entry"); + if (n < 0) + error->all(FLERR, "Potential file is missing an entry for: {} {} {}", elements[i], + elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_edip_multi.cpp b/src/MANYBODY/pair_edip_multi.cpp index 4710dcce0a..cb50426033 100644 --- a/src/MANYBODY/pair_edip_multi.cpp +++ b/src/MANYBODY/pair_edip_multi.cpp @@ -687,11 +687,13 @@ void PairEDIPMulti::setup() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_extep.cpp b/src/MANYBODY/pair_extep.cpp index 7f6d266050..f8446e16eb 100644 --- a/src/MANYBODY/pair_extep.cpp +++ b/src/MANYBODY/pair_extep.cpp @@ -696,11 +696,13 @@ void PairExTeP::setup() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_gw.cpp b/src/MANYBODY/pair_gw.cpp index 3e948880ca..ba315bdf70 100644 --- a/src/MANYBODY/pair_gw.cpp +++ b/src/MANYBODY/pair_gw.cpp @@ -427,11 +427,13 @@ void PairGW::setup_params() if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { if (n >= 0) - error->all(FLERR,"Potential file has duplicate entry"); + error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_nb3b_harmonic.cpp b/src/MANYBODY/pair_nb3b_harmonic.cpp index d74c504aea..3b25ac00a3 100644 --- a/src/MANYBODY/pair_nb3b_harmonic.cpp +++ b/src/MANYBODY/pair_nb3b_harmonic.cpp @@ -314,11 +314,15 @@ void PairNb3bHarmonic::setup_params() n = -1; for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR, "Potential file has duplicate entry"); + if (n >= 0) + error->all(FLERR, "Potential file has a duplicate entry for: {} {} {}", elements[i], + elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR, "Potential file is missing an entry"); + if (n < 0) + error->all(FLERR, "Potential file is missing an entry for: {} {} {}", elements[i], + elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index de2a7ac8d6..ce1f8193fd 100644 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -438,11 +438,13 @@ void PairSW::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index 37ea0bfebf..8b4a51ae95 100644 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -543,11 +543,13 @@ void PairTersoff::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_tersoff_mod.cpp b/src/MANYBODY/pair_tersoff_mod.cpp index bc34edfb75..f2edf81ba5 100644 --- a/src/MANYBODY/pair_tersoff_mod.cpp +++ b/src/MANYBODY/pair_tersoff_mod.cpp @@ -177,11 +177,13 @@ void PairTersoffMOD::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_tersoff_table.cpp b/src/MANYBODY/pair_tersoff_table.cpp index dee1fd3237..421d2c1e14 100644 --- a/src/MANYBODY/pair_tersoff_table.cpp +++ b/src/MANYBODY/pair_tersoff_table.cpp @@ -896,11 +896,13 @@ void PairTersoffTable::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_threebody_table.cpp b/src/MANYBODY/pair_threebody_table.cpp index 2f4bc83f5a..044f69a8da 100644 --- a/src/MANYBODY/pair_threebody_table.cpp +++ b/src/MANYBODY/pair_threebody_table.cpp @@ -403,11 +403,15 @@ void PairThreebodyTable::setup_params() n = -1; for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR, "Potential file has duplicate entry"); + if (n >= 0) + error->all(FLERR, "Potential file has a duplicate entry for: {} {} {}", elements[i], + elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR, "Potential file is missing an entry"); + if (n < 0) + error->all(FLERR, "Potential file is missing an entry for: {} {} {}", elements[i], + elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MANYBODY/pair_vashishta.cpp b/src/MANYBODY/pair_vashishta.cpp index 6ce6c6f59a..30855fa6da 100644 --- a/src/MANYBODY/pair_vashishta.cpp +++ b/src/MANYBODY/pair_vashishta.cpp @@ -410,11 +410,13 @@ void PairVashishta::setup_params() for (m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement && k == params[m].kelement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {} {} {}", + elements[i], elements[j], elements[k]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {} {} {}", + elements[i], elements[j], elements[k]); elem3param[i][j][k] = n; } diff --git a/src/MISC/pair_agni.cpp b/src/MISC/pair_agni.cpp index 46cc630f2d..ee744173fc 100644 --- a/src/MISC/pair_agni.cpp +++ b/src/MISC/pair_agni.cpp @@ -406,11 +406,11 @@ void PairAGNI::setup_params() n = -1; for (m = 0; m < nparams; m++) { if (i == params[m].ielement) { - if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + if (n >= 0) error->all(FLERR,"Potential file has a duplicate entry for: {}", elements[i]); n = m; } } - if (n < 0) error->all(FLERR,"Potential file is missing an entry"); + if (n < 0) error->all(FLERR,"Potential file is missing an entry for: {}", elements[i]); elem1param[i] = n; } From cdf600b8cd81354d859b38e91165bf1c5401c795 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Jul 2022 14:34:09 -0400 Subject: [PATCH 086/443] update description --- doc/src/Developer_updating.rst | 36 ++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/doc/src/Developer_updating.rst b/doc/src/Developer_updating.rst index 13e1772589..f33632d91a 100644 --- a/doc/src/Developer_updating.rst +++ b/doc/src/Developer_updating.rst @@ -1,16 +1,21 @@ Notes for updating code written for older LAMMPS versions --------------------------------------------------------- -This section documents how C++ source files that were written for an -older version of LAMMPS need to be updated to be compatible with the -current and future version(s). Due to the active development of LAMMPS -it is likely to always be incomplete. Please contact developer@lammps.org -in case you run across an issue that is not (yet) listed here. Please -also review the latest information about the LAMMPS :doc:`programming style -conventions `. +This section documents how C++ source files that are available *outside +of the LAMMPS source distribution* (e.g. in external USER packages or as +source files provided as a supplement to a publication) that are written +for an older version of LAMMPS and thus need to be updated to be +compatible with the current version of LAMMPS. Due to the active +development of LAMMPS it is likely to always be incomplete. Please +contact developer@lammps.org in case you run across an issue that is not +(yet) listed here. Please also review the latest information about the +LAMMPS :doc:`programming style conventions `, especially +if you are considering to submit the updated version for inclusion into +the LAMMPS distribution. -Available topics in chronological order are: +Available topics in mostly chronological order are: +- `Setting flags in the constructor`_ - `Rename of pack/unpack_comm() to pack/unpack_forward_comm()`_ - `Use ev_init() to initialize variables derived from eflag and vflag`_ - `Use utils::numeric() functions instead of force->numeric()`_ @@ -21,6 +26,21 @@ Available topics in chronological order are: ---- +Setting flags in the constructor +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As LAMMPS gains additional functionality, new flags may need to be set +in the constructor or a class to signal compatibility with such features. +Most of the time the defaults are chosen conservatively, but sometimes +the conservative choice is the uncommon choice, and then those settings +need to be made when updating code. + +Pair styles: + + - ``manybody_flag``: set to 1 if your pair style is not pair-wise additive + - ``restartinfo``: set to 0 if your pair style does not store data in restart files + + Rename of pack/unpack_comm() to pack/unpack_forward_comm() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 87d1aef54360c2a2cea44dbfcbff818a0f0f6b1a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 24 Jul 2022 18:12:04 -0400 Subject: [PATCH 087/443] clarify whom to contact with questions about pre-built binaries. update ubuntu info --- doc/src/Install.rst | 18 ++++-- doc/src/Install_conda.rst | 7 ++ doc/src/Install_linux.rst | 130 ++++++++++++++++---------------------- 3 files changed, 76 insertions(+), 79 deletions(-) diff --git a/doc/src/Install.rst b/doc/src/Install.rst index 157bd32208..04e5333fea 100644 --- a/doc/src/Install.rst +++ b/doc/src/Install.rst @@ -3,10 +3,20 @@ Install LAMMPS You can download LAMMPS as an executable or as source code. -With source code, you also have to :doc:`build LAMMPS `. But you -have more flexibility as to what features to include or exclude in the -build. If you plan to :doc:`modify or extend LAMMPS `, then you -need the source code. +When downloading the LAMMPS source code, you also have to :doc:`build +LAMMPS `. But you have more flexibility as to what features to +include or exclude in the build. When you download and install +pre-compiled LAMMPS executables, you are limited to install which +version of LAMMPS is available and which features are included of these +builds. If you plan to :doc:`modify or extend LAMMPS `, then +you **must** build LAMMPS from the source code. + +.. note:: + + If you have questions about the pre-compiled LAMMPS executables, you + need to contact the people preparing those executables. The LAMMPS + developers have no control over their choices of how they configure + and build their packages and when they update them. .. toctree:: :maxdepth: 1 diff --git a/doc/src/Install_conda.rst b/doc/src/Install_conda.rst index 972c09d7d3..efb7b6146a 100644 --- a/doc/src/Install_conda.rst +++ b/doc/src/Install_conda.rst @@ -38,3 +38,10 @@ up the Conda capability. .. _openkim: https://openkim.org .. _conda: https://docs.conda.io/en/latest/index.html .. _mini_conda_install: https://docs.conda.io/en/latest/miniconda.html + +.. note:: + + If you have questions about these pre-compiled LAMMPS executables, + you need to contact the people preparing those packages. The LAMMPS + developers have no control over their choices of how they configure + and build their packages and when they update them. diff --git a/doc/src/Install_linux.rst b/doc/src/Install_linux.rst index bc44fe3b07..15a244f117 100644 --- a/doc/src/Install_linux.rst +++ b/doc/src/Install_linux.rst @@ -3,13 +3,19 @@ Download an executable for Linux Binaries are available for different versions of Linux: -| :ref:`Pre-built Ubuntu Linux executables ` -| :ref:`Pre-built Fedora Linux executables ` -| :ref:`Pre-built EPEL Linux executables (RHEL, CentOS) ` -| :ref:`Pre-built OpenSuse Linux executables ` -| :ref:`Gentoo Linux executable ` -| :ref:`Arch Linux build-script ` -| +- :ref:`Pre-built Ubuntu Linux executables ` +- :ref:`Pre-built Fedora Linux executables ` +- :ref:`Pre-built EPEL Linux executables (RHEL, CentOS) ` +- :ref:`Pre-built OpenSuse Linux executables ` +- :ref:`Gentoo Linux executable ` +- :ref:`Arch Linux build-script ` + +.. note:: + + If you have questions about these pre-compiled LAMMPS executables, + you need to contact the people preparing those packages. The LAMMPS + developers have no control over their choices of how they configure + and build their packages and when they update them. ---------- @@ -18,41 +24,28 @@ Binaries are available for different versions of Linux: Pre-built Ubuntu Linux executables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A pre-built LAMMPS executable suitable for running on the latest -Ubuntu Linux versions, can be downloaded as a Debian package. This -allows you to install LAMMPS with a single command, and stay -up-to-date with the current stable version of LAMMPS by simply updating -your operating system. Please note, that the repository below offers -two LAMMPS packages, ``lammps-daily`` and ``lammps-stable``. The -LAMMPS developers recommend to use the ``lammps-stable`` package for -any production simulations. The ``lammps-daily`` package is built -from the LAMMPS development sources, and those versions may have known -issues and bugs when new features are added and the software has not -undergone full release testing. - -To install the appropriate personal-package archives (PPAs), do the -following once: - -.. code-block:: bash - - $ sudo add-apt-repository ppa:gladky-anton/lammps - $ sudo add-apt-repository ppa:openkim/latest - $ sudo apt-get update +A pre-built LAMMPS executable suitable for running on the latest Ubuntu +Linux versions, can be downloaded as a Debian package. This allows you +to install LAMMPS with a single command, and stay (mostly) up-to-date +with the current stable version of LAMMPS by simply updating your +operating system. To install LAMMPS do the following once: .. code-block:: bash - $ sudo apt-get install lammps-stable + $ sudo apt-get install lammps -This downloads an executable named ``lmp_stable`` to your box, which -can then be used in the usual way to run input scripts: +This downloads an executable named ``lmp`` to your box and multiple +packages with supporting data, examples and libraries as well as any +missing dependencies. This executable can then be used in the usual way +to run input scripts: .. code-block:: bash - $ lmp_stable -in in.lj + $ lmp -in in.lj -To update LAMMPS to the most current stable version, do the following: +To update LAMMPS to the latest packaged version, do the following: .. code-block:: bash @@ -60,44 +53,24 @@ To update LAMMPS to the most current stable version, do the following: which will also update other packages on your system. -To get a copy of the current documentation and examples: - -.. code-block:: bash - - $ sudo apt-get install lammps-stable-doc - -which will download the doc files in -``/usr/share/doc/lammps-stable-doc/doc`` and example problems in -``/usr/share/doc/lammps-doc/examples``. - -To get a copy of the current potentials files: - -.. code-block:: bash - - $ sudo apt-get install lammps-stable-data - -which will download the potentials files to -``/usr/share/lammps-stable/potentials``. The ``lmp_stable`` binary is -hard-coded to look for potential files in this directory (it does not -use the ``LAMMPS_POTENTIALS`` environment variable, as described -in :doc:`pair_coeff ` command). - -The ``lmp_stable`` binary is built with the :ref:`KIM package ` which -results in the above command also installing the ``kim-api`` binaries when LAMMPS -is installed. In order to use potentials from `openkim.org `_, you -can install the ``openkim-models`` package +The ``lmp`` binary is built with the :ref:`KIM package ` included, +which results in the above command also installing the ``kim-api`` +binaries when LAMMPS is installed. In order to use potentials from +`openkim.org `_, you can also install the ``openkim-models`` +package .. code-block:: bash $ sudo apt-get install openkim-models +Or use the KIM-API commands to download and install individual models. To un-install LAMMPS, do the following: .. code-block:: bash - $ sudo apt-get remove lammps-stable + $ sudo apt-get remove lammps -Please use ``lmp_stable -help`` to see which compilation options, packages, +Please use ``lmp -help`` to see which compilation options, packages, and styles are included in the binary. Thanks to Anton Gladky (gladky.anton at gmail.com) for setting up this @@ -110,21 +83,21 @@ Ubuntu package capability. Pre-built Fedora Linux executables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Pre-built LAMMPS packages for stable releases are available -in the Fedora Linux distribution as of version 28. The packages -can be installed via the dnf package manager. There are 3 basic -varieties (lammps = no MPI, lammps-mpich = MPICH MPI library, -lammps-openmpi = OpenMPI MPI library) and for each support for -linking to the C library interface (lammps-devel, lammps-mpich-devel, -lammps-openmpi-devel), the header for compiling programs using -the C library interface (lammps-headers), and the LAMMPS python -module for Python 3. All packages can be installed at the same -time and the name of the LAMMPS executable is ``lmp`` and ``lmp_openmpi`` -or ``lmp_mpich`` respectively. By default, ``lmp`` will refer to the -serial executable, unless one of the MPI environment modules is loaded -(``module load mpi/mpich-x86_64`` or ``module load mpi/openmpi-x86_64``). -Then the corresponding parallel LAMMPS executable can be used. -The same mechanism applies when loading the LAMMPS python module. +Pre-built LAMMPS packages for stable releases are available in the +Fedora Linux distribution as of Fedora version 28. The packages can be +installed via the dnf package manager. There are 3 basic varieties +(lammps = no MPI, lammps-mpich = MPICH MPI library, lammps-openmpi = +OpenMPI MPI library) and for each support for linking to the C library +interface (lammps-devel, lammps-mpich-devel, lammps-openmpi-devel), the +header for compiling programs using the C library interface +(lammps-headers), and the LAMMPS python module for Python 3. All +packages can be installed at the same time and the name of the LAMMPS +executable is ``lmp`` and ``lmp_openmpi`` or ``lmp_mpich`` respectively. +By default, ``lmp`` will refer to the serial executable, unless one of +the MPI environment modules is loaded (``module load mpi/mpich-x86_64`` +or ``module load mpi/openmpi-x86_64``). Then the corresponding parallel +LAMMPS executable can be used. The same mechanism applies when loading +the LAMMPS python module. To install LAMMPS with OpenMPI and run an input ``in.lj`` with 2 CPUs do: @@ -273,3 +246,10 @@ Alternatively, you may use an AUR helper to install these packages. Note that the AUR provides build-scripts that download the source and the build the package on your machine. + +.. note:: + + It looks like the Arch Linux AUR repository build scripts for LAMMPS + have not been updated since the 29 October 2020 version. You may want + to consider installing a more current version of LAMMPS from source + directly. From 762e79c49dcd4309629fe5a97b5f4cdc1d0b4ade Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 08:56:51 -0400 Subject: [PATCH 088/443] initialize possibly uninitialized variabled --- src/AMOEBA/amoeba_polar.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/AMOEBA/amoeba_polar.cpp b/src/AMOEBA/amoeba_polar.cpp index f0670ea8c6..b8020cb513 100644 --- a/src/AMOEBA/amoeba_polar.cpp +++ b/src/AMOEBA/amoeba_polar.cpp @@ -499,6 +499,18 @@ void PairAmoeba::polar_real() urc3[k] = rc3[k] * factor_uscale; urc5[k] = rc5[k] * factor_uscale; } + } else { + // avoid uninitialized data access when damp == 0.0 + psc3 = psc5 = psc7 = dsc3 = dsc5 = dsc7 = usc3 = usc5 = 0.0; + psr3 = psr5 = psr7 = dsr3 = dsr5 = dsr7 = usr5 = 0.0; + prc3[0] = prc3[1] = prc3[2] = 0.0; + drc3[0] = drc3[1] = drc3[2] = 0.0; + prc5[0] = prc5[1] = prc5[2] = 0.0; + drc5[0] = drc5[1] = drc5[2] = 0.0; + prc7[0] = prc7[1] = prc7[2] = 0.0; + drc7[0] = drc7[1] = drc7[2] = 0.0; + urc3[0] = urc3[1] = urc3[2] = 0.0; + urc5[0] = urc5[1] = urc5[2] = 0.0; } // apply charge penetration damping to scale factors From bcc49aca844343a838fbc8bf801b759f5a7251a3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 09:01:26 -0400 Subject: [PATCH 089/443] fix logic issue --- src/AMOEBA/amoeba_utils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AMOEBA/amoeba_utils.cpp b/src/AMOEBA/amoeba_utils.cpp index b01b9f11b6..332b62708e 100644 --- a/src/AMOEBA/amoeba_utils.cpp +++ b/src/AMOEBA/amoeba_utils.cpp @@ -84,9 +84,9 @@ void PairAmoeba::kmpole() if (bondneigh[j] < smallest) { smallest = bondneigh[j]; k = j; + bondneigh[k] = bondneigh[m]; + bondneigh[m] = smallest; } - bondneigh[k] = bondneigh[m]; - bondneigh[m] = smallest; } } From e99494d838c8fa3034e919222c0367c0a33affd0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 09:02:54 -0400 Subject: [PATCH 090/443] fix copy-n-paste error --- src/AMOEBA/amoeba_kspace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AMOEBA/amoeba_kspace.cpp b/src/AMOEBA/amoeba_kspace.cpp index 22b83c1b59..5e12deae1c 100644 --- a/src/AMOEBA/amoeba_kspace.cpp +++ b/src/AMOEBA/amoeba_kspace.cpp @@ -1137,7 +1137,7 @@ void PairAmoeba::kewald() // NOTE: also worry about satisfying Tinker minfft ? while (!factorable(ndfft1)) ndfft1++; - while (!factorable(ndfft2)) ndfft3++; + while (!factorable(ndfft2)) ndfft2++; while (!factorable(ndfft3)) ndfft3++; } From 6dc966408704ed604b209539aec4c4d087f55392 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 09:06:09 -0400 Subject: [PATCH 091/443] avoid uninitialized data access --- src/AMOEBA/angle_amoeba.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/AMOEBA/angle_amoeba.cpp b/src/AMOEBA/angle_amoeba.cpp index 4b9342f058..33b89a29f5 100644 --- a/src/AMOEBA/angle_amoeba.cpp +++ b/src/AMOEBA/angle_amoeba.cpp @@ -53,6 +53,9 @@ AngleAmoeba::AngleAmoeba(LAMMPS *lmp) : Angle(lmp) ub_k = nullptr; ub_r0 = nullptr; + + setflag_a = setflag_ba = setflag_ub = nullptr; + enable_angle = enable_urey = 0; } /* ---------------------------------------------------------------------- */ From f736248efb484b1f199eceb75c4d5969262fcc7e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 09:17:37 -0400 Subject: [PATCH 092/443] replace calls to pow() with faster functions for integer powers --- src/AMOEBA/amoeba_hal.cpp | 13 +++++++++---- src/AMOEBA/amoeba_induce.cpp | 9 ++++++--- src/AMOEBA/amoeba_kspace.cpp | 11 +++++++---- src/AMOEBA/amoeba_multipole.cpp | 5 ++++- src/AMOEBA/amoeba_polar.cpp | 10 +++++++--- src/AMOEBA/amoeba_repulsion.cpp | 2 +- src/AMOEBA/pair_amoeba.cpp | 7 +++++-- 7 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/AMOEBA/amoeba_hal.cpp b/src/AMOEBA/amoeba_hal.cpp index 21bb7ad099..896595945e 100644 --- a/src/AMOEBA/amoeba_hal.cpp +++ b/src/AMOEBA/amoeba_hal.cpp @@ -16,12 +16,17 @@ #include "atom.h" #include "error.h" +#include "math_special.h" #include "neigh_list.h" #include using namespace LAMMPS_NS; +using MathSpecial::square; +using MathSpecial::cube; +using MathSpecial::powint; + enum{VDWL,REPULSE,QFER,DISP,MPOLE,POLAR,USOLV,DISP_LONG,MPOLE_LONG,POLAR_LONG}; /* ---------------------------------------------------------------------- @@ -114,14 +119,14 @@ void PairAmoeba::hal() } eps *= factor_hal; - rv7 = pow(rv,7.0); - rik6 = pow(rik2,3.0); + rv7 = powint(rv,7); + rik6 = cube(rik2); rik7 = rik6 * rik; rho = rik7 + ghal*rv7; tau = (dhal+1.0) / (rik + dhal*rv); - tau7 = pow(tau,7.0); + tau7 = powint(tau,7); dtau = tau / (dhal+1.0); - gtau = eps*tau7*rik6*(ghal+1.0)*pow(rv7/rho,2.0); + gtau = eps*tau7*rik6*(ghal+1.0)*square(rv7/rho); e = eps*tau7*rv7*((ghal+1.0)*rv7/rho-2.0); de = -7.0 * (dtau*e+gtau); diff --git a/src/AMOEBA/amoeba_induce.cpp b/src/AMOEBA/amoeba_induce.cpp index 3d9d7809cc..43688cef94 100644 --- a/src/AMOEBA/amoeba_induce.cpp +++ b/src/AMOEBA/amoeba_induce.cpp @@ -22,6 +22,7 @@ #include "fft3d_wrap.h" #include "fix_store.h" #include "math_const.h" +#include "math_special.h" #include "memory.h" #include "my_page.h" #include "neigh_list.h" @@ -32,6 +33,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +using MathSpecial::cube; + enum{INDUCE,RSD,SETUP_AMOEBA,SETUP_HIPPO,KMPOLE,AMGROUP}; // forward comm enum{FIELD,ZRSD,TORQUE,UFLD}; // reverse comm enum{VDWL,REPULSE,QFER,DISP,MPOLE,POLAR,USOLV,DISP_LONG,MPOLE_LONG,POLAR_LONG}; @@ -732,7 +735,7 @@ void PairAmoeba::uscale0b(int mode, double **rsd, double **rsdp, damp = pdi * pdamp[jtype]; if (damp != 0.0) { pgamma = MIN(pti,thole[jtype]); - damp = -pgamma * pow((r/damp),3.0); + damp = -pgamma * cube(r/damp); if (damp > -50.0) { expdamp = exp(damp); scale3 *= 1.0 - expdamp; @@ -1332,7 +1335,7 @@ void PairAmoeba::udirect2b(double **field, double **fieldp) } } else { pgamma = MIN(pti,thole[jtype]); - damp = pgamma * pow(r/damp,3.0); + damp = pgamma * cube(r/damp); if (damp < 50.0) { expdamp = exp(-damp); scale3 = 1.0 - expdamp; @@ -1384,7 +1387,7 @@ void PairAmoeba::udirect2b(double **field, double **fieldp) damp = pdi * pdamp[jtype]; if (damp != 0.0) { pgamma = MIN(pti,thole[jtype]); - damp = pgamma * pow(r/damp,3.0); + damp = pgamma * cube(r/damp); if (damp < 50.0) { expdamp = exp(-damp); scale3 = 1.0 - expdamp; diff --git a/src/AMOEBA/amoeba_kspace.cpp b/src/AMOEBA/amoeba_kspace.cpp index 5e12deae1c..51b206b6d8 100644 --- a/src/AMOEBA/amoeba_kspace.cpp +++ b/src/AMOEBA/amoeba_kspace.cpp @@ -17,6 +17,7 @@ #include "atom.h" #include "domain.h" #include "math_const.h" +#include "math_special.h" #include "memory.h" #include @@ -24,6 +25,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +using MathSpecial::powint; + #define ANINT(x) ((x)>0 ? floor((x)+0.5) : ceil((x)-0.5)) /* ---------------------------------------------------------------------- @@ -173,13 +176,13 @@ void PairAmoeba::dftmod(double *bsmod, double *bsarray, int nfft, int order) factor = MY_PI * k / nfft; for (j = 1; j <= jcut; j++) { arg = factor / (factor + MY_PI*j); - sum1 += pow(arg,order); - sum2 += pow(arg,order2); + sum1 += powint(arg,order); + sum2 += powint(arg,order2); } for (j = 1; j <= jcut; j++) { arg = factor / (factor - MY_PI*j); - sum1 += pow(arg,order); - sum2 += pow(arg,order2); + sum1 += powint(arg,order); + sum2 += powint(arg,order2); } zeta = sum2 / sum1; } diff --git a/src/AMOEBA/amoeba_multipole.cpp b/src/AMOEBA/amoeba_multipole.cpp index 5d11bde1ab..8466a8fe1d 100644 --- a/src/AMOEBA/amoeba_multipole.cpp +++ b/src/AMOEBA/amoeba_multipole.cpp @@ -20,6 +20,7 @@ #include "domain.h" #include "fft3d_wrap.h" #include "math_const.h" +#include "math_special.h" #include "memory.h" #include "neigh_list.h" @@ -29,6 +30,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +using MathSpecial::square; + enum{FIELD,ZRSD,TORQUE,UFLD}; // reverse comm enum{VDWL,REPULSE,QFER,DISP,MPOLE,POLAR,USOLV,DISP_LONG,MPOLE_LONG,POLAR_LONG}; @@ -670,7 +673,7 @@ void PairAmoeba::multipole_kspace() nzlo = m_kspace->nzlo_fft; nzhi = m_kspace->nzhi_fft; - pterm = pow((MY_PI/aewald),2.0); + pterm = square(MY_PI/aewald); volterm = MY_PI * volbox; n = 0; diff --git a/src/AMOEBA/amoeba_polar.cpp b/src/AMOEBA/amoeba_polar.cpp index b8020cb513..ad6b585f25 100644 --- a/src/AMOEBA/amoeba_polar.cpp +++ b/src/AMOEBA/amoeba_polar.cpp @@ -20,6 +20,7 @@ #include "domain.h" #include "fft3d_wrap.h" #include "math_const.h" +#include "math_special.h" #include "memory.h" #include "neigh_list.h" @@ -29,6 +30,9 @@ using namespace LAMMPS_NS; using namespace MathConst; +using MathSpecial::square; +using MathSpecial::cube; + enum{FIELD,ZRSD,TORQUE,UFLD}; // reverse comm enum{MUTUAL,OPT,TCG,DIRECT}; enum{VDWL,REPULSE,QFER,DISP,MPOLE,POLAR,USOLV,DISP_LONG,MPOLE_LONG,POLAR_LONG}; @@ -82,7 +86,7 @@ void PairAmoeba::polar() // compute the Ewald self-energy torque and virial terms - term = (4.0/3.0) * felec * pow(aewald,3.0) / MY_PIS; + term = (4.0/3.0) * felec * cube(aewald) / MY_PIS; for (i = 0; i < nlocal; i++) { dix = rpole[i][1]; @@ -454,7 +458,7 @@ void PairAmoeba::polar_real() damp = pdi * pdamp[jtype]; if (damp != 0.0) { pgamma = MIN(pti,thole[jtype]); - damp = pgamma * pow(r/damp,3.0); + damp = pgamma * cube(r/damp); if (damp < 50.0) { expdamp = exp(-damp); sc3 = 1.0 - expdamp; @@ -1272,7 +1276,7 @@ void PairAmoeba::polar_kspace() int nlocal = atom->nlocal; double volbox = domain->prd[0] * domain->prd[1] * domain->prd[2]; - pterm = pow((MY_PI/aewald),2.0); + pterm = square(MY_PI/aewald); volterm = MY_PI * volbox; // initialize variables required for the scalar summation diff --git a/src/AMOEBA/amoeba_repulsion.cpp b/src/AMOEBA/amoeba_repulsion.cpp index 0784a32d0b..041d74e54d 100644 --- a/src/AMOEBA/amoeba_repulsion.cpp +++ b/src/AMOEBA/amoeba_repulsion.cpp @@ -504,7 +504,7 @@ void PairAmoeba::damprep(double r, double r2, double rr1, double rr3, dmpk24 = dmpk23 * dmpk2; dmpk25 = dmpk24 * dmpk2; term = dmpi22 - dmpk22; - pre = 8192.0 * dmpi23 * dmpk23 / pow(term,4.0); + pre = 8192.0 * dmpi23 * dmpk23 / (term*term*term*term); tmp = 4.0 * dmpi2 * dmpk2 / term; s = (dampi-tmp)*expk + (dampk+tmp)*expi; diff --git a/src/AMOEBA/pair_amoeba.cpp b/src/AMOEBA/pair_amoeba.cpp index be5f9c73df..e8b7b71753 100644 --- a/src/AMOEBA/pair_amoeba.cpp +++ b/src/AMOEBA/pair_amoeba.cpp @@ -25,6 +25,7 @@ #include "force.h" #include "gridcomm.h" #include "group.h" +#include "math_special.h" #include "memory.h" #include "modify.h" #include "my_page.h" @@ -40,6 +41,8 @@ using namespace LAMMPS_NS; +using MathSpecial::powint; + enum{INDUCE,RSD,SETUP_AMOEBA,SETUP_HIPPO,KMPOLE,AMGROUP,PVAL}; // forward comm enum{FIELD,ZRSD,TORQUE,UFLD}; // reverse comm enum{ARITHMETIC,GEOMETRIC,CUBIC_MEAN,R_MIN,SIGMA,DIAMETER,HARMONIC,HHG,W_H}; @@ -1956,7 +1959,7 @@ void PairAmoeba::choose(int which) // taper coeffs - double denom = pow(off-cut,5.0); + double denom = powint(off-cut,5); c0 = off*off2 * (off2 - 5.0*off*cut + 10.0*cut2) / denom; c1 = -30.0 * off2*cut2 / denom; c2 = 30.0 * (off2*cut+off*cut2) / denom; @@ -2026,7 +2029,7 @@ void PairAmoeba::mix() } else if (epsilon_rule == HHG) { eij = 4.0 * (ei*ej) / ((sei+sej)*(sei+sej)); } else if (epsilon_rule == W_H) { - eij = 2.0 * (sei*sej) * pow(ri*rj,3.0) / (pow(ri,6.0) + pow(rj,6.0)); + eij = 2.0 * (sei*sej) * powint(ri*rj,3) / (powint(ri,6) + powint(rj,6)); } else { eij = sei * sej; } From 7b54b974d3dbc1f29f6eaa68fea2adf034f47447 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 11:48:21 -0400 Subject: [PATCH 093/443] remove dead code --- src/dump_custom.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/dump_custom.h b/src/dump_custom.h index b27a9950cd..dd653d5e98 100644 --- a/src/dump_custom.h +++ b/src/dump_custom.h @@ -127,11 +127,6 @@ class DumpCustom : public Dump { void header_item(bigint); void header_item_triclinic(bigint); - typedef int (DumpCustom::*FnPtrConvert)(int, double *); - FnPtrConvert convert_choice; // ptr to convert data functions - int convert_image(int, double *); - int convert_noimage(int, double *); - typedef void (DumpCustom::*FnPtrWrite)(int, double *); FnPtrWrite write_choice; // ptr to write data functions void write_binary(int, double *); From 5f6785017138f173bfa14e7552f3537fd97e3674 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Jul 2022 22:32:59 -0400 Subject: [PATCH 094/443] correct typos --- doc/src/Intro_citing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/Intro_citing.rst b/doc/src/Intro_citing.rst index e10b1857f1..aaf62028ae 100644 --- a/doc/src/Intro_citing.rst +++ b/doc/src/Intro_citing.rst @@ -33,9 +33,9 @@ initial versions of LAMMPS is: DOI for the LAMMPS source code ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LAMMPS developers use the `Zenodo service at CERN `_ -to create digital object identifies (DOI) for stable releases of the -LAMMPS source code. There are two types of DOIs for the LAMMPS source code. +The LAMMPS developers use the `Zenodo service at CERN `_ +to create digital object identifiers (DOI) for stable releases of the +LAMMPS source code. There are two types of DOIs for the LAMMPS source code. The canonical DOI for **all** versions of LAMMPS, which will always point to the **latest** stable release version is: From d347a27a396dde34254739e17f5876e9fa32d0f1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 26 Jul 2022 09:18:21 -0400 Subject: [PATCH 095/443] add reference --- doc/src/label.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/label.rst b/doc/src/label.rst index 710a1b1b40..430587135f 100644 --- a/doc/src/label.rst +++ b/doc/src/label.rst @@ -38,7 +38,7 @@ Restrictions Related commands """""""""""""""" -none +:doc:`jump `, :doc:`next ` Default From b2cdc4091908478a3054b55d48d3e2516ccdf6ef Mon Sep 17 00:00:00 2001 From: Paulius Velesko Date: Tue, 26 Jul 2022 16:00:43 +0000 Subject: [PATCH 096/443] Enable CHIP-SPV support --- cmake/Modules/Packages/GPU.cmake | 14 ++++++++++++-- lib/gpu/lal_pre_cuda_hip.h | 12 ++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/cmake/Modules/Packages/GPU.cmake b/cmake/Modules/Packages/GPU.cmake index 75569aa55d..36409378be 100644 --- a/cmake/Modules/Packages/GPU.cmake +++ b/cmake/Modules/Packages/GPU.cmake @@ -233,7 +233,7 @@ elseif(GPU_API STREQUAL "OPENCL") elseif(GPU_API STREQUAL "HIP") if(NOT DEFINED HIP_PATH) if(NOT DEFINED ENV{HIP_PATH}) - set(HIP_PATH "/opt/rocm/hip" CACHE PATH "Path to HIP installation") + message(FATAL_ERROR "GPU_API=HIP requires HIP_PATH to be defined") else() set(HIP_PATH $ENV{HIP_PATH} CACHE PATH "Path to HIP installation") endif() @@ -261,6 +261,8 @@ elseif(GPU_API STREQUAL "HIP") if(HIP_PLATFORM STREQUAL "hcc" OR HIP_PLATFORM STREQUAL "amd") set(HIP_ARCH "gfx906" CACHE STRING "HIP target architecture") + elseif(HIP_PLATFORM STREQUAL "spirv") + set(HIP_ARCH "spirv" CACHE STRING "HIP target architecture") elseif(HIP_PLATFORM STREQUAL "nvcc") find_package(CUDA REQUIRED) set(HIP_ARCH "sm_50" CACHE STRING "HIP primary CUDA architecture (e.g. sm_60)") @@ -321,7 +323,15 @@ elseif(GPU_API STREQUAL "HIP") set(CUBIN_FILE "${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}.cubin") set(CUBIN_H_FILE "${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h") - if(HIP_PLATFORM STREQUAL "hcc" OR HIP_PLATFORM STREQUAL "amd") + if(HIP_PLATFORM STREQUAL "spirv") + configure_file(${CU_FILE} ${CU_CPP_FILE} COPYONLY) + + add_custom_command(OUTPUT ${CUBIN_FILE} + VERBATIM COMMAND ${HIP_HIPCC_EXECUTABLE} -c -O3 -DUSE_HIP -D_${GPU_PREC_SETTING} -DLAMMPS_${LAMMPS_SIZES} -I${LAMMPS_LIB_SOURCE_DIR}/gpu -o ${CUBIN_FILE} ${CU_CPP_FILE} + DEPENDS ${CU_CPP_FILE} + COMMENT "Gerating ${CU_NAME}.cubin") + + elseif(HIP_PLATFORM STREQUAL "hcc" OR HIP_PLATFORM STREQUAL "amd") configure_file(${CU_FILE} ${CU_CPP_FILE} COPYONLY) if(HIP_COMPILER STREQUAL "clang") diff --git a/lib/gpu/lal_pre_cuda_hip.h b/lib/gpu/lal_pre_cuda_hip.h index 47a005b998..f6ab1b5b6b 100644 --- a/lib/gpu/lal_pre_cuda_hip.h +++ b/lib/gpu/lal_pre_cuda_hip.h @@ -30,7 +30,7 @@ // ------------------------------------------------------------------------- -#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) +#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) || defined(__HIP_PLATFORM_SPIRV__) #define CONFIG_ID 303 #define SIMD_SIZE 64 #else @@ -112,7 +112,7 @@ // KERNEL MACROS - TEXTURES // ------------------------------------------------------------------------- -#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) +#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) || defined(__HIP_PLATFORM_SPIRV__) #define _texture(name, type) __device__ type* name #define _texture_2d(name, type) __device__ type* name #else @@ -135,8 +135,8 @@ ans=__hiloint2double(qt.y, qt.x); \ } #else - #define fetch4(ans,i,pos_tex) ans=tex1Dfetch(pos_tex, i); - #define fetch(ans,i,q_tex) ans=tex1Dfetch(q_tex,i); + #define fetch4(ans,i,pos_tex) tex1Dfetch(&ans, pos_tex, i); + #define fetch(ans,i,q_tex) tex1Dfetch(&ans, q_tex,i); #endif #else #define fetch4(ans,i,x) ans=x[i] @@ -152,7 +152,7 @@ #define mu_tex mu_ #endif -#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) +#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) || defined(__HIP_PLATFORM_SPIRV__) #undef fetch4 #undef fetch @@ -209,7 +209,7 @@ #endif #endif -#if defined(CUDA_PRE_NINE) || defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) +#if defined(CUDA_PRE_NINE) || defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) || defined(__HIP_PLATFORM_SPIRV__) #ifdef _SINGLE_SINGLE #define shfl_down __shfl_down From e973a4b31c74f3fab26010e324a863d8b02a6bd1 Mon Sep 17 00:00:00 2001 From: Paulius Velesko Date: Tue, 26 Jul 2022 16:14:43 +0000 Subject: [PATCH 097/443] workaround for CHIP-SPV different textrure func --- .gitignore | 1 - lib/gpu/lal_pre_cuda_hip.h | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0cc211ab09..bd2d0ea705 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,3 @@ out/RelWithDebInfo out/Release out/x86 out/x64 -benchmark/* diff --git a/lib/gpu/lal_pre_cuda_hip.h b/lib/gpu/lal_pre_cuda_hip.h index f6ab1b5b6b..ec666a2863 100644 --- a/lib/gpu/lal_pre_cuda_hip.h +++ b/lib/gpu/lal_pre_cuda_hip.h @@ -134,9 +134,12 @@ int2 qt = tex1Dfetch(q_tex,i); \ ans=__hiloint2double(qt.y, qt.x); \ } + #elseif defined(__HIP_PLATFORM_SPIRV__) + #define fetch4(ans,i,pos_tex) tex1Dfetch(&ans, pos_tex, i); + #define fetch(ans,i,q_tex) tex1Dfetch(&ans, q_tex,i); #else - #define fetch4(ans,i,pos_tex) tex1Dfetch(&ans, pos_tex, i); - #define fetch(ans,i,q_tex) tex1Dfetch(&ans, q_tex,i); + #define fetch4(ans,i,pos_tex) ans=tex1Dfetch(pos_tex, i); + #define fetch(ans,i,q_tex) ans=tex1Dfetch(q_tex,i); #endif #else #define fetch4(ans,i,x) ans=x[i] From 4f8a1ca52685f65965aab558641b7ce58b39c86e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 26 Jul 2022 12:32:42 -0400 Subject: [PATCH 098/443] correct formatting --- doc/lammps.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/lammps.1 b/doc/lammps.1 index 5f1c25867e..586627258e 100644 --- a/doc/lammps.1 +++ b/doc/lammps.1 @@ -161,7 +161,7 @@ list references for specific cite-able features used during a run. .TP \fB\-pk