diff --git a/doc/Manual.html b/doc/Manual.html
index a721809ec6..47656b8839 100644
--- a/doc/Manual.html
+++ b/doc/Manual.html
@@ -1,7 +1,7 @@
These are additional commands in USER packages, which can be used if
@@ -544,8 +544,8 @@ letters in parenthesis: c = USER-CUDA, g = GPU, i = USER-INTEL, k =
KOKKOS, o = USER-OMP, t = OPT.
@@ -570,9 +570,9 @@ letters in parenthesis: c = USER-CUDA, g = GPU, i = USER-INTEL, k =
KOKKOS, o = USER-OMP, t = OPT.
These are additional angle styles in USER packages, which can be used
@@ -597,8 +597,8 @@ letters in parenthesis: c = USER-CUDA, g = GPU, i = USER-INTEL, k =
KOKKOS, o = USER-OMP, t = OPT.
These are additional dihedral styles in USER packages, which can be
@@ -624,7 +624,7 @@ KOKKOS, o = USER-OMP, t = OPT.
These are additional improper styles in USER packages, which can be
diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt
index 95fa426074..7849ef3e4c 100644
--- a/doc/Section_commands.txt
+++ b/doc/Section_commands.txt
@@ -430,6 +430,7 @@ in the command's documentation.
"prd"_prd.html,
"print"_print.html,
"processors"_processors.html,
+"python"_python.html,
"quit"_quit.html,
"read_data"_read_data.html,
"read_dump"_read_dump.html,
@@ -889,9 +890,9 @@ KOKKOS, o = USER-OMP, t = OPT.
"none"_bond_none.html,
"hybrid"_bond_hybrid.html,
"class2 (o)"_bond_class2.html,
-"fene (o)"_bond_fene.html,
+"fene (ko)"_bond_fene.html,
"fene/expand (o)"_bond_fene_expand.html,
-"harmonic (o)"_bond_harmonic.html,
+"harmonic (ko)"_bond_harmonic.html,
"morse (o)"_bond_morse.html,
"nonlinear (o)"_bond_nonlinear.html,
"quartic (o)"_bond_quartic.html,
@@ -918,13 +919,13 @@ KOKKOS, o = USER-OMP, t = OPT.
"none"_angle_none.html,
"hybrid"_angle_hybrid.html,
-"charmm (o)"_angle_charmm.html,
+"charmm (ko)"_angle_charmm.html,
"class2 (o)"_angle_class2.html,
"cosine (o)"_angle_cosine.html,
"cosine/delta (o)"_angle_cosine_delta.html,
"cosine/periodic (o)"_angle_cosine_periodic.html,
"cosine/squared (o)"_angle_cosine_squared.html,
-"harmonic (o)"_angle_harmonic.html,
+"harmonic (ko)"_angle_harmonic.html,
"table (o)"_angle_table.html :tb(c=4,ea=c)
These are additional angle styles in USER packages, which can be used
@@ -953,12 +954,12 @@ KOKKOS, o = USER-OMP, t = OPT.
"none"_dihedral_none.html,
"hybrid"_dihedral_hybrid.html,
-"charmm (o)"_dihedral_charmm.html,
+"charmm (ko)"_dihedral_charmm.html,
"class2 (o)"_dihedral_class2.html,
"harmonic (o)"_dihedral_harmonic.html,
"helix (o)"_dihedral_helix.html,
"multi/harmonic (o)"_dihedral_multi_harmonic.html,
-"opls (o)"_dihedral_opls.html :tb(c=4,ea=c)
+"opls (ko)"_dihedral_opls.html :tb(c=4,ea=c)
These are additional dihedral styles in USER packages, which can be
used if "LAMMPS is built with the appropriate
@@ -986,7 +987,7 @@ KOKKOS, o = USER-OMP, t = OPT.
"hybrid"_improper_hybrid.html,
"class2 (o)"_improper_class2.html,
"cvff (o)"_improper_cvff.html,
-"harmonic (o)"_improper_harmonic.html,
+"harmonic (ko)"_improper_harmonic.html,
"umbrella (o)"_improper_umbrella.html :tb(c=4,ea=c)
These are additional improper styles in USER packages, which can be
diff --git a/doc/angle_charmm.html b/doc/angle_charmm.html
index 1b801b934b..bfac8e0760 100644
--- a/doc/angle_charmm.html
+++ b/doc/angle_charmm.html
@@ -11,6 +11,8 @@
angle_style charmm command
+angle_style charmm/kk command
+
angle_style charmm/omp command
Syntax:
diff --git a/doc/angle_charmm.txt b/doc/angle_charmm.txt
index ba54f5d47d..482a172b11 100644
--- a/doc/angle_charmm.txt
+++ b/doc/angle_charmm.txt
@@ -7,6 +7,7 @@
:line
angle_style charmm command :h3
+angle_style charmm/kk command :h3
angle_style charmm/omp command :h3
[Syntax:]
diff --git a/doc/angle_harmonic.html b/doc/angle_harmonic.html
index c0facca14f..f5b02202ef 100644
--- a/doc/angle_harmonic.html
+++ b/doc/angle_harmonic.html
@@ -11,6 +11,8 @@
angle_style harmonic command
+angle_style harmonic/kk command
+
angle_style harmonic/omp command
Syntax:
diff --git a/doc/angle_harmonic.txt b/doc/angle_harmonic.txt
index f67b37c92b..620ba0785b 100644
--- a/doc/angle_harmonic.txt
+++ b/doc/angle_harmonic.txt
@@ -7,6 +7,7 @@
:line
angle_style harmonic command :h3
+angle_style harmonic/kk command :h3
angle_style harmonic/omp command :h3
[Syntax:]
diff --git a/doc/bond_fene.html b/doc/bond_fene.html
index 3d14da7c09..e75edad892 100644
--- a/doc/bond_fene.html
+++ b/doc/bond_fene.html
@@ -11,6 +11,8 @@
bond_style fene command
+bond_style fene/kk command
+
bond_style fene/omp command
Syntax:
diff --git a/doc/bond_fene.txt b/doc/bond_fene.txt
index f5e84124c2..46b38214e4 100644
--- a/doc/bond_fene.txt
+++ b/doc/bond_fene.txt
@@ -7,6 +7,7 @@
:line
bond_style fene command :h3
+bond_style fene/kk command :h3
bond_style fene/omp command :h3
[Syntax:]
diff --git a/doc/bond_harmonic.html b/doc/bond_harmonic.html
index 60e58f86e0..f3738011b7 100644
--- a/doc/bond_harmonic.html
+++ b/doc/bond_harmonic.html
@@ -11,6 +11,8 @@
bond_style harmonic command
+bond_style harmonic/kk command
+
bond_style harmonic/omp command
Syntax:
diff --git a/doc/bond_harmonic.txt b/doc/bond_harmonic.txt
index 4a71e1f879..e25647ecdb 100644
--- a/doc/bond_harmonic.txt
+++ b/doc/bond_harmonic.txt
@@ -7,6 +7,7 @@
:line
bond_style harmonic command :h3
+bond_style harmonic/kk command :h3
bond_style harmonic/omp command :h3
[Syntax:]
diff --git a/doc/dihedral_charmm.html b/doc/dihedral_charmm.html
index 3ab0a05968..10a1588f63 100644
--- a/doc/dihedral_charmm.html
+++ b/doc/dihedral_charmm.html
@@ -11,6 +11,8 @@
dihedral_style charmm command
+dihedral_style charmm/kk command
+
dihedral_style charmm/omp command
Syntax:
diff --git a/doc/dihedral_charmm.txt b/doc/dihedral_charmm.txt
index aa5ace275a..1fc0195f3a 100644
--- a/doc/dihedral_charmm.txt
+++ b/doc/dihedral_charmm.txt
@@ -7,6 +7,7 @@
:line
dihedral_style charmm command :h3
+dihedral_style charmm/kk command :h3
dihedral_style charmm/omp command :h3
[Syntax:]
diff --git a/doc/dihedral_opls.html b/doc/dihedral_opls.html
index 3908fd58e6..133841c79c 100644
--- a/doc/dihedral_opls.html
+++ b/doc/dihedral_opls.html
@@ -11,6 +11,8 @@
dihedral_style opls command
+dihedral_style opls/kk command
+
dihedral_style opls/omp command
Syntax:
diff --git a/doc/dihedral_opls.txt b/doc/dihedral_opls.txt
index 51f17c4d56..17fd72344a 100644
--- a/doc/dihedral_opls.txt
+++ b/doc/dihedral_opls.txt
@@ -7,6 +7,7 @@
:line
dihedral_style opls command :h3
+dihedral_style opls/kk command :h3
dihedral_style opls/omp command :h3
[Syntax:]
diff --git a/doc/improper_harmonic.html b/doc/improper_harmonic.html
index 9fac112af9..771d27faaa 100644
--- a/doc/improper_harmonic.html
+++ b/doc/improper_harmonic.html
@@ -11,6 +11,8 @@
improper_style harmonic command
+improper_style harmonic/kk command
+
improper_style harmonic/omp command
Syntax:
diff --git a/doc/improper_harmonic.txt b/doc/improper_harmonic.txt
index 8561f3da46..7887fa59f6 100644
--- a/doc/improper_harmonic.txt
+++ b/doc/improper_harmonic.txt
@@ -7,6 +7,7 @@
:line
improper_style harmonic command :h3
+improper_style harmonic/kk command :h3
improper_style harmonic/omp command :h3
[Syntax:]
diff --git a/lib/python/Makefile.lammps.python2 b/lib/python/Makefile.lammps.python2
new file mode 100644
index 0000000000..8538994694
--- /dev/null
+++ b/lib/python/Makefile.lammps.python2
@@ -0,0 +1,6 @@
+# Settings that the LAMMPS build will import when this package library is used
+# See the README file for more explanation
+
+python_SYSINC = $(shell which python2-config > /dev/null 2>&1 && python2-config --includes || python-config --includes )
+python_SYSLIB = $(shell which python2-config > /dev/null 2>&1 && python2-config --ldflags || python-config --ldflags)
+python_SYSPATH =
diff --git a/src/Depend.sh b/src/Depend.sh
index 99ce03fbec..a344db2ba5 100644
--- a/src/Depend.sh
+++ b/src/Depend.sh
@@ -72,6 +72,7 @@ if (test $1 = "KSPACE") then
depend DIPOLE
depend CORESHELL
depend GPU
+ depend KOKKOS
depend OPT
depend USER-CUDA
depend USER-OMP
@@ -82,6 +83,7 @@ fi
if (test $1 = "MANYBODY") then
depend GPU
+ depend KOKKOS
depend OPT
depend USER-CUDA
depend USER-MISC
@@ -90,6 +92,7 @@ fi
if (test $1 = "MOLECULE") then
depend GPU
+ depend KOKKOS
depend USER-CUDA
depend USER-MISC
depend USER-OMP
diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh
index bceb82a0b3..91dd935da6 100644
--- a/src/KOKKOS/Install.sh
+++ b/src/KOKKOS/Install.sh
@@ -26,9 +26,14 @@ action () {
touch ../accelerator_kokkos.h
touch ../memory.h
+touch ../special.cpp
# list of files with optional dependcies
+action angle_charmm_kokkos.cpp angle_charmm.cpp
+action angle_charmm_kokkos.h angle_charmm.h
+action angle_harmonic_kokkos.cpp angle_harmonic.cpp
+action angle_harmonic_kokkos.h angle_harmonic.h
action atom_kokkos.cpp
action atom_kokkos.h
action atom_vec_angle_kokkos.cpp atom_vec_angle.cpp
@@ -45,20 +50,32 @@ action atom_vec_kokkos.cpp
action atom_vec_kokkos.h
action atom_vec_molecular_kokkos.cpp atom_vec_molecular.cpp
action atom_vec_molecular_kokkos.h atom_vec_molecular.h
+action bond_fene_kokkos.cpp bond_fene.cpp
+action bond_fene_kokkos.h bond_fene.h
+action bond_harmonic_kokkos.cpp bond_harmonic.cpp
+action bond_harmonic_kokkos.h bond_harmonic.h
action comm_kokkos.cpp
action comm_kokkos.h
+action dihedral_charmm_kokkos.cpp dihedral_charmm.cpp
+action dihedral_charmm_kokkos.h dihedral_charmm.h
+action dihedral_opls_kokkos.cpp dihedral_opls.cpp
+action dihedral_opls_kokkos.h dihedral_opls.h
action domain_kokkos.cpp
action domain_kokkos.h
action fix_langevin_kokkos.cpp
action fix_langevin_kokkos.h
action fix_nve_kokkos.cpp
action fix_nve_kokkos.h
+action improper_harmonic_kokkos.cpp improper_harmonic.cpp
+action improper_harmonic_kokkos.h improper_harmonic.h
action kokkos.cpp
action kokkos.h
action kokkos_type.h
action memory_kokkos.h
action modify_kokkos.cpp
action modify_kokkos.h
+action neigh_bond_kokkos.cpp
+action neigh_bond_kokkos.h
action neigh_full_kokkos.h
action neigh_list_kokkos.cpp
action neigh_list_kokkos.h
diff --git a/src/KOKKOS/angle_charmm_kokkos.cpp b/src/KOKKOS/angle_charmm_kokkos.cpp
new file mode 100755
index 0000000000..180cac613d
--- /dev/null
+++ b/src/KOKKOS/angle_charmm_kokkos.cpp
@@ -0,0 +1,421 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Stan Moore (SNL)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdlib.h"
+#include "angle_charmm_kokkos.h"
+#include "atom_kokkos.h"
+#include "neighbor_kokkos.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+#include "atom_masks.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+template
+AngleCharmmKokkos::AngleCharmmKokkos(LAMMPS *lmp) : AngleCharmm(lmp)
+{
+ atomKK = (AtomKokkos *) atom;
+ neighborKK = (NeighborKokkos *) neighbor;
+ execution_space = ExecutionSpaceFromDevice::space;
+ datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK;
+ datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK;
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+AngleCharmmKokkos::~AngleCharmmKokkos()
+{
+ if (!copymode) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->destroy_kokkos(k_vatom,vatom);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void AngleCharmmKokkos::compute(int eflag_in, int vflag_in)
+{
+ eflag = eflag_in;
+ vflag = vflag_in;
+
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = 0;
+
+ // reallocate per-atom arrays if necessary
+
+ if (eflag_atom) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->create_kokkos(k_eatom,eatom,maxeatom,"angle:eatom");
+ d_eatom = k_eatom.d_view;
+ }
+ if (vflag_atom) {
+ memory->destroy_kokkos(k_vatom,vatom);
+ memory->create_kokkos(k_vatom,vatom,maxvatom,6,"angle:vatom");
+ d_vatom = k_vatom.d_view;
+ }
+
+ atomKK->sync(execution_space,datamask_read);
+ k_k.template sync();
+ k_theta0.template sync();
+ k_k_ub.template sync();
+ k_r_ub.template sync();
+ if (eflag || vflag) atomKK->modified(execution_space,datamask_modify);
+ else atomKK->modified(execution_space,F_MASK);
+
+ x = atomKK->k_x.view();
+ f = atomKK->k_f.view();
+ neighborKK->k_anglelist.template sync();
+ anglelist = neighborKK->k_anglelist.view();
+ int nanglelist = neighborKK->nanglelist;
+ nlocal = atom->nlocal;
+ newton_bond = force->newton_bond;
+
+ copymode = 1;
+
+ // loop over neighbors of my atoms
+
+ EV_FLOAT ev;
+
+ if (evflag) {
+ if (newton_bond) {
+ Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nanglelist),*this,ev);
+ } else {
+ Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nanglelist),*this,ev);
+ }
+ } else {
+ if (newton_bond) {
+ Kokkos::parallel_for(Kokkos::RangePolicy >(0,nanglelist),*this);
+ } else {
+ Kokkos::parallel_for(Kokkos::RangePolicy >(0,nanglelist),*this);
+ }
+ }
+ DeviceType::fence();
+
+ if (eflag_global) energy += ev.evdwl;
+ if (vflag_global) {
+ virial[0] += ev.v[0];
+ virial[1] += ev.v[1];
+ virial[2] += ev.v[2];
+ virial[3] += ev.v[3];
+ virial[4] += ev.v[4];
+ virial[5] += ev.v[5];
+ }
+
+ if (eflag_atom) {
+ k_eatom.template modify();
+ k_eatom.template sync();
+ }
+
+ if (vflag_atom) {
+ k_vatom.template modify();
+ k_vatom.template sync();
+ }
+
+ copymode = 0;
+}
+
+template
+template
+KOKKOS_INLINE_FUNCTION
+void AngleCharmmKokkos::operator()(TagAngleCharmmCompute, const int &n, EV_FLOAT& ev) const {
+
+ // The f array is atomic
+ Kokkos::View > a_f = f;
+
+ const int i1 = anglelist(n,0);
+ const int i2 = anglelist(n,1);
+ const int i3 = anglelist(n,2);
+ const int type = anglelist(n,3);
+
+ // 1st bond
+
+ const F_FLOAT delx1 = x(i1,0) - x(i2,0);
+ const F_FLOAT dely1 = x(i1,1) - x(i2,1);
+ const F_FLOAT delz1 = x(i1,2) - x(i2,2);
+
+ const F_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ const F_FLOAT r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ const F_FLOAT delx2 = x(i3,0) - x(i2,0);
+ const F_FLOAT dely2 = x(i3,1) - x(i2,1);
+ const F_FLOAT delz2 = x(i3,2) - x(i2,2);
+
+ const F_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ const F_FLOAT r2 = sqrt(rsq2);
+
+ // Urey-Bradley bond
+
+ const F_FLOAT delxUB = x(i3,0) - x(i1,0);
+ const F_FLOAT delyUB = x(i3,1) - x(i1,1);
+ const F_FLOAT delzUB = x(i3,2) - x(i1,2);
+
+ const F_FLOAT rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB;
+ const F_FLOAT rUB = sqrt(rsqUB);
+
+ // Urey-Bradley force & energy
+
+ const F_FLOAT dr = rUB - d_r_ub[type];
+ const F_FLOAT rk = d_k_ub[type] * dr;
+
+ F_FLOAT forceUB = 0.0;
+ if (rUB > 0.0) forceUB = -2.0*rk/rUB;
+
+ E_FLOAT eangle = 0.0;
+ if (eflag) eangle = rk*dr;
+
+ // angle (cos and sin)
+
+ F_FLOAT c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ F_FLOAT s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // harmonic force & energy
+
+ const F_FLOAT dtheta = acos(c) - d_theta0[type];
+ const F_FLOAT tk = d_k[type] * dtheta;
+
+ if (eflag) eangle += tk*dtheta;
+
+ const F_FLOAT a = -2.0 * tk * s;
+ const F_FLOAT a11 = a*c / rsq1;
+ const F_FLOAT a12 = -a / (r1*r2);
+ const F_FLOAT a22 = a*c / rsq2;
+
+ F_FLOAT f1[3],f3[3];
+ f1[0] = a11*delx1 + a12*delx2 - delxUB*forceUB;
+ f1[1] = a11*dely1 + a12*dely2 - delyUB*forceUB;
+ f1[2] = a11*delz1 + a12*delz2 - delzUB*forceUB;
+
+ f3[0] = a22*delx2 + a12*delx1 + delxUB*forceUB;
+ f3[1] = a22*dely2 + a12*dely1 + delyUB*forceUB;
+ f3[2] = a22*delz2 + a12*delz1 + delzUB*forceUB;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ a_f(i1,0) += f1[0];
+ a_f(i1,1) += f1[1];
+ a_f(i1,2) += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ a_f(i2,0) -= f1[0] + f3[0];
+ a_f(i2,1) -= f1[1] + f3[1];
+ a_f(i2,2) -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ a_f(i3,0) += f3[0];
+ a_f(i3,1) += f3[1];
+ a_f(i3,2) += f3[2];
+ }
+
+ if (EVFLAG) ev_tally(ev,i1,i2,i3,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2);
+}
+
+template
+template
+KOKKOS_INLINE_FUNCTION
+void AngleCharmmKokkos::operator()(TagAngleCharmmCompute, const int &n) const {
+ EV_FLOAT ev;
+ this->template operator()(TagAngleCharmmCompute(), n, ev);
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void AngleCharmmKokkos::allocate()
+{
+ AngleCharmm::allocate();
+
+ int n = atom->nangletypes;
+ k_k = DAT::tdual_ffloat_1d("AngleCharmm::k",n+1);
+ k_theta0 = DAT::tdual_ffloat_1d("AngleCharmm::theta0",n+1);
+ k_k_ub = DAT::tdual_ffloat_1d("AngleCharmm::k_ub",n+1);
+ k_r_ub = DAT::tdual_ffloat_1d("AngleCharmm::r_ub",n+1);
+
+ d_k = k_k.d_view;
+ d_theta0 = k_theta0.d_view;
+ d_k_ub = k_k_ub.d_view;
+ d_r_ub = k_r_ub.d_view;
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more types
+------------------------------------------------------------------------- */
+
+template
+void AngleCharmmKokkos::coeff(int narg, char **arg)
+{
+ AngleCharmm::coeff(narg, arg);
+
+ int n = atom->nangletypes;
+ for (int i = 1; i <= n; i++) {
+ k_k.h_view[i] = k[i];
+ k_theta0.h_view[i] = theta0[i];
+ k_k_ub.h_view[i] = k_ub[i];
+ k_r_ub.h_view[i] = r_ub[i];
+ }
+
+ k_k.template modify();
+ k_theta0.template modify();
+ k_k_ub.template modify();
+ k_r_ub.template modify();
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+ virial = r1F1 + r2F2 + r3F3 = (r1-r2) F1 + (r3-r2) F3 = del1*f1 + del2*f3
+------------------------------------------------------------------------- */
+
+template
+//template
+KOKKOS_INLINE_FUNCTION
+void AngleCharmmKokkos::ev_tally(EV_FLOAT &ev, const int i, const int j, const int k,
+ F_FLOAT &eangle, F_FLOAT *f1, F_FLOAT *f3,
+ const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1,
+ const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const
+{
+ E_FLOAT eanglethird;
+ F_FLOAT v[6];
+
+ // The eatom and vatom arrays are atomic
+ Kokkos::View > v_eatom = k_eatom.view();
+ Kokkos::View > v_vatom = k_vatom.view();
+
+ if (eflag_either) {
+ if (eflag_global) {
+ if (newton_bond) ev.evdwl += eangle;
+ else {
+ eanglethird = THIRD*eangle;
+
+ if (i < nlocal) ev.evdwl += eanglethird;
+ if (j < nlocal) ev.evdwl += eanglethird;
+ if (k < nlocal) ev.evdwl += eanglethird;
+ }
+ }
+ if (eflag_atom) {
+ eanglethird = THIRD*eangle;
+
+ if (newton_bond || i < nlocal) v_eatom[i] += eanglethird;
+ if (newton_bond || j < nlocal) v_eatom[j] += eanglethird;
+ if (newton_bond || k < nlocal) v_eatom[k] += eanglethird;
+ }
+ }
+
+ if (vflag_either) {
+ v[0] = delx1*f1[0] + delx2*f3[0];
+ v[1] = dely1*f1[1] + dely2*f3[1];
+ v[2] = delz1*f1[2] + delz2*f3[2];
+ v[3] = delx1*f1[1] + delx2*f3[1];
+ v[4] = delx1*f1[2] + delx2*f3[2];
+ v[5] = dely1*f1[2] + dely2*f3[2];
+
+ if (vflag_global) {
+ if (newton_bond) {
+ ev.v[0] += v[0];
+ ev.v[1] += v[1];
+ ev.v[2] += v[2];
+ ev.v[3] += v[3];
+ ev.v[4] += v[4];
+ ev.v[5] += v[5];
+ } else {
+ if (i < nlocal) {
+ ev.v[0] += THIRD*v[0];
+ ev.v[1] += THIRD*v[1];
+ ev.v[2] += THIRD*v[2];
+ ev.v[3] += THIRD*v[3];
+ ev.v[4] += THIRD*v[4];
+ ev.v[5] += THIRD*v[5];
+ }
+ if (j < nlocal) {
+ ev.v[0] += THIRD*v[0];
+ ev.v[1] += THIRD*v[1];
+ ev.v[2] += THIRD*v[2];
+ ev.v[3] += THIRD*v[3];
+ ev.v[4] += THIRD*v[4];
+ ev.v[5] += THIRD*v[5];
+ }
+ if (k < nlocal) {
+ ev.v[0] += THIRD*v[0];
+
+ ev.v[1] += THIRD*v[1];
+ ev.v[2] += THIRD*v[2];
+ ev.v[3] += THIRD*v[3];
+ ev.v[4] += THIRD*v[4];
+ ev.v[5] += THIRD*v[5];
+ }
+ }
+ }
+
+ if (vflag_atom) {
+ if (newton_bond || i < nlocal) {
+ v_vatom(i,0) += THIRD*v[0];
+ v_vatom(i,1) += THIRD*v[1];
+ v_vatom(i,2) += THIRD*v[2];
+ v_vatom(i,3) += THIRD*v[3];
+ v_vatom(i,4) += THIRD*v[4];
+ v_vatom(i,5) += THIRD*v[5];
+ }
+ if (newton_bond || j < nlocal) {
+ v_vatom(j,0) += THIRD*v[0];
+ v_vatom(j,1) += THIRD*v[1];
+ v_vatom(j,2) += THIRD*v[2];
+ v_vatom(j,3) += THIRD*v[3];
+ v_vatom(j,4) += THIRD*v[4];
+ v_vatom(j,5) += THIRD*v[5];
+ }
+ if (newton_bond || k < nlocal) {
+ v_vatom(k,0) += THIRD*v[0];
+ v_vatom(k,1) += THIRD*v[1];
+ v_vatom(k,2) += THIRD*v[2];
+ v_vatom(k,3) += THIRD*v[3];
+ v_vatom(k,4) += THIRD*v[4];
+ v_vatom(k,5) += THIRD*v[5];
+
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template class AngleCharmmKokkos;
+#ifdef KOKKOS_HAVE_CUDA
+template class AngleCharmmKokkos;
+#endif
\ No newline at end of file
diff --git a/src/KOKKOS/angle_charmm_kokkos.h b/src/KOKKOS/angle_charmm_kokkos.h
new file mode 100755
index 0000000000..e97147c258
--- /dev/null
+++ b/src/KOKKOS/angle_charmm_kokkos.h
@@ -0,0 +1,95 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+#ifdef ANGLE_CLASS
+
+AngleStyle(charmm/kk,AngleCharmmKokkos)
+AngleStyle(charmm/kk/device,AngleCharmmKokkos)
+AngleStyle(charmm/kk/host,AngleCharmmKokkos)
+
+#else
+
+#ifndef LMP_ANGLE_CHARMM_KOKKOS_H
+#define LMP_ANGLE_CHARMM_KOKKOS_H
+
+#include "angle_charmm.h"
+#include "kokkos_type.h"
+
+namespace LAMMPS_NS {
+
+template
+struct TagAngleCharmmCompute{};
+
+template
+class AngleCharmmKokkos : public AngleCharmm {
+ public:
+ typedef DeviceType device_type;
+ typedef EV_FLOAT value_type;
+
+ AngleCharmmKokkos(class LAMMPS *);
+ virtual ~AngleCharmmKokkos();
+ virtual void compute(int, int);
+ virtual void coeff(int, char **);
+
+ template
+ KOKKOS_INLINE_FUNCTION
+ void operator()(TagAngleCharmmCompute, const int&, EV_FLOAT&) const;
+
+ template
+ KOKKOS_INLINE_FUNCTION
+ void operator()(TagAngleCharmmCompute, const int&) const;
+
+ //template
+ KOKKOS_INLINE_FUNCTION
+ void ev_tally(EV_FLOAT &ev, const int i, const int j, const int k,
+ F_FLOAT &eangle, F_FLOAT *f1, F_FLOAT *f3,
+ const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1,
+ const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const;
+
+ protected:
+ class AtomKokkos *atomKK;
+ class NeighborKokkos *neighborKK;
+
+ typename ArrayTypes::t_x_array_randomread x;
+ typename ArrayTypes::t_f_array f;
+ typename ArrayTypes::t_int_2d anglelist;
+
+ DAT::tdual_efloat_1d k_eatom;
+ DAT::tdual_virial_array k_vatom;
+ DAT::t_efloat_1d d_eatom;
+ DAT::t_virial_array d_vatom;
+
+ int nlocal,newton_bond;
+ int eflag,vflag;
+
+ DAT::tdual_ffloat_1d k_k;
+ DAT::tdual_ffloat_1d k_theta0;
+ DAT::tdual_ffloat_1d k_k_ub;
+ DAT::tdual_ffloat_1d k_r_ub;
+
+ DAT::t_ffloat_1d d_k;
+ DAT::t_ffloat_1d d_theta0;
+ DAT::t_ffloat_1d d_k_ub;
+ DAT::t_ffloat_1d d_r_ub;
+
+ virtual void allocate();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+*/
diff --git a/src/KOKKOS/angle_harmonic_kokkos.cpp b/src/KOKKOS/angle_harmonic_kokkos.cpp
new file mode 100755
index 0000000000..dee0e8246d
--- /dev/null
+++ b/src/KOKKOS/angle_harmonic_kokkos.cpp
@@ -0,0 +1,391 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Stan Moore (SNL)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdlib.h"
+#include "angle_harmonic_kokkos.h"
+#include "atom_kokkos.h"
+#include "neighbor_kokkos.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+#include "atom_masks.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+template
+AngleHarmonicKokkos::AngleHarmonicKokkos(LAMMPS *lmp) : AngleHarmonic(lmp)
+{
+ atomKK = (AtomKokkos *) atom;
+ neighborKK = (NeighborKokkos *) neighbor;
+ execution_space = ExecutionSpaceFromDevice::space;
+ datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK;
+ datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK;
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+AngleHarmonicKokkos::~AngleHarmonicKokkos()
+{
+ if (!copymode) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->destroy_kokkos(k_vatom,vatom);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void AngleHarmonicKokkos::compute(int eflag_in, int vflag_in)
+{
+ eflag = eflag_in;
+ vflag = vflag_in;
+
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = 0;
+
+ // reallocate per-atom arrays if necessary
+
+ if (eflag_atom) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->create_kokkos(k_eatom,eatom,maxeatom,"angle:eatom");
+ d_eatom = k_eatom.d_view;
+ }
+ if (vflag_atom) {
+ memory->destroy_kokkos(k_vatom,vatom);
+ memory->create_kokkos(k_vatom,vatom,maxvatom,6,"angle:vatom");
+ d_vatom = k_vatom.d_view;
+ }
+
+ atomKK->sync(execution_space,datamask_read);
+ k_k.template sync();
+ k_theta0.template sync();
+ if (eflag || vflag) atomKK->modified(execution_space,datamask_modify);
+ else atomKK->modified(execution_space,F_MASK);
+
+ x = atomKK->k_x.view();
+ f = atomKK->k_f.view();
+ neighborKK->k_anglelist.template sync();
+ anglelist = neighborKK->k_anglelist.view();
+ int nanglelist = neighborKK->nanglelist;
+ nlocal = atom->nlocal;
+ newton_bond = force->newton_bond;
+
+ copymode = 1;
+
+ // loop over neighbors of my atoms
+
+ EV_FLOAT ev;
+
+ if (evflag) {
+ if (newton_bond) {
+ Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nanglelist),*this,ev);
+ } else {
+ Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nanglelist),*this,ev);
+ }
+ } else {
+ if (newton_bond) {
+ Kokkos::parallel_for(Kokkos::RangePolicy >(0,nanglelist),*this);
+ } else {
+ Kokkos::parallel_for(Kokkos::RangePolicy >(0,nanglelist),*this);
+ }
+ }
+ DeviceType::fence();
+
+ if (eflag_global) energy += ev.evdwl;
+ if (vflag_global) {
+ virial[0] += ev.v[0];
+ virial[1] += ev.v[1];
+ virial[2] += ev.v[2];
+ virial[3] += ev.v[3];
+ virial[4] += ev.v[4];
+ virial[5] += ev.v[5];
+ }
+
+ if (eflag_atom) {
+ k_eatom.template modify();
+ k_eatom.template sync();
+ }
+
+ if (vflag_atom) {
+ k_vatom.template modify();
+ k_vatom.template sync();
+ }
+
+ copymode = 0;
+}
+
+template
+template
+KOKKOS_INLINE_FUNCTION
+void AngleHarmonicKokkos::operator()(TagAngleHarmonicCompute, const int &n, EV_FLOAT& ev) const {
+
+ // The f array is atomic
+ Kokkos::View > a_f = f;
+
+ const int i1 = anglelist(n,0);
+ const int i2 = anglelist(n,1);
+ const int i3 = anglelist(n,2);
+ const int type = anglelist(n,3);
+
+ // 1st bond
+
+ const F_FLOAT delx1 = x(i1,0) - x(i2,0);
+ const F_FLOAT dely1 = x(i1,1) - x(i2,1);
+ const F_FLOAT delz1 = x(i1,2) - x(i2,2);
+
+ const F_FLOAT rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ const F_FLOAT r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ const F_FLOAT delx2 = x(i3,0) - x(i2,0);
+ const F_FLOAT dely2 = x(i3,1) - x(i2,1);
+ const F_FLOAT delz2 = x(i3,2) - x(i2,2);
+
+ const F_FLOAT rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ const F_FLOAT r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ F_FLOAT c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ F_FLOAT s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // force & energy
+
+ const F_FLOAT dtheta = acos(c) - d_theta0[type];
+ const F_FLOAT tk = d_k[type] * dtheta;
+
+ F_FLOAT eangle = 0.0;
+ if (eflag) eangle = tk*dtheta;
+
+ const F_FLOAT a = -2.0 * tk * s;
+ const F_FLOAT a11 = a*c / rsq1;
+ const F_FLOAT a12 = -a / (r1*r2);
+ const F_FLOAT a22 = a*c / rsq2;
+
+ F_FLOAT f1[3],f3[3];
+ 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) {
+ a_f(i1,0) += f1[0];
+ a_f(i1,1) += f1[1];
+ a_f(i1,2) += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ a_f(i2,0) -= f1[0] + f3[0];
+ a_f(i2,1) -= f1[1] + f3[1];
+ a_f(i2,2) -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ a_f(i3,0) += f3[0];
+ a_f(i3,1) += f3[1];
+ a_f(i3,2) += f3[2];
+ }
+
+ if (EVFLAG) ev_tally(ev,i1,i2,i3,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2);
+}
+
+template
+template
+KOKKOS_INLINE_FUNCTION
+void AngleHarmonicKokkos::operator()(TagAngleHarmonicCompute, const int &n) const {
+ EV_FLOAT ev;
+ this->template operator()(TagAngleHarmonicCompute(), n, ev);
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void AngleHarmonicKokkos::allocate()
+{
+ AngleHarmonic::allocate();
+
+ int n = atom->nangletypes;
+ k_k = DAT::tdual_ffloat_1d("AngleHarmonic::k",n+1);
+ k_theta0 = DAT::tdual_ffloat_1d("AngleHarmonic::theta0",n+1);
+
+ d_k = k_k.d_view;
+ d_theta0 = k_theta0.d_view;
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more types
+------------------------------------------------------------------------- */
+
+template
+void AngleHarmonicKokkos::coeff(int narg, char **arg)
+{
+ AngleHarmonic::coeff(narg, arg);
+
+ int n = atom->nangletypes;
+ for (int i = 1; i <= n; i++) {
+ k_k.h_view[i] = k[i];
+ k_theta0.h_view[i] = theta0[i];
+ }
+
+ k_k.template modify();
+ k_theta0.template modify();
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+ virial = r1F1 + r2F2 + r3F3 = (r1-r2) F1 + (r3-r2) F3 = del1*f1 + del2*f3
+------------------------------------------------------------------------- */
+
+template
+//template
+KOKKOS_INLINE_FUNCTION
+void AngleHarmonicKokkos::ev_tally(EV_FLOAT &ev, const int i, const int j, const int k,
+ F_FLOAT &eangle, F_FLOAT *f1, F_FLOAT *f3,
+ const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1,
+ const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const
+{
+ E_FLOAT eanglethird;
+ F_FLOAT v[6];
+
+ // The eatom and vatom arrays are atomic
+ Kokkos::View > v_eatom = k_eatom.view();
+ Kokkos::View > v_vatom = k_vatom.view();
+
+ if (eflag_either) {
+ if (eflag_global) {
+ if (newton_bond) ev.evdwl += eangle;
+ else {
+ eanglethird = THIRD*eangle;
+
+ if (i < nlocal) ev.evdwl += eanglethird;
+ if (j < nlocal) ev.evdwl += eanglethird;
+ if (k < nlocal) ev.evdwl += eanglethird;
+ }
+ }
+ if (eflag_atom) {
+ eanglethird = THIRD*eangle;
+
+ if (newton_bond || i < nlocal) v_eatom[i] += eanglethird;
+ if (newton_bond || j < nlocal) v_eatom[j] += eanglethird;
+ if (newton_bond || k < nlocal) v_eatom[k] += eanglethird;
+ }
+ }
+
+ if (vflag_either) {
+ v[0] = delx1*f1[0] + delx2*f3[0];
+ v[1] = dely1*f1[1] + dely2*f3[1];
+ v[2] = delz1*f1[2] + delz2*f3[2];
+ v[3] = delx1*f1[1] + delx2*f3[1];
+ v[4] = delx1*f1[2] + delx2*f3[2];
+ v[5] = dely1*f1[2] + dely2*f3[2];
+
+ if (vflag_global) {
+ if (newton_bond) {
+ ev.v[0] += v[0];
+ ev.v[1] += v[1];
+ ev.v[2] += v[2];
+ ev.v[3] += v[3];
+ ev.v[4] += v[4];
+ ev.v[5] += v[5];
+ } else {
+ if (i < nlocal) {
+ ev.v[0] += THIRD*v[0];
+ ev.v[1] += THIRD*v[1];
+ ev.v[2] += THIRD*v[2];
+ ev.v[3] += THIRD*v[3];
+ ev.v[4] += THIRD*v[4];
+ ev.v[5] += THIRD*v[5];
+ }
+ if (j < nlocal) {
+ ev.v[0] += THIRD*v[0];
+ ev.v[1] += THIRD*v[1];
+ ev.v[2] += THIRD*v[2];
+ ev.v[3] += THIRD*v[3];
+ ev.v[4] += THIRD*v[4];
+ ev.v[5] += THIRD*v[5];
+ }
+ if (k < nlocal) {
+ ev.v[0] += THIRD*v[0];
+
+ ev.v[1] += THIRD*v[1];
+ ev.v[2] += THIRD*v[2];
+ ev.v[3] += THIRD*v[3];
+ ev.v[4] += THIRD*v[4];
+ ev.v[5] += THIRD*v[5];
+ }
+ }
+ }
+
+ if (vflag_atom) {
+ if (newton_bond || i < nlocal) {
+ v_vatom(i,0) += THIRD*v[0];
+ v_vatom(i,1) += THIRD*v[1];
+ v_vatom(i,2) += THIRD*v[2];
+ v_vatom(i,3) += THIRD*v[3];
+ v_vatom(i,4) += THIRD*v[4];
+ v_vatom(i,5) += THIRD*v[5];
+ }
+ if (newton_bond || j < nlocal) {
+ v_vatom(j,0) += THIRD*v[0];
+ v_vatom(j,1) += THIRD*v[1];
+ v_vatom(j,2) += THIRD*v[2];
+ v_vatom(j,3) += THIRD*v[3];
+ v_vatom(j,4) += THIRD*v[4];
+ v_vatom(j,5) += THIRD*v[5];
+ }
+ if (newton_bond || k < nlocal) {
+ v_vatom(k,0) += THIRD*v[0];
+ v_vatom(k,1) += THIRD*v[1];
+ v_vatom(k,2) += THIRD*v[2];
+ v_vatom(k,3) += THIRD*v[3];
+ v_vatom(k,4) += THIRD*v[4];
+ v_vatom(k,5) += THIRD*v[5];
+
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template class AngleHarmonicKokkos;
+#ifdef KOKKOS_HAVE_CUDA
+template class AngleHarmonicKokkos;
+#endif
\ No newline at end of file
diff --git a/src/KOKKOS/angle_harmonic_kokkos.h b/src/KOKKOS/angle_harmonic_kokkos.h
new file mode 100755
index 0000000000..a1b152bcb4
--- /dev/null
+++ b/src/KOKKOS/angle_harmonic_kokkos.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+#ifdef ANGLE_CLASS
+
+AngleStyle(harmonic/kk,AngleHarmonicKokkos)
+AngleStyle(harmonic/kk/device,AngleHarmonicKokkos)
+AngleStyle(harmonic/kk/host,AngleHarmonicKokkos)
+
+#else
+
+#ifndef LMP_ANGLE_HARMONIC_KOKKOS_H
+#define LMP_ANGLE_HARMONIC_KOKKOS_H
+
+#include "angle_harmonic.h"
+#include "kokkos_type.h"
+
+namespace LAMMPS_NS {
+
+template
+struct TagAngleHarmonicCompute{};
+
+template
+class AngleHarmonicKokkos : public AngleHarmonic {
+
+ public:
+ typedef DeviceType device_type;
+ typedef EV_FLOAT value_type;
+
+ AngleHarmonicKokkos(class LAMMPS *);
+ virtual ~AngleHarmonicKokkos();
+ virtual void compute(int, int);
+ virtual void coeff(int, char **);
+
+ template
+ KOKKOS_INLINE_FUNCTION
+ void operator()(TagAngleHarmonicCompute, const int&, EV_FLOAT&) const;
+
+ template
+ KOKKOS_INLINE_FUNCTION
+ void operator()(TagAngleHarmonicCompute, const int&) const;
+
+ //template
+ KOKKOS_INLINE_FUNCTION
+ void ev_tally(EV_FLOAT &ev, const int i, const int j, const int k,
+ F_FLOAT &eangle, F_FLOAT *f1, F_FLOAT *f3,
+ const F_FLOAT &delx1, const F_FLOAT &dely1, const F_FLOAT &delz1,
+ const F_FLOAT &delx2, const F_FLOAT &dely2, const F_FLOAT &delz2) const;
+
+ protected:
+ class AtomKokkos *atomKK;
+ class NeighborKokkos *neighborKK;
+
+ typename ArrayTypes::t_x_array_randomread x;
+ typename ArrayTypes::t_f_array f;
+ typename ArrayTypes::t_int_2d anglelist;
+
+ DAT::tdual_efloat_1d k_eatom;
+ DAT::tdual_virial_array k_vatom;
+ DAT::t_efloat_1d d_eatom;
+ DAT::t_virial_array d_vatom;
+
+ int nlocal,newton_bond;
+ int eflag,vflag;
+
+ DAT::tdual_ffloat_1d k_k;
+ DAT::tdual_ffloat_1d k_theta0;
+
+ DAT::t_ffloat_1d d_k;
+ DAT::t_ffloat_1d d_theta0;
+
+ virtual void allocate();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+*/
diff --git a/src/KOKKOS/atom_vec_angle_kokkos.cpp b/src/KOKKOS/atom_vec_angle_kokkos.cpp
index e1f73064d7..d78014120f 100644
--- a/src/KOKKOS/atom_vec_angle_kokkos.cpp
+++ b/src/KOKKOS/atom_vec_angle_kokkos.cpp
@@ -1636,6 +1636,7 @@ void AtomVecAngleKokkos::data_atom(double *coord, imageint imagetmp,
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
+ atomKK->modified(Host,ALL_MASK);
h_tag(nlocal) = atoi(values[0]);
h_molecule(nlocal) = atoi(values[1]);
diff --git a/src/KOKKOS/atom_vec_bond_kokkos.cpp b/src/KOKKOS/atom_vec_bond_kokkos.cpp
index a5ed6163a7..a991c594f3 100644
--- a/src/KOKKOS/atom_vec_bond_kokkos.cpp
+++ b/src/KOKKOS/atom_vec_bond_kokkos.cpp
@@ -1507,6 +1507,7 @@ void AtomVecBondKokkos::data_atom(double *coord, imageint imagetmp,
{
int nlocal = atomKK->nlocal;
if (nlocal == nmax) grow(0);
+ atomKK->modified(Host,ALL_MASK);
h_tag(nlocal) = atoi(values[0]);
h_molecule(nlocal) = atoi(values[1]);
diff --git a/src/KOKKOS/atom_vec_full_kokkos.cpp b/src/KOKKOS/atom_vec_full_kokkos.cpp
index 6623fa2f25..0d3893432e 100644
--- a/src/KOKKOS/atom_vec_full_kokkos.cpp
+++ b/src/KOKKOS/atom_vec_full_kokkos.cpp
@@ -1970,6 +1970,7 @@ void AtomVecFullKokkos::data_atom(double *coord, imageint imagetmp,
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
+ atomKK->modified(Host,ALL_MASK);
h_tag(nlocal) = atoi(values[0]);
h_molecule(nlocal) = atoi(values[1]);
@@ -2176,7 +2177,7 @@ void AtomVecFullKokkos::sync(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.sync();
atomKK->k_improper_atom2.sync();
atomKK->k_improper_atom3.sync();
- atomKK->k_improper_atom3.sync();
+ atomKK->k_improper_atom4.sync();
}
} else {
if (mask & X_MASK) atomKK->k_x.sync();
@@ -2218,7 +2219,7 @@ void AtomVecFullKokkos::sync(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.sync();
atomKK->k_improper_atom2.sync();
atomKK->k_improper_atom3.sync();
- atomKK->k_improper_atom3.sync();
+ atomKK->k_improper_atom4.sync();
}
}
}
@@ -2267,7 +2268,7 @@ void AtomVecFullKokkos::modified(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.modify();
atomKK->k_improper_atom2.modify();
atomKK->k_improper_atom3.modify();
- atomKK->k_improper_atom3.modify();
+ atomKK->k_improper_atom4.modify();
}
} else {
if (mask & X_MASK) atomKK->k_x.modify();
@@ -2309,7 +2310,7 @@ void AtomVecFullKokkos::modified(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.modify();
atomKK->k_improper_atom2.modify();
atomKK->k_improper_atom3.modify();
- atomKK->k_improper_atom3.modify();
+ atomKK->k_improper_atom4.modify();
}
}
}
diff --git a/src/KOKKOS/atom_vec_molecular_kokkos.cpp b/src/KOKKOS/atom_vec_molecular_kokkos.cpp
index 7c48b2dc85..256514eb7f 100644
--- a/src/KOKKOS/atom_vec_molecular_kokkos.cpp
+++ b/src/KOKKOS/atom_vec_molecular_kokkos.cpp
@@ -1895,6 +1895,7 @@ void AtomVecMolecularKokkos::data_atom(double *coord, imageint imagetmp,
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
+ atomKK->modified(Host,ALL_MASK);
h_tag(nlocal) = atoi(values[0]);
h_molecule(nlocal) = atoi(values[1]);
@@ -2094,7 +2095,7 @@ void AtomVecMolecularKokkos::sync(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.sync();
atomKK->k_improper_atom2.sync();
atomKK->k_improper_atom3.sync();
- atomKK->k_improper_atom3.sync();
+ atomKK->k_improper_atom4.sync();
}
} else {
if (mask & X_MASK) atomKK->k_x.sync();
@@ -2135,7 +2136,7 @@ void AtomVecMolecularKokkos::sync(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.sync();
atomKK->k_improper_atom2.sync();
atomKK->k_improper_atom3.sync();
- atomKK->k_improper_atom3.sync();
+ atomKK->k_improper_atom4.sync();
}
}
}
@@ -2183,7 +2184,7 @@ void AtomVecMolecularKokkos::modified(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.modify();
atomKK->k_improper_atom2.modify();
atomKK->k_improper_atom3.modify();
- atomKK->k_improper_atom3.modify();
+ atomKK->k_improper_atom4.modify();
}
} else {
if (mask & X_MASK) atomKK->k_x.modify();
@@ -2224,7 +2225,7 @@ void AtomVecMolecularKokkos::modified(ExecutionSpace space, unsigned int mask)
atomKK->k_improper_atom1.modify();
atomKK->k_improper_atom2.modify();
atomKK->k_improper_atom3.modify();
- atomKK->k_improper_atom3.modify();
+ atomKK->k_improper_atom4.modify();
}
}
}
diff --git a/src/KOKKOS/bond_fene_kokkos.cpp b/src/KOKKOS/bond_fene_kokkos.cpp
new file mode 100755
index 0000000000..a0543fd8a8
--- /dev/null
+++ b/src/KOKKOS/bond_fene_kokkos.cpp
@@ -0,0 +1,385 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Stan Moore (SNL)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdlib.h"
+#include "bond_fene_kokkos.h"
+#include "atom_kokkos.h"
+#include "neighbor_kokkos.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "error.h"
+#include "atom_masks.h"
+
+using namespace LAMMPS_NS;
+
+
+/* ---------------------------------------------------------------------- */
+
+template
+BondFENEKokkos::BondFENEKokkos(LAMMPS *lmp) : BondFENE(lmp)
+{
+ atomKK = (AtomKokkos *) atom;
+ neighborKK = (NeighborKokkos *) neighbor;
+ execution_space = ExecutionSpaceFromDevice::space;
+ datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK;
+ datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK;
+
+ k_warning_flag = DAT::tdual_int_scalar("Bond:warning_flag");
+ d_warning_flag = k_warning_flag.view();
+ h_warning_flag = k_warning_flag.h_view;
+
+ k_error_flag = DAT::tdual_int_scalar("Bond:error_flag");
+ d_error_flag = k_error_flag.view();
+ h_error_flag = k_error_flag.h_view;
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+BondFENEKokkos::~BondFENEKokkos()
+{
+ if (!copymode) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->destroy_kokkos(k_vatom,vatom);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void BondFENEKokkos::compute(int eflag_in, int vflag_in)
+{
+ eflag = eflag_in;
+ vflag = vflag_in;
+
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = 0;
+
+ // reallocate per-atom arrays if necessary
+
+ if (eflag_atom) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->create_kokkos(k_eatom,eatom,maxeatom,"bond:eatom");
+ d_eatom = k_eatom.d_view;
+ }
+ if (vflag_atom) {
+ memory->destroy_kokkos(k_vatom,vatom);
+ memory->create_kokkos(k_vatom,vatom,maxvatom,6,"bond:vatom");
+ d_vatom = k_vatom.d_view;
+ }
+
+ atomKK->sync(execution_space,datamask_read);
+ k_k.template sync();
+ k_r0.template sync();
+ k_epsilon.template sync();
+ k_sigma.template sync();
+ if (eflag || vflag) atomKK->modified(execution_space,datamask_modify);
+ else atomKK->modified(execution_space,F_MASK);
+
+ x = atomKK->k_x.view();
+ f = atomKK->k_f.view();
+ neighborKK->k_bondlist.template sync();
+ bondlist = neighborKK->k_bondlist.view();
+ int nbondlist = neighborKK->nbondlist;
+ nlocal = atom->nlocal;
+ newton_bond = force->newton_bond;
+
+ h_warning_flag() = 0;
+ k_warning_flag.template modify();
+ k_warning_flag.template sync();
+
+ h_error_flag() = 0;
+ k_error_flag.template modify();
+ k_error_flag.template sync();
+
+ copymode = 1;
+
+ // loop over neighbors of my atoms
+
+ EV_FLOAT ev;
+
+ if (evflag) {
+ if (newton_bond) {
+ Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nbondlist),*this,ev);
+ } else {
+ Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nbondlist),*this,ev);
+ }
+ } else {
+ if (newton_bond) {
+ Kokkos::parallel_for(Kokkos::RangePolicy >(0,nbondlist),*this);
+ } else {
+ Kokkos::parallel_for(Kokkos::RangePolicy >(0,nbondlist),*this);
+ }
+ }
+ DeviceType::fence();
+
+ k_warning_flag.template modify();
+ k_warning_flag.template sync();
+ if (h_warning_flag())
+ error->warning(FLERR,"FENE bond too long",0);
+
+ k_error_flag.template modify();
+ k_error_flag.template sync();
+ if (h_error_flag())
+ error->one(FLERR,"Bad FENE bond");
+
+ if (eflag_global) energy += ev.evdwl;
+ if (vflag_global) {
+ virial[0] += ev.v[0];
+ virial[1] += ev.v[1];
+ virial[2] += ev.v[2];
+ virial[3] += ev.v[3];
+ virial[4] += ev.v[4];
+ virial[5] += ev.v[5];
+ }
+
+ if (eflag_atom) {
+ k_eatom.template modify();
+ k_eatom.template sync();
+ }
+
+ if (vflag_atom) {
+ k_vatom.template modify();
+ k_vatom.template sync();
+ }
+
+ copymode = 0;
+}
+
+template
+template
+KOKKOS_INLINE_FUNCTION
+void BondFENEKokkos::operator()(TagBondFENECompute, const int &n, EV_FLOAT& ev) const {
+
+ if (d_error_flag()) return;
+
+ // The f array is atomic
+ Kokkos::View > a_f = f;
+
+ const int i1 = bondlist(n,0);
+ const int i2 = bondlist(n,1);
+ const int type = bondlist(n,2);
+
+ const F_FLOAT delx = x(i1,0) - x(i2,0);
+ const F_FLOAT dely = x(i1,1) - x(i2,1);
+ const F_FLOAT delz = x(i1,2) - x(i2,2);
+
+ // force from log term
+
+ const F_FLOAT rsq = delx*delx + dely*dely + delz*delz;
+ const F_FLOAT r0sq = d_r0[type] * d_r0[type];
+ F_FLOAT rlogarg = 1.0 - rsq/r0sq;
+
+ // if r -> r0, then rlogarg < 0.0 which is an error
+ // issue a warning and reset rlogarg = epsilon
+ // if r > 2*r0 something serious is wrong, abort
+
+ if (rlogarg < 0.1) {
+ if (!d_warning_flag())
+ Kokkos::atomic_fetch_add(&d_warning_flag(),1);
+ if (rlogarg <= -3.0 && !d_error_flag())
+ Kokkos::atomic_fetch_add(&d_error_flag(),1);
+ rlogarg = 0.1;
+ }
+
+ F_FLOAT fbond = -d_k[type]/rlogarg;
+
+ // force from LJ term
+
+ F_FLOAT sr6 = 0.0;
+ if (rsq < TWO_1_3*d_sigma[type]*d_sigma[type]) {
+ const F_FLOAT sr2 = d_sigma[type]*d_sigma[type]/rsq;
+ sr6 = sr2*sr2*sr2;
+ fbond += 48.0*d_epsilon[type]*sr6*(sr6-0.5)/rsq;
+ }
+
+ // energy
+
+ F_FLOAT ebond = 0.0;
+ if (eflag) {
+ ebond = -0.5 * d_k[type]*r0sq*log(rlogarg);
+ if (rsq < TWO_1_3*d_sigma[type]*d_sigma[type])
+ ebond += 4.0*d_epsilon[type]*sr6*(sr6-1.0) + d_epsilon[type];
+ }
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ a_f(i1,0) += delx*fbond;
+ a_f(i1,1) += dely*fbond;
+ a_f(i1,2) += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ a_f(i2,0) -= delx*fbond;
+ a_f(i2,1) -= dely*fbond;
+ a_f(i2,2) -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally(ev,i1,i2,ebond,fbond,delx,dely,delz);
+}
+
+template
+template
+KOKKOS_INLINE_FUNCTION
+void BondFENEKokkos::operator()(TagBondFENECompute, const int &n) const {
+ EV_FLOAT ev;
+ this->template operator()(TagBondFENECompute(), n, ev);
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void BondFENEKokkos::allocate()
+{
+ BondFENE::allocate();
+
+ int n = atom->nbondtypes;
+ k_k = DAT::tdual_ffloat_1d("BondFene::k",n+1);
+ k_r0 = DAT::tdual_ffloat_1d("BondFene::r0",n+1);
+ k_epsilon = DAT::tdual_ffloat_1d("BondFene::epsilon",n+1);
+ k_sigma = DAT::tdual_ffloat_1d("BondFene::sigma",n+1);
+
+ d_k = k_k.d_view;
+ d_r0 = k_r0.d_view;
+ d_epsilon = k_epsilon.d_view;
+ d_sigma = k_sigma.d_view;
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one type
+------------------------------------------------------------------------- */
+
+template
+void BondFENEKokkos::coeff(int narg, char **arg)
+{
+ BondFENE::coeff(narg, arg);
+
+ int n = atom->nbondtypes;
+ for (int i = 1; i <= n; i++) {
+ k_k.h_view[i] = k[i];
+ k_r0.h_view[i] = r0[i];
+ k_epsilon.h_view[i] = epsilon[i];
+ k_sigma.h_view[i] = sigma[i];
+ }
+
+ k_k.template modify();
+ k_r0.template modify();
+ k_epsilon.template modify();
+ k_sigma.template modify();
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+------------------------------------------------------------------------- */
+
+template
+//template
+KOKKOS_INLINE_FUNCTION
+void BondFENEKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j,
+ const F_FLOAT &ebond, const F_FLOAT &fbond, const F_FLOAT &delx,
+ const F_FLOAT &dely, const F_FLOAT &delz) const
+{
+ E_FLOAT ebondhalf;
+ F_FLOAT v[6];
+
+ // The eatom and vatom arrays are atomic
+ Kokkos::View > v_eatom = k_eatom.view();
+ Kokkos::View > v_vatom = k_vatom.view();
+
+ if (eflag_either) {
+ if (eflag_global) {
+ if (newton_bond) ev.evdwl += ebond;
+ else {
+ ebondhalf = 0.5*ebond;
+ if (i < nlocal) ev.evdwl += ebondhalf;
+ if (j < nlocal) ev.evdwl += ebondhalf;
+ }
+ }
+ if (eflag_atom) {
+ ebondhalf = 0.5*ebond;
+ if (newton_bond || i < nlocal) v_eatom[i] += ebondhalf;
+ if (newton_bond || j < nlocal) v_eatom[j] += ebondhalf;
+ }
+ }
+
+ if (vflag_either) {
+ v[0] = delx*delx*fbond;
+ v[1] = dely*dely*fbond;
+ v[2] = delz*delz*fbond;
+ v[3] = delx*dely*fbond;
+ v[4] = delx*delz*fbond;
+ v[5] = dely*delz*fbond;
+
+ if (vflag_global) {
+ if (newton_bond) {
+ ev.v[0] += v[0];
+ ev.v[1] += v[1];
+ ev.v[2] += v[2];
+ ev.v[3] += v[3];
+ ev.v[4] += v[4];
+ ev.v[5] += v[5];
+ } else {
+ if (i < nlocal) {
+ ev.v[0] += 0.5*v[0];
+ ev.v[1] += 0.5*v[1];
+ ev.v[2] += 0.5*v[2];
+ ev.v[3] += 0.5*v[3];
+ ev.v[4] += 0.5*v[4];
+ ev.v[5] += 0.5*v[5];
+ }
+ if (j < nlocal) {
+ ev.v[0] += 0.5*v[0];
+ ev.v[1] += 0.5*v[1];
+ ev.v[2] += 0.5*v[2];
+ ev.v[3] += 0.5*v[3];
+ ev.v[4] += 0.5*v[4];
+ ev.v[5] += 0.5*v[5];
+ }
+ }
+ }
+
+ if (vflag_atom) {
+ if (newton_bond || i < nlocal) {
+ v_vatom(i,0) += 0.5*v[0];
+ v_vatom(i,1) += 0.5*v[1];
+ v_vatom(i,2) += 0.5*v[2];
+ v_vatom(i,3) += 0.5*v[3];
+ v_vatom(i,4) += 0.5*v[4];
+ v_vatom(i,5) += 0.5*v[5];
+ }
+ if (newton_bond || j < nlocal) {
+ v_vatom(j,0) += 0.5*v[0];
+ v_vatom(j,1) += 0.5*v[1];
+ v_vatom(j,2) += 0.5*v[2];
+ v_vatom(j,3) += 0.5*v[3];
+ v_vatom(j,4) += 0.5*v[4];
+ v_vatom(j,5) += 0.5*v[5];
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template class BondFENEKokkos;
+#ifdef KOKKOS_HAVE_CUDA
+template class BondFENEKokkos;
+#endif
\ No newline at end of file
diff --git a/src/KOKKOS/bond_fene_kokkos.h b/src/KOKKOS/bond_fene_kokkos.h
new file mode 100755
index 0000000000..fae5a373ab
--- /dev/null
+++ b/src/KOKKOS/bond_fene_kokkos.h
@@ -0,0 +1,103 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+#ifdef BOND_CLASS
+
+BondStyle(fene/kk,BondFENEKokkos)
+BondStyle(fene/kk/device,BondFENEKokkos)
+BondStyle(fene/kk/host,BondFENEKokkos)
+
+#else
+
+#ifndef LMP_BOND_FENE_KOKKOS_H
+#define LMP_BOND_FENE_KOKKOS_H
+
+#include "bond_fene.h"
+#include "kokkos_type.h"
+
+namespace LAMMPS_NS {
+
+template
+struct TagBondFENECompute{};
+
+template
+class BondFENEKokkos : public BondFENE {
+ public:
+ typedef DeviceType device_type;
+ typedef EV_FLOAT value_type;
+ typedef ArrayTypes AT;
+
+ BondFENEKokkos(class LAMMPS *);
+ virtual ~BondFENEKokkos();
+ virtual void compute(int, int);
+ virtual void coeff(int, char **);
+
+ template
+ KOKKOS_INLINE_FUNCTION
+ void operator()(TagBondFENECompute, const int&, EV_FLOAT&) const;
+
+ template
+ KOKKOS_INLINE_FUNCTION
+ void operator()(TagBondFENECompute, const int&) const;
+
+ //template
+ KOKKOS_INLINE_FUNCTION
+ void ev_tally(EV_FLOAT &ev, const int &i, const int &j,
+ const F_FLOAT &ebond, const F_FLOAT &fbond, const F_FLOAT &delx,
+ const F_FLOAT &dely, const F_FLOAT &delz) const;
+
+ protected:
+ class AtomKokkos *atomKK;
+ class NeighborKokkos *neighborKK;
+
+ typename ArrayTypes::t_x_array_randomread x;
+ typename ArrayTypes::t_f_array f;
+ typename ArrayTypes::t_int_2d bondlist;
+
+ DAT::tdual_efloat_1d k_eatom;
+ DAT::tdual_virial_array k_vatom;
+ DAT::t_efloat_1d d_eatom;
+ DAT::t_virial_array d_vatom;
+
+ DAT::tdual_int_scalar k_warning_flag;
+ typename AT::t_int_scalar d_warning_flag;
+ HAT::t_int_scalar h_warning_flag;
+
+ DAT::tdual_int_scalar k_error_flag;
+ typename AT::t_int_scalar d_error_flag;
+ HAT::t_int_scalar h_error_flag;
+
+ int nlocal,newton_bond;
+ int eflag,vflag;
+
+ DAT::tdual_ffloat_1d k_k;
+ DAT::tdual_ffloat_1d k_r0;
+ DAT::tdual_ffloat_1d k_epsilon;
+ DAT::tdual_ffloat_1d k_sigma;
+
+ DAT::t_ffloat_1d d_k;
+ DAT::t_ffloat_1d d_r0;
+ DAT::t_ffloat_1d d_epsilon;
+ DAT::t_ffloat_1d d_sigma;
+
+ virtual void allocate();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+*/
diff --git a/src/KOKKOS/bond_harmonic_kokkos.cpp b/src/KOKKOS/bond_harmonic_kokkos.cpp
new file mode 100755
index 0000000000..f90df92fb3
--- /dev/null
+++ b/src/KOKKOS/bond_harmonic_kokkos.cpp
@@ -0,0 +1,323 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Stan Moore (SNL)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdlib.h"
+#include "bond_harmonic_kokkos.h"
+#include "atom_kokkos.h"
+#include "neighbor_kokkos.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "error.h"
+#include "atom_masks.h"
+
+using namespace LAMMPS_NS;
+
+
+/* ---------------------------------------------------------------------- */
+
+template
+BondHarmonicKokkos::BondHarmonicKokkos(LAMMPS *lmp) : BondHarmonic(lmp)
+{
+ atomKK = (AtomKokkos *) atom;
+ neighborKK = (NeighborKokkos *) neighbor;
+ execution_space = ExecutionSpaceFromDevice::space;
+ datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK;
+ datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK;
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+BondHarmonicKokkos::~BondHarmonicKokkos()
+{
+ if (!copymode) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->destroy_kokkos(k_vatom,vatom);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+template
+void BondHarmonicKokkos::compute(int eflag_in, int vflag_in)
+{
+ eflag = eflag_in;
+ vflag = vflag_in;
+
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = 0;
+
+ // reallocate per-atom arrays if necessary
+
+ if (eflag_atom) {
+ memory->destroy_kokkos(k_eatom,eatom);
+ memory->create_kokkos(k_eatom,eatom,maxeatom,"bond:eatom");
+ d_eatom = k_eatom.d_view;
+ }
+ if (vflag_atom) {
+ memory->destroy_kokkos(k_vatom,vatom);
+ memory->create_kokkos(k_vatom,vatom,maxvatom,6,"bond:vatom");
+ d_vatom = k_vatom.d_view;
+ }
+
+ atomKK->sync(execution_space,datamask_read);
+ k_k.template sync();
+ k_r0.template sync();
+ if (eflag || vflag) atomKK->modified(execution_space,datamask_modify);
+ else atomKK->modified(execution_space,F_MASK);
+
+ x = atomKK->k_x.view