diff --git a/src/USER-MISC/compute_pressure_cylinder.cpp b/src/USER-MISC/compute_pressure_cylinder.cpp new file mode 100644 index 0000000000..bae6398691 --- /dev/null +++ b/src/USER-MISC/compute_pressure_cylinder.cpp @@ -0,0 +1,493 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" +#include "stdlib.h" +#include "compute_pressure_cylinder.h" +#include "atom.h" +#include "update.h" +#include "force.h" +#include "pair.h" +#include "neighbor.h" +#include "neigh_request.h" +#include "neigh_list.h" +#include "group.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +static const char cite_compute_pressure_cylinder[] = + "compute pressure/cylinder:\n\n" + "@Article{Addington,\n" + " author = {C. K. Addington, Y. Long, K. E. Gubbins},\n" + " title = {The pressure in interfaces having cylindrical geometry},\n" + " journal = {J.~Chem.~Phys.},\n" + " year = 2018,\n" + " volume = 149,\n" + " pages = {084109}\n" + "}\n\n"; + +if (lmp->citeme) lmp->citeme->add(cite_compute_pressure_cylinder); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Calculate the configurational components of the pressure tensor in + cylindrical geometry, according to the formulation of Addington et al. (2018) + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ + +ComputePressureCyl::ComputePressureCyl(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg) +{ + if (narg != 7) error->all(FLERR,"Illegal compute pressure/cylinder command"); + + zlo=force->numeric(FLERR,arg[3]); + zhi=force->numeric(FLERR,arg[4]); + Rmax=force->numeric(FLERR,arg[5]); + bin_width=force->numeric(FLERR,arg[6]); + + nbins=(int)(Rmax/bin_width); + + nzbins=(int)((zhi-zlo)/bin_width); + + array_flag=1; + vector_flag=0; + extarray=0; + size_array_cols = 5; // r, number density, Pr, Pphi, Pz + size_array_rows = nbins; + + Pr_temp = new double[nbins]; + Pr_all = new double[nbins]; + Pz_temp = new double[nbins]; + Pz_all = new double[nbins]; + Pphi_temp = new double[nbins]; + Pphi_all = new double[nbins]; + R = new double[nbins]; + R2 = new double[nbins]; + PrAinv = new double[nbins]; + PzAinv = new double[nbins]; + Rinv = new double[nbins]; + binz = new double[nzbins]; + + R2kin = new double[nbins]; + density_temp = new double[nbins]; + invVbin = new double[nbins]; + density_all = new double[nbins]; + + memory->create(array,nbins,5,"PN:array"); + + nphi=360; + tangent = new double[nphi]; + ephi_x = new double[nphi]; + ephi_y = new double[nphi]; + + nktv2p = force->nktv2p; + +} + +/* ---------------------------------------------------------------------- */ + +ComputePressureCyl::~ComputePressureCyl() +{ + // count all of these for memory usage + memory->destroy(array); + delete [] R; + delete [] Rinv; + delete [] R2; + delete [] R2kin; + delete [] invVbin; + delete [] density_temp; + delete [] density_all; + delete [] tangent; + delete [] ephi_x; + delete [] ephi_y; + delete [] Pr_temp; + delete [] Pr_all; + delete [] Pz_temp; + delete [] Pz_all; + delete [] Pphi_temp; + delete [] Pphi_all; + delete [] PrAinv; + delete [] PzAinv; + delete [] binz; +} + +/* ---------------------------------------------------------------------- */ + +void ComputePressureCyl::init() +{ + if (force->pair == NULL) + error->all(FLERR,"No pair style is defined for compute pressure/cylinder"); + if (force->pair->single_enable == 0) + error->all(FLERR,"Pair style does not support compute pressure/cylinder"); + + double phi; + + for (int iphi=0;iphirequest(this,instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; + + for (int zzz=0;zzzntimestep; + + int ibin; + + // clear pressures + for (ibin=0;ibinx; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + // invoke half neighbor list (will copy or build if necessary) + neighbor->build_one(list); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // calculate number density (by radius) + double temp_R2; + for (i=0;izlo) + { + temp_R2=x[i][0]*x[i][0]+x[i][1]*x[i][1]; + if (temp_R2>R2kin[nbins-1]) continue; // outside of Rmax + + for (j=0;jpair; + double **cutsq = force->pair->cutsq; + + double r1=0.0; + double r2=0.0; + double risq,rjsq; + double ri,rj,rij,fij; + double A,B,C,Bsq,A2inv,A4,D; + double alpha1,alpha2,aij; + double xi,yi,zi,dx,dy,dz; + double m,xR,yR,zR,fn; + double alpha,xL,yL,zL,L2,ftphi,ftz; + double sqrtD; + double lower_z,upper_z; + + for (ii = 0; ii < inum; ii++) + { + i = ilist[ii]; + if (!(mask[i] & groupbit)) continue; + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itag = tag[i]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + r1=x[i][0]*x[i][0]+x[i][1]*x[i][1]; + + for (jj = 0; jj < jnum; jj++) + { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + + if (!(mask[j] & groupbit)) continue; + + // itag = jtag is possible for long cutoffs that include images of self + // do calculation only on appropriate processor + if (newton_pair == 0 && j >= nlocal) + { + jtag = tag[j]; + if (itag > jtag) + { + if ((itag+jtag) % 2 == 0) continue; + } + else if (itag < jtag) + { + if ((itag+jtag) % 2 == 1) continue; + } + else + { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) + { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + + r2=x[j][0]*x[j][0]+x[j][1]*x[j][1]; + + // ri is smaller of r1 and r2 + if (r2= cutsq[itype][jtype]) continue; + + eng = pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); + + A=dx*dx+dy*dy; + B=2.0*(xi*dx+yi*dy); + + // normal pressure contribution P_rhorho + for (ibin=0;ibin0.0 && alpha1<1.0) + { + zR=zi+alpha1*dz; + if (zRzlo) + { + xR=xi+alpha1*dx; + yR=yi+alpha1*dy; + fn=fpair*fabs(xR*dx+yR*dy); + + Pr_temp[ibin]+=fn; + } + } + if (alpha2>0.0 && alpha2<1.0) + { + zR=zi+alpha2*dz; + if (zRzlo) + { + xR=xi+alpha2*dx; + yR=yi+alpha2*dy; + fn=fpair*fabs(xR*dx+yR*dy); + + Pr_temp[ibin]+=fn; + } + } + } + + // azimuthal pressure contribution (P_phiphi) + for (int iphi=0;iphi=1.0 || alpha<=0.0) continue; + + // no contribution (outside of averaging region) + zL=zi+alpha*dz; + if (zL>zhi || zLR2kin[nbins-1]) continue; + + ftphi=fabs(dx*ephi_x[iphi]+dy*ephi_y[iphi])*fpair; + + // add to appropriate bin + for (ibin=0;ibinbinz[zbin] && x[j][2]>binz[zbin]) continue; + if (x[i][2]R2kin[nbins-1]) continue; + + ftz=fabs(dz)*fpair; + + // add to appropriate bin + for (ibin=0;ibin