Page MenuHomec4science

pair_gran_hooke_omp.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 23, 00:28

pair_gran_hooke_omp.cpp

/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_gran_hooke_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHookeOMP::PairGranHookeOMP(LAMMPS *lmp) :
PairGranHooke(lmp), ThrOMP(lmp, PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairGranHookeOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
#pragma omp parallel default(shared)
#endif
{
int ifrom, ito, tid;
double **f, **torque;
f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
torque = atom->torque + tid*nall;
if (evflag)
if (force->newton_pair) eval<1,1>(f, torque, ifrom, ito, tid);
else eval<1,0>(f, torque, ifrom, ito, tid);
else
if (force->newton_pair) eval<0,1>(f, torque, ifrom, ito, tid);
else eval<0,0>(f, torque, ifrom, ito, tid);
// reduce per thread forces and torque into global arrays.
data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
} // end of omp parallel region
// reduce per thread energy and virial, if requested.
if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int NEWTON_PAIR>
void PairGranHookeOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,ft,fs1,fs2,fs3;
int *ilist,*jlist,*numneigh,**firstneigh;
double **x = atom->x;
double **v = atom->v;
double **omega = atom->omega;
double *radius = atom->radius;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double fxtmp,fytmp,fztmp;
double t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
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;
radj = radius[j];
radsum = radi + radj;
if (rsq < radsum*radsum) {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal forces = Hookian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// force normalization
fn = xmu * fabs(ccel*r);
fs = meff*gammat*vrel;
if (vrel != 0.0) ft = MIN(fn,fs) / vrel;
else ft = 0.0;
// tangential force due to tangential velocity damping
fs1 = -ft*vtr1;
fs2 = -ft*vtr2;
fs3 = -ft*vtr3;
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
fxtmp += fx;
fytmp += fy;
fztmp += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
t1tmp -= radi*tor1;
t2tmp -= radi*tor2;
t3tmp -= radi*tor3;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
torque[i][0] += t1tmp;
torque[i][1] += t2tmp;
torque[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairGranHookeOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairGranHooke::memory_usage();
return bytes;
}

Event Timeline