#include "bond_harmonic_shift_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "timer.h"
#include <cmath>
#include "suffix.h"
using namespace LAMMPS_NS;
BondHarmonicShiftOMP::BondHarmonicShiftOMP(class LAMMPS *lmp)
: BondHarmonicShift(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
void BondHarmonicShiftOMP::compute(int eflag, int vflag)
{
ev_init(eflag,vflag);
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
thr->timer(Timer::START);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (inum > 0) {
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
}
thr->timer(Timer::BOND);
reduce_thr(this, eflag, vflag, thr);
} }
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondHarmonicShiftOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
const dbl3_t * _noalias const x = (dbl3_t *) atom->x[0];
dbl3_t * _noalias const f = (dbl3_t *) thr->get_f()[0];
const int3_t * _noalias const bondlist = (int3_t *) neighbor->bondlist[0];
const int nlocal = atom->nlocal;
ebond = 0.0;
for (n = nfrom; n < nto; n++) {
i1 = bondlist[n].a;
i2 = bondlist[n].b;
type = bondlist[n].t;
delx = x[i1].x - x[i2].x;
dely = x[i1].y - x[i2].y;
delz = x[i1].z - x[i2].z;
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
rk = k[type] * dr;
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
if (EFLAG)
ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
if (NEWTON_BOND || i1 < nlocal) {
f[i1].x += delx*fbond;
f[i1].y += dely*fbond;
f[i1].z += delz*fbond;
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2].x -= delx*fbond;
f[i2].y -= dely*fbond;
f[i2].z -= delz*fbond;
}
if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}