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 @@ LAMMPS-ICMS Users Manual - + @@ -22,7 +22,7 @@

LAMMPS-ICMS Documentation

-

14 Mar 2015 version +

18 Mar 2015 version

Version info:

diff --git a/doc/Manual.pdf b/doc/Manual.pdf index f95aaa88cb..e47d062b63 100644 Binary files a/doc/Manual.pdf and b/doc/Manual.pdf differ diff --git a/doc/Manual.txt b/doc/Manual.txt index efe857be24..131ed47c29 100644 --- a/doc/Manual.txt +++ b/doc/Manual.txt @@ -1,7 +1,7 @@ LAMMPS-ICMS Users Manual LAMMPS Users Manual - + @@ -19,7 +19,7 @@

LAMMPS-ICMS Documentation :c,h3 -14 Mar 2015 version :c,h4 +18 Mar 2015 version :c,h4 Version info: :h4 diff --git a/doc/Section_commands.html b/doc/Section_commands.html index d351a5353f..be864200a1 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -383,12 +383,12 @@ in the command's documentation. logmassminimizemin_modifymin_stylemolecule nebneigh_modifyneighbornewtonnextpackage pair_coeffpair_modifypair_stylepair_writepartitionprd -printprocessorsquitread_dataread_dumpread_restart -regionreplicatererunreset_timesteprestartrun -run_stylesetshellspecial_bondssuffixtad -temperthermothermo_modifythermo_styletimestepuncompute -undumpunfixunitsvariablevelocitywrite_data -write_dumpwrite_restart +printprocessorspythonquitread_dataread_dump +read_restartregionreplicatererunreset_timesteprestart +runrun_stylesetshellspecial_bondssuffix +tadtemperthermothermo_modifythermo_styletimestep +uncomputeundumpunfixunitsvariablevelocity +write_datawrite_dumpwrite_restart

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.

- - + +
nonehybridclass2 (o)fene (o)
fene/expand (o)harmonic (o)morse (o)nonlinear (o)
nonehybridclass2 (o)fene (ko)
fene/expand (o)harmonic (ko)morse (o)nonlinear (o)
quartic (o)table (o)
@@ -570,9 +570,9 @@ letters in parenthesis: c = USER-CUDA, g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT.

- + -
nonehybridcharmm (o)class2 (o)
nonehybridcharmm (ko)class2 (o)
cosine (o)cosine/delta (o)cosine/periodic (o)cosine/squared (o)
harmonic (o)table (o) +
harmonic (ko)table (o)

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.

- - +
nonehybridcharmm (o)class2 (o)
harmonic (o)helix (o)multi/harmonic (o)opls (o) +
nonehybridcharmm (ko)class2 (o)
harmonic (o)helix (o)multi/harmonic (o)opls (ko)

These are additional dihedral styles in USER packages, which can be @@ -624,7 +624,7 @@ KOKKOS, o = USER-OMP, t = OPT.

-
nonehybridclass2 (o)cvff (o)
harmonic (o)umbrella (o) +
harmonic (ko)umbrella (o)

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(); + 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; + + 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(); + + 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 BondHarmonicKokkos::operator()(TagBondHarmonicCompute, const int &n, EV_FLOAT& ev) const { + + // 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); + + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const F_FLOAT r = sqrt(rsq); + const F_FLOAT dr = r - d_r0[type]; + const F_FLOAT rk = d_k[type] * dr; + + // force & energy + + F_FLOAT fbond = 0.0; + if (r > 0.0) fbond = -2.0*rk/r; + + F_FLOAT ebond = 0.0; + if (eflag) + ebond = rk*dr; + + // 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 BondHarmonicKokkos::operator()(TagBondHarmonicCompute, const int &n) const { + EV_FLOAT ev; + this->template operator()(TagBondHarmonicCompute(), n, ev); +} + +/* ---------------------------------------------------------------------- */ + +template +void BondHarmonicKokkos::allocate() +{ + BondHarmonic::allocate(); + + int n = atom->nbondtypes; + k_k = DAT::tdual_ffloat_1d("BondHarmonic::k",n+1); + k_r0 = DAT::tdual_ffloat_1d("BondHarmonic::r0",n+1); + + d_k = k_k.d_view; + d_r0 = k_r0.d_view; +} + +/* ---------------------------------------------------------------------- + set coeffs for one type +------------------------------------------------------------------------- */ + +template +void BondHarmonicKokkos::coeff(int narg, char **arg) +{ + BondHarmonic::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_k.template modify(); + k_r0.template modify(); +} + +/* ---------------------------------------------------------------------- + tally energy and virial into global and per-atom accumulators +------------------------------------------------------------------------- */ + +template +//template +KOKKOS_INLINE_FUNCTION +void BondHarmonicKokkos::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 BondHarmonicKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class BondHarmonicKokkos; +#endif \ No newline at end of file diff --git a/src/KOKKOS/bond_harmonic_kokkos.h b/src/KOKKOS/bond_harmonic_kokkos.h new file mode 100755 index 0000000000..cf20b4fe26 --- /dev/null +++ b/src/KOKKOS/bond_harmonic_kokkos.h @@ -0,0 +1,91 @@ +/* -*- 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(harmonic/kk,BondHarmonicKokkos) +BondStyle(harmonic/kk/device,BondHarmonicKokkos) +BondStyle(harmonic/kk/host,BondHarmonicKokkos) + +#else + +#ifndef LMP_BOND_HARMONIC_KOKKOS_H +#define LMP_BOND_HARMONIC_KOKKOS_H + +#include "bond_harmonic.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +struct TagBondHarmonicCompute{}; + +template +class BondHarmonicKokkos : public BondHarmonic { + + public: + typedef DeviceType device_type; + typedef EV_FLOAT value_type; + + BondHarmonicKokkos(class LAMMPS *); + virtual ~BondHarmonicKokkos(); + virtual void compute(int, int); + virtual void coeff(int, char **); + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagBondHarmonicCompute, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagBondHarmonicCompute, 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; + + int nlocal,newton_bond; + int eflag,vflag; + + DAT::tdual_ffloat_1d k_k; + DAT::tdual_ffloat_1d k_r0; + + DAT::t_ffloat_1d d_k; + DAT::t_ffloat_1d d_r0; + + virtual void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 8c3b825acd..bcbf1efc7e 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -888,10 +888,11 @@ void CommKokkos::borders_device() { // reset global->local map - if (map_style) atom->map_set(); if (exec_space == Host) k_sendlist.sync(); atomKK->modified(exec_space,ALL_MASK); DeviceType::fence(); + atomKK->sync(Host,TAG_MASK); + if (map_style) atom->map_set(); } /* ---------------------------------------------------------------------- realloc the size of the send buffer as needed with BUFFACTOR and bufextra diff --git a/src/KOKKOS/dihedral_charmm_kokkos.cpp b/src/KOKKOS/dihedral_charmm_kokkos.cpp new file mode 100755 index 0000000000..6d7275fed2 --- /dev/null +++ b/src/KOKKOS/dihedral_charmm_kokkos.cpp @@ -0,0 +1,745 @@ +/* ---------------------------------------------------------------------- + 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 "dihedral_charmm_kokkos.h" +#include "atom_kokkos.h" +#include "comm.h" +#include "neighbor_kokkos.h" +#include "domain.h" +#include "force.h" +#include "pair.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define TOLERANCE 0.05 + +/* ---------------------------------------------------------------------- */ + +template +DihedralCharmmKokkos::DihedralCharmmKokkos(LAMMPS *lmp) : DihedralCharmm(lmp) +{ + atomKK = (AtomKokkos *) atom; + neighborKK = (NeighborKokkos *) neighbor; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK | TYPE_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + + k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); + d_warning_flag = k_warning_flag.view(); + h_warning_flag = k_warning_flag.h_view; +} + +/* ---------------------------------------------------------------------- */ + +template +DihedralCharmmKokkos::~DihedralCharmmKokkos() +{ + if (!copymode) { + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void DihedralCharmmKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = 0; + + // insure pair->ev_tally() will use 1-4 virial contribution + + if (weightflag && vflag_global == 2) + force->pair->vflag_either = force->pair->vflag_global = 1; + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memory->destroy_kokkos(k_eatom,eatom); + memory->create_kokkos(k_eatom,eatom,maxeatom,"dihedral:eatom"); + d_eatom = k_eatom.d_view; + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"dihedral:vatom"); + d_vatom = k_vatom.d_view; + } + + k_eatom_pair = DAT::tdual_efloat_1d("dihedral:eatom_pair",maxeatom); + k_vatom_pair = DAT::tdual_virial_array("dihedral:vatom_pair",maxvatom); + + atomKK->sync(execution_space,datamask_read); + k_lj14_1.template sync(); + k_lj14_2.template sync(); + k_lj14_3.template sync(); + k_lj14_4.template sync(); + k_k.template sync(); + k_multiplicity.template sync(); + k_shift.template sync(); + k_cos_shift.template sync(); + k_sin_shift.template sync(); + k_weight.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(); + q = atomKK->k_q.view(); + atomtype = atomKK->k_type.view(); + neighborKK->k_dihedrallist.template sync(); + dihedrallist = neighborKK->k_dihedrallist.view(); + int ndihedrallist = neighborKK->ndihedrallist; + nlocal = atom->nlocal; + newton_bond = force->newton_bond; + qqrd2e = force->qqrd2e; + + h_warning_flag() = 0; + k_warning_flag.template modify(); + k_warning_flag.template sync(); + + copymode = 1; + + // loop over neighbors of my atoms + + EVM_FLOAT evm; + + if (evflag) { + if (newton_bond) { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,ndihedrallist),*this,evm); + } else { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,ndihedrallist),*this,evm); + } + } else { + if (newton_bond) { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,ndihedrallist),*this); + } else { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,ndihedrallist),*this); + } + } + DeviceType::fence(); + + // error check + + k_warning_flag.template modify(); + k_warning_flag.template sync(); + if (h_warning_flag()) + error->warning(FLERR,"Dihedral problem",0); + + if (eflag_global) { + energy += evm.emol; + force->pair->eng_vdwl += evm.evdwl; + force->pair->eng_coul += evm.ecoul; + } + if (vflag_global) { + virial[0] += evm.v[0]; + virial[1] += evm.v[1]; + virial[2] += evm.v[2]; + virial[3] += evm.v[3]; + virial[4] += evm.v[4]; + virial[5] += evm.v[5]; + + force->pair->virial[0] += evm.vp[0]; + force->pair->virial[1] += evm.vp[1]; + force->pair->virial[2] += evm.vp[2]; + force->pair->virial[3] += evm.vp[3]; + force->pair->virial[4] += evm.vp[4]; + force->pair->virial[5] += evm.vp[5]; + } + + // don't yet have dualviews for eatom and vatom in pair_kokkos, + // so need to manually copy these to pair style + + int n = nlocal; + if (newton_bond) n += atom->nghost; + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + + k_eatom_pair.template modify(); + k_eatom_pair.template sync(); + for (int i = 0; i < n; i++) + force->pair->eatom[i] += k_eatom_pair.h_view(i); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + + k_vatom_pair.template modify(); + k_vatom_pair.template sync(); + for (int i = 0; i < n; i++) { + force->pair->vatom[i][0] += k_vatom_pair.h_view(i,0); + force->pair->vatom[i][1] += k_vatom_pair.h_view(i,1); + force->pair->vatom[i][2] += k_vatom_pair.h_view(i,2); + force->pair->vatom[i][3] += k_vatom_pair.h_view(i,3); + force->pair->vatom[i][4] += k_vatom_pair.h_view(i,4); + force->pair->vatom[i][5] += k_vatom_pair.h_view(i,5); + } + } + + copymode = 0; +} + +template +template +KOKKOS_INLINE_FUNCTION +void DihedralCharmmKokkos::operator()(TagDihedralCharmmCompute, const int &n, EVM_FLOAT& evm) const { + + // The f array is atomic + Kokkos::View > a_f = f; + + const int i1 = dihedrallist(n,0); + const int i2 = dihedrallist(n,1); + const int i3 = dihedrallist(n,2); + const int i4 = dihedrallist(n,3); + const int type = dihedrallist(n,4); + + // 1st bond + + const F_FLOAT vb1x = x(i1,0) - x(i2,0); + const F_FLOAT vb1y = x(i1,1) - x(i2,1); + const F_FLOAT vb1z = x(i1,2) - x(i2,2); + + // 2nd bond + + const F_FLOAT vb2x = x(i3,0) - x(i2,0); + const F_FLOAT vb2y = x(i3,1) - x(i2,1); + const F_FLOAT vb2z = x(i3,2) - x(i2,2); + + const F_FLOAT vb2xm = -vb2x; + const F_FLOAT vb2ym = -vb2y; + const F_FLOAT vb2zm = -vb2z; + + // 3rd bond + + const F_FLOAT vb3x = x(i4,0) - x(i3,0); + const F_FLOAT vb3y = x(i4,1) - x(i3,1); + const F_FLOAT vb3z = x(i4,2) - x(i3,2); + + const F_FLOAT ax = vb1y*vb2zm - vb1z*vb2ym; + const F_FLOAT ay = vb1z*vb2xm - vb1x*vb2zm; + const F_FLOAT az = vb1x*vb2ym - vb1y*vb2xm; + const F_FLOAT bx = vb3y*vb2zm - vb3z*vb2ym; + const F_FLOAT by = vb3z*vb2xm - vb3x*vb2zm; + const F_FLOAT bz = vb3x*vb2ym - vb3y*vb2xm; + + const F_FLOAT rasq = ax*ax + ay*ay + az*az; + const F_FLOAT rbsq = bx*bx + by*by + bz*bz; + const F_FLOAT rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; + const F_FLOAT rg = sqrt(rgsq); + + F_FLOAT rginv,ra2inv,rb2inv; + rginv = ra2inv = rb2inv = 0.0; + if (rg > 0) rginv = 1.0/rg; + if (rasq > 0) ra2inv = 1.0/rasq; + if (rbsq > 0) rb2inv = 1.0/rbsq; + const F_FLOAT rabinv = sqrt(ra2inv*rb2inv); + + F_FLOAT c = (ax*bx + ay*by + az*bz)*rabinv; + F_FLOAT s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); + + // error check + + if ((c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) && !d_warning_flag()) + Kokkos::atomic_fetch_add(&d_warning_flag(),1); + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + const int m = d_multiplicity[type]; + F_FLOAT p = 1.0; + F_FLOAT ddf1,df1; + ddf1 = df1 = 0.0; + + for (int i = 0; i < m; i++) { + ddf1 = p*c - df1*s; + df1 = p*s + df1*c; + p = ddf1; + } + + p = p*d_cos_shift[type] + df1*d_sin_shift[type]; + df1 = df1*d_cos_shift[type] - ddf1*d_sin_shift[type]; + df1 *= -m; + p += 1.0; + + if (m == 0) { + p = 1.0 + d_cos_shift[type]; + df1 = 0.0; + } + + E_FLOAT edihedral = 0.0; + if (eflag) edihedral = d_k[type] * p; + + const F_FLOAT fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; + const F_FLOAT hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; + const F_FLOAT fga = fg*ra2inv*rginv; + const F_FLOAT hgb = hg*rb2inv*rginv; + const F_FLOAT gaa = -ra2inv*rg; + const F_FLOAT gbb = rb2inv*rg; + + const F_FLOAT dtfx = gaa*ax; + const F_FLOAT dtfy = gaa*ay; + const F_FLOAT dtfz = gaa*az; + const F_FLOAT dtgx = fga*ax - hgb*bx; + const F_FLOAT dtgy = fga*ay - hgb*by; + const F_FLOAT dtgz = fga*az - hgb*bz; + const F_FLOAT dthx = gbb*bx; + const F_FLOAT dthy = gbb*by; + const F_FLOAT dthz = gbb*bz; + + const F_FLOAT df = -d_k[type] * df1; + + const F_FLOAT sx2 = df*dtgx; + const F_FLOAT sy2 = df*dtgy; + const F_FLOAT sz2 = df*dtgz; + + F_FLOAT f1[3],f2[3],f3[3],f4[3]; + f1[0] = df*dtfx; + f1[1] = df*dtfy; + f1[2] = df*dtfz; + + f2[0] = sx2 - f1[0]; + f2[1] = sy2 - f1[1]; + f2[2] = sz2 - f1[2]; + + f4[0] = df*dthx; + f4[1] = df*dthy; + f4[2] = df*dthz; + + f3[0] = -sx2 - f4[0]; + f3[1] = -sy2 - f4[1]; + f3[2] = -sz2 - f4[2]; + + // apply force to each of 4 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) += f2[0]; + a_f(i2,1) += f2[1]; + a_f(i2,2) += f2[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 (NEWTON_BOND || i4 < nlocal) { + a_f(i4,0) += f4[0]; + a_f(i4,1) += f4[1]; + a_f(i4,2) += f4[2]; + } + + if (EVFLAG) + ev_tally(evm,i1,i2,i3,i4,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z); + + // 1-4 LJ and Coulomb interactions + // tally energy/virial in pair, using newton_bond as newton flag + + if (d_weight[type] > 0.0) { + const int itype = atomtype[i1]; + const int jtype = atomtype[i4]; + + const F_FLOAT delx = x(i1,0) - x(i4,0); + const F_FLOAT dely = x(i1,1) - x(i4,1); + const F_FLOAT delz = x(i1,2) - x(i4,2); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const F_FLOAT r2inv = 1.0/rsq; + const F_FLOAT r6inv = r2inv*r2inv*r2inv; + + F_FLOAT forcecoul; + if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; + else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); + const F_FLOAT forcelj = r6inv * (d_lj14_1(itype,jtype)*r6inv - d_lj14_2(itype,jtype)); + const F_FLOAT fpair = d_weight[type] * (forcelj+forcecoul)*r2inv; + + F_FLOAT ecoul = 0.0; + F_FLOAT evdwl = 0.0; + if (eflag) { + ecoul = d_weight[type] * forcecoul; + evdwl = r6inv * (d_lj14_3(itype,jtype)*r6inv - d_lj14_4(itype,jtype)); + evdwl *= d_weight[type]; + } + + if (newton_bond || i1 < nlocal) { + a_f(i1,0) += delx*fpair; + a_f(i1,1) += dely*fpair; + a_f(i1,2) += delz*fpair; + } + if (newton_bond || i4 < nlocal) { + a_f(i4,0) -= delx*fpair; + a_f(i4,1) -= dely*fpair; + a_f(i4,2) -= delz*fpair; + } + + if (EVFLAG) ev_tally(evm,i1,i4,evdwl,ecoul,fpair,delx,dely,delz); + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void DihedralCharmmKokkos::operator()(TagDihedralCharmmCompute, const int &n) const { + EVM_FLOAT evm; + this->template operator()(TagDihedralCharmmCompute(), n, evm); +} + +/* ---------------------------------------------------------------------- */ + +template +void DihedralCharmmKokkos::allocate() +{ + DihedralCharmm::allocate(); + + int n = atom->ntypes; + k_lj14_1 = DAT::tdual_ffloat_2d("DihedralCharmm:lj14_1",n+1,n+1); + k_lj14_2 = DAT::tdual_ffloat_2d("DihedralCharmm:lj14_2",n+1,n+1); + k_lj14_3 = DAT::tdual_ffloat_2d("DihedralCharmm:lj14_3",n+1,n+1); + k_lj14_4 = DAT::tdual_ffloat_2d("DihedralCharmm:lj14_4",n+1,n+1); + + d_lj14_1 = k_lj14_1.d_view; + d_lj14_2 = k_lj14_2.d_view; + d_lj14_3 = k_lj14_3.d_view; + d_lj14_4 = k_lj14_4.d_view; + + int nd = atom->ndihedraltypes; + k_k = DAT::tdual_ffloat_1d("DihedralCharmm::k",nd+1); + k_multiplicity = DAT::tdual_ffloat_1d("DihedralCharmm::multiplicity",nd+1); + k_shift = DAT::tdual_ffloat_1d("DihedralCharmm::shift",nd+1); + k_cos_shift = DAT::tdual_ffloat_1d("DihedralCharmm::cos_shift",nd+1); + k_sin_shift = DAT::tdual_ffloat_1d("DihedralCharmm::sin_shift",nd+1); + k_weight = DAT::tdual_ffloat_1d("DihedralCharmm::weight",nd+1); + + d_k = k_k.d_view; + d_multiplicity = k_multiplicity.d_view; + d_shift = k_shift.d_view; + d_cos_shift = k_cos_shift.d_view; + d_sin_shift = k_sin_shift.d_view; + d_weight = k_weight.d_view; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more types +------------------------------------------------------------------------- */ + +template +void DihedralCharmmKokkos::coeff(int narg, char **arg) +{ + DihedralCharmm::coeff(narg, arg); + + int n = atom->ndihedraltypes; + for (int i = 1; i <= n; i++) { + k_k.h_view[i] = k[i]; + k_multiplicity.h_view[i] = multiplicity[i]; + k_shift.h_view[i] = shift[i]; + k_cos_shift.h_view[i] = cos_shift[i]; + k_sin_shift.h_view[i] = sin_shift[i]; + k_weight.h_view[i] = weight[i]; + } + + k_k.template modify(); + k_multiplicity.template modify(); + k_shift.template modify(); + k_cos_shift.template modify(); + k_sin_shift.template modify(); + k_weight.template modify(); +} + +/* ---------------------------------------------------------------------- + error check and initialize all values needed for force computation +------------------------------------------------------------------------- */ + +template +void DihedralCharmmKokkos::init_style() +{ + DihedralCharmm::init_style(); + + if (weightflag) { + int n = atom->ntypes; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + k_lj14_1.h_view(i,j) = lj14_1[i][j]; + k_lj14_2.h_view(i,j) = lj14_2[i][j]; + k_lj14_3.h_view(i,j) = lj14_3[i][j]; + k_lj14_4.h_view(i,j) = lj14_4[i][j]; + } + } + } + + k_lj14_1.template modify(); + k_lj14_2.template modify(); + k_lj14_3.template modify(); + k_lj14_4.template modify(); +} + +/* ---------------------------------------------------------------------- + tally energy and virial into global and per-atom accumulators + virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4 + = (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4 + = vb1*f1 + vb2*f3 + (vb3+vb2)*f4 +------------------------------------------------------------------------- */ + +template +//template +KOKKOS_INLINE_FUNCTION +void DihedralCharmmKokkos::ev_tally(EVM_FLOAT &evm, const int i1, const int i2, const int i3, const int i4, + F_FLOAT &edihedral, F_FLOAT *f1, F_FLOAT *f3, F_FLOAT *f4, + const F_FLOAT &vb1x, const F_FLOAT &vb1y, const F_FLOAT &vb1z, + const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, + const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const +{ + E_FLOAT edihedralquarter; + 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) evm.emol += edihedral; + else { + edihedralquarter = 0.25*edihedral; + if (i1 < nlocal) evm.emol += edihedralquarter; + if (i2 < nlocal) evm.emol += edihedralquarter; + if (i3 < nlocal) evm.emol += edihedralquarter; + if (i4 < nlocal) evm.emol += edihedralquarter; + } + } + if (eflag_atom) { + edihedralquarter = 0.25*edihedral; + if (newton_bond || i1 < nlocal) v_eatom[i1] += edihedralquarter; + if (newton_bond || i2 < nlocal) v_eatom[i2] += edihedralquarter; + if (newton_bond || i3 < nlocal) v_eatom[i3] += edihedralquarter; + if (newton_bond || i4 < nlocal) v_eatom[i4] += edihedralquarter; + } + } + + if (vflag_either) { + v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0]; + v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1]; + v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2]; + v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1]; + v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2]; + v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2]; + + if (vflag_global) { + if (newton_bond) { + evm.v[0] += v[0]; + evm.v[1] += v[1]; + evm.v[2] += v[2]; + evm.v[3] += v[3]; + evm.v[4] += v[4]; + evm.v[5] += v[5]; + } else { + if (i1 < nlocal) { + evm.v[0] += 0.25*v[0]; + evm.v[1] += 0.25*v[1]; + evm.v[2] += 0.25*v[2]; + evm.v[3] += 0.25*v[3]; + evm.v[4] += 0.25*v[4]; + evm.v[5] += 0.25*v[5]; + } + if (i2 < nlocal) { + evm.v[0] += 0.25*v[0]; + evm.v[1] += 0.25*v[1]; + evm.v[2] += 0.25*v[2]; + evm.v[3] += 0.25*v[3]; + evm.v[4] += 0.25*v[4]; + evm.v[5] += 0.25*v[5]; + } + if (i3 < nlocal) { + evm.v[0] += 0.25*v[0]; + evm.v[1] += 0.25*v[1]; + evm.v[2] += 0.25*v[2]; + evm.v[3] += 0.25*v[3]; + evm.v[4] += 0.25*v[4]; + evm.v[5] += 0.25*v[5]; + } + if (i4 < nlocal) { + evm.v[0] += 0.25*v[0]; + evm.v[1] += 0.25*v[1]; + evm.v[2] += 0.25*v[2]; + evm.v[3] += 0.25*v[3]; + evm.v[4] += 0.25*v[4]; + evm.v[5] += 0.25*v[5]; + } + } + } + + if (vflag_atom) { + if (newton_bond || i1 < nlocal) { + v_vatom(i1,0) += 0.25*v[0]; + v_vatom(i1,1) += 0.25*v[1]; + v_vatom(i1,2) += 0.25*v[2]; + v_vatom(i1,3) += 0.25*v[3]; + v_vatom(i1,4) += 0.25*v[4]; + v_vatom(i1,5) += 0.25*v[5]; + } + if (newton_bond || i2 < nlocal) { + v_vatom(i2,0) += 0.25*v[0]; + v_vatom(i2,1) += 0.25*v[1]; + v_vatom(i2,2) += 0.25*v[2]; + v_vatom(i2,3) += 0.25*v[3]; + v_vatom(i2,4) += 0.25*v[4]; + v_vatom(i2,5) += 0.25*v[5]; + } + if (newton_bond || i3 < nlocal) { + v_vatom(i3,0) += 0.25*v[0]; + v_vatom(i3,1) += 0.25*v[1]; + v_vatom(i3,2) += 0.25*v[2]; + v_vatom(i3,3) += 0.25*v[3]; + v_vatom(i3,4) += 0.25*v[4]; + v_vatom(i3,5) += 0.25*v[5]; + } + if (newton_bond || i4 < nlocal) { + v_vatom(i4,0) += 0.25*v[0]; + v_vatom(i4,1) += 0.25*v[1]; + v_vatom(i4,2) += 0.25*v[2]; + v_vatom(i4,3) += 0.25*v[3]; + v_vatom(i4,4) += 0.25*v[4]; + v_vatom(i4,5) += 0.25*v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + need i < nlocal test since called by bond_quartic and dihedral_charmm +------------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void DihedralCharmmKokkos::ev_tally(EVM_FLOAT &evm, const int i, const int j, + const F_FLOAT &evdwl, const F_FLOAT &ecoul, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const +{ + E_FLOAT evdwlhalf,ecoulhalf,epairhalf; + F_FLOAT v[6]; + + // The eatom and vatom arrays are atomic + Kokkos::View > v_eatom_pair = k_eatom_pair.view(); + Kokkos::View > v_vatom_pair = k_vatom_pair.view(); + + if (eflag_either) { + if (eflag_global) { + if (newton_bond) { + evm.evdwl += evdwl; + evm.ecoul += ecoul; + } else { + evdwlhalf = 0.5*evdwl; + ecoulhalf = 0.5*ecoul; + if (i < nlocal) { + evm.evdwl += evdwlhalf; + evm.ecoul += ecoulhalf; + } + if (j < nlocal) { + evm.evdwl += evdwlhalf; + evm.ecoul += ecoulhalf; + } + } + } + if (eflag_atom) { + epairhalf = 0.5 * (evdwl + ecoul); + if (newton_bond || i < nlocal) v_eatom_pair[i] += epairhalf; + if (newton_bond || j < nlocal) v_eatom_pair[j] += epairhalf; + } + } + + if (vflag_either) { + v[0] = delx*delx*fpair; + v[1] = dely*dely*fpair; + v[2] = delz*delz*fpair; + v[3] = delx*dely*fpair; + v[4] = delx*delz*fpair; + v[5] = dely*delz*fpair; + + if (vflag_global) { + if (newton_bond) { + evm.vp[0] += v[0]; + evm.vp[1] += v[1]; + evm.vp[2] += v[2]; + evm.vp[3] += v[3]; + evm.vp[4] += v[4]; + evm.vp[5] += v[5]; + } else { + if (i < nlocal) { + evm.vp[0] += 0.5*v[0]; + evm.vp[1] += 0.5*v[1]; + evm.vp[2] += 0.5*v[2]; + evm.vp[3] += 0.5*v[3]; + evm.vp[4] += 0.5*v[4]; + evm.vp[5] += 0.5*v[5]; + } + if (j < nlocal) { + evm.vp[0] += 0.5*v[0]; + evm.vp[1] += 0.5*v[1]; + evm.vp[2] += 0.5*v[2]; + evm.vp[3] += 0.5*v[3]; + evm.vp[4] += 0.5*v[4]; + evm.vp[5] += 0.5*v[5]; + } + } + } + + if (vflag_atom) { + if (newton_bond || i < nlocal) { + v_vatom_pair(i,0) += 0.5*v[0]; + v_vatom_pair(i,1) += 0.5*v[1]; + v_vatom_pair(i,2) += 0.5*v[2]; + v_vatom_pair(i,3) += 0.5*v[3]; + v_vatom_pair(i,4) += 0.5*v[4]; + v_vatom_pair(i,5) += 0.5*v[5]; + } + if (newton_bond || j < nlocal) { + v_vatom_pair(j,0) += 0.5*v[0]; + v_vatom_pair(j,1) += 0.5*v[1]; + v_vatom_pair(j,2) += 0.5*v[2]; + v_vatom_pair(j,3) += 0.5*v[3]; + v_vatom_pair(j,4) += 0.5*v[4]; + v_vatom_pair(j,5) += 0.5*v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template class DihedralCharmmKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class DihedralCharmmKokkos; +#endif \ No newline at end of file diff --git a/src/KOKKOS/dihedral_charmm_kokkos.h b/src/KOKKOS/dihedral_charmm_kokkos.h new file mode 100755 index 0000000000..3b8590541d --- /dev/null +++ b/src/KOKKOS/dihedral_charmm_kokkos.h @@ -0,0 +1,186 @@ +/* -*- 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 DIHEDRAL_CLASS + +DihedralStyle(charmm/kk,DihedralCharmmKokkos) +DihedralStyle(charmm/kk/device,DihedralCharmmKokkos) +DihedralStyle(charmm/kk/host,DihedralCharmmKokkos) + +#else + +#ifndef LMP_DIHEDRAL_CHARMM_KOKKOS_H +#define LMP_DIHEDRAL_CHARMM_KOKKOS_H + +#include "dihedral_charmm.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +struct s_EVM_FLOAT { + E_FLOAT evdwl; + E_FLOAT ecoul; + E_FLOAT emol; + F_FLOAT v[6]; + F_FLOAT vp[6]; + KOKKOS_INLINE_FUNCTION + s_EVM_FLOAT() { + evdwl = 0; + ecoul = 0; + emol = 0; + v[0] = 0; v[1] = 0; v[2] = 0; + v[3] = 0; v[4] = 0; v[5] = 0; + vp[0] = 0; vp[1] = 0; vp[2] = 0; + vp[3] = 0; vp[4] = 0; vp[5] = 0; + } + + KOKKOS_INLINE_FUNCTION + void operator+=(const s_EVM_FLOAT &rhs) { + evdwl += rhs.evdwl; + ecoul += rhs.ecoul; + emol += rhs.emol; + v[0] += rhs.v[0]; + v[1] += rhs.v[1]; + v[2] += rhs.v[2]; + v[3] += rhs.v[3]; + v[4] += rhs.v[4]; + v[5] += rhs.v[5]; + vp[0] += rhs.vp[0]; + vp[1] += rhs.vp[1]; + vp[2] += rhs.vp[2]; + vp[3] += rhs.vp[3]; + vp[4] += rhs.vp[4]; + vp[5] += rhs.vp[5]; + } + + KOKKOS_INLINE_FUNCTION + void operator+=(const volatile s_EVM_FLOAT &rhs) volatile { + evdwl += rhs.evdwl; + ecoul += rhs.ecoul; + emol += rhs.emol; + v[0] += rhs.v[0]; + v[1] += rhs.v[1]; + v[2] += rhs.v[2]; + v[3] += rhs.v[3]; + v[4] += rhs.v[4]; + v[5] += rhs.v[5]; + vp[0] += rhs.vp[0]; + vp[1] += rhs.vp[1]; + vp[2] += rhs.vp[2]; + vp[3] += rhs.vp[3]; + vp[4] += rhs.vp[4]; + vp[5] += rhs.vp[5]; + } +}; +typedef struct s_EVM_FLOAT EVM_FLOAT; + +template +struct TagDihedralCharmmCompute{}; + +template +class DihedralCharmmKokkos : public DihedralCharmm { + public: + typedef DeviceType device_type; + typedef EVM_FLOAT value_type; + typedef ArrayTypes AT; + + DihedralCharmmKokkos(class LAMMPS *); + virtual ~DihedralCharmmKokkos(); + virtual void compute(int, int); + virtual void coeff(int, char **); + virtual void init_style(); + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagDihedralCharmmCompute, const int&, EVM_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagDihedralCharmmCompute, const int&) const; + + //template + KOKKOS_INLINE_FUNCTION + void ev_tally(EVM_FLOAT &evm, const int i1, const int i2, const int i3, const int i4, + F_FLOAT &edihedral, F_FLOAT *f1, F_FLOAT *f3, F_FLOAT *f4, + const F_FLOAT &vb1x, const F_FLOAT &vb1y, const F_FLOAT &vb1z, + const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, + const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + + KOKKOS_INLINE_FUNCTION + void ev_tally(EVM_FLOAT &evm, const int i, const int j, + const F_FLOAT &evdwl, const F_FLOAT &ecoul, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const; + + protected: + class AtomKokkos *atomKK; + class NeighborKokkos *neighborKK; + + typename AT::t_x_array_randomread x; + typename AT::t_int_1d_randomread atomtype; + typename AT::t_ffloat_1d_randomread q; + typename AT::t_f_array f; + typename AT::t_int_2d dihedrallist; + + 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_efloat_1d k_eatom_pair; + DAT::tdual_virial_array k_vatom_pair; + DAT::t_efloat_1d d_eatom_pair; + DAT::t_virial_array d_vatom_pair; + + int nlocal,newton_bond; + int eflag,vflag; + double qqrd2e; + + DAT::tdual_int_scalar k_warning_flag; + typename AT::t_int_scalar d_warning_flag; + HAT::t_int_scalar h_warning_flag; + + DAT::tdual_ffloat_2d k_lj14_1; + DAT::tdual_ffloat_2d k_lj14_2; + DAT::tdual_ffloat_2d k_lj14_3; + DAT::tdual_ffloat_2d k_lj14_4; + + DAT::t_ffloat_2d d_lj14_1; + DAT::t_ffloat_2d d_lj14_2; + DAT::t_ffloat_2d d_lj14_3; + DAT::t_ffloat_2d d_lj14_4; + + DAT::tdual_ffloat_1d k_k; + DAT::tdual_ffloat_1d k_multiplicity; + DAT::tdual_ffloat_1d k_shift; + DAT::tdual_ffloat_1d k_sin_shift; + DAT::tdual_ffloat_1d k_cos_shift; + DAT::tdual_ffloat_1d k_weight; + + DAT::t_ffloat_1d d_k; + DAT::t_ffloat_1d d_multiplicity; + DAT::t_ffloat_1d d_shift; + DAT::t_ffloat_1d d_sin_shift; + DAT::t_ffloat_1d d_cos_shift; + DAT::t_ffloat_1d d_weight; + + virtual void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/dihedral_opls_kokkos.cpp b/src/KOKKOS/dihedral_opls_kokkos.cpp new file mode 100755 index 0000000000..8aaa052676 --- /dev/null +++ b/src/KOKKOS/dihedral_opls_kokkos.cpp @@ -0,0 +1,521 @@ +/* ---------------------------------------------------------------------- + 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 "dihedral_opls_kokkos.h" +#include "atom_kokkos.h" +#include "comm.h" +#include "neighbor_kokkos.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "memory.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; + +#define TOLERANCE 0.05 +#define SMALL 0.001 +#define SMALLER 0.00001 + +/* ---------------------------------------------------------------------- */ + +template +DihedralOPLSKokkos::DihedralOPLSKokkos(LAMMPS *lmp) : DihedralOPLS(lmp) +{ + atomKK = (AtomKokkos *) atom; + neighborKK = (NeighborKokkos *) neighbor; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | Q_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + + k_warning_flag = DAT::tdual_int_scalar("Dihedral:warning_flag"); + d_warning_flag = k_warning_flag.view(); + h_warning_flag = k_warning_flag.h_view; +} + +/* ---------------------------------------------------------------------- */ + +template +DihedralOPLSKokkos::~DihedralOPLSKokkos() +{ + if (!copymode) { + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void DihedralOPLSKokkos::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,"dihedral:eatom"); + d_eatom = k_eatom.d_view; + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"dihedral:vatom"); + d_vatom = k_vatom.d_view; + } + + atomKK->sync(execution_space,datamask_read); + k_k1.template sync(); + k_k2.template sync(); + k_k3.template sync(); + k_k4.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_dihedrallist.template sync(); + dihedrallist = neighborKK->k_dihedrallist.view(); + int ndihedrallist = neighborKK->ndihedrallist; + nlocal = atom->nlocal; + newton_bond = force->newton_bond; + + h_warning_flag() = 0; + k_warning_flag.template modify(); + k_warning_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,ndihedrallist),*this,ev); + } else { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,ndihedrallist),*this,ev); + } + } else { + if (newton_bond) { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,ndihedrallist),*this); + } else { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,ndihedrallist),*this); + } + } + DeviceType::fence(); + + // error check + + k_warning_flag.template modify(); + k_warning_flag.template sync(); + if (h_warning_flag()) + error->warning(FLERR,"Dihedral problem",0); + + 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 DihedralOPLSKokkos::operator()(TagDihedralOPLSCompute, const int &n, EV_FLOAT& ev) const { + + // The f array is atomic + Kokkos::View > a_f = f; + + const int i1 = dihedrallist(n,0); + const int i2 = dihedrallist(n,1); + const int i3 = dihedrallist(n,2); + const int i4 = dihedrallist(n,3); + const int type = dihedrallist(n,4); + + // 1st bond + + const F_FLOAT vb1x = x(i1,0) - x(i2,0); + const F_FLOAT vb1y = x(i1,1) - x(i2,1); + const F_FLOAT vb1z = x(i1,2) - x(i2,2); + + // 2nd bond + + const F_FLOAT vb2x = x(i3,0) - x(i2,0); + const F_FLOAT vb2y = x(i3,1) - x(i2,1); + const F_FLOAT vb2z = x(i3,2) - x(i2,2); + + const F_FLOAT vb2xm = -vb2x; + const F_FLOAT vb2ym = -vb2y; + const F_FLOAT vb2zm = -vb2z; + + // 3rd bond + + const F_FLOAT vb3x = x(i4,0) - x(i3,0); + const F_FLOAT vb3y = x(i4,1) - x(i3,1); + const F_FLOAT vb3z = x(i4,2) - x(i3,2); + + // c0 calculation + + const F_FLOAT sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + const F_FLOAT sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + const F_FLOAT sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + const F_FLOAT rb1 = sqrt(sb1); + const F_FLOAT rb3 = sqrt(sb3); + + const F_FLOAT c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; + + // 1st and 2nd angle + + const F_FLOAT b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; + const F_FLOAT b1mag = sqrt(b1mag2); + const F_FLOAT b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; + const F_FLOAT b2mag = sqrt(b2mag2); + const F_FLOAT b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; + const F_FLOAT b3mag = sqrt(b3mag2); + + F_FLOAT ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z; + const F_FLOAT r12c1 = 1.0 / (b1mag*b2mag); + const F_FLOAT c1mag = ctmp * r12c1; + + ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z; + const F_FLOAT r12c2 = 1.0 / (b2mag*b3mag); + const F_FLOAT c2mag = ctmp * r12c2; + + // cos and sin of 2 angles and final c + + F_FLOAT sin2 = MAX(1.0 - c1mag*c1mag,0.0); + F_FLOAT sc1 = sqrt(sin2); + if (sc1 < SMALL) sc1 = SMALL; + sc1 = 1.0/sc1; + + sin2 = MAX(1.0 - c2mag*c2mag,0.0); + F_FLOAT sc2 = sqrt(sin2); + if (sc2 < SMALL) sc2 = SMALL; + sc2 = 1.0/sc2; + + const F_FLOAT s1 = sc1 * sc1; + const F_FLOAT s2 = sc2 * sc2; + F_FLOAT s12 = sc1 * sc2; + F_FLOAT c = (c0 + c1mag*c2mag) * s12; + + const F_FLOAT cx = vb1y*vb2z - vb1z*vb2y; + const F_FLOAT cy = vb1z*vb2x - vb1x*vb2z; + const F_FLOAT cz = vb1x*vb2y - vb1y*vb2x; + const F_FLOAT cmag = sqrt(cx*cx + cy*cy + cz*cz); + const F_FLOAT dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag; + + // error check + + if ((c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) && !d_warning_flag()) + Kokkos::atomic_fetch_add(&d_warning_flag(),1); + + if (c > 1.0) c = 1.0; + if (c < -1.0) c = -1.0; + + // force & energy + // p = sum (i=1,4) k_i * (1 + (-1)**(i+1)*cos(i*phi) ) + // pd = dp/dc + + F_FLOAT phi = acos(c); + if (dx < 0.0) phi *= -1.0; + F_FLOAT si = sin(phi); + if (fabs(si) < SMALLER) si = SMALLER; + const F_FLOAT siinv = 1.0/si; + + const F_FLOAT p = d_k1[type]*(1.0 + c) + d_k2[type]*(1.0 - cos(2.0*phi)) + + d_k3[type]*(1.0 + cos(3.0*phi)) + d_k4[type]*(1.0 - cos(4.0*phi)) ; + const F_FLOAT pd = d_k1[type] - 2.0*d_k2[type]*sin(2.0*phi)*siinv + + 3.0*d_k3[type]*sin(3.0*phi)*siinv - 4.0*d_k4[type]*sin(4.0*phi)*siinv; + + E_FLOAT edihedral = 0.0; + if (eflag) edihedral = p; + + const F_FLOAT a = pd; + c = c * a; + s12 = s12 * a; + const F_FLOAT a11 = c*sb1*s1; + const F_FLOAT a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2)); + const F_FLOAT a33 = c*sb3*s2; + const F_FLOAT a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12); + const F_FLOAT a13 = -rb1*rb3*s12; + const F_FLOAT a23 = r12c2 * (c2mag*c*s2 + c1mag*s12); + + const F_FLOAT sx2 = a12*vb1x + a22*vb2x + a23*vb3x; + const F_FLOAT sy2 = a12*vb1y + a22*vb2y + a23*vb3y; + const F_FLOAT sz2 = a12*vb1z + a22*vb2z + a23*vb3z; + + F_FLOAT f1[3],f2[3],f3[3],f4[3]; + f1[0] = a11*vb1x + a12*vb2x + a13*vb3x; + f1[1] = a11*vb1y + a12*vb2y + a13*vb3y; + f1[2] = a11*vb1z + a12*vb2z + a13*vb3z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a13*vb1x + a23*vb2x + a33*vb3x; + f4[1] = a13*vb1y + a23*vb2y + a33*vb3y; + f4[2] = a13*vb1z + a23*vb2z + a33*vb3z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // apply force to each of 4 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) += f2[0]; + a_f(i2,1) += f2[1]; + a_f(i2,2) += f2[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 (NEWTON_BOND || i4 < nlocal) { + a_f(i4,0) += f4[0]; + a_f(i4,1) += f4[1]; + a_f(i4,2) += f4[2]; + } + + if (EVFLAG) + ev_tally(ev,i1,i2,i3,i4,edihedral,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z); +} + +template +template +KOKKOS_INLINE_FUNCTION +void DihedralOPLSKokkos::operator()(TagDihedralOPLSCompute, const int &n) const { + EV_FLOAT ev; + this->template operator()(TagDihedralOPLSCompute(), n, ev); +} + +/* ---------------------------------------------------------------------- */ + +template +void DihedralOPLSKokkos::allocate() +{ + DihedralOPLS::allocate(); + + int n = atom->ndihedraltypes; + k_k1 = DAT::tdual_ffloat_1d("DihedralOPLS::k1",n+1); + k_k2 = DAT::tdual_ffloat_1d("DihedralOPLS::k2",n+1); + k_k3 = DAT::tdual_ffloat_1d("DihedralOPLS::k3",n+1); + k_k4 = DAT::tdual_ffloat_1d("DihedralOPLS::k4",n+1); + + d_k1 = k_k1.d_view; + d_k2 = k_k2.d_view; + d_k3 = k_k3.d_view; + d_k4 = k_k4.d_view; +} + +/* ---------------------------------------------------------------------- + set coeffs for one type +------------------------------------------------------------------------- */ + +template +void DihedralOPLSKokkos::coeff(int narg, char **arg) +{ + DihedralOPLS::coeff(narg, arg); + + int n = atom->ndihedraltypes; + for (int i = 1; i <= n; i++) { + k_k1.h_view[i] = k1[i]; + k_k2.h_view[i] = k2[i]; + k_k3.h_view[i] = k3[i]; + k_k4.h_view[i] = k4[i]; + } + + k_k1.template modify(); + k_k2.template modify(); + k_k3.template modify(); + k_k4.template modify(); +} + +/* ---------------------------------------------------------------------- + tally energy and virial into global and per-atom accumulators + virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4 + = (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4 + = vb1*f1 + vb2*f3 + (vb3+vb2)*f4 +------------------------------------------------------------------------- */ + +template +//template +KOKKOS_INLINE_FUNCTION +void DihedralOPLSKokkos::ev_tally(EV_FLOAT &ev, const int i1, const int i2, const int i3, const int i4, + F_FLOAT &edihedral, F_FLOAT *f1, F_FLOAT *f3, F_FLOAT *f4, + const F_FLOAT &vb1x, const F_FLOAT &vb1y, const F_FLOAT &vb1z, + const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, + const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const +{ + E_FLOAT edihedralquarter; + 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 += edihedral; + else { + edihedralquarter = 0.25*edihedral; + if (i1 < nlocal) ev.evdwl += edihedralquarter; + if (i2 < nlocal) ev.evdwl += edihedralquarter; + if (i3 < nlocal) ev.evdwl += edihedralquarter; + if (i4 < nlocal) ev.evdwl += edihedralquarter; + } + } + if (eflag_atom) { + edihedralquarter = 0.25*edihedral; + if (newton_bond || i1 < nlocal) v_eatom[i1] += edihedralquarter; + if (newton_bond || i2 < nlocal) v_eatom[i2] += edihedralquarter; + if (newton_bond || i3 < nlocal) v_eatom[i3] += edihedralquarter; + if (newton_bond || i4 < nlocal) v_eatom[i4] += edihedralquarter; + } + } + + if (vflag_either) { + v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0]; + v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1]; + v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2]; + v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1]; + v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2]; + v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[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 (i1 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + if (i2 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + if (i3 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + if (i4 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + } + } + + if (vflag_atom) { + if (newton_bond || i1 < nlocal) { + v_vatom(i1,0) += 0.25*v[0]; + v_vatom(i1,1) += 0.25*v[1]; + v_vatom(i1,2) += 0.25*v[2]; + v_vatom(i1,3) += 0.25*v[3]; + v_vatom(i1,4) += 0.25*v[4]; + v_vatom(i1,5) += 0.25*v[5]; + } + if (newton_bond || i2 < nlocal) { + v_vatom(i2,0) += 0.25*v[0]; + v_vatom(i2,1) += 0.25*v[1]; + v_vatom(i2,2) += 0.25*v[2]; + v_vatom(i2,3) += 0.25*v[3]; + v_vatom(i2,4) += 0.25*v[4]; + v_vatom(i2,5) += 0.25*v[5]; + } + if (newton_bond || i3 < nlocal) { + v_vatom(i3,0) += 0.25*v[0]; + v_vatom(i3,1) += 0.25*v[1]; + v_vatom(i3,2) += 0.25*v[2]; + v_vatom(i3,3) += 0.25*v[3]; + v_vatom(i3,4) += 0.25*v[4]; + v_vatom(i3,5) += 0.25*v[5]; + } + if (newton_bond || i4 < nlocal) { + v_vatom(i4,0) += 0.25*v[0]; + v_vatom(i4,1) += 0.25*v[1]; + v_vatom(i4,2) += 0.25*v[2]; + v_vatom(i4,3) += 0.25*v[3]; + v_vatom(i4,4) += 0.25*v[4]; + v_vatom(i4,5) += 0.25*v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template class DihedralOPLSKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class DihedralOPLSKokkos; +#endif \ No newline at end of file diff --git a/src/KOKKOS/dihedral_opls_kokkos.h b/src/KOKKOS/dihedral_opls_kokkos.h new file mode 100755 index 0000000000..07432e9ff6 --- /dev/null +++ b/src/KOKKOS/dihedral_opls_kokkos.h @@ -0,0 +1,101 @@ +/* -*- 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 DIHEDRAL_CLASS + +DihedralStyle(charmm/kk,DihedralOPLSKokkos) +DihedralStyle(charmm/kk/device,DihedralOPLSKokkos) +DihedralStyle(charmm/kk/host,DihedralOPLSKokkos) + +#else + +#ifndef LMP_DIHEDRAL_OPLS_KOKKOS_H +#define LMP_DIHEDRAL_OPLS_KOKKOS_H + +#include "dihedral_opls.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +struct TagDihedralOPLSCompute{}; + +template +class DihedralOPLSKokkos : public DihedralOPLS { + public: + typedef DeviceType device_type; + typedef EV_FLOAT value_type; + typedef ArrayTypes AT; + + DihedralOPLSKokkos(class LAMMPS *); + virtual ~DihedralOPLSKokkos(); + virtual void compute(int, int); + virtual void coeff(int, char **); + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagDihedralOPLSCompute, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagDihedralOPLSCompute, const int&) const; + + //template + KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int i1, const int i2, const int i3, const int i4, + F_FLOAT &edihedral, F_FLOAT *f1, F_FLOAT *f3, F_FLOAT *f4, + const F_FLOAT &vb1x, const F_FLOAT &vb1y, const F_FLOAT &vb1z, + const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, + const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + + protected: + class AtomKokkos *atomKK; + class NeighborKokkos *neighborKK; + + typename AT::t_x_array_randomread x; + typename AT::t_f_array f; + typename AT::t_int_2d dihedrallist; + + 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_int_scalar k_warning_flag; + typename AT::t_int_scalar d_warning_flag; + HAT::t_int_scalar h_warning_flag; + + DAT::tdual_ffloat_1d k_k1; + DAT::tdual_ffloat_1d k_k2; + DAT::tdual_ffloat_1d k_k3; + DAT::tdual_ffloat_1d k_k4; + + DAT::t_ffloat_1d d_k1; + DAT::t_ffloat_1d d_k2; + DAT::t_ffloat_1d d_k3; + DAT::t_ffloat_1d d_k4; + + virtual void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/improper_harmonic_kokkos.cpp b/src/KOKKOS/improper_harmonic_kokkos.cpp new file mode 100755 index 0000000000..4f96a65c1d --- /dev/null +++ b/src/KOKKOS/improper_harmonic_kokkos.cpp @@ -0,0 +1,472 @@ +/* ---------------------------------------------------------------------- + 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 "mpi.h" +#include "math.h" +#include "stdlib.h" +#include "improper_harmonic_kokkos.h" +#include "atom_kokkos.h" +#include "comm.h" +#include "neighbor_kokkos.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define TOLERANCE 0.05 +#define SMALL 0.001 + +/* ---------------------------------------------------------------------- */ + +template +ImproperHarmonicKokkos::ImproperHarmonicKokkos(LAMMPS *lmp) : ImproperHarmonic(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("Dihedral:warning_flag"); + d_warning_flag = k_warning_flag.view(); + h_warning_flag = k_warning_flag.h_view; +} + +/* ---------------------------------------------------------------------- */ + +template +ImproperHarmonicKokkos::~ImproperHarmonicKokkos() +{ + if (!copymode) { + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void ImproperHarmonicKokkos::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,"improper:eatom"); + d_eatom = k_eatom.d_view; + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"improper:vatom"); + d_vatom = k_vatom.d_view; + } + + atomKK->sync(execution_space,datamask_read); + k_k.template sync(); + k_chi.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_improperlist.template sync(); + improperlist = neighborKK->k_improperlist.view(); + int nimproperlist = neighborKK->nimproperlist; + nlocal = atom->nlocal; + newton_bond = force->newton_bond; + + h_warning_flag() = 0; + k_warning_flag.template modify(); + k_warning_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,nimproperlist),*this,ev); + } else { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nimproperlist),*this,ev); + } + } else { + if (newton_bond) { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,nimproperlist),*this); + } else { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,nimproperlist),*this); + } + } + DeviceType::fence(); + + // error check + + k_warning_flag.template modify(); + k_warning_flag.template sync(); + if (h_warning_flag()) + error->warning(FLERR,"Dihedral problem",0); + + 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 ImproperHarmonicKokkos::operator()(TagImproperHarmonicCompute, const int &n, EV_FLOAT& ev) const { + + // The f array is atomic + Kokkos::View > a_f = f; + + const int i1 = improperlist(n,0); + const int i2 = improperlist(n,1); + const int i3 = improperlist(n,2); + const int i4 = improperlist(n,3); + const int type = improperlist(n,4); + + // geometry of 4-body + + const F_FLOAT vb1x = x(i1,0) - x(i2,0); + const F_FLOAT vb1y = x(i1,1) - x(i2,1); + const F_FLOAT vb1z = x(i1,2) - x(i2,2); + + const F_FLOAT vb2x = x(i3,0) - x(i2,0); + const F_FLOAT vb2y = x(i3,1) - x(i2,1); + const F_FLOAT vb2z = x(i3,2) - x(i2,2); + + const F_FLOAT vb3x = x(i4,0) - x(i3,0); + const F_FLOAT vb3y = x(i4,1) - x(i3,1); + const F_FLOAT vb3z = x(i4,2) - x(i3,2); + + const F_FLOAT ss1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z); + const F_FLOAT ss2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z); + const F_FLOAT ss3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z); + + const F_FLOAT r1 = sqrt(ss1); + const F_FLOAT r2 = sqrt(ss2); + const F_FLOAT r3 = sqrt(ss3); + + // sin and cos of improper + + const F_FLOAT c0 = (vb1x * vb3x + vb1y * vb3y + vb1z * vb3z) * r1 * r3; + const F_FLOAT c1 = (vb1x * vb2x + vb1y * vb2y + vb1z * vb2z) * r1 * r2; + const F_FLOAT c2 = -(vb3x * vb2x + vb3y * vb2y + vb3z * vb2z) * r3 * r2; + + F_FLOAT s1 = 1.0 - c1*c1; + if (s1 < SMALL) s1 = SMALL; + s1 = 1.0 / s1; + + F_FLOAT s2 = 1.0 - c2*c2; + if (s2 < SMALL) s2 = SMALL; + s2 = 1.0 / s2; + + F_FLOAT s12 = sqrt(s1*s2); + F_FLOAT c = (c1*c2 + c0) * s12; + + // error check + + if ((c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) && !d_warning_flag()) + Kokkos::atomic_fetch_add(&d_warning_flag(),1); + + 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; + + // force & energy + + const F_FLOAT domega = acos(c) - d_chi[type]; + F_FLOAT a = d_k[type] * domega; + + F_FLOAT eimproper = 0.0; + if (eflag) eimproper = a*domega; + + a = -a * 2.0/s; + c = c * a; + s12 = s12 * a; + const F_FLOAT a11 = c*ss1*s1; + const F_FLOAT a22 = -ss2 * (2.0*c0*s12 - c*(s1+s2)); + const F_FLOAT a33 = c*ss3*s2; + const F_FLOAT a12 = -r1*r2*(c1*c*s1 + c2*s12); + const F_FLOAT a13 = -r1*r3*s12; + const F_FLOAT a23 = r2*r3*(c2*c*s2 + c1*s12); + + const F_FLOAT sx2 = a22*vb2x + a23*vb3x + a12*vb1x; + const F_FLOAT sy2 = a22*vb2y + a23*vb3y + a12*vb1y; + const F_FLOAT sz2 = a22*vb2z + a23*vb3z + a12*vb1z; + + F_FLOAT f1[3],f2[3],f3[3],f4[3]; + f1[0] = a12*vb2x + a13*vb3x + a11*vb1x; + f1[1] = a12*vb2y + a13*vb3y + a11*vb1y; + f1[2] = a12*vb2z + a13*vb3z + a11*vb1z; + + f2[0] = -sx2 - f1[0]; + f2[1] = -sy2 - f1[1]; + f2[2] = -sz2 - f1[2]; + + f4[0] = a23*vb2x + a33*vb3x + a13*vb1x; + f4[1] = a23*vb2y + a33*vb3y + a13*vb1y; + f4[2] = a23*vb2z + a33*vb3z + a13*vb1z; + + f3[0] = sx2 - f4[0]; + f3[1] = sy2 - f4[1]; + f3[2] = sz2 - f4[2]; + + // apply force to each of 4 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) += f2[0]; + a_f(i2,1) += f2[1]; + a_f(i2,2) += f2[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 (NEWTON_BOND || i4 < nlocal) { + a_f(i4,0) += f4[0]; + a_f(i4,1) += f4[1]; + a_f(i4,2) += f4[2]; + } + + if (EVFLAG) + ev_tally(ev,i1,i2,i3,i4,eimproper,f1,f3,f4, + vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z); +} + +template +template +KOKKOS_INLINE_FUNCTION +void ImproperHarmonicKokkos::operator()(TagImproperHarmonicCompute, const int &n) const { + EV_FLOAT ev; + this->template operator()(TagImproperHarmonicCompute(), n, ev); +} + +/* ---------------------------------------------------------------------- */ + +template +void ImproperHarmonicKokkos::allocate() +{ + ImproperHarmonic::allocate(); + + int n = atom->nimpropertypes; + k_k = DAT::tdual_ffloat_1d("ImproperHarmonic::k",n+1); + k_chi = DAT::tdual_ffloat_1d("ImproperHarmonic::chi",n+1); + + d_k = k_k.d_view; + d_chi = k_chi.d_view; +} + +/* ---------------------------------------------------------------------- + set coeffs for one type +------------------------------------------------------------------------- */ + +template +void ImproperHarmonicKokkos::coeff(int narg, char **arg) +{ + ImproperHarmonic::coeff(narg, arg); + + int n = atom->nimpropertypes; + for (int i = 1; i <= n; i++) { + k_k.h_view[i] = k[i]; + k_chi.h_view[i] = chi[i]; + } + + k_k.template modify(); + k_chi.template modify(); +} + +/* ---------------------------------------------------------------------- + tally energy and virial into global and per-atom accumulators + virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4 + = (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4 + = vb1*f1 + vb2*f3 + (vb3+vb2)*f4 +------------------------------------------------------------------------- */ + +template +//template +KOKKOS_INLINE_FUNCTION +void ImproperHarmonicKokkos::ev_tally(EV_FLOAT &ev, const int i1, const int i2, const int i3, const int i4, + F_FLOAT &eimproper, F_FLOAT *f1, F_FLOAT *f3, F_FLOAT *f4, + const F_FLOAT &vb1x, const F_FLOAT &vb1y, const F_FLOAT &vb1z, + const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, + const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const +{ + E_FLOAT eimproperquarter; + 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 += eimproper; + else { + eimproperquarter = 0.25*eimproper; + if (i1 < nlocal) ev.evdwl += eimproperquarter; + if (i2 < nlocal) ev.evdwl += eimproperquarter; + if (i3 < nlocal) ev.evdwl += eimproperquarter; + if (i4 < nlocal) ev.evdwl += eimproperquarter; + } + } + if (eflag_atom) { + eimproperquarter = 0.25*eimproper; + if (newton_bond || i1 < nlocal) v_eatom[i1] += eimproperquarter; + if (newton_bond || i2 < nlocal) v_eatom[i2] += eimproperquarter; + if (newton_bond || i3 < nlocal) v_eatom[i3] += eimproperquarter; + if (newton_bond || i4 < nlocal) v_eatom[i4] += eimproperquarter; + } + } + + if (vflag_either) { + v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0]; + v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1]; + v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2]; + v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1]; + v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2]; + v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[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 (i1 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + if (i2 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + if (i3 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + if (i4 < nlocal) { + ev.v[0] += 0.25*v[0]; + ev.v[1] += 0.25*v[1]; + ev.v[2] += 0.25*v[2]; + ev.v[3] += 0.25*v[3]; + ev.v[4] += 0.25*v[4]; + ev.v[5] += 0.25*v[5]; + } + } + } + + if (vflag_atom) { + if (newton_bond || i1 < nlocal) { + v_vatom(i1,0) += 0.25*v[0]; + v_vatom(i1,1) += 0.25*v[1]; + v_vatom(i1,2) += 0.25*v[2]; + v_vatom(i1,3) += 0.25*v[3]; + v_vatom(i1,4) += 0.25*v[4]; + v_vatom(i1,5) += 0.25*v[5]; + } + if (newton_bond || i2 < nlocal) { + v_vatom(i2,0) += 0.25*v[0]; + v_vatom(i2,1) += 0.25*v[1]; + v_vatom(i2,2) += 0.25*v[2]; + v_vatom(i2,3) += 0.25*v[3]; + v_vatom(i2,4) += 0.25*v[4]; + v_vatom(i2,5) += 0.25*v[5]; + } + if (newton_bond || i3 < nlocal) { + v_vatom(i3,0) += 0.25*v[0]; + v_vatom(i3,1) += 0.25*v[1]; + v_vatom(i3,2) += 0.25*v[2]; + v_vatom(i3,3) += 0.25*v[3]; + v_vatom(i3,4) += 0.25*v[4]; + v_vatom(i3,5) += 0.25*v[5]; + } + if (newton_bond || i4 < nlocal) { + v_vatom(i4,0) += 0.25*v[0]; + v_vatom(i4,1) += 0.25*v[1]; + v_vatom(i4,2) += 0.25*v[2]; + v_vatom(i4,3) += 0.25*v[3]; + v_vatom(i4,4) += 0.25*v[4]; + v_vatom(i4,5) += 0.25*v[5]; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template class ImproperHarmonicKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class ImproperHarmonicKokkos; +#endif \ No newline at end of file diff --git a/src/KOKKOS/improper_harmonic_kokkos.h b/src/KOKKOS/improper_harmonic_kokkos.h new file mode 100755 index 0000000000..d48eb7b0aa --- /dev/null +++ b/src/KOKKOS/improper_harmonic_kokkos.h @@ -0,0 +1,97 @@ +/* -*- 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 DIHEDRAL_CLASS + +ImproperStyle(harmonic/kk,ImproperHarmonicKokkos) +ImproperStyle(harmonic/kk/device,ImproperHarmonicKokkos) +ImproperStyle(harmonic/kk/host,ImproperHarmonicKokkos) + +#else + +#ifndef LMP_IMPROPER_HARMONIC_KOKKOS_H +#define LMP_IMPROPER_HARMONIC_KOKKOS_H + +#include "improper_harmonic.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +struct TagImproperHarmonicCompute{}; + +template +class ImproperHarmonicKokkos : public ImproperHarmonic { + public: + typedef DeviceType device_type; + typedef EV_FLOAT value_type; + typedef ArrayTypes AT; + + ImproperHarmonicKokkos(class LAMMPS *); + virtual ~ImproperHarmonicKokkos(); + virtual void compute(int, int); + virtual void coeff(int, char **); + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagImproperHarmonicCompute, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagImproperHarmonicCompute, const int&) const; + + //template + KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int i1, const int i2, const int i3, const int i4, + F_FLOAT &eimproper, F_FLOAT *f1, F_FLOAT *f3, F_FLOAT *f4, + const F_FLOAT &vb1x, const F_FLOAT &vb1y, const F_FLOAT &vb1z, + const F_FLOAT &vb2x, const F_FLOAT &vb2y, const F_FLOAT &vb2z, + const F_FLOAT &vb3x, const F_FLOAT &vb3y, const F_FLOAT &vb3z) const; + + protected: + class AtomKokkos *atomKK; + class NeighborKokkos *neighborKK; + + typename AT::t_x_array_randomread x; + typename AT::t_f_array f; + typename AT::t_int_2d improperlist; + + 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_int_scalar k_warning_flag; + typename AT::t_int_scalar d_warning_flag; + HAT::t_int_scalar h_warning_flag; + + DAT::tdual_ffloat_1d k_k; + DAT::tdual_ffloat_1d k_chi; + + DAT::t_ffloat_1d d_k; + DAT::t_ffloat_1d d_chi; + + virtual void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index 4f4f5f45c3..ebedfbadcc 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -232,7 +232,7 @@ typedef tdual_tagint_1d::t_dev_const_um t_tagint_1d_const_um; typedef tdual_tagint_1d::t_dev_const_randomread t_tagint_1d_randomread; typedef Kokkos:: - DualView + DualView tdual_tagint_2d; typedef tdual_tagint_2d::t_dev t_tagint_2d; typedef tdual_tagint_2d::t_dev_const t_tagint_2d_const; @@ -455,7 +455,7 @@ typedef tdual_tagint_1d::t_host_const_um t_tagint_1d_const_um; typedef tdual_tagint_1d::t_host_const_randomread t_tagint_1d_randomread; typedef Kokkos:: - DualView + DualView tdual_tagint_2d; typedef tdual_tagint_2d::t_host t_tagint_2d; typedef tdual_tagint_2d::t_host_const t_tagint_2d_const; diff --git a/src/KOKKOS/neigh_bond_kokkos.cpp b/src/KOKKOS/neigh_bond_kokkos.cpp new file mode 100755 index 0000000000..e5c8f4de2f --- /dev/null +++ b/src/KOKKOS/neigh_bond_kokkos.cpp @@ -0,0 +1,1284 @@ +/* ---------------------------------------------------------------------- + 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 "neigh_bond_kokkos.h" +#include "atom_kokkos.h" +#include "atom_vec.h" +#include "molecule.h" +#include "force.h" +#include "update.h" +#include "domain_kokkos.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" +#include "modify.h" +#include "fix.h" +#include "string.h" +#include "atom_masks.h" +#include "domain.h" + +using namespace LAMMPS_NS; + +#define BONDDELTA 10000 + +enum{IGNORE,WARN,ERROR}; // same as thermo.cpp + +/* ---------------------------------------------------------------------- */ + +template +NeighBondKokkos::NeighBondKokkos(LAMMPS *lmp) : Pointers(lmp) +{ + MPI_Comm_rank(world,&me); + + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; + + k_nlist = DAT::tdual_int_scalar("NeighBond:nlist"); + d_nlist = k_nlist.view(); + h_nlist = k_nlist.h_view; + + k_fail_flag = DAT::tdual_int_scalar("NeighBond:fail_flag"); + d_fail_flag = k_fail_flag.view(); + h_fail_flag = k_fail_flag.h_view; + + maxbond = 0; + maxangle = 0; + maxdihedral = 0; + maximproper = 0; +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::init_topology_kk() { + + atomKK = (AtomKokkos *) atom; + atomKK->sync(Host,BOND_MASK | ANGLE_MASK | DIHEDRAL_MASK | IMPROPER_MASK); + + // topology lists + + // 1st time allocation of topology lists + + if (atom->molecular && atom->nbonds && maxbond == 0) { + memory->destroy(neighbor->bondlist); + memory->create_kokkos(k_bondlist,neighbor->bondlist,maxbond,3,"neigh:neighbor->bondlist"); + } + + if (atom->molecular && atom->nangles && maxangle == 0) { + memory->destroy(neighbor->anglelist); + memory->create_kokkos(k_anglelist,neighbor->anglelist,maxangle,4,"neigh:neighbor->anglelist"); + } + + if (atom->molecular && atom->ndihedrals && maxdihedral == 0) { + memory->destroy(neighbor->dihedrallist); + memory->create_kokkos(k_dihedrallist,neighbor->dihedrallist,maxdihedral,5,"neigh:neighbor->dihedrallist"); + } + + if (atom->molecular && atom->nimpropers && maximproper == 0) { + memory->destroy(neighbor->improperlist); + memory->create_kokkos(k_improperlist,neighbor->improperlist,maximproper,5,"neigh:neighbor->improperlist"); + } + + // set flags that determine which topology neighboring routines to use + // bonds,etc can only be broken for atom->molecular = 1, not 2 + // SHAKE sets bonds and angles negative + // bond_quartic sets bonds to 0 + // delete_bonds sets all interactions negative + + int i,m; + int bond_off = 0; + int angle_off = 0; + for (i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"shake") == 0) + bond_off = angle_off = 1; + if (force->bond && force->bond_match("quartic")) bond_off = 1; + + if (atom->avec->bonds_allow && atom->molecular == 1) { + for (i = 0; i < atom->nlocal; i++) { + if (bond_off) break; + for (m = 0; m < atom->num_bond[i]; m++) + if (atom->bond_type[i][m] <= 0) bond_off = 1; + } + } + + if (atom->avec->angles_allow && atom->molecular == 1) { + for (i = 0; i < atom->nlocal; i++) { + if (angle_off) break; + for (m = 0; m < atom->num_angle[i]; m++) + if (atom->angle_type[i][m] <= 0) angle_off = 1; + } + } + + int dihedral_off = 0; + if (atom->avec->dihedrals_allow && atom->molecular == 1) { + for (i = 0; i < atom->nlocal; i++) { + if (dihedral_off) break; + for (m = 0; m < atom->num_dihedral[i]; m++) + if (atom->dihedral_type[i][m] <= 0) dihedral_off = 1; + } + } + + int improper_off = 0; + if (atom->avec->impropers_allow && atom->molecular == 1) { + for (i = 0; i < atom->nlocal; i++) { + if (improper_off) break; + for (m = 0; m < atom->num_improper[i]; m++) + if (atom->improper_type[i][m] <= 0) improper_off = 1; + } + } + + // sync on/off settings across all procs + + int on_or_off = bond_off; + MPI_Allreduce(&on_or_off,&bond_off,1,MPI_INT,MPI_MAX,world); + on_or_off = angle_off; + MPI_Allreduce(&on_or_off,&angle_off,1,MPI_INT,MPI_MAX,world); + on_or_off = dihedral_off; + MPI_Allreduce(&on_or_off,&dihedral_off,1,MPI_INT,MPI_MAX,world); + on_or_off = improper_off; + MPI_Allreduce(&on_or_off,&improper_off,1,MPI_INT,MPI_MAX,world); + + // set ptrs to topology build functions + + if (atom->molecular == 2) bond_build_kk = &NeighBondKokkos::bond_template; + else if (bond_off) bond_build_kk = &NeighBondKokkos::bond_partial; + else bond_build_kk = &NeighBondKokkos::bond_all; + + if (atom->molecular == 2) angle_build_kk = &NeighBondKokkos::angle_template; + else if (angle_off) angle_build_kk = &NeighBondKokkos::angle_partial; + else angle_build_kk = &NeighBondKokkos::angle_all; + + if (atom->molecular == 2) dihedral_build_kk = &NeighBondKokkos::dihedral_template; + else if (dihedral_off) dihedral_build_kk = &NeighBondKokkos::dihedral_partial; + else dihedral_build_kk = &NeighBondKokkos::dihedral_all; + + if (atom->molecular == 2) improper_build_kk = &NeighBondKokkos::improper_template; + else if (improper_off) improper_build_kk = &NeighBondKokkos::improper_partial; + else improper_build_kk = &NeighBondKokkos::improper_all; + + // set topology neighbor list counts to 0 + // in case all are turned off but potential is still defined + + neighbor->nbondlist = neighbor->nanglelist = neighbor->ndihedrallist = neighbor->nimproperlist = 0; +} + +/* ---------------------------------------------------------------------- + build all topology neighbor lists every few timesteps + normally built with pair lists, but USER-CUDA separates them +------------------------------------------------------------------------- */ + +template +void NeighBondKokkos::build_topology_kk() +{ + atomKK->sync(execution_space, X_MASK | TAG_MASK); + int nall = atom->nlocal + atom->nghost; + + nlocal = atom->nlocal; + x = atomKK->k_x.view(); + tag = atomKK->k_tag.view(); + newton_bond = force->newton_bond; + + lostbond = output->thermo->lostbond; + + // don't yet have atom_map_kokkos routines, so move data from host to device + + if (atom->map_style != 1) + error->all(FLERR,"Must use map style array with Kokkos for topology"); + + int* map_array_host = atom->get_map_array(); + int map_size = atom->get_map_size(); + k_map_array = DAT::tdual_int_1d("NeighBond:map_array",map_size); + for (int i=0; i(); + k_map_array.template sync(); + map_array = k_map_array.view(); + + int* sametag_host = atomKK->sametag; + k_sametag = DAT::tdual_int_1d("NeighBond:sametag",nall); + for (int i=0; i(); + k_sametag.template sync(); + sametag = k_sametag.view(); + + if (force->bond) (this->*bond_build_kk)(); + if (force->angle) (this->*angle_build_kk)(); + if (force->dihedral) (this->*dihedral_build_kk)(); + if (force->improper) (this->*improper_build_kk)(); +} + +/* ---------------------------------------------------------------------- */ + +// bondlist, anglelist, dihedrallist, improperlist +// no longer store map_array() of the bond partners +// instead store domain->closest_image() of the bond partners of atom I +// this enables distances between list atoms to be calculated +// w/out invoking domain->minimium_image(), e.g. in bond->compute() + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::bond_all() +{ + atomKK->sync(execution_space, BOND_MASK); + v_bondlist = k_bondlist.view(); + num_bond = atomKK->k_num_bond.view(); + bond_atom = atomKK->k_bond_atom.view(); + bond_type = atomKK->k_bond_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->nbondlist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maxbond = neighbor->nbondlist + BONDDELTA; + memory->grow_kokkos(k_bondlist,neighbor->bondlist,maxbond,3,"neighbor:neighbor->bondlist"); + v_bondlist = k_bondlist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Bond atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) bond_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondBondAll, const int &i, int &nmissing) const { + for (int m = 0; m < num_bond[i]; m++) { + int atom1 = map_array(bond_atom(i,m)); + if (atom1 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + if (newton_bond || i < atom1) { + const int nbondlist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (nbondlist >= maxbond && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_bondlist(nbondlist,0) = i; + v_bondlist(nbondlist,1) = atom1; + v_bondlist(nbondlist,2) = bond_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::bond_template() +{ + error->all(FLERR,"Cannot (yet) use molecular templates with Kokkos"); +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::bond_partial() +{ + atomKK->sync(execution_space, BOND_MASK); + v_bondlist = k_bondlist.view(); + num_bond = atomKK->k_num_bond.view(); + bond_atom = atomKK->k_bond_atom.view(); + bond_type = atomKK->k_bond_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->nbondlist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maxbond = neighbor->nbondlist + BONDDELTA; + memory->grow_kokkos(k_bondlist,neighbor->bondlist,maxbond,3,"neighbor:neighbor->bondlist"); + v_bondlist = k_bondlist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Bond atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) bond_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondBondPartial, const int &i, int &nmissing) const { + for (int m = 0; m < num_bond[i]; m++) { + if (bond_type(i,m) <= 0) continue; + int atom1 = map_array(bond_atom(i,m)); + if (atom1 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + if (newton_bond || i < atom1) { + const int nbondlist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (nbondlist >= maxbond && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_bondlist(nbondlist,0) = i; + v_bondlist(nbondlist,1) = atom1; + v_bondlist(nbondlist,2) = bond_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::bond_check() +{ + int flag = 0; + + update_domain_variables(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,neighbor->nbondlist),*this,flag); + DeviceType::fence(); + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) error->all(FLERR,"Bond extent > half of periodic box length"); +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondBondCheck, const int &m, int &flag) const { + const int i = v_bondlist(m,0); + const int j = v_bondlist(m,1); + X_FLOAT dxstart,dystart,dzstart; + X_FLOAT dx,dy,dz; + dxstart = dx = x(i,0) - x(j,0); + dystart = dy = x(i,1) - x(j,1); + dzstart = dz = x(i,2) - x(j,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::angle_all() +{ + atomKK->sync(execution_space, ANGLE_MASK); + v_anglelist = k_anglelist.view(); + num_angle = atomKK->k_num_angle.view(); + angle_atom1 = atomKK->k_angle_atom1.view(); + angle_atom2 = atomKK->k_angle_atom2.view(); + angle_atom3 = atomKK->k_angle_atom3.view(); + angle_type = atomKK->k_angle_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->nanglelist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maxangle = neighbor->nanglelist + BONDDELTA; + memory->grow_kokkos(k_anglelist,neighbor->anglelist,maxangle,4,"neighbor:neighbor->anglelist"); + v_anglelist = k_anglelist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Angle atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) angle_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondAngleAll, const int &i, int &nmissing) const { + for (int m = 0; m < num_angle[i]; m++) { + int atom1 = map_array(angle_atom1(i,m)); + int atom2 = map_array(angle_atom2(i,m)); + int atom3 = map_array(angle_atom3(i,m)); + if (atom1 == -1 || atom2 == -1 || atom3 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + atom2 = closest_image(i,atom2); + atom3 = closest_image(i,atom3); + if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { + const int nanglelist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (nanglelist >= maxangle && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_anglelist(nanglelist,0) = atom1; + v_anglelist(nanglelist,1) = atom2; + v_anglelist(nanglelist,2) = atom3; + v_anglelist(nanglelist,3) = angle_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::angle_template() +{ + error->all(FLERR,"Cannot (yet) use molecular templates with Kokkos"); +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::angle_partial() +{ + atomKK->sync(execution_space, ANGLE_MASK); + v_anglelist = k_anglelist.view(); + num_angle = atomKK->k_num_angle.view(); + angle_atom1 = atomKK->k_angle_atom1.view(); + angle_atom2 = atomKK->k_angle_atom2.view(); + angle_atom3 = atomKK->k_angle_atom3.view(); + angle_type = atomKK->k_angle_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->nanglelist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maxangle = neighbor->nanglelist + BONDDELTA; + memory->grow_kokkos(k_anglelist,neighbor->anglelist,maxangle,4,"neighbor:neighbor->anglelist"); + v_anglelist = k_anglelist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Angle atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) angle_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondAnglePartial, const int &i, int &nmissing) const { + for (int m = 0; m < num_angle[i]; m++) { + if (angle_type(i,m) <= 0) continue; + int atom1 = map_array(angle_atom1(i,m)); + int atom2 = map_array(angle_atom2(i,m)); + int atom3 = map_array(angle_atom3(i,m)); + if (atom1 == -1 || atom2 == -1 || atom3 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + atom2 = closest_image(i,atom2); + atom3 = closest_image(i,atom3); + if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { + const int nanglelist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (nanglelist >= maxangle && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_anglelist(nanglelist,0) = atom1; + v_anglelist(nanglelist,1) = atom2; + v_anglelist(nanglelist,2) = atom3; + v_anglelist(nanglelist,3) = angle_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::angle_check() +{ + int flag = 0; + + // check all 3 distances + // in case angle potential computes any of them + + update_domain_variables(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,neighbor->nanglelist),*this,flag); + DeviceType::fence(); + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) error->all(FLERR,"Angle extent > half of periodic box length"); +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondAngleCheck, const int &m, int &flag) const { + const int i = v_anglelist(m,0); + const int j = v_anglelist(m,1); + const int k = v_anglelist(m,2); + X_FLOAT dxstart,dystart,dzstart; + X_FLOAT dx,dy,dz; + dxstart = dx = x(i,0) - x(j,0); + dystart = dy = x(i,1) - x(j,1); + dzstart = dz = x(i,2) - x(j,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(i,0) - x(k,0); + dystart = dy = x(i,1) - x(k,1); + dzstart = dz = x(i,2) - x(k,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(j,0) - x(k,0); + dystart = dy = x(j,1) - x(k,1); + dzstart = dz = x(j,2) - x(k,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::dihedral_all() +{ + atomKK->sync(execution_space, DIHEDRAL_MASK); + v_dihedrallist = k_dihedrallist.view(); + num_dihedral = atomKK->k_num_dihedral.view(); + dihedral_atom1 = atomKK->k_dihedral_atom1.view(); + dihedral_atom2 = atomKK->k_dihedral_atom2.view(); + dihedral_atom3 = atomKK->k_dihedral_atom3.view(); + dihedral_atom4 = atomKK->k_dihedral_atom4.view(); + dihedral_type = atomKK->k_dihedral_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->ndihedrallist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maxdihedral = neighbor->ndihedrallist + BONDDELTA; + memory->grow_kokkos(k_dihedrallist,neighbor->dihedrallist,maxdihedral,5,"neighbor:neighbor->dihedrallist"); + v_dihedrallist = k_dihedrallist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Dihedral atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) dihedral_check(neighbor->ndihedrallist,v_dihedrallist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondDihedralAll, const int &i, int &nmissing) const { + for (int m = 0; m < num_dihedral[i]; m++) { + int atom1 = map_array(dihedral_atom1(i,m)); + int atom2 = map_array(dihedral_atom2(i,m)); + int atom3 = map_array(dihedral_atom3(i,m)); + int atom4 = map_array(dihedral_atom4(i,m)); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + atom2 = closest_image(i,atom2); + atom3 = closest_image(i,atom3); + atom4 = closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + const int ndihedrallist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (ndihedrallist >= maxdihedral && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_dihedrallist(ndihedrallist,0) = atom1; + v_dihedrallist(ndihedrallist,1) = atom2; + v_dihedrallist(ndihedrallist,2) = atom3; + v_dihedrallist(ndihedrallist,3) = atom4; + v_dihedrallist(ndihedrallist,4) = dihedral_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::dihedral_template() +{ + error->all(FLERR,"Cannot (yet) use molecular templates with Kokkos"); +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::dihedral_partial() +{ + atomKK->sync(execution_space, DIHEDRAL_MASK); + v_dihedrallist = k_dihedrallist.view(); + num_dihedral = atomKK->k_num_dihedral.view(); + dihedral_atom1 = atomKK->k_dihedral_atom1.view(); + dihedral_atom2 = atomKK->k_dihedral_atom2.view(); + dihedral_atom3 = atomKK->k_dihedral_atom3.view(); + dihedral_atom4 = atomKK->k_dihedral_atom4.view(); + dihedral_type = atomKK->k_dihedral_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->ndihedrallist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maxdihedral = neighbor->ndihedrallist + BONDDELTA; + memory->grow_kokkos(k_dihedrallist,neighbor->dihedrallist,maxdihedral,5,"neighbor:neighbor->dihedrallist"); + v_dihedrallist = k_dihedrallist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Dihedral atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) dihedral_check(neighbor->ndihedrallist,v_dihedrallist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondDihedralPartial, const int &i, int &nmissing) const { + for (int m = 0; m < num_dihedral[i]; m++) { + if (dihedral_type(i,m) <= 0) continue; + int atom1 = map_array(dihedral_atom1(i,m)); + int atom2 = map_array(dihedral_atom2(i,m)); + int atom3 = map_array(dihedral_atom3(i,m)); + int atom4 = map_array(dihedral_atom4(i,m)); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + atom2 = closest_image(i,atom2); + atom3 = closest_image(i,atom3); + atom4 = closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + const int ndihedrallist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (ndihedrallist >= maxdihedral && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_dihedrallist(ndihedrallist,0) = atom1; + v_dihedrallist(ndihedrallist,1) = atom2; + v_dihedrallist(ndihedrallist,2) = atom3; + v_dihedrallist(ndihedrallist,3) = atom4; + v_dihedrallist(ndihedrallist,4) = dihedral_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::dihedral_check(int nlist, typename AT::t_int_2d list_in) +{ + list = list_in; + int flag = 0; + + // check all 6 distances + // in case dihedral/improper potential computes any of them + + update_domain_variables(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlist),*this,flag); + DeviceType::fence(); + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) + error->all(FLERR,"Dihedral/improper extent > half of periodic box length"); +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondDihedralCheck, const int &m, int &flag) const { + const int i = list(m,0); + const int j = list(m,1); + const int k = list(m,2); + const int l = list(m,3); + X_FLOAT dxstart,dystart,dzstart; + X_FLOAT dx,dy,dz; + dxstart = dx = x(i,0) - x(j,0); + dystart = dy = x(i,1) - x(j,1); + dzstart = dz = x(i,2) - x(j,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(i,0) - x(k,0); + dystart = dy = x(i,1) - x(k,1); + dzstart = dz = x(i,2) - x(k,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(i,0) - x(l,0); + dystart = dy = x(i,1) - x(l,1); + dzstart = dz = x(i,2) - x(l,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(j,0) - x(k,0); + dystart = dy = x(j,1) - x(k,1); + dzstart = dz = x(j,2) - x(k,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(j,0) - x(l,0); + dystart = dy = x(j,1) - x(l,1); + dzstart = dz = x(j,2) - x(l,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x(k,0) - x(l,0); + dystart = dy = x(k,1) - x(l,1); + dzstart = dz = x(k,2) - x(l,2); + minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; +} + + + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::improper_all() +{ + atomKK->sync(execution_space, IMPROPER_MASK); + v_improperlist = k_improperlist.view(); + num_improper = atomKK->k_num_improper.view(); + improper_atom1 = atomKK->k_improper_atom1.view(); + improper_atom2 = atomKK->k_improper_atom2.view(); + improper_atom3 = atomKK->k_improper_atom3.view(); + improper_atom4 = atomKK->k_improper_atom4.view(); + improper_type = atomKK->k_improper_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->nimproperlist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maximproper = neighbor->nimproperlist + BONDDELTA; + memory->grow_kokkos(k_improperlist,neighbor->improperlist,maximproper,5,"neighbor:neighbor->improperlist"); + v_improperlist = k_improperlist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Improper atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) dihedral_check(neighbor->nimproperlist,v_improperlist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondImproperAll, const int &i, int &nmissing) const { + for (int m = 0; m < num_improper[i]; m++) { + int atom1 = map_array(improper_atom1(i,m)); + int atom2 = map_array(improper_atom2(i,m)); + int atom3 = map_array(improper_atom3(i,m)); + int atom4 = map_array(improper_atom4(i,m)); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + atom2 = closest_image(i,atom2); + atom3 = closest_image(i,atom3); + atom4 = closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + const int nimproperlist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (nimproperlist >= maximproper && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_improperlist(nimproperlist,0) = atom1; + v_improperlist(nimproperlist,1) = atom2; + v_improperlist(nimproperlist,2) = atom3; + v_improperlist(nimproperlist,3) = atom4; + v_improperlist(nimproperlist,4) = improper_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::improper_template() +{ + error->all(FLERR,"Cannot (yet) use molecular templates with Kokkos"); +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::improper_partial() +{ + atomKK->sync(execution_space, IMPROPER_MASK); + v_improperlist = k_improperlist.view(); + num_improper = atomKK->k_num_improper.view(); + improper_atom1 = atomKK->k_improper_atom1.view(); + improper_atom2 = atomKK->k_improper_atom2.view(); + improper_atom3 = atomKK->k_improper_atom3.view(); + improper_atom4 = atomKK->k_improper_atom4.view(); + improper_type = atomKK->k_improper_type.view(); + + // Cannot grow a Kokkos view in a parallel loop, so + // if the capacity of the list is exceeded, count the size + // needed, reallocate on the host, and then + // repeat the parallel loop again + + do { + nmissing = 0; + + h_nlist() = 0; + k_nlist.template modify(); + k_nlist.template sync(); + + h_fail_flag() = 0; + k_fail_flag.template modify(); + k_fail_flag.template sync(); + + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); + DeviceType::fence(); + + k_nlist.template modify(); + k_nlist.template sync(); + neighbor->nimproperlist = h_nlist(); + + k_fail_flag.template modify(); + k_fail_flag.template sync(); + if (h_fail_flag()) { + maximproper = neighbor->nimproperlist + BONDDELTA; + memory->grow_kokkos(k_improperlist,neighbor->improperlist,maximproper,5,"neighbor:neighbor->improperlist"); + v_improperlist = k_improperlist.view(); + } + } while (h_fail_flag()); + + if (nmissing && lostbond == ERROR) { + char str[128]; + sprintf(str,"Improper atoms missing on proc %d at step " BIGINT_FORMAT, + me,update->ntimestep); + error->one(FLERR,str); + } + + if (neighbor->cluster_check) dihedral_check(neighbor->nimproperlist,v_improperlist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::operator()(TagNeighBondImproperPartial, const int &i, int &nmissing) const { + for (int m = 0; m < num_improper[i]; m++) { + if (improper_type(i,m) <= 0) continue; + int atom1 = map_array(improper_atom1(i,m)); + int atom2 = map_array(improper_atom2(i,m)); + int atom3 = map_array(improper_atom3(i,m)); + int atom4 = map_array(improper_atom4(i,m)); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) return; + continue; + } + atom1 = closest_image(i,atom1); + atom2 = closest_image(i,atom2); + atom3 = closest_image(i,atom3); + atom4 = closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + const int nimproperlist = Kokkos::atomic_fetch_add(&d_nlist(),1); + if (nimproperlist >= maximproper && !d_fail_flag()) + Kokkos::atomic_fetch_add(&d_fail_flag(),1); + if (d_fail_flag()) continue; + v_improperlist(nimproperlist,0) = atom1; + v_improperlist(nimproperlist,1) = atom2; + v_improperlist(nimproperlist,2) = atom3; + v_improperlist(nimproperlist,3) = atom4; + v_improperlist(nimproperlist,4) = improper_type(i,m); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int NeighBondKokkos::closest_image(const int i, int j) const +{ + if (j < 0) return j; + + const X_FLOAT xi0 = x(i,0); + const X_FLOAT xi1 = x(i,1); + const X_FLOAT xi2 = x(i,2); + + int closest = j; + X_FLOAT delx = xi0 - x(j,0); + X_FLOAT dely = xi1 - x(j,1); + X_FLOAT delz = xi2 - x(j,2); + X_FLOAT rsqmin = delx*delx + dely*dely + delz*delz; + X_FLOAT rsq; + + while (sametag[j] >= 0) { + j = sametag[j]; + delx = xi0 - x(j,0); + dely = xi1 - x(j,1); + delz = xi2 - x(j,2); + rsq = delx*delx + dely*dely + delz*delz; + if (rsq < rsqmin) { + rsqmin = rsq; + closest = j; + } + } + return closest; +} + +/* ---------------------------------------------------------------------- + minimum image convention + use 1/2 of box size as test + for triclinic, also add/subtract tilt factors in other dims as needed +------------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void NeighBondKokkos::minimum_image(X_FLOAT &dx, X_FLOAT &dy, X_FLOAT &dz) const +{ + if (triclinic == 0) { + if (xperiodic) { + if (fabs(dx) > xprd_half) { + if (dx < 0.0) dx += xprd; + else dx -= xprd; + } + } + if (yperiodic) { + if (fabs(dy) > yprd_half) { + if (dy < 0.0) dy += yprd; + else dy -= yprd; + } + } + if (zperiodic) { + if (fabs(dz) > zprd_half) { + if (dz < 0.0) dz += zprd; + else dz -= zprd; + } + } + + } else { + if (zperiodic) { + if (fabs(dz) > zprd_half) { + if (dz < 0.0) { + dz += zprd; + dy += yz; + dx += xz; + } else { + dz -= zprd; + dy -= yz; + dx -= xz; + } + } + } + if (yperiodic) { + if (fabs(dy) > yprd_half) { + if (dy < 0.0) { + dy += yprd; + dx += xy; + } else { + dy -= yprd; + dx -= xy; + } + } + } + if (xperiodic) { + if (fabs(dx) > xprd_half) { + if (dx < 0.0) dx += xprd; + else dx -= xprd; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NeighBondKokkos::update_domain_variables() +{ + triclinic = domain->triclinic; + xperiodic = domain->xperiodic; + xprd_half = domain->xprd_half; + xprd = domain->xprd; + yperiodic = domain->yperiodic; + yprd_half = domain->yprd_half; + yprd = domain->yprd; + zperiodic = domain->zperiodic; + zprd_half = domain->zprd_half; + zprd = domain->zprd; + xy = domain->xy; + xz = domain->xz; + yz = domain->yz; +} + +/* ---------------------------------------------------------------------- */ + +template class NeighBondKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class NeighBondKokkos; +#endif \ No newline at end of file diff --git a/src/KOKKOS/neigh_bond_kokkos.h b/src/KOKKOS/neigh_bond_kokkos.h new file mode 100755 index 0000000000..e9c42c5075 --- /dev/null +++ b/src/KOKKOS/neigh_bond_kokkos.h @@ -0,0 +1,176 @@ +/* -*- 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. +------------------------------------------------------------------------- */ + +#ifndef LMP_NEIGH_BOND_KOKKOS_H +#define LMP_NEIGH_BOND_KOKKOS_H + +#include "neighbor.h" +#include "kokkos_type.h" +#include "domain_kokkos.h" +#include "pointers.h" + +namespace LAMMPS_NS { + +struct TagNeighBondBondAll{}; +struct TagNeighBondBondPartial{}; +struct TagNeighBondBondCheck{}; +struct TagNeighBondAngleAll{}; +struct TagNeighBondAnglePartial{}; +struct TagNeighBondAngleCheck{}; +struct TagNeighBondDihedralAll{}; +struct TagNeighBondDihedralPartial{}; +struct TagNeighBondDihedralCheck{}; +struct TagNeighBondImproperAll{}; +struct TagNeighBondImproperPartial{}; + +template +class NeighBondKokkos : protected Pointers { + public: + typedef ArrayTypes AT; + typedef int value_type; + + NeighBondKokkos(class LAMMPS *); + ~NeighBondKokkos() {} + void init_topology_kk(); + void build_topology_kk(); + + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondBondAll, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondBondPartial, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondBondCheck, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondAngleAll, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondAnglePartial, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondAngleCheck, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondDihedralAll, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondDihedralPartial, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondDihedralCheck, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondImproperAll, const int&, int&) const; + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighBondImproperPartial, const int&, int&) const; + + DAT::tdual_int_2d k_bondlist; + DAT::tdual_int_2d k_anglelist; + DAT::tdual_int_2d k_dihedrallist; + DAT::tdual_int_2d k_improperlist; + + // KOKKOS host/device flag and data masks + ExecutionSpace execution_space; + unsigned int datamask_read,datamask_modify; + + int maxbond,maxangle,maxdihedral,maximproper; // size of bond lists + int me; + + private: + class AtomKokkos *atomKK; + + DAT::tdual_int_1d k_map_array; + typename AT::t_int_1d_randomread map_array; + + DAT::tdual_int_1d k_sametag; + typename AT::t_int_1d_randomread sametag; + + typename AT::t_int_2d v_bondlist; + typename AT::t_int_2d v_anglelist; + typename AT::t_int_2d v_dihedrallist; + typename AT::t_int_2d v_improperlist; + typename AT::t_int_2d list; + + typename AT::t_x_array_randomread x; + typename AT::t_tagint_1d_randomread tag; + + typename AT::t_int_1d num_bond; + typename AT::t_int_2d bond_type; + typename AT::t_tagint_2d bond_atom; + + typename AT::t_int_1d num_angle; + typename AT::t_int_2d angle_type; + typename AT::t_tagint_2d angle_atom1,angle_atom2,angle_atom3; + + typename AT::t_int_1d num_dihedral; + typename AT::t_int_2d dihedral_type; + typename AT::t_tagint_2d dihedral_atom1,dihedral_atom2, + dihedral_atom3,dihedral_atom4; + + typename AT::t_int_1d num_improper; + typename AT::t_int_2d improper_type; + typename AT::t_tagint_2d improper_atom1,improper_atom2, + improper_atom3,improper_atom4; + + DAT::tdual_int_scalar k_nlist; + typename AT::t_int_scalar d_nlist; + HAT::t_int_scalar h_nlist; + + DAT::tdual_int_scalar k_fail_flag; + typename AT::t_int_scalar d_fail_flag; + HAT::t_int_scalar h_fail_flag; + + KOKKOS_INLINE_FUNCTION + int closest_image(const int, int) const; + + KOKKOS_INLINE_FUNCTION + void minimum_image(X_FLOAT &dx, X_FLOAT &dy, X_FLOAT &dz) const; + + void update_domain_variables(); + + // topology build functions + + typedef void (NeighBondKokkos::*BondPtr)(); // ptrs to topology build functions + + BondPtr bond_build_kk; // ptr to bond list functions + void bond_all(); // bond list with all bonds + void bond_template(); // bond list with templated bonds + void bond_partial(); // exclude certain bonds + void bond_check(); + + BondPtr angle_build_kk; // ptr to angle list functions + void angle_all(); // angle list with all angles + void angle_template(); // angle list with templated bonds + void angle_partial(); // exclude certain angles + void angle_check(); + + BondPtr dihedral_build_kk; // ptr to dihedral list functions + void dihedral_all(); // dihedral list with all dihedrals + void dihedral_template(); // dihedral list with templated bonds + void dihedral_partial(); // exclude certain dihedrals + void dihedral_check(int, typename AT::t_int_2d list); + + BondPtr improper_build_kk; // ptr to improper list functions + void improper_all(); // improper list with all impropers + void improper_template(); // improper list with templated bonds + void improper_partial(); // exclude certain impropers + + int nlocal,newton_bond,lostbond,nmissing; + + int triclinic; + int xperiodic,yperiodic,zperiodic; + X_FLOAT xprd_half,yprd_half,zprd_half; + X_FLOAT xprd,yprd,zprd; + X_FLOAT xy,xz,yz; +}; + +} + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index 133ac7cea0..493a5e546e 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -16,6 +16,10 @@ #include "pair.h" #include "neigh_request.h" #include "memory.h" +#include "update.h" +#include "atom_masks.h" +#include "error.h" +#include "kokkos.h" using namespace LAMMPS_NS; @@ -23,7 +27,8 @@ enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp /* ---------------------------------------------------------------------- */ -NeighborKokkos::NeighborKokkos(LAMMPS *lmp) : Neighbor(lmp) +NeighborKokkos::NeighborKokkos(LAMMPS *lmp) : Neighbor(lmp), + neighbond_device(lmp),neighbond_host(lmp) { atoms_per_bin = 16; @@ -35,32 +40,40 @@ NeighborKokkos::NeighborKokkos(LAMMPS *lmp) : Neighbor(lmp) lists_device = NULL; pair_build_device = NULL; stencil_create_device = NULL; + + device_flag = 0; } /* ---------------------------------------------------------------------- */ NeighborKokkos::~NeighborKokkos() { - memory->destroy_kokkos(k_cutneighsq,cutneighsq); - cutneighsq = NULL; - - for (int i = 0; i < nlist_host; i++) delete lists_host[i]; - delete [] lists_host; - for (int i = 0; i < nlist_device; i++) delete lists_device[i]; - delete [] lists_device; - - delete [] pair_build_device; - delete [] pair_build_host; - - memory->destroy_kokkos(k_ex1_type,ex1_type); - memory->destroy_kokkos(k_ex2_type,ex2_type); - memory->destroy_kokkos(k_ex1_group,ex1_group); - memory->destroy_kokkos(k_ex2_group,ex2_group); - memory->destroy_kokkos(k_ex_mol_group,ex_mol_group); - memory->destroy_kokkos(k_ex1_bit,ex1_bit); - memory->destroy_kokkos(k_ex2_bit,ex2_bit); - memory->destroy_kokkos(k_ex_mol_bit,ex_mol_bit); - + if (!copymode) { + memory->destroy_kokkos(k_cutneighsq,cutneighsq); + cutneighsq = NULL; + + for (int i = 0; i < nlist_host; i++) delete lists_host[i]; + delete [] lists_host; + for (int i = 0; i < nlist_device; i++) delete lists_device[i]; + delete [] lists_device; + + delete [] pair_build_device; + delete [] pair_build_host; + + memory->destroy_kokkos(k_ex1_type,ex1_type); + memory->destroy_kokkos(k_ex2_type,ex2_type); + memory->destroy_kokkos(k_ex1_group,ex1_group); + memory->destroy_kokkos(k_ex2_group,ex2_group); + memory->destroy_kokkos(k_ex_mol_group,ex_mol_group); + memory->destroy_kokkos(k_ex1_bit,ex1_bit); + memory->destroy_kokkos(k_ex2_bit,ex2_bit); + memory->destroy_kokkos(k_ex_mol_bit,ex_mol_bit); + + memory->destroy_kokkos(k_bondlist,bondlist); + memory->destroy_kokkos(k_anglelist,anglelist); + memory->destroy_kokkos(k_dihedrallist,dihedrallist); + memory->destroy_kokkos(k_improperlist,improperlist); + } } /* ---------------------------------------------------------------------- */ @@ -144,6 +157,11 @@ int NeighborKokkos::init_lists_kokkos() } } + // 1st time allocation of xhold + + if (dist_check) + xhold = DAT::tdual_x_array("neigh:xhold",maxhold); + // return # of non-Kokkos lists return nlist; @@ -270,14 +288,204 @@ void NeighborKokkos::choose_build(int index, NeighRequest *rq) Neighbor::choose_build(index,rq); } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + if any atom moved trigger distance (half of neighbor skin) return 1 + shrink trigger distance if box size has changed + conservative shrink procedure: + compute distance each of 8 corners of box has moved since last reneighbor + reduce skin distance by sum of 2 largest of the 8 values + new trigger = 1/2 of reduced skin distance + for orthogonal box, only need 2 lo/hi corners + for triclinic, need all 8 corners since deformations can displace all 8 +------------------------------------------------------------------------- */ -void NeighborKokkos::build_kokkos(int i) +int NeighborKokkos::check_distance() { - if (lists_host[blist[i]]) - (this->*pair_build_host[blist[i]])(lists_host[blist[i]]); - else if (lists_device[blist[i]]) - (this->*pair_build_device[blist[i]])(lists_device[blist[i]]); + if (nlist_device) + check_distance_kokkos(); + else + check_distance_kokkos(); +} + +template +int NeighborKokkos::check_distance_kokkos() +{ + typedef DeviceType device_type; + + double delx,dely,delz,rsq; + double delta,delta1,delta2; + + if (boxcheck) { + if (triclinic == 0) { + delx = bboxlo[0] - boxlo_hold[0]; + dely = bboxlo[1] - boxlo_hold[1]; + delz = bboxlo[2] - boxlo_hold[2]; + delta1 = sqrt(delx*delx + dely*dely + delz*delz); + delx = bboxhi[0] - boxhi_hold[0]; + dely = bboxhi[1] - boxhi_hold[1]; + delz = bboxhi[2] - boxhi_hold[2]; + delta2 = sqrt(delx*delx + dely*dely + delz*delz); + delta = 0.5 * (skin - (delta1+delta2)); + deltasq = delta*delta; + } else { + domain->box_corners(); + delta1 = delta2 = 0.0; + for (int i = 0; i < 8; i++) { + delx = corners[i][0] - corners_hold[i][0]; + dely = corners[i][1] - corners_hold[i][1]; + delz = corners[i][2] - corners_hold[i][2]; + delta = sqrt(delx*delx + dely*dely + delz*delz); + if (delta > delta1) delta1 = delta; + else if (delta > delta2) delta2 = delta; + } + delta = 0.5 * (skin - (delta1+delta2)); + deltasq = delta*delta; + } + } else deltasq = triggersq; + + atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); + x = atomKK->k_x; + xhold.sync(); + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int flag = 0; + copymode = 1; + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,nlocal),*this,flag); + DeviceType::fence(); + copymode = 0; + + int flagall; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world); + if (flagall && ago == MAX(every,delay)) ndanger++; + return flagall; +} + +template +KOKKOS_INLINE_FUNCTION +void NeighborKokkos::operator()(TagNeighborCheckDistance, const int &i, int &flag) const { + typedef DeviceType device_type; + const X_FLOAT delx = x.view()(i,0) - xhold.view()(i,0); + const X_FLOAT dely = x.view()(i,1) - xhold.view()(i,1); + const X_FLOAT delz = x.view()(i,2) - xhold.view()(i,2); + const X_FLOAT rsq = delx*delx + dely*dely + delz*delz; + if (rsq > deltasq) flag = 1; +} + +/* ---------------------------------------------------------------------- + build perpetuals neighbor lists + called at setup and every few timesteps during run or minimization + topology lists also built if topoflag = 1, USER-CUDA calls with topoflag = 0 +------------------------------------------------------------------------- */ + + +void NeighborKokkos::build(int topoflag) +{ + if (nlist_device) + this->template build_kokkos(topoflag); + else + this->template build_kokkos(topoflag); +} + +template +void NeighborKokkos::build_kokkos(int topoflag) +{ + typedef DeviceType device_type; + + int i; + + ago = 0; + ncalls++; + lastcall = update->ntimestep; + + // store current atom positions and box size if needed + + if (dist_check) { + atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); + x = atomKK->k_x; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + if (nlocal > maxhold) { + maxhold = atom->nmax; + xhold = DAT::tdual_x_array("neigh:xhold",maxhold); + } + copymode = 1; + Kokkos::parallel_for(Kokkos::RangePolicy >(0,nlocal),*this); + DeviceType::fence(); + copymode = 0; + xhold.modify(); + if (boxcheck) { + if (triclinic == 0) { + boxlo_hold[0] = bboxlo[0]; + boxlo_hold[1] = bboxlo[1]; + boxlo_hold[2] = bboxlo[2]; + boxhi_hold[0] = bboxhi[0]; + boxhi_hold[1] = bboxhi[1]; + boxhi_hold[2] = bboxhi[2]; + } else { + domain->box_corners(); + corners = domain->corners; + for (i = 0; i < 8; i++) { + corners_hold[i][0] = corners[i][0]; + corners_hold[i][1] = corners[i][1]; + corners_hold[i][2] = corners[i][2]; + } + } + } + } + + // if any lists store neighbors of ghosts: + // invoke grow() if nlocal+nghost exceeds previous list size + // else only invoke grow() if nlocal exceeds previous list size + // only for lists with growflag set and which are perpetual (glist) + + if (anyghostlist && atom->nlocal+atom->nghost > maxatom) { + maxatom = atom->nmax; + for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxatom); + } else if (atom->nlocal > maxatom) { + maxatom = atom->nmax; + for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxatom); + } + + // extend atom bin list if necessary + + if (style != NSQ && atom->nmax > maxbin) { + maxbin = atom->nmax; + memory->destroy(bins); + memory->create(bins,maxbin,"bins"); + } + + // check that using special bond flags will not overflow neigh lists + + if (atom->nlocal+atom->nghost > NEIGHMASK) + error->one(FLERR,"Too many local+ghost atoms for neighbor list"); + + // invoke building of pair and molecular topology neighbor lists + // only for pairwise lists with buildflag set + // blist is for standard neigh lists, otherwise is a Kokkos list + + for (i = 0; i < nblist; i++) { + if (lists[blist[i]]) + (this->*pair_build[blist[i]])(lists[blist[i]]); + else { + if (lists_host[blist[i]]) + (this->*pair_build_host[blist[i]])(lists_host[blist[i]]); + else if (lists_device[blist[i]]) + (this->*pair_build_device[blist[i]])(lists_device[blist[i]]); + } + } + + if (atom->molecular && topoflag) + build_topology_kokkos(); +} + +template +KOKKOS_INLINE_FUNCTION +void NeighborKokkos::operator()(TagNeighborXhold, const int &i) const { + typedef DeviceType device_type; + xhold.view()(i,0) = x.view()(i,0); + xhold.view()(i,1) = x.view()(i,1); + xhold.view()(i,2) = x.view()(i,2); } /* ---------------------------------------------------------------------- */ @@ -323,6 +531,49 @@ void NeighborKokkos::modify_mol_group_grow_kokkos(){ k_ex_mol_group.modify(); } +/* ---------------------------------------------------------------------- */ + +void NeighborKokkos::init_topology_kokkos() { + if (nlist_device) { + neighbond_device.init_topology_kk(); + } else { + neighbond_host.init_topology_kk(); + } +} + +/* ---------------------------------------------------------------------- + build all topology neighbor lists every few timesteps + normally built with pair lists, but USER-CUDA separates them +------------------------------------------------------------------------- */ + +void NeighborKokkos::build_topology_kokkos() { + if (nlist_device) { + neighbond_device.build_topology_kk(); + + k_bondlist = neighbond_device.k_bondlist; + k_anglelist = neighbond_device.k_anglelist; + k_dihedrallist = neighbond_device.k_dihedrallist; + k_improperlist = neighbond_device.k_improperlist; + + k_bondlist.modify(); + k_anglelist.modify(); + k_dihedrallist.modify(); + k_improperlist.modify(); + } else { + neighbond_host.build_topology_kk(); + + k_bondlist = neighbond_host.k_bondlist; + k_anglelist = neighbond_host.k_anglelist; + k_dihedrallist = neighbond_host.k_dihedrallist; + k_improperlist = neighbond_host.k_improperlist; + + k_bondlist.modify(); + k_anglelist.modify(); + k_dihedrallist.modify(); + k_improperlist.modify(); + } +} + // include to trigger instantiation of templated functions #include "neigh_full_kokkos.h" diff --git a/src/KOKKOS/neighbor_kokkos.h b/src/KOKKOS/neighbor_kokkos.h index 03c52dc030..a461c2d0f8 100644 --- a/src/KOKKOS/neighbor_kokkos.h +++ b/src/KOKKOS/neighbor_kokkos.h @@ -16,6 +16,7 @@ #include "neighbor.h" #include "neigh_list_kokkos.h" +#include "neigh_bond_kokkos.h" #include "kokkos_type.h" #include @@ -274,8 +275,16 @@ struct NeighborClusterKokkosBuildFunctor { } }; +template +struct TagNeighborCheckDistance{}; + +template +struct TagNeighborXhold{}; + class NeighborKokkos : public Neighbor { public: + typedef int value_type; + class AtomKokkos *atomKK; int nlist_host; // pairwise neighbor lists on Host @@ -283,10 +292,26 @@ class NeighborKokkos : public Neighbor { int nlist_device; // pairwise neighbor lists on Device NeighListKokkos **lists_device; + NeighBondKokkos neighbond_host; + NeighBondKokkos neighbond_device; + + DAT::tdual_int_2d k_bondlist; + DAT::tdual_int_2d k_anglelist; + DAT::tdual_int_2d k_dihedrallist; + DAT::tdual_int_2d k_improperlist; + NeighborKokkos(class LAMMPS *); ~NeighborKokkos(); void init(); + template + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighborCheckDistance, const int&, int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagNeighborXhold, const int&) const; + private: int atoms_per_bin; DAT::tdual_xfloat_2d k_cutneighsq; @@ -300,6 +325,12 @@ class NeighborKokkos : public Neighbor { DAT::tdual_int_1d k_ex_mol_group; DAT::tdual_int_1d k_ex_mol_bit; + DAT::tdual_x_array x; + DAT::tdual_x_array xhold; + + X_FLOAT deltasq; + int device_flag; + void init_cutneighsq_kokkos(int); int init_lists_kokkos(); void init_list_flags1_kokkos(int); @@ -309,11 +340,16 @@ class NeighborKokkos : public Neighbor { void init_ex_bit_kokkos(); void init_ex_mol_bit_kokkos(); void choose_build(int, NeighRequest *); - void build_kokkos(int); + virtual int check_distance(); + template int check_distance_kokkos(); + virtual void build(int); + template void build_kokkos(int); void setup_bins_kokkos(int); void modify_ex_type_grow_kokkos(); void modify_ex_group_grow_kokkos(); void modify_mol_group_grow_kokkos(); + void init_topology_kokkos(); + void build_topology_kokkos(); typedef void (NeighborKokkos::*PairPtrHost) (class NeighListKokkos *); diff --git a/src/MANYBODY/pair_eam.cpp b/src/MANYBODY/pair_eam.cpp index 2a14a1a37c..60616e4f1f 100644 --- a/src/MANYBODY/pair_eam.cpp +++ b/src/MANYBODY/pair_eam.cpp @@ -69,57 +69,57 @@ PairEAM::PairEAM(LAMMPS *lmp) : Pair(lmp) PairEAM::~PairEAM() { - if (!copymode) { - memory->destroy(rho); - memory->destroy(fp); + if (copymode) return; - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - delete [] map; - delete [] type2frho; - memory->destroy(type2rhor); - memory->destroy(type2z2r); - } + memory->destroy(rho); + memory->destroy(fp); - if (funcfl) { - for (int i = 0; i < nfuncfl; i++) { - delete [] funcfl[i].file; - memory->destroy(funcfl[i].frho); - memory->destroy(funcfl[i].rhor); - memory->destroy(funcfl[i].zr); - } - memory->sfree(funcfl); - } - - if (setfl) { - for (int i = 0; i < setfl->nelements; i++) delete [] setfl->elements[i]; - delete [] setfl->elements; - delete [] setfl->mass; - memory->destroy(setfl->frho); - memory->destroy(setfl->rhor); - memory->destroy(setfl->z2r); - delete setfl; - } - - if (fs) { - for (int i = 0; i < fs->nelements; i++) delete [] fs->elements[i]; - delete [] fs->elements; - delete [] fs->mass; - memory->destroy(fs->frho); - memory->destroy(fs->rhor); - memory->destroy(fs->z2r); - delete fs; - } - - memory->destroy(frho); - memory->destroy(rhor); - memory->destroy(z2r); - - memory->destroy(frho_spline); - memory->destroy(rhor_spline); - memory->destroy(z2r_spline); + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + delete [] map; + delete [] type2frho; + memory->destroy(type2rhor); + memory->destroy(type2z2r); } + + if (funcfl) { + for (int i = 0; i < nfuncfl; i++) { + delete [] funcfl[i].file; + memory->destroy(funcfl[i].frho); + memory->destroy(funcfl[i].rhor); + memory->destroy(funcfl[i].zr); + } + memory->sfree(funcfl); + } + + if (setfl) { + for (int i = 0; i < setfl->nelements; i++) delete [] setfl->elements[i]; + delete [] setfl->elements; + delete [] setfl->mass; + memory->destroy(setfl->frho); + memory->destroy(setfl->rhor); + memory->destroy(setfl->z2r); + delete setfl; + } + + if (fs) { + for (int i = 0; i < fs->nelements; i++) delete [] fs->elements[i]; + delete [] fs->elements; + delete [] fs->mass; + memory->destroy(fs->frho); + memory->destroy(fs->rhor); + memory->destroy(fs->z2r); + delete fs; + } + + memory->destroy(frho); + memory->destroy(rhor); + memory->destroy(z2r); + + memory->destroy(frho_spline); + memory->destroy(rhor_spline); + memory->destroy(z2r_spline); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp index b6d2978ceb..228ea1c601 100644 --- a/src/MOLECULE/angle_charmm.cpp +++ b/src/MOLECULE/angle_charmm.cpp @@ -40,7 +40,7 @@ AngleCharmm::AngleCharmm(LAMMPS *lmp) : Angle(lmp) {} AngleCharmm::~AngleCharmm() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(theta0); diff --git a/src/MOLECULE/angle_charmm.h b/src/MOLECULE/angle_charmm.h index 92a00c6b40..738ec69e11 100644 --- a/src/MOLECULE/angle_charmm.h +++ b/src/MOLECULE/angle_charmm.h @@ -30,7 +30,7 @@ class AngleCharmm : public Angle { AngleCharmm(class LAMMPS *); virtual ~AngleCharmm(); virtual void compute(int, int); - void coeff(int, char **); + virtual void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); @@ -40,7 +40,7 @@ class AngleCharmm : public Angle { protected: double *k,*theta0,*k_ub,*r_ub; - void allocate(); + virtual void allocate(); }; } diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp index 9bb7adbebc..4fdf42ed49 100644 --- a/src/MOLECULE/angle_harmonic.cpp +++ b/src/MOLECULE/angle_harmonic.cpp @@ -36,7 +36,7 @@ AngleHarmonic::AngleHarmonic(LAMMPS *lmp) : Angle(lmp) {} AngleHarmonic::~AngleHarmonic() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(theta0); diff --git a/src/MOLECULE/angle_harmonic.h b/src/MOLECULE/angle_harmonic.h index 9c2f5a157d..0731980f44 100644 --- a/src/MOLECULE/angle_harmonic.h +++ b/src/MOLECULE/angle_harmonic.h @@ -30,7 +30,7 @@ class AngleHarmonic : public Angle { AngleHarmonic(class LAMMPS *); virtual ~AngleHarmonic(); virtual void compute(int, int); - void coeff(int, char **); + virtual void coeff(int, char **); double equilibrium_angle(int); void write_restart(FILE *); void read_restart(FILE *); @@ -40,7 +40,7 @@ class AngleHarmonic : public Angle { protected: double *k,*theta0; - void allocate(); + virtual void allocate(); }; } diff --git a/src/MOLECULE/bond_fene.cpp b/src/MOLECULE/bond_fene.cpp index 1554c77195..e72fbaa40a 100644 --- a/src/MOLECULE/bond_fene.cpp +++ b/src/MOLECULE/bond_fene.cpp @@ -36,7 +36,7 @@ BondFENE::BondFENE(LAMMPS *lmp) : Bond(lmp) BondFENE::~BondFENE() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(r0); diff --git a/src/MOLECULE/bond_fene.h b/src/MOLECULE/bond_fene.h index 3dad4daf43..3ad7fa95fa 100644 --- a/src/MOLECULE/bond_fene.h +++ b/src/MOLECULE/bond_fene.h @@ -30,7 +30,7 @@ class BondFENE : public Bond { BondFENE(class LAMMPS *); virtual ~BondFENE(); virtual void compute(int, int); - void coeff(int, char **); + virtual void coeff(int, char **); void init_style(); double equilibrium_distance(int); void write_restart(FILE *); @@ -42,7 +42,7 @@ class BondFENE : public Bond { double TWO_1_3; double *k,*r0,*epsilon,*sigma; - void allocate(); + virtual void allocate(); }; } diff --git a/src/MOLECULE/bond_harmonic.cpp b/src/MOLECULE/bond_harmonic.cpp index aeb50eb928..573e610238 100644 --- a/src/MOLECULE/bond_harmonic.cpp +++ b/src/MOLECULE/bond_harmonic.cpp @@ -32,7 +32,7 @@ BondHarmonic::BondHarmonic(LAMMPS *lmp) : Bond(lmp) {} BondHarmonic::~BondHarmonic() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(r0); diff --git a/src/MOLECULE/bond_harmonic.h b/src/MOLECULE/bond_harmonic.h index 329d2d307d..4c72352895 100644 --- a/src/MOLECULE/bond_harmonic.h +++ b/src/MOLECULE/bond_harmonic.h @@ -40,7 +40,7 @@ class BondHarmonic : public Bond { protected: double *k,*r0; - void allocate(); + virtual void allocate(); }; } diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp index a72ae07e1d..5e8fef6442 100644 --- a/src/MOLECULE/dihedral_charmm.cpp +++ b/src/MOLECULE/dihedral_charmm.cpp @@ -47,7 +47,7 @@ DihedralCharmm::DihedralCharmm(LAMMPS *lmp) : Dihedral(lmp) DihedralCharmm::~DihedralCharmm() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(multiplicity); diff --git a/src/MOLECULE/dihedral_charmm.h b/src/MOLECULE/dihedral_charmm.h index a35d342145..6ebb4f977a 100644 --- a/src/MOLECULE/dihedral_charmm.h +++ b/src/MOLECULE/dihedral_charmm.h @@ -30,8 +30,8 @@ class DihedralCharmm : public Dihedral { DihedralCharmm(class LAMMPS *); virtual ~DihedralCharmm(); virtual void compute(int, int); - void coeff(int, char **); - void init_style(); + virtual void coeff(int, char **); + virtual void init_style(); void write_restart(FILE *); void read_restart(FILE *); void write_data(FILE *); @@ -42,7 +42,7 @@ class DihedralCharmm : public Dihedral { double **lj14_1,**lj14_2,**lj14_3,**lj14_4; int implicit,weightflag; - void allocate(); + virtual void allocate(); }; } diff --git a/src/MOLECULE/dihedral_opls.cpp b/src/MOLECULE/dihedral_opls.cpp index f73b85f9b4..b85f0d36f7 100644 --- a/src/MOLECULE/dihedral_opls.cpp +++ b/src/MOLECULE/dihedral_opls.cpp @@ -44,7 +44,7 @@ DihedralOPLS::DihedralOPLS(LAMMPS *lmp) : Dihedral(lmp) DihedralOPLS::~DihedralOPLS() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k1); memory->destroy(k2); diff --git a/src/MOLECULE/dihedral_opls.h b/src/MOLECULE/dihedral_opls.h index 238a67cf3c..106dbe2431 100644 --- a/src/MOLECULE/dihedral_opls.h +++ b/src/MOLECULE/dihedral_opls.h @@ -38,7 +38,7 @@ class DihedralOPLS : public Dihedral { protected: double *k1,*k2,*k3,*k4; - void allocate(); + virtual void allocate(); }; } diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp index 4a357834a3..c11601347b 100644 --- a/src/MOLECULE/improper_harmonic.cpp +++ b/src/MOLECULE/improper_harmonic.cpp @@ -42,7 +42,7 @@ ImproperHarmonic::ImproperHarmonic(LAMMPS *lmp) : Improper(lmp) ImproperHarmonic::~ImproperHarmonic() { - if (allocated) { + if (allocated && !copymode) { memory->destroy(setflag); memory->destroy(k); memory->destroy(chi); diff --git a/src/MOLECULE/improper_harmonic.h b/src/MOLECULE/improper_harmonic.h index 16e9418fc4..c4c606b557 100644 --- a/src/MOLECULE/improper_harmonic.h +++ b/src/MOLECULE/improper_harmonic.h @@ -30,7 +30,7 @@ class ImproperHarmonic : public Improper { ImproperHarmonic(class LAMMPS *); virtual ~ImproperHarmonic(); virtual void compute(int, int); - void coeff(int, char **); + virtual void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); void write_data(FILE *); @@ -38,7 +38,7 @@ class ImproperHarmonic : public Improper { protected: double *k,*chi; - void allocate(); + virtual void allocate(); }; } diff --git a/src/Make.py b/src/Make.py index 9297289db9..90869e8214 100755 --- a/src/Make.py +++ b/src/Make.py @@ -1751,8 +1751,8 @@ class MakeReader: varinfo = [] newlines = [] pattern = "(\S+\s+=\s+)(.*)" - multiline = 0 conditional = 0 + multiline = 0 self.ccindex = self.lmpindex = 0 for line in lines: diff --git a/src/angle.cpp b/src/angle.cpp index 99fd5c21a9..3913db685a 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -46,12 +46,16 @@ Angle::Angle(LAMMPS *lmp) : Pointers(lmp) execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; + + copymode = 0; } /* ---------------------------------------------------------------------- */ Angle::~Angle() { + if (copymode) return; + memory->destroy(eatom); memory->destroy(vatom); } diff --git a/src/angle.h b/src/angle.h index 3f05739c8f..535fe2b229 100644 --- a/src/angle.h +++ b/src/angle.h @@ -35,6 +35,7 @@ class Angle : protected Pointers { // KOKKOS host/device flag and data masks ExecutionSpace execution_space; unsigned int datamask_read,datamask_modify; + int copymode; Angle(class LAMMPS *); virtual ~Angle(); diff --git a/src/angle_hybrid.h b/src/angle_hybrid.h index 4cddff2c61..46ec7d5959 100644 --- a/src/angle_hybrid.h +++ b/src/angle_hybrid.h @@ -78,6 +78,14 @@ E: Angle style hybrid cannot have none as an argument Self-explanatory. +E: BondAngle coeff for hybrid angle has invalid format + +UNDOCUMENTED + +E: BondBond coeff for hybrid angle has invalid format + +UNDOCUMENTED + E: Angle coeff for hybrid has invalid style Angle style hybrid uses another angle style as one of its diff --git a/src/atom.h b/src/atom.h index 1ba60b6ca5..2de70119a3 100644 --- a/src/atom.h +++ b/src/atom.h @@ -302,9 +302,9 @@ E: Atom IDs must be used for molecular systems Atom IDs are used to identify and find partner atoms in bonds. -E: Invalid atom style +E: Unknown atom style -The choice of atom style is unknown. +UNDOCUMENTED E: Could not find atom_modify first group ID @@ -467,4 +467,8 @@ E: Too many atom sorting bins This is likely due to an immense simulation box that has blown up to a large size. +U: Invalid atom style + +The choice of atom style is unknown. + */ diff --git a/src/atom_vec.h b/src/atom_vec.h index c1baab248f..ef341d1d0d 100644 --- a/src/atom_vec.h +++ b/src/atom_vec.h @@ -162,4 +162,8 @@ E: USER-CUDA package requires a cuda enabled atom_style Self-explanatory. +E: KOKKOS package requires a kokkos enabled atom_style + +UNDOCUMENTED + */ diff --git a/src/atom_vec_body.h b/src/atom_vec_body.h index 2cea81e80b..a8bca5f12a 100644 --- a/src/atom_vec_body.h +++ b/src/atom_vec_body.h @@ -122,9 +122,9 @@ E: Invalid atom_style body command No body style argument was provided. -E: Invalid body style +E: Unknown body style -The choice of body style is unknown. +UNDOCUMENTED E: Per-processor system is too big @@ -143,4 +143,8 @@ E: Assigning body parameters to non-body atom Self-explanatory. +U: Invalid body style + +The choice of body style is unknown. + */ diff --git a/src/balance.h b/src/balance.h index 2bf0b95620..54a60de948 100644 --- a/src/balance.h +++ b/src/balance.h @@ -105,9 +105,13 @@ E: Cannot balance in z dimension for 2d simulation Self-explanatory. -E: Balance dynamic string is invalid +E: Balance shift string is invalid -The string can only contain the characters "x", "y", or "z". +UNDOCUMENTED + +E: Balance rcb cannot be used with comm_style brick + +UNDOCUMENTED E: Lost atoms via balance: original %ld current %ld @@ -119,4 +123,8 @@ This should not occur. It means two or more cutting plane locations are on top of each other or out of order. Report the problem to the developers. +U: Balance dynamic string is invalid + +The string can only contain the characters "x", "y", or "z". + */ diff --git a/src/bond.cpp b/src/bond.cpp index f4104a7b65..3ce0e26f81 100644 --- a/src/bond.cpp +++ b/src/bond.cpp @@ -47,12 +47,16 @@ Bond::Bond(LAMMPS *lmp) : Pointers(lmp) execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; + + copymode = 0; } /* ---------------------------------------------------------------------- */ Bond::~Bond() { + if (copymode) return; + memory->destroy(eatom); memory->destroy(vatom); } diff --git a/src/bond.h b/src/bond.h index a802142f4b..a38fc97f13 100644 --- a/src/bond.h +++ b/src/bond.h @@ -35,6 +35,7 @@ class Bond : protected Pointers { // KOKKOS host/device flag and data masks ExecutionSpace execution_space; unsigned int datamask_read,datamask_modify; + int copymode; Bond(class LAMMPS *); virtual ~Bond(); diff --git a/src/comm.h b/src/comm.h index 0e6dfa2fbf..87a9a5f9f3 100644 --- a/src/comm.h +++ b/src/comm.h @@ -142,4 +142,60 @@ class Comm : protected Pointers { /* ERROR/WARNING messages: +W: OMP_NUM_THREADS environment is not set. + +UNDOCUMENTED + +E: Illegal ... command + +UNDOCUMENTED + +E: Invalid group in comm_modify command + +UNDOCUMENTED + +E: Comm_modify group != atom_modify first group + +UNDOCUMENTED + +E: Invalid cutoff in comm_modify command + +UNDOCUMENTED + +E: Specified processors != physical processors + +UNDOCUMENTED + +E: Cannot use processors part command without using partitions + +UNDOCUMENTED + +E: Invalid partitions in processors part command + +UNDOCUMENTED + +E: Sending partition in processors part command is already a sender + +UNDOCUMENTED + +E: Receiving partition in processors part command is already a receiver + +UNDOCUMENTED + +E: Processors grid numa and map style are incompatible + +UNDOCUMENTED + +E: Processors part option and grid style are incompatible + +UNDOCUMENTED + +E: Bad grid of processors + +UNDOCUMENTED + +E: Processor count in z must be 1 for 2d simulation + +UNDOCUMENTED + */ diff --git a/src/comm_brick.h b/src/comm_brick.h index ae84d6c2a8..f39746bc41 100644 --- a/src/comm_brick.h +++ b/src/comm_brick.h @@ -92,66 +92,70 @@ class CommBrick : public Comm { /* ERROR/WARNING messages: -W: OMP_NUM_THREADS environment is not set. +E: Cannot change to comm_style brick from tiled layout + +UNDOCUMENTED + +U: OMP_NUM_THREADS environment is not set. This environment variable must be set appropriately to use the USER-OMP pacakge. -E: Bad grid of processors +U: Bad grid of processors The 3d grid of processors defined by the processors command does not match the number of processors LAMMPS is being run on. -E: Processor count in z must be 1 for 2d simulation +U: Processor count in z must be 1 for 2d simulation Self-explanatory. -E: Illegal ... command +U: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Invalid group in communicate command +U: Invalid group in communicate command Self-explanatory. -E: Communicate group != atom_modify first group +U: Communicate group != atom_modify first group Self-explanatory. -E: Invalid cutoff in communicate command +U: Invalid cutoff in communicate command Specified cutoff must be >= 0.0. -E: Specified processors != physical processors +U: Specified processors != physical processors The 3d grid of processors defined by the processors command does not match the number of processors LAMMPS is being run on. -E: Cannot use processors part command without using partitions +U: Cannot use processors part command without using partitions See the command-line -partition switch. -E: Invalid partitions in processors part command +U: Invalid partitions in processors part command Valid partitions are numbered 1 to N and the sender and receiver cannot be the same partition. -E: Sending partition in processors part command is already a sender +U: Sending partition in processors part command is already a sender Cannot specify a partition to be a sender twice. -E: Receiving partition in processors part command is already a receiver +U: Receiving partition in processors part command is already a receiver Cannot specify a partition to be a receiver twice. -E: Processors grid numa and map style are incompatible +U: Processors grid numa and map style are incompatible Using numa for gstyle in the processors command requires using cart for the map option. -E: Processors part option and grid style are incompatible +U: Processors part option and grid style are incompatible Cannot use gstyle numa or custom with the part option. diff --git a/src/comm_tiled.h b/src/comm_tiled.h index 91b501279e..e5aa3453bc 100644 --- a/src/comm_tiled.h +++ b/src/comm_tiled.h @@ -152,4 +152,32 @@ class CommTiled : public Comm { /* ERROR/WARNING messages: +E: USER-CUDA package does not yet support comm_style tiled + +UNDOCUMENTED + +E: KOKKOS package does not yet support comm_style tiled + +UNDOCUMENTED + +E: Cannot yet use comm_style tiled with triclinic box + +UNDOCUMENTED + +E: Cannot yet use comm_style tiled with multi-mode comm + +UNDOCUMENTED + +E: Communication cutoff for comm_style tiled cannot exceed periodic box length + +UNDOCUMENTED + +E: Comm tiled mis-match in box drop brick + +UNDOCUMENTED + +E: Comm tiled invalid index in box drop brick + +UNDOCUMENTED + */ diff --git a/src/compute.h b/src/compute.h index cd2567399f..6f536a0bf5 100644 --- a/src/compute.h +++ b/src/compute.h @@ -191,17 +191,17 @@ E: Compute does not allow an extra compute or fix to be reset This is an internal LAMMPS error. Please report it to the developers. -W: Atom with molecule ID = 0 included in compute molecule group +U: Atom with molecule ID = 0 included in compute molecule group The group used in a compute command that operates on moleclues includes atoms with no molecule ID. This is probably not what you want. -E: Too many molecules for compute +U: Too many molecules for compute The limit is 2^31 = ~2 billion molecules. -W: One or more compute molecules has atoms not in group +U: One or more compute molecules has atoms not in group The group used in a compute command that operates on moleclues does not include all the atoms in some molecules. This is probably not diff --git a/src/compute_chunk_atom.cpp b/src/compute_chunk_atom.cpp index d83643b047..9a4c0c5c9e 100644 --- a/src/compute_chunk_atom.cpp +++ b/src/compute_chunk_atom.cpp @@ -548,7 +548,7 @@ void ComputeChunkAtom::compute_peratom() set lock, so that nchunk will not change from startstep to stopstep called by fix ave/chunk for duration of its Nfreq epoch OK if called by multiple fix ave/chunk commands - error if all callers do not have same duration + but error if all callers do not have same duration last caller holds the lock, so it can also unlock lockstop can be positive for final step of finite-size time window or can be -1 for infinite-size time window diff --git a/src/compute_chunk_atom.h b/src/compute_chunk_atom.h index aa42a1f0c4..0f8aea18cc 100644 --- a/src/compute_chunk_atom.h +++ b/src/compute_chunk_atom.h @@ -118,7 +118,99 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -W: More than one compute ke/atom +E: Region ID for compute chunk/atom does not exist + +UNDOCUMENTED + +E: Compute chunk/atom molecule for non-molecular system + +UNDOCUMENTED + +E: Compute chunk/atom without bins cannot use discard mixed + +UNDOCUMENTED + +E: Compute ID for compute chunk/atom does not exist + +UNDOCUMENTED + +E: Compute chunk/atom compute does not calculate per-atom values + +UNDOCUMENTED + +E: Compute chunk/atom compute does not calculate a per-atom vector + +UNDOCUMENTED + +E: Compute chunk/atom compute does not calculate a per-atom array + +UNDOCUMENTED + +E: Compute chunk/atom compute array is accessed out-of-range + +UNDOCUMENTED + +E: Fix ID for compute chunk/atom does not exist + +UNDOCUMENTED + +E: Compute chunk/atom fix does not calculate per-atom values + +UNDOCUMENTED + +E: Compute chunk/atom fix does not calculate a per-atom vector + +UNDOCUMENTED + +E: Compute chunk/atom fix does not calculate a per-atom array + +UNDOCUMENTED + +E: Compute chunk/atom fix array is accessed out-of-range + +UNDOCUMENTED + +E: Variable name for compute chunk/atom does not exist + +UNDOCUMENTED + +E: Compute chunk/atom variable is not atom-style variable + +UNDOCUMENTED + +E: Compute chunk/atom for triclinic boxes requires units reduced + +UNDOCUMENTED + +E: Molecule IDs too large for compute chunk/atom + +UNDOCUMENTED + +E: Compute chunk/atom ids once but nchunk is not once + +UNDOCUMENTED + +E: Two fix ave/chunk commands using same compute chunk/atom command in incompatible ways + +UNDOCUMENTED + +E: Fix used in compute chunk/atom not computed at compatible time + +UNDOCUMENTED + +W: One or more chunks do not contain all atoms in molecule + +UNDOCUMENTED + +E: Invalid bin bounds in fix ave/spatial + +UNDOCUMENTED + +E: Cannot use compute chunk/atom bin z for 2d model + +UNDOCUMENTED + +U: More than one compute ke/atom It is not efficient to use compute ke/atom more than once. diff --git a/src/compute_com_chunk.h b/src/compute_com_chunk.h index 543a565900..eeb62208b3 100644 --- a/src/compute_com_chunk.h +++ b/src/compute_com_chunk.h @@ -65,11 +65,19 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute com/molecule requires molecular atom style +E: Chunk/atom compute does not exist for compute com/chunk + +UNDOCUMENTED + +E: Compute com/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute com/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute com/molecule +U: Molecule count changed in compute com/molecule Number of molecules must remain constant over time. diff --git a/src/compute_gyration_chunk.h b/src/compute_gyration_chunk.h index 85ed59e14f..9d3a24faf8 100644 --- a/src/compute_gyration_chunk.h +++ b/src/compute_gyration_chunk.h @@ -69,11 +69,19 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute gyration/molecule requires molecular atom style +E: Chunk/atom compute does not exist for compute gyration/chunk + +UNDOCUMENTED + +E: Compute gyration/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute gyration/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute gyration/molecule +U: Molecule count changed in compute gyration/molecule Number of molecules must remain constant over time. diff --git a/src/compute_inertia_chunk.h b/src/compute_inertia_chunk.h index a42b18149e..a7f802b266 100644 --- a/src/compute_inertia_chunk.h +++ b/src/compute_inertia_chunk.h @@ -64,11 +64,19 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute inertia/molecule requires molecular atom style +E: Chunk/atom compute does not exist for compute inertia/chunk + +UNDOCUMENTED + +E: Compute inertia/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute inertia/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute inertia/molecule +U: Molecule count changed in compute inertia/molecule Number of molecules must remain constant over time. diff --git a/src/compute_msd_chunk.h b/src/compute_msd_chunk.h index 269fb153ba..97e2a2578b 100644 --- a/src/compute_msd_chunk.h +++ b/src/compute_msd_chunk.h @@ -67,11 +67,23 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute com/molecule requires molecular atom style +E: Chunk/atom compute does not exist for compute msd/chunk + +UNDOCUMENTED + +E: Compute msd/chunk does not use chunk/atom compute + +UNDOCUMENTED + +E: Compute msd/chunk nchunk is not static + +UNDOCUMENTED + +U: Compute com/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute com/molecule +U: Molecule count changed in compute com/molecule Number of molecules must remain constant over time. diff --git a/src/compute_pressure.h b/src/compute_pressure.h index e2f25ae75d..7b0b99ef45 100644 --- a/src/compute_pressure.h +++ b/src/compute_pressure.h @@ -74,10 +74,9 @@ E: Compute pressure temperature ID does not compute temperature The compute ID assigned to a pressure computation must compute temperature. -E: Must use 'kspace_modify pressure/scalar no' to get individual -components of pressure tensor with kspace_style MSM +E: Compute pressure requires temperature ID to include kinetic energy -Self-explanatory. +UNDOCUMENTED E: Virial was not tallied on needed timestep @@ -85,4 +84,13 @@ You are using a thermo keyword that requires potentials to have tallied the virial, but they didn't on this timestep. See the variable doc page for ideas on how to make this work. +E: Kspace_modify pressure/scalar no required for components of pressure tensor with kspace_style msm + +UNDOCUMENTED + +U: Must use 'kspace_modify pressure/scalar no' to get individual +components of pressure tensor with kspace_style MSM + +Self-explanatory. + */ diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h index e9e957918b..67fe83eeab 100644 --- a/src/compute_property_atom.h +++ b/src/compute_property_atom.h @@ -143,12 +143,12 @@ E: Compute property/atom for atom property that isn't allocated Self-explanatory. -E: Compute property/atom floating point vector does not exist +E: Compute property/atom integer vector does not exist The command is accessing a vector added by the fix property/atom command, that does not exist. -E: Compute property/atom integer vector does not exist +E: Compute property/atom floating point vector does not exist The command is accessing a vector added by the fix property/atom command, that does not exist. diff --git a/src/compute_property_chunk.h b/src/compute_property_chunk.h index 21e9078d5d..5cb52b2af1 100644 --- a/src/compute_property_chunk.h +++ b/src/compute_property_chunk.h @@ -75,15 +75,43 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute property/molecule requires molecular atom style +E: Compute chunk/atom stores no IDs for compute property/chunk + +UNDOCUMENTED + +E: Compute chunk/atom stores no coord1 for compute property/chunk + +UNDOCUMENTED + +E: Compute chunk/atom stores no coord2 for compute property/chunk + +UNDOCUMENTED + +E: Compute chunk/atom stores no coord3 for compute property/chunk + +UNDOCUMENTED + +E: Invalid keyword in compute property/chunk command + +UNDOCUMENTED + +E: Chunk/atom compute does not exist for compute property/chunk + +UNDOCUMENTED + +E: Compute property/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute property/molecule requires molecular atom style Self-explanatory. -E: Invalid keyword in compute property/molecule command +U: Invalid keyword in compute property/molecule command Self-explanatory. -E: Molecule count changed in compute property/molecule +U: Molecule count changed in compute property/molecule Number of molecules must remain constant over time. diff --git a/src/compute_reduce.h b/src/compute_reduce.h index 9701f0e61e..fa7cb911df 100644 --- a/src/compute_reduce.h +++ b/src/compute_reduce.h @@ -74,6 +74,10 @@ E: Region ID for compute reduce/region does not exist Self-explanatory. +E: Unkown derived compute reduce style + +UNDOCUMENTED + E: Compute reduce replace requires min or max mode Self-explanatory. diff --git a/src/compute_stress_atom.h b/src/compute_stress_atom.h index 07fde385e5..ffb1d87095 100644 --- a/src/compute_stress_atom.h +++ b/src/compute_stress_atom.h @@ -57,6 +57,14 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. +E: Could not find compute stress/atom temperature ID + +UNDOCUMENTED + +E: Compute stress/atom temperature ID does not compute temperature + +UNDOCUMENTED + E: Per-atom virial was not tallied on needed timestep You are using a thermo keyword that requires potentials to have diff --git a/src/compute_temp_chunk.h b/src/compute_temp_chunk.h index 2f2fba24c7..67ce89a951 100644 --- a/src/compute_temp_chunk.h +++ b/src/compute_temp_chunk.h @@ -82,11 +82,35 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute com/molecule requires molecular atom style +E: Could not find compute ID for temperature bias + +UNDOCUMENTED + +E: Bias compute does not calculate temperature + +UNDOCUMENTED + +E: Bias compute does not calculate a velocity bias + +UNDOCUMENTED + +E: Cannot use both com and bias with compute temp/chunk + +UNDOCUMENTED + +E: Chunk/atom compute does not exist for compute temp/chunk + +UNDOCUMENTED + +E: Compute temp/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute com/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute com/molecule +U: Molecule count changed in compute com/molecule Number of molecules must remain constant over time. diff --git a/src/compute_torque_chunk.h b/src/compute_torque_chunk.h index 2a684939f1..b52bb00501 100644 --- a/src/compute_torque_chunk.h +++ b/src/compute_torque_chunk.h @@ -64,11 +64,19 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute inertia/molecule requires molecular atom style +E: Chunk/atom compute does not exist for compute torque/chunk + +UNDOCUMENTED + +E: Compute torque/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute inertia/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute inertia/molecule +U: Molecule count changed in compute inertia/molecule Number of molecules must remain constant over time. diff --git a/src/compute_vcm_chunk.h b/src/compute_vcm_chunk.h index dd49ab8dcf..d3cceafe73 100644 --- a/src/compute_vcm_chunk.h +++ b/src/compute_vcm_chunk.h @@ -65,11 +65,19 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Compute vcm/molecule requires molecular atom style +E: Chunk/atom compute does not exist for compute vcm/chunk + +UNDOCUMENTED + +E: Compute vcm/chunk does not use chunk/atom compute + +UNDOCUMENTED + +U: Compute vcm/molecule requires molecular atom style Self-explanatory. -E: Molecule count changed in compute vcm/molecule +U: Molecule count changed in compute vcm/molecule Number of molecules must remain constant over time. diff --git a/src/create_atoms.h b/src/create_atoms.h index 1117c170e1..3a501549ac 100644 --- a/src/create_atoms.h +++ b/src/create_atoms.h @@ -95,6 +95,14 @@ W: Molecule template for create_atoms has multiple molecules The create_atoms command will only create molecules of a single type, i.e. the first molecule in the template. +E: Cannot use create_atoms rotate unless single style + +UNDOCUMENTED + +E: Invalid create_atoms rotation vector for 2d model + +UNDOCUMENTED + E: Invalid atom type in create_atoms command The create_box command specified the range of valid atom types. @@ -119,6 +127,18 @@ E: Create_atoms molecule has atom IDs, but system does not The atom_style id command can be used to force atom IDs to be stored. +E: Incomplete use of variables in create_atoms command + +UNDOCUMENTED + +E: Variable name for create_atoms does not exist + +UNDOCUMENTED + +E: Variable for create_atoms is invalid style + +UNDOCUMENTED + E: Cannot create atoms with undefined lattice Must use the lattice command before using the create_atoms diff --git a/src/create_bonds.h b/src/create_bonds.h index ea9295f3c1..69842e3383 100644 --- a/src/create_bonds.h +++ b/src/create_bonds.h @@ -42,10 +42,17 @@ class CreateBonds : protected Pointers { /* ERROR/WARNING messages: -E: Delete_atoms command before simulation box is defined +E: Create_bonds command before simulation box is defined -The delete_atoms command cannot be used before a read_data, -read_restart, or create_box command. +UNDOCUMENTED + +E: Cannot use create_bonds unless atoms have IDs + +UNDOCUMENTED + +E: Cannot use create_bonds with non-molecular system + +UNDOCUMENTED E: Illegal ... command @@ -53,25 +60,62 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Cannot use delete_atoms unless atoms have IDs +E: Cannot find create_bonds group ID + +UNDOCUMENTED + +E: Invalid bond type in create_bonds command + +UNDOCUMENTED + +E: Create_bonds requires a pair style be defined + +UNDOCUMENTED + +E: Create_bonds max distance > neighbor cutoff + +UNDOCUMENTED + +W: Create_bonds max distance > minimum neighbor cutoff + +UNDOCUMENTED + +E: Create_bonds command requires special_bonds 1-2 weights be 0.0 + +UNDOCUMENTED + +E: Create_bonds command requires no kspace_style be defined + +UNDOCUMENTED + +E: New bond exceeded bonds per atom in create_bonds + +UNDOCUMENTED + +U: Delete_atoms command before simulation box is defined + +The delete_atoms command cannot be used before a read_data, +read_restart, or create_box command. + +U: Cannot use delete_atoms unless atoms have IDs Your atoms do not have IDs, so the delete_atoms command cannot be used. -E: Could not find delete_atoms group ID +U: Could not find delete_atoms group ID Group ID used in the delete_atoms command does not exist. -E: Could not find delete_atoms region ID +U: Could not find delete_atoms region ID Region ID used in the delete_atoms command does not exist. -E: Delete_atoms requires a pair style be defined +U: Delete_atoms requires a pair style be defined This is because atom deletion within a cutoff uses a pairwise neighbor list. -E: Delete_atoms cutoff > neighbor cutoff +U: Delete_atoms cutoff > neighbor cutoff Cannot delete atoms further away than a processor knows about. diff --git a/src/delete_atoms.h b/src/delete_atoms.h index de2f9e19e4..a051080106 100644 --- a/src/delete_atoms.h +++ b/src/delete_atoms.h @@ -93,7 +93,27 @@ E: Delete_atoms requires a pair style be defined This is because atom deletion within a cutoff uses a pairwise neighbor list. -E: Delete_atoms cutoff > neighbor cutoff +E: Delete_atoms cutoff > max neighbor cutoff + +UNDOCUMENTED + +W: Delete_atoms cutoff > minimum neighbor cutoff + +UNDOCUMENTED + +E: Cannot delete_atoms bond yes for non-molecular systems + +UNDOCUMENTED + +E: Cannot use delete_atoms bond yes with atom_style template + +UNDOCUMENTED + +E: Cannot delete_atoms mol yes for non-molecular systems + +UNDOCUMENTED + +U: Delete_atoms cutoff > neighbor cutoff Cannot delete atoms further away than a processor knows about. diff --git a/src/dihedral.cpp b/src/dihedral.cpp index d6e24c6ef3..8cd66bee1f 100644 --- a/src/dihedral.cpp +++ b/src/dihedral.cpp @@ -47,12 +47,16 @@ Dihedral::Dihedral(LAMMPS *lmp) : Pointers(lmp) execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; + + copymode = 0; } /* ---------------------------------------------------------------------- */ Dihedral::~Dihedral() { + if (copymode) return; + memory->destroy(eatom); memory->destroy(vatom); } diff --git a/src/dihedral.h b/src/dihedral.h index 5d8c250605..e16c26a629 100644 --- a/src/dihedral.h +++ b/src/dihedral.h @@ -35,6 +35,7 @@ class Dihedral : protected Pointers { // KOKKOS host/device flag and data masks ExecutionSpace execution_space; unsigned int datamask_read,datamask_modify; + int copymode; Dihedral(class LAMMPS *); virtual ~Dihedral(); diff --git a/src/domain.h b/src/domain.h index c5f74f6b28..f74ccf49a6 100644 --- a/src/domain.h +++ b/src/domain.h @@ -230,6 +230,10 @@ bond/angle/dihedral. LAMMPS computes this by taking the maximum bond length, multiplying by the number of bonds in the interaction (e.g. 3 for a dihedral) and adding a small amount of stretch. +W: Proc sub-domain size < neighbor skin, could lead to lost atoms + +UNDOCUMENTED + E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the @@ -240,9 +244,9 @@ E: Reuse of region ID A region ID cannot be used twice. -E: Invalid region style +E: Unknown region style -The choice of region style is unknown. +UNDOCUMENTED E: Delete region ID does not exist @@ -253,4 +257,8 @@ E: Both sides of boundary must be periodic Cannot specify a boundary as periodic only on the lo or hi side. Must be periodic on both sides. +U: Invalid region style + +The choice of region style is unknown. + */ diff --git a/src/dump_custom.h b/src/dump_custom.h index ea3c5ecff8..36d306afbd 100644 --- a/src/dump_custom.h +++ b/src/dump_custom.h @@ -216,10 +216,18 @@ E: Could not find dump custom variable name Self-explanatory. +E: Could not find custom per-atom property ID + +UNDOCUMENTED + E: Region ID for dump custom does not exist Self-explanatory. +E: Compute used in dump between runs is not current + +UNDOCUMENTED + E: Threshhold for an atom property that isn't allocated A dump threshhold has been requested on a quantity that is @@ -230,11 +238,6 @@ E: Dumping an atom property that isn't allocated The chosen atom style does not define the per-atom quantity being dumped. -E: Dumping an atom quantity that isn't allocated - -Only per-atom quantities that are defined for the atom style being -used are allowed. - E: Dump custom compute does not compute per-atom info Self-explanatory. @@ -272,6 +275,14 @@ E: Dump custom variable is not atom-style variable Only atom-style variables generate per-atom quantities, needed for dump output. +E: Custom per-atom property ID is not floating point + +UNDOCUMENTED + +E: Custom per-atom property ID is not integer + +UNDOCUMENTED + E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the @@ -338,8 +349,21 @@ E: Dump modify variable is not atom-style variable Self-explanatory. +E: Could not find dump modify custom atom floating point property ID + +UNDOCUMENTED + +E: Could not find dump modify custom atom integer property ID + +UNDOCUMENTED + E: Invalid dump_modify threshhold operator Operator keyword used for threshold specification in not recognized. +U: Dumping an atom quantity that isn't allocated + +Only per-atom quantities that are defined for the atom style being +used are allowed. + */ diff --git a/src/dump_local.h b/src/dump_local.h index 862ddf21a5..f4a080dc53 100644 --- a/src/dump_local.h +++ b/src/dump_local.h @@ -114,6 +114,10 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. +E: Compute used in dump between runs is not current + +UNDOCUMENTED + E: Dump local count is not consistent across input fields Every column of output must be the same length. diff --git a/src/fix.cpp b/src/fix.cpp index 60e11de5aa..e670b380cd 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -99,11 +99,11 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) Fix::~Fix() { - if (!copymode) { - delete [] id; - delete [] style; - memory->destroy(vatom); - } + if (copymode) return; + + delete [] id; + delete [] style; + memory->destroy(vatom); } /* ---------------------------------------------------------------------- diff --git a/src/fix_adapt.h b/src/fix_adapt.h index 4cce642d30..24fb1c1445 100644 --- a/src/fix_adapt.h +++ b/src/fix_adapt.h @@ -79,6 +79,10 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. +E: Cannot use dynamic group with fix adapt atom + +UNDOCUMENTED + E: Variable name for fix adapt does not exist Self-explanatory. @@ -111,4 +115,8 @@ E: Fix adapt requires atom attribute charge The atom style being used does not specify an atom charge. +E: Could not find fix adapt storage fix ID + +UNDOCUMENTED + */ diff --git a/src/fix_ave_atom.cpp b/src/fix_ave_atom.cpp index fd69b1e05c..e611c888b8 100644 --- a/src/fix_ave_atom.cpp +++ b/src/fix_ave_atom.cpp @@ -43,8 +43,6 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : nrepeat = force->inumeric(FLERR,arg[4]); peratom_freq = force->inumeric(FLERR,arg[5]); - time_depend = 1; - // parse remaining values which = new int[narg-6]; @@ -198,6 +196,7 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) : // once in end_of_step() can set timestep for ones actually invoked irepeat = 0; + nvalid_last = -1; nvalid = nextvalid(); modify->addstep_compute_all(nvalid); } @@ -281,9 +280,13 @@ void FixAveAtom::end_of_step() int i,j,m,n; // skip if not step which requires doing something + // error check if timestep was reset in an invalid manner bigint ntimestep = update->ntimestep; + if (ntimestep < nvalid_last || ntimestep > nvalid) + error->all(FLERR,"Invalid timestep resets for fix ave/time"); if (ntimestep != nvalid) return; + nvalid_last = nvalid; // zero if first step diff --git a/src/fix_ave_atom.h b/src/fix_ave_atom.h index 7186f0df8d..187d5ab922 100644 --- a/src/fix_ave_atom.h +++ b/src/fix_ave_atom.h @@ -44,7 +44,7 @@ class FixAveAtom : public Fix { private: int nvalues; int nrepeat,irepeat; - bigint nvalid; + bigint nvalid,nvalid_last; int *which,*argindex,*value2index; char **ids; double **array; diff --git a/src/fix_ave_chunk.cpp b/src/fix_ave_chunk.cpp index fc7995754b..596f748082 100644 --- a/src/fix_ave_chunk.cpp +++ b/src/fix_ave_chunk.cpp @@ -56,7 +56,6 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : global_freq = nfreq; no_change_box = 1; - time_depend = 1; // parse values until one isn't recognized @@ -298,7 +297,8 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : } // increment lock counter in compute chunk/atom - // only if nrepeat > 1, so that locking spans multiple timesteps + // only if nrepeat > 1 or ave = RUNNING/WINDOW, + // so that locking spans multiple timesteps int icompute = modify->find_compute(idchunk); if (icompute < 0) @@ -306,7 +306,9 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Fix ave/chunk does not use chunk/atom compute"); - if (nrepeat > 1) cchunk->lockcount++; + + if (nrepeat > 1 || ave == RUNNING || ave == WINDOW) cchunk->lockcount++; + if (ave == RUNNING || ave == WINDOW) cchunk->lock(this,update->ntimestep,-1); // print file comment lines @@ -378,6 +380,7 @@ FixAveChunk::FixAveChunk(LAMMPS *lmp, int narg, char **arg) : // since don't know a priori which are invoked by this fix // once in end_of_step() can set timestep for ones actually invoked + nvalid_last = -1; nvalid = nextvalid(); modify->addstep_compute_all(nvalid); } @@ -409,10 +412,11 @@ FixAveChunk::~FixAveChunk() // decrement lock counter in compute chunk/atom, it if still exists - if (nrepeat > 1) { + if (nrepeat > 1 || ave == RUNNING || ave == WINDOW) { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; + if (ave == RUNNING || ave == WINDOW) cchunk->unlock(this); cchunk->lockcount--; } } @@ -503,16 +507,19 @@ void FixAveChunk::end_of_step() int i,j,m,n,index; // skip if not step which requires doing something + // error check if timestep was reset in an invalid manner bigint ntimestep = update->ntimestep; + if (ntimestep < nvalid_last || ntimestep > nvalid) + error->all(FLERR,"Invalid timestep resets for fix ave/time"); if (ntimestep != nvalid) return; + nvalid_last = nvalid; // first sample within single Nfreq epoch // zero out arrays that accumulate over many samples, but not across epochs // invoke setup_chunks() to determine current nchunk // re-allocate per-chunk arrays if needed - // then invoke lock() so nchunk cannot change until Nfreq epoch is over - // use final arg = -1 for infinite-time window + // invoke lock() so nchunk cannot change until Nfreq epoch is over // wrap setup_chunks in clearstep/addstep b/c it may invoke computes // both nevery and nfreq are future steps, // since call below to cchunk->ichunk() @@ -526,8 +533,8 @@ void FixAveChunk::end_of_step() modify->addstep_compute(ntimestep+nfreq); } allocate(); - if (ave == RUNNING || ave == WINDOW) cchunk->lock(this,ntimestep,-1); - else cchunk->lock(this,ntimestep,ntimestep+(nrepeat-1)*nevery); + if (nrepeat > 1 && ave == ONE) + cchunk->lock(this,ntimestep,ntimestep+(nrepeat-1)*nevery); for (m = 0; m < nchunk; m++) { count_many[m] = count_sum[m] = 0.0; for (i = 0; i < nvalues; i++) values_many[m][i] = 0.0; @@ -714,6 +721,8 @@ void FixAveChunk::end_of_step() // exception is scaleflag = NOSCALE : no normalize by atom count // check last so other options can take precedence + double mvv2e = force->mvv2e; + if (normflag == ALL) { for (m = 0; m < nchunk; m++) { count_many[m] += count_one[m]; @@ -726,7 +735,8 @@ void FixAveChunk::end_of_step() if (count_many[m] > 0.0) for (j = 0; j < nvalues; j++) { if (which[j] == TEMPERATURE) - values_many[m][j] += values_one[m][j] / (cdof + adof*count_many[m]); + values_many[m][j] += mvv2e*values_one[m][j] / + (cdof + adof*count_many[m]); else if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS || scaleflag == NOSCALE) values_many[m][j] += values_one[m][j]; @@ -754,7 +764,7 @@ void FixAveChunk::end_of_step() // unlock compute chunk/atom at end of Nfreq epoch // do not unlock if ave = RUNNING or WINDOW - if (ave == ONE) cchunk->unlock(this); + if (nrepeat > 1 && ave == ONE) cchunk->unlock(this); // time average across samples // if normflag = ALL, final is total value / total count @@ -775,7 +785,7 @@ void FixAveChunk::end_of_step() if (count_sum[m] > 0.0) for (j = 0; j < nvalues; j++) { if (which[j] == TEMPERATURE) - values_sum[m][j] /= (cdof + adof*count_sum[m]); + values_sum[m][j] *= mvv2e / (cdof + adof*count_sum[m]); else if (which[j] == DENSITY_MASS) values_sum[m][j] *= mv2d/repeat; else if (which[j] == DENSITY_NUMBER || scaleflag == NOSCALE) diff --git a/src/fix_ave_chunk.h b/src/fix_ave_chunk.h index 98d74fbea4..0db550cb5f 100644 --- a/src/fix_ave_chunk.h +++ b/src/fix_ave_chunk.h @@ -41,7 +41,7 @@ class FixAveChunk : public Fix { int me,nvalues; int nrepeat,nfreq,irepeat; int normflag,scaleflag,overwrite,biasflag,colextra; - bigint nvalid; + bigint nvalid,nvalid_last; double adof,cdof; char *tstring,*sstring,*id_bias; int *which,*argindex,*value2index; @@ -86,86 +86,166 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Cannot use fix ave/spatial z for 2 dimensional model +E: Cannot open fix ave/chunk file %s + +UNDOCUMENTED + +E: Could not find compute ID for temperature bias + +UNDOCUMENTED + +E: Bias compute does not calculate temperature + +UNDOCUMENTED + +E: Bias compute does not calculate a velocity bias + +UNDOCUMENTED + +E: Compute ID for fix ave/chunk does not exist + +UNDOCUMENTED + +E: Fix ave/chunk compute does not calculate per-atom values + +UNDOCUMENTED + +E: Fix ave/chunk compute does not calculate a per-atom vector + +UNDOCUMENTED + +E: Fix ave/chunk compute does not calculate a per-atom array + +UNDOCUMENTED + +E: Fix ave/chunk compute vector is accessed out-of-range + +UNDOCUMENTED + +E: Fix ID for fix ave/chunk does not exist + +UNDOCUMENTED + +E: Fix ave/chunk fix does not calculate per-atom values + +UNDOCUMENTED + +E: Fix ave/chunk fix does not calculate a per-atom vector + +UNDOCUMENTED + +E: Fix ave/chunk fix does not calculate a per-atom array + +UNDOCUMENTED + +E: Fix ave/chunk fix vector is accessed out-of-range + +UNDOCUMENTED + +E: Variable name for fix ave/chunk does not exist + +UNDOCUMENTED + +E: Fix ave/chunk variable is not atom-style variable + +UNDOCUMENTED + +E: Chunk/atom compute does not exist for fix ave/chunk + +UNDOCUMENTED + +E: Fix ave/chunk does not use chunk/atom compute + +UNDOCUMENTED + +E: Fix for fix ave/chunk not computed at compatible time + +UNDOCUMENTED + +E: Fix ave/chunk missed timestep + +UNDOCUMENTED + +U: Cannot use fix ave/spatial z for 2 dimensional model Self-explanatory. -E: Same dimension twice in fix ave/spatial +U: Same dimension twice in fix ave/spatial Self-explanatory. -E: Region ID for fix ave/spatial does not exist +U: Region ID for fix ave/spatial does not exist Self-explanatory. -E: Cannot open fix ave/spatial file %s +U: Cannot open fix ave/spatial file %s The specified file cannot be opened. Check that the path and name are correct. -E: Compute ID for fix ave/spatial does not exist +U: Compute ID for fix ave/spatial does not exist Self-explanatory. -E: Fix ave/spatial compute does not calculate per-atom values +U: Fix ave/spatial compute does not calculate per-atom values A compute used by fix ave/spatial must generate per-atom values. -E: Fix ave/spatial compute does not calculate a per-atom vector +U: Fix ave/spatial compute does not calculate a per-atom vector A compute used by fix ave/spatial must generate per-atom values. -E: Fix ave/spatial compute does not calculate a per-atom array +U: Fix ave/spatial compute does not calculate a per-atom array Self-explanatory. -E: Fix ave/spatial compute vector is accessed out-of-range +U: Fix ave/spatial compute vector is accessed out-of-range The index for the vector is out of bounds. -E: Fix ID for fix ave/spatial does not exist +U: Fix ID for fix ave/spatial does not exist Self-explanatory. -E: Fix ave/spatial fix does not calculate per-atom values +U: Fix ave/spatial fix does not calculate per-atom values A fix used by fix ave/spatial must generate per-atom values. -E: Fix ave/spatial fix does not calculate a per-atom vector +U: Fix ave/spatial fix does not calculate a per-atom vector A fix used by fix ave/spatial must generate per-atom values. -E: Fix ave/spatial fix does not calculate a per-atom array +U: Fix ave/spatial fix does not calculate a per-atom array Self-explanatory. -E: Fix ave/spatial fix vector is accessed out-of-range +U: Fix ave/spatial fix vector is accessed out-of-range The index for the vector is out of bounds. -E: Variable name for fix ave/spatial does not exist +U: Variable name for fix ave/spatial does not exist Self-explanatory. -E: Fix ave/spatial variable is not atom-style variable +U: Fix ave/spatial variable is not atom-style variable A variable used by fix ave/spatial must generate per-atom values. -E: Fix ave/spatial for triclinic boxes requires units reduced +U: Fix ave/spatial for triclinic boxes requires units reduced Self-explanatory. -E: Fix ave/spatial settings invalid with changing box size +U: Fix ave/spatial settings invalid with changing box size If the box size changes, only the units reduced option can be used. -E: Fix for fix ave/spatial not computed at compatible time +U: Fix for fix ave/spatial not computed at compatible time Fixes generate their values on specific timesteps. Fix ave/spatial is requesting a value on a non-allowed timestep. -E: Fix ave/spatial missed timestep +U: Fix ave/spatial missed timestep You cannot reset the timestep to a value beyond where the fix expects to next perform averaging. diff --git a/src/fix_ave_correlate.cpp b/src/fix_ave_correlate.cpp index 79bbec7654..9940162c45 100644 --- a/src/fix_ave_correlate.cpp +++ b/src/fix_ave_correlate.cpp @@ -55,7 +55,6 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): nfreq = force->inumeric(FLERR,arg[5]); global_freq = nfreq; - time_depend = 1; // parse values until one isn't recognized @@ -304,6 +303,7 @@ FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg): lastindex = -1; firstindex = 0; nsample = 0; + nvalid_last = -1; nvalid = nextvalid(); modify->addstep_compute_all(nvalid); } @@ -391,9 +391,13 @@ void FixAveCorrelate::end_of_step() double scalar; // skip if not step which requires doing something + // error check if timestep was reset in an invalid manner bigint ntimestep = update->ntimestep; + if (ntimestep < nvalid_last || ntimestep > nvalid) + error->all(FLERR,"Invalid timestep resets for fix ave/time"); if (ntimestep != nvalid) return; + nvalid_last = nvalid; // accumulate results of computes,fixes,variables to origin // compute/fix/variable may invoke computes so wrap with clear/add diff --git a/src/fix_ave_correlate.h b/src/fix_ave_correlate.h index 9ab563ab7e..6f9c606d78 100644 --- a/src/fix_ave_correlate.h +++ b/src/fix_ave_correlate.h @@ -39,7 +39,7 @@ class FixAveCorrelate : public Fix { private: int me,nvalues; int nrepeat,nfreq; - bigint nvalid; + bigint nvalid,nvalid_last; int *which,*argindex,*value2index; char **ids; FILE *fp; diff --git a/src/fix_ave_histo.cpp b/src/fix_ave_histo.cpp index a413ada1d3..f3bf0a1cd4 100644 --- a/src/fix_ave_histo.cpp +++ b/src/fix_ave_histo.cpp @@ -62,7 +62,6 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : array_flag = 1; size_array_cols = 3; extarray = 0; - time_depend = 1; lo = force->numeric(FLERR,arg[6]); hi = force->numeric(FLERR,arg[7]); @@ -503,6 +502,7 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : // since don't know a priori which are invoked by this fix // once in end_of_step() can set timestep for ones actually invoked + nvalid_last = -1; nvalid = nextvalid(); modify->addstep_compute_all(nvalid); } @@ -589,9 +589,13 @@ void FixAveHisto::end_of_step() int i,j,m; // skip if not step which requires doing something + // error check if timestep was reset in an invalid manner bigint ntimestep = update->ntimestep; + if (ntimestep < nvalid_last || ntimestep > nvalid) + error->all(FLERR,"Invalid timestep resets for fix ave/time"); if (ntimestep != nvalid) return; + nvalid_last = nvalid; // zero if first step diff --git a/src/fix_ave_histo.h b/src/fix_ave_histo.h index 2d6bee353e..f4da2d5a22 100644 --- a/src/fix_ave_histo.h +++ b/src/fix_ave_histo.h @@ -40,7 +40,7 @@ class FixAveHisto : public Fix { private: int me,nvalues; int nrepeat,nfreq,irepeat; - bigint nvalid; + bigint nvalid,nvalid_last; int *which,*argindex,*value2index; char **ids; FILE *fp; diff --git a/src/fix_ave_spatial.cpp b/src/fix_ave_spatial.cpp index b8ae02bfc1..a31995fa7a 100644 --- a/src/fix_ave_spatial.cpp +++ b/src/fix_ave_spatial.cpp @@ -66,7 +66,6 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : global_freq = nfreq; no_change_box = 1; - time_depend = 1; ndim = 0; int iarg = 6; @@ -431,6 +430,7 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : // since don't know a priori which are invoked by this fix // once in end_of_step() can set timestep for ones actually invoked + nvalid_last = -1; nvalid = nextvalid(); modify->addstep_compute_all(nvalid); } @@ -549,9 +549,13 @@ void FixAveSpatial::end_of_step() int i,j,m,n; // skip if not step which requires doing something + // error check if timestep was reset in an invalid manner bigint ntimestep = update->ntimestep; + if (ntimestep < nvalid_last || ntimestep > nvalid) + error->all(FLERR,"Invalid timestep resets for fix ave/time"); if (ntimestep != nvalid) return; + nvalid_last = nvalid; // update region if necessary diff --git a/src/fix_ave_spatial.h b/src/fix_ave_spatial.h index f38c4251ee..2e39d0fcaa 100644 --- a/src/fix_ave_spatial.h +++ b/src/fix_ave_spatial.h @@ -40,7 +40,7 @@ class FixAveSpatial : public Fix { private: int me,nvalues; int nrepeat,nfreq,irepeat; - bigint nvalid; + bigint nvalid,nvalid_last; int ndim,normflag,regionflag,overwrite,discard; char *tstring,*sstring,*idregion; int *which,*argindex,*value2index; @@ -88,6 +88,10 @@ class FixAveSpatial : public Fix { /* ERROR/WARNING messages: +W: The fix ave/spatial command has been replaced by the more flexible fix ave/chunk and compute chunk/atom commands -- fix ave/spatial will be removed in the summer of 2015 + +UNDOCUMENTED + E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the @@ -102,6 +106,10 @@ E: Same dimension twice in fix ave/spatial Self-explanatory. +E: No input values for fix ave/spatial + +UNDOCUMENTED + E: Region ID for fix ave/spatial does not exist Self-explanatory. @@ -173,6 +181,10 @@ E: Fix for fix ave/spatial not computed at compatible time Fixes generate their values on specific timesteps. Fix ave/spatial is requesting a value on a non-allowed timestep. +E: Invalid bin bounds in fix ave/spatial + +UNDOCUMENTED + E: Fix ave/spatial missed timestep You cannot reset the timestep to a value beyond where the fix diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp index f406b650b5..c06825b71c 100644 --- a/src/fix_ave_time.cpp +++ b/src/fix_ave_time.cpp @@ -54,7 +54,6 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : nfreq = force->inumeric(FLERR,arg[5]); global_freq = nfreq; - time_depend = 1; // scan values to count them // then read options so know mode = SCALAR/VECTOR before re-reading values @@ -277,11 +276,14 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : // enable locking of row count by this fix for computes of variable length // only if nrepeat > 1, so that locking spans multiple timesteps - if (any_variable_length && nrepeat > 1) { + if (any_variable_length && + (nrepeat > 1 || ave == RUNNING || ave == WINDOW)) { for (int i = 0; i < nvalues; i++) if (varlen[i]) { int icompute = modify->find_compute(ids[i]); modify->compute[icompute]->lock_enable(); + if (ave == RUNNING || ave == WINDOW) + modify->compute[icompute]->lock(this,update->ntimestep,-1); } } @@ -444,6 +446,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : // since don't know a priori which are invoked by this fix // once in end_of_step() can set timestep for ones actually invoked + nvalid_last = -1; nvalid = nextvalid(); modify->addstep_compute_all(nvalid); } @@ -453,13 +456,17 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : FixAveTime::~FixAveTime() { // decrement lock counter in compute chunk/atom, it if still exists - // NOTE: better comment - if (any_variable_length && nrepeat > 1) { + if (any_variable_length && + (nrepeat > 1 || ave == RUNNING || ave == WINDOW)) { for (int i = 0; i < nvalues; i++) if (varlen[i]) { int icompute = modify->find_compute(ids[i]); - if (icompute >= 0) modify->compute[icompute]->lock_disable(); + if (icompute >= 0) { + if (ave == RUNNING || ave == WINDOW) + modify->compute[icompute]->unlock(this); + modify->compute[icompute]->lock_disable(); + } } } @@ -543,9 +550,13 @@ void FixAveTime::setup(int vflag) void FixAveTime::end_of_step() { // skip if not step which requires doing something + // error check if timestep was reset in an invalid manner bigint ntimestep = update->ntimestep; + if (ntimestep < nvalid_last || ntimestep > nvalid) + error->all(FLERR,"Invalid timestep resets for fix ave/time"); if (ntimestep != nvalid) return; + nvalid_last = nvalid; if (mode == SCALAR) invoke_scalar(ntimestep); else invoke_vector(ntimestep); @@ -728,9 +739,10 @@ void FixAveTime::invoke_vector(bigint ntimestep) bigint ntimestep = update->ntimestep; for (i = 0; i < nvalues; i++) { if (!varlen[i]) continue; - Compute *compute = modify->compute[value2index[i]]; - if (ave == RUNNING || ave == WINDOW) compute->lock(this,ntimestep,-1); - else compute->lock(this,ntimestep,ntimestep+(nrepeat-1)*nevery); + if (nrepeat > 1 && ave == ONE) { + Compute *compute = modify->compute[value2index[i]]; + compute->lock(this,ntimestep,ntimestep+(nrepeat-1)*nevery); + } } } @@ -813,7 +825,7 @@ void FixAveTime::invoke_vector(bigint ntimestep) // unlock any variable length computes at end of Nfreq epoch // do not unlock if ave = RUNNING or WINDOW - if (any_variable_length && ave == ONE) { + if (any_variable_length && nrepeat > 1 && ave == ONE) { for (i = 0; i < nvalues; i++) { if (!varlen[i]) continue; Compute *compute = modify->compute[value2index[i]]; diff --git a/src/fix_ave_time.h b/src/fix_ave_time.h index df34bac56f..f98ea3b96a 100644 --- a/src/fix_ave_time.h +++ b/src/fix_ave_time.h @@ -41,7 +41,7 @@ class FixAveTime : public Fix { private: int me,nvalues; int nrepeat,nfreq,irepeat; - bigint nvalid; + bigint nvalid,nvalid_last; int *which,*argindex,*value2index,*offcol; int *varlen; // 1 if value is from variable-length compute char **ids; @@ -127,6 +127,10 @@ E: Fix ave/time fix does not calculate a vector Self-explanatory. +E: Fix ave/time fix vector cannot be variable length + +UNDOCUMENTED + E: Fix ave/time fix vector is accessed out-of-range The index for the vector is out of bounds. @@ -140,6 +144,10 @@ E: Fix ave/time fix does not calculate an array Self-explanatory. +E: Fix ave/time fix array cannot be variable length + +UNDOCUMENTED + E: Fix ave/time fix array is accessed out-of-range An index for the array is out of bounds. @@ -156,16 +164,16 @@ E: Fix ave/time cannot use variable with vector mode Variables produce scalar values. -E: Fix ave/time columns are inconsistent lengths - -Self-explanatory. - E: Fix ave/time cannot set output array intensive/extensive from these inputs One of more of the vector inputs has individual elements which are flagged as intensive or extensive. Such an input cannot be flagged as all intensive/extensive when turned into an array by fix ave/time. +E: Fix ave/time columns are inconsistent lengths + +Self-explanatory. + E: Cannot open fix ave/time file %s The specified file cannot be opened. Check that the path and name are diff --git a/src/fix_balance.h b/src/fix_balance.h index 775d885d8d..967ea6efac 100644 --- a/src/fix_balance.h +++ b/src/fix_balance.h @@ -72,16 +72,24 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Fix balance string is invalid +E: Fix balance shift string is invalid -The string can only contain the characters "x", "y", or "z". +UNDOCUMENTED -E: Fix balance string is invalid for 2d simulation +E: Fix balance rcb cannot be used with comm_style brick -The string cannot contain the letter "z". +UNDOCUMENTED E: Cannot open fix balance output file Self-explanatory. +U: Fix balance string is invalid + +The string can only contain the characters "x", "y", or "z". + +U: Fix balance string is invalid for 2d simulation + +The string cannot contain the letter "z". + */ diff --git a/src/fix_group.h b/src/fix_group.h index c5a1db106c..fd0944844f 100644 --- a/src/fix_group.h +++ b/src/fix_group.h @@ -50,4 +50,28 @@ class FixGroup : public Fix { /* ERROR/WARNING messages: +E: Illegal ... command + +UNDOCUMENTED + +E: Region ID for group dynamic does not exist + +UNDOCUMENTED + +E: Variable name for group dynamic does not exist + +UNDOCUMENTED + +E: Group dynamic parent group cannot be dynamic + +UNDOCUMENTED + +E: Variable for group dynamic is invalid style + +UNDOCUMENTED + +W: One or more dynamic groups may not be updated at correct point in timestep + +UNDOCUMENTED + */ diff --git a/src/fix_store_state.h b/src/fix_store_state.h index fdc6ddc1d1..2f68fdd036 100644 --- a/src/fix_store_state.h +++ b/src/fix_store_state.h @@ -143,6 +143,14 @@ E: Fix store/state compute array is accessed out-of-range Self-explanatory. +E: Custom integer vector does not exist + +UNDOCUMENTED + +E: Custom floating point vector does not exist + +UNDOCUMENTED + E: Fix ID for fix store/state does not exist Self-explanatory @@ -177,4 +185,12 @@ E: Fix store/state variable is not atom-style variable Only atom-style variables calculate per-atom quantities. +E: Custom integer vector for fix store/state does not exist + +UNDOCUMENTED + +E: Custom floating point vector for fix store/state does not exist + +UNDOCUMENTED + */ diff --git a/src/fix_temp_csvr.h b/src/fix_temp_csvr.h index c9e77cc065..fe0f0214cf 100644 --- a/src/fix_temp_csvr.h +++ b/src/fix_temp_csvr.h @@ -68,6 +68,14 @@ E: Fix temp/csvr period must be > 0.0 Self-explanatory. +E: Illegal fix temp/csvr random seed + +UNDOCUMENTED + +E: Fix temp/csvr is not compatible with fix shake + +UNDOCUMENTED + E: Variable name for fix temp/csvr does not exist Self-explanatory. @@ -80,10 +88,6 @@ E: Temperature ID for fix temp/csvr does not exist Self-explanatory. -E: Computed temperature for fix temp/csvr cannot be 0.0 - -Self-explanatory. - E: Fix temp/csvr variable returned negative temperature Self-explanatory. @@ -102,4 +106,8 @@ The fix_modify command is specifying a temperature computation that computes a temperature on a different group of atoms than the fix itself operates on. This is probably not what you want to do. +U: Computed temperature for fix temp/csvr cannot be 0.0 + +Self-explanatory. + */ diff --git a/src/fix_vector.h b/src/fix_vector.h index 48179e03aa..1e042504a0 100644 --- a/src/fix_vector.h +++ b/src/fix_vector.h @@ -55,4 +55,60 @@ class FixVector : public Fix { /* ERROR/WARNING messages: +E: Illegal ... command + +UNDOCUMENTED + +E: Compute ID for fix vector does not exist + +UNDOCUMENTED + +E: Fix vector compute does not calculate a scalar + +UNDOCUMENTED + +E: Fix vector compute does not calculate a vector + +UNDOCUMENTED + +E: Fix vector compute vector is accessed out-of-range + +UNDOCUMENTED + +E: Fix ID for fix vector does not exist + +UNDOCUMENTED + +E: Fix vector fix does not calculate a scalar + +UNDOCUMENTED + +E: Fix vector fix does not calculate a vector + +UNDOCUMENTED + +E: Fix vector fix vector is accessed out-of-range + +UNDOCUMENTED + +E: Fix for fix vector not computed at compatible time + +UNDOCUMENTED + +E: Variable name for fix vector does not exist + +UNDOCUMENTED + +E: Fix vector variable is not equal-style variable + +UNDOCUMENTED + +E: Fix vector cannot set output array intensive/extensive from these inputs + +UNDOCUMENTED + +E: Overflow of allocated fix vector storage + +UNDOCUMENTED + */ diff --git a/src/force.h b/src/force.h index 200fcd00af..539374a86e 100644 --- a/src/force.h +++ b/src/force.h @@ -125,29 +125,33 @@ class Force : protected Pointers { /* ERROR/WARNING messages: -E: Invalid pair style +E: Unknown pair style -The choice of pair style is unknown. +UNDOCUMENTED -E: Invalid bond style +E: Unknown bond style -The choice of bond style is unknown. +UNDOCUMENTED -E: Invalid angle style +E: Unknown angle style -The choice of angle style is unknown. +UNDOCUMENTED -E: Invalid dihedral style +E: Unknown dihedral style -The choice of dihedral style is unknown. +UNDOCUMENTED -E: Invalid improper style +E: Unknown improper style -The choice of improper style is unknown. +UNDOCUMENTED -E: Invalid kspace style +E: Cannot yet use KSpace solver with grid with comm style tiled -The choice of kspace style is unknown. +UNDOCUMENTED + +E: Unknown kspace style + +UNDOCUMENTED E: Illegal ... command @@ -161,4 +165,28 @@ A command with an argument that specifies an integer or range of integers is using a value that is less than 1 or greater than the maximum allowed limit. +U: Invalid pair style + +The choice of pair style is unknown. + +U: Invalid bond style + +The choice of bond style is unknown. + +U: Invalid angle style + +The choice of angle style is unknown. + +U: Invalid dihedral style + +The choice of dihedral style is unknown. + +U: Invalid improper style + +The choice of improper style is unknown. + +U: Invalid kspace style + +The choice of kspace style is unknown. + */ diff --git a/src/group.h b/src/group.h index 7b941665ec..3d6f313e46 100644 --- a/src/group.h +++ b/src/group.h @@ -118,6 +118,14 @@ E: Cannot delete group currently used by atom_modify first Self-explanatory. +E: Could not find group clear group ID + +UNDOCUMENTED + +E: Cannot clear group all + +UNDOCUMENTED + E: Too many groups The maximum number of atom groups (including the "all" group) is @@ -139,4 +147,28 @@ E: Group ID does not exist A group ID used in the group command does not exist. +E: Cannot subtract groups using a dynamic group + +UNDOCUMENTED + +E: Cannot union groups using a dynamic group + +UNDOCUMENTED + +E: Cannot intersect groups using a dynamic group + +UNDOCUMENTED + +E: Group dynamic cannot reference itself + +UNDOCUMENTED + +E: Group dynamic parent group does not exist + +UNDOCUMENTED + +E: Group all cannot be made dynamic + +UNDOCUMENTED + */ diff --git a/src/improper.cpp b/src/improper.cpp index 90460d76ce..643e7a63ff 100644 --- a/src/improper.cpp +++ b/src/improper.cpp @@ -44,12 +44,16 @@ Improper::Improper(LAMMPS *lmp) : Pointers(lmp) execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; + + copymode = 0; } /* ---------------------------------------------------------------------- */ Improper::~Improper() -{ +{ + if (copymode) return; + memory->destroy(eatom); memory->destroy(vatom); } diff --git a/src/improper.h b/src/improper.h index 77c38af766..039da0ab84 100644 --- a/src/improper.h +++ b/src/improper.h @@ -35,6 +35,7 @@ class Improper : protected Pointers { // KOKKOS host/device flag and data masks ExecutionSpace execution_space; unsigned int datamask_read,datamask_modify; + int copymode; Improper(class LAMMPS *); virtual ~Improper(); diff --git a/src/input.h b/src/input.h index 3023955993..56c2f5c7cd 100644 --- a/src/input.h +++ b/src/input.h @@ -313,10 +313,25 @@ E: Package command after simulation box is defined The package command cannot be used afer a read_data, read_restart, or create_box command. -E: Package cuda command without USER-CUDA installed +E: Package cuda command without USER-CUDA package enabled -The USER-CUDA package must be installed via "make yes-user-cuda" -before LAMMPS is built. +UNDOCUMENTED + +E: Package gpu command without GPU package installed + +UNDOCUMENTED + +E: Package kokkos command without KOKKOS package enabled + +UNDOCUMENTED + +E: Package omp command without USER-OMP package installed + +UNDOCUMENTED + +E: Package intel command without USER-INTEL package installed + +UNDOCUMENTED E: Pair_coeff command before simulation box is defined @@ -350,4 +365,9 @@ E: Units command after simulation box is defined The units command cannot be used after a read_data, read_restart, or create_box command. +U: Package cuda command without USER-CUDA installed + +The USER-CUDA package must be installed via "make yes-user-cuda" +before LAMMPS is built. + */ diff --git a/src/kspace.h b/src/kspace.h index 157e028e58..dc82b9b732 100644 --- a/src/kspace.h +++ b/src/kspace.h @@ -216,6 +216,18 @@ E: KSpace style is incompatible with Pair style Setting a kspace style requires that a pair style with a long-range Coulombic or dispersion component be used. +W: Using kspace solver on system with no charge + +UNDOCUMENTED + +E: System is not charge neutral, net charge = %g + +UNDOCUMENTED + +W: System is not charge neutral, net charge = %g + +UNDOCUMENTED + W: For better accuracy use 'pair_modify table 0' The user-specified force accuracy cannot be achieved unless the table diff --git a/src/lammps.h b/src/lammps.h index 0af9721708..672ea9541f 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -78,10 +78,9 @@ E: Cannot use -reorder after -partition Self-explanatory. See doc page discussion of command-line switches. -E: Processor partitions are inconsistent +E: Processor partitions do not match number of allocated processors -The total number of processors in all partitions must match the number -of processors LAMMPS is running on. +UNDOCUMENTED E: Must use -in switch with multiple partitions @@ -158,9 +157,46 @@ This error occurs whenthe sizes of smallint, imageint, tagint, bigint, as defined in src/lmptype.h are not what is expected. Contact the developers if this occurs. +E: Cannot use -cuda on and -kokkos on together + +UNDOCUMENTED + E: Cannot use -cuda on without USER-CUDA installed The USER-CUDA package must be installed via "make yes-user-cuda" before LAMMPS is built. +E: Cannot use -kokkos on without KOKKOS installed + +UNDOCUMENTED + +E: Using suffix cuda without USER-CUDA package enabled + +UNDOCUMENTED + +E: Using suffix gpu without GPU package installed + +UNDOCUMENTED + +E: Using suffix intel without USER-INTEL package installed + +UNDOCUMENTED + +E: Using suffix kk without KOKKOS package enabled + +UNDOCUMENTED + +E: Using suffix omp without USER-OMP package installed + +UNDOCUMENTED + +E: Too many -pk arguments in command line + +UNDOCUMENTED + +U: Processor partitions are inconsistent + +The total number of processors in all partitions must match the number +of processors LAMMPS is running on. + */ diff --git a/src/memory.h b/src/memory.h index 1cc3b9ccb6..1af77cb771 100644 --- a/src/memory.h +++ b/src/memory.h @@ -32,6 +32,8 @@ class Memory : protected Pointers { void fail(const char *); // Kokkos memory allocation functions + // could provide a dummy any Kokkos memory function + // called in main LAMMPS even when not built with KOKKOS package #ifdef LMP_KOKKOS #include "memory_kokkos.h" diff --git a/src/modify.h b/src/modify.h index 8275927847..bf373406c7 100644 --- a/src/modify.h +++ b/src/modify.h @@ -156,6 +156,14 @@ class Modify : protected Pointers { /* ERROR/WARNING messages: +E: Fix %s does not allow use of dynamic group + +UNDOCUMENTED + +E: Compute %s does not allow use of dynamic group + +UNDOCUMENTED + W: One or more atoms are time integrated more than once This is probably an error since you typically do not want to @@ -190,9 +198,9 @@ The ID and style of a fix match for a fix you are changing with a fix command, but the new group you are specifying does not match the old group. -E: Invalid fix style +E: Unknown fix style -The choice of fix style is unknown. +UNDOCUMENTED E: Could not find fix_modify ID @@ -206,9 +214,9 @@ E: Reuse of compute ID A compute ID cannot be used twice. -E: Invalid compute style +E: Unknown compute style -Self-explanatory. +UNDOCUMENTED E: Could not find compute_modify ID @@ -218,4 +226,12 @@ E: Could not find compute ID to delete Self-explanatory. +U: Invalid fix style + +The choice of fix style is unknown. + +U: Invalid compute style + +Self-explanatory. + */ diff --git a/src/molecule.h b/src/molecule.h index a786c0c5d1..8efd4a3d02 100644 --- a/src/molecule.h +++ b/src/molecule.h @@ -204,6 +204,10 @@ E: Molecule file has special flags but no bonds Self-explanatory. +E: Molecule file has bonds but no special flags + +UNDOCUMENTED + E: Molecule file shake info is incomplete All 3 SHAKE sections are needed. diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 8567d74297..53924f2cea 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -154,35 +154,39 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) dihedrallist = NULL; maximproper = 0; improperlist = NULL; + + copymode = 0; } /* ---------------------------------------------------------------------- */ Neighbor::~Neighbor() { + if (copymode) return; + memory->destroy(cutneighsq); memory->destroy(cutneighghostsq); delete [] cuttype; delete [] cuttypesq; delete [] fixchecklist; - + memory->destroy(xhold); - + memory->destroy(binhead); memory->destroy(bins); - + memory->destroy(ex1_type); memory->destroy(ex2_type); memory->destroy(ex_type); - + memory->destroy(ex1_group); memory->destroy(ex2_group); delete [] ex1_bit; delete [] ex2_bit; - + memory->destroy(ex_mol_group); delete [] ex_mol_bit; - + for (int i = 0; i < nlist; i++) delete lists[i]; delete [] lists; delete [] pair_build; @@ -190,12 +194,12 @@ Neighbor::~Neighbor() delete [] blist; delete [] glist; delete [] slist; - + for (int i = 0; i < nrequest; i++) delete requests[i]; memory->sfree(requests); for (int i = 0; i < old_nrequest; i++) delete old_requests[i]; memory->sfree(old_requests); - + memory->destroy(bondlist); memory->destroy(anglelist); memory->destroy(dihedrallist); @@ -832,6 +836,11 @@ void Neighbor::init() // 1st time allocation of topology lists + if (lmp->kokkos) { + init_topology_kokkos(); + return; + } + if (atom->molecular && atom->nbonds && maxbond == 0) { if (nprocs == 1) maxbond = atom->nbonds; else maxbond = static_cast (LB_FACTOR * atom->nbonds / nprocs); @@ -1523,11 +1532,8 @@ void Neighbor::build(int topoflag) // only for pairwise lists with buildflag set // blist is for standard neigh lists, otherwise is a Kokkos list - for (i = 0; i < nblist; i++) { - if (lists[blist[i]]) - (this->*pair_build[blist[i]])(lists[blist[i]]); - else build_kokkos(i); - } + for (i = 0; i < nblist; i++) + (this->*pair_build[blist[i]])(lists[blist[i]]); if (atom->molecular && topoflag) build_topology(); } diff --git a/src/neighbor.h b/src/neighbor.h index 8224a97e10..0ebd13efc8 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -85,6 +85,8 @@ class Neighbor : protected Pointers { bigint memory_usage(); int exclude_setting(); + int cluster_check; // 1 if check bond/angle/etc satisfies minimg + protected: int me,nprocs; @@ -103,7 +105,6 @@ class Neighbor : protected Pointers { double *cuttypesq; // cuttype squared double triggersq; // trigger = build when atom moves this dist - int cluster_check; // 1 if check bond/angle/etc satisfies minimg double **xhold; // atom coords at last neighbor build int maxhold; // size of xhold array @@ -189,6 +190,10 @@ class Neighbor : protected Pointers { virtual void init_list_grow_kokkos(int) {} virtual void build_kokkos(int) {} virtual void setup_bins_kokkos(int) {} + virtual void init_topology_kokkos() {} + virtual void build_topology_kokkos() {} + + int copymode; // pairwise build functions diff --git a/src/output.h b/src/output.h index cda9e800ee..412387ed6a 100644 --- a/src/output.h +++ b/src/output.h @@ -119,6 +119,10 @@ E: Thermo every variable returned a bad timestep The variable must return a timestep greater than the current timestep. +E: Thermo_modify every variable returned a bad timestep + +UNDOCUMENTED + E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the @@ -137,9 +141,9 @@ E: Invalid dump frequency Dump frequency must be 1 or greater. -E: Invalid dump style +E: Unknown dump style -The choice of dump style is unknown. +UNDOCUMENTED E: Cound not find dump_modify ID @@ -170,4 +174,8 @@ E: Both restart files must use MPI-IO or neither Self-explanatory. +U: Invalid dump style + +The choice of dump style is unknown. + */ diff --git a/src/pair.cpp b/src/pair.cpp index 27811567c4..40a8993294 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -112,10 +112,10 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp) Pair::~Pair() { - if (!copymode) { - memory->destroy(eatom); - memory->destroy(vatom); - } + if (copymode) return; + + memory->destroy(eatom); + memory->destroy(vatom); } /* ---------------------------------------------------------------------- diff --git a/src/pair.h b/src/pair.h index e7278a0d70..e9f75f4135 100644 --- a/src/pair.h +++ b/src/pair.h @@ -273,6 +273,10 @@ E: All pair coeffs are not set All pair coefficients must be set in the data file or by the pair_coeff command before running a simulation. +E: Fix adapt interface to this pair style not supported + +UNDOCUMENTED + E: Pair style requres a KSpace style Self-explanatory. diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp index 5eaadd72c9..24b930af1e 100644 --- a/src/pair_buck.cpp +++ b/src/pair_buck.cpp @@ -38,7 +38,9 @@ PairBuck::PairBuck(LAMMPS *lmp) : Pair(lmp) PairBuck::~PairBuck() { - if (allocated && !copymode) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); diff --git a/src/pair_coul_dsf.cpp b/src/pair_coul_dsf.cpp index 51cf676678..2fa7b69fc9 100644 --- a/src/pair_coul_dsf.cpp +++ b/src/pair_coul_dsf.cpp @@ -52,7 +52,9 @@ PairCoulDSF::PairCoulDSF(LAMMPS *lmp) : Pair(lmp) PairCoulDSF::~PairCoulDSF() { - if (allocated && !copymode) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); } diff --git a/src/pair_coul_streitz.h b/src/pair_coul_streitz.h index bf849f9610..cfef076f4b 100644 --- a/src/pair_coul_streitz.h +++ b/src/pair_coul_streitz.h @@ -89,4 +89,44 @@ class PairCoulStreitz : public Pair { /* ERROR/WARNING messages: +E: Illegal ... command + +UNDOCUMENTED + +E: Incorrect args for pair coefficients + +UNDOCUMENTED + +E: Pair style coul/sm requires atom attribute q + +UNDOCUMENTED + +E: Pair style requires KSpace style ewald + +UNDOCUMENTED + +E: All pair coeffs are not set + +UNDOCUMENTED + +E: Cannot open coul/Streitz potential file %s + +UNDOCUMENTED + +E: Incorrect format in coul/Streitz potential file + +UNDOCUMENTED + +E: Illegal coul/Streitz parameter + +UNDOCUMENTED + +E: Potential file has duplicate entry + +UNDOCUMENTED + +E: Potential file is missing an entry + +UNDOCUMENTED + */ diff --git a/src/pair_coul_wolf.cpp b/src/pair_coul_wolf.cpp index 9d0d783e36..170f458346 100644 --- a/src/pair_coul_wolf.cpp +++ b/src/pair_coul_wolf.cpp @@ -43,7 +43,9 @@ PairCoulWolf::PairCoulWolf(LAMMPS *lmp) : Pair(lmp) PairCoulWolf::~PairCoulWolf() { - if (allocated && !copymode) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); } diff --git a/src/pair_hybrid.h b/src/pair_hybrid.h index d69bfa7780..306795bd72 100644 --- a/src/pair_hybrid.h +++ b/src/pair_hybrid.h @@ -125,6 +125,10 @@ E: Pair hybrid sub-style does not support single call You are attempting to invoke a single() call on a pair style that doesn't support it. +E: Unknown pair_modify hybrid sub-style + +UNDOCUMENTED + E: Coulomb cutoffs of pair hybrid sub-styles do not match If using a Kspace solver, all Coulomb cutoffs of long pair styles must diff --git a/src/read_data.h b/src/read_data.h index 685c707b8e..313adf4728 100644 --- a/src/read_data.h +++ b/src/read_data.h @@ -100,19 +100,31 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. +E: Fix ID for read_data does not exist + +Self-explanatory. + E: Cannot read_data after simulation box is defined The read_data command cannot be used after a read_data, read_restart, or create_box command. +E: Cannot read_data add and merge + +UNDOCUMENTED + +E: Cannot use non-zero z offset in read_data for 2d simulation + +UNDOCUMENTED + E: Cannot run 2d simulation with nonperiodic Z dimension Use the boundary command to make the z dimension periodic in order to run a 2d simulation. -E: Fix ID for read_data does not exist +W: Atom style in data file differs from currently defined atom style -Self-explanatory. +UNDOCUMENTED E: Must read Atoms before Velocities @@ -190,6 +202,10 @@ E: Must define pair_style before Pair Coeffs Must use a pair_style command before reading a data file that defines Pair Coeffs. +W: Pair style in data file differs from currently defined pair style + +UNDOCUMENTED + E: Must define pair_style before PairIJ Coeffs Must use a pair_style command before reading a data file that defines @@ -204,6 +220,10 @@ E: Must define bond_style before Bond Coeffs Must use a bond_style command before reading a data file that defines Bond Coeffs. +W: Bond style in data file differs from currently defined bond style + +UNDOCUMENTED + E: Invalid data file section: Angle Coeffs Atom style does not allow angles. @@ -213,6 +233,10 @@ E: Must define angle_style before Angle Coeffs Must use an angle_style command before reading a data file that defines Angle Coeffs. +W: Angle style in data file differs from currently defined angle style + +UNDOCUMENTED + E: Invalid data file section: Dihedral Coeffs Atom style does not allow dihedrals. @@ -222,6 +246,10 @@ E: Must define dihedral_style before Dihedral Coeffs Must use a dihedral_style command before reading a data file that defines Dihedral Coeffs. +W: Dihedral style in data file differs from currently defined dihedral style + +UNDOCUMENTED + E: Invalid data file section: Improper Coeffs Atom style does not allow impropers. @@ -231,6 +259,10 @@ E: Must define improper_style before Improper Coeffs Must use an improper_style command before reading a data file that defines Improper Coeffs. +W: Improper style in data file differs from currently defined improper style + +UNDOCUMENTED + E: Invalid data file section: BondBond Coeffs Atom style does not allow angles. @@ -322,6 +354,10 @@ E: Needed bonus data not in data file Some atom styles require bonus data. See the read_data doc page for details. +E: Read_data shrink wrap did not assign all atoms correctly + +UNDOCUMENTED + E: Unexpected end of data file LAMMPS hit the end of the data file while attempting to read a @@ -418,6 +454,26 @@ E: Too many lines in one body in data file - boost MAXBODY MAXBODY is a setting at the top of the src/read_data.cpp file. Set it larger and re-compile the code. +E: Unexpected end of PairCoeffs section + +UNDOCUMENTED + +E: Unexpected end of BondCoeffs section + +UNDOCUMENTED + +E: Unexpected end of AngleCoeffs section + +UNDOCUMENTED + +E: Unexpected end of DihedralCoeffs section + +UNDOCUMENTED + +E: Unexpected end of ImproperCoeffs section + +UNDOCUMENTED + E: Cannot open gzipped file LAMMPS was compiled without support for reading and writing gzipped diff --git a/src/read_dump.h b/src/read_dump.h index 95a7306fd5..9878957122 100644 --- a/src/read_dump.h +++ b/src/read_dump.h @@ -113,9 +113,9 @@ E: Dump file does not contain requested snapshot Self-explanatory. -E: Invalid dump reader style +E: Unknown dump reader style -Self-explanatory. +UNDOCUMENTED E: No box information in dump. You have to use 'box no' @@ -157,4 +157,8 @@ E: If read_dump purges it cannot replace or trim These operations are not compatible. See the read_dump doc page for details. +U: Invalid dump reader style + +Self-explanatory. + */ diff --git a/src/read_restart.h b/src/read_restart.h index bf6a793258..f54f4bdde6 100644 --- a/src/read_restart.h +++ b/src/read_restart.h @@ -99,11 +99,9 @@ E: Invalid flag in peratom section of restart file The format of this section of the file is not correct. -E: Did not assign all atoms correctly +E: Did not assign all restart atoms correctly -Atoms read in from a data file were not assigned correctly to -processors. This is likely due to some atom coordinates being -outside a non-periodic simulation box. +UNDOCUMENTED E: Cannot open dir to search for restart file @@ -216,4 +214,10 @@ E: Restart file byte ordering is not recognized The file does not appear to be a LAMMPS restart file since it doesn't contain a recognized byte-orderomg flag at the beginning. +U: Did not assign all atoms correctly + +Atoms read in from a data file were not assigned correctly to +processors. This is likely due to some atom coordinates being +outside a non-periodic simulation box. + */ diff --git a/src/rerun.h b/src/rerun.h index c3b5568550..3484052357 100644 --- a/src/rerun.h +++ b/src/rerun.h @@ -52,4 +52,8 @@ E: Rerun dump file does not contain requested snapshot Self-explanatory. +E: Read rerun dump file timestep > specified stop + +UNDOCUMENTED + */ diff --git a/src/special.cpp b/src/special.cpp index 4a37c3d798..7f863b229e 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -18,6 +18,7 @@ #include "atom_vec.h" #include "force.h" #include "comm.h" +#include "accelerator_kokkos.h" #include "memory.h" #include "error.h" @@ -572,9 +573,17 @@ void Special::combine() fprintf(logfile," %d = max # of special neighbors\n",atom->maxspecial); } - memory->destroy(atom->special); + if (lmp->kokkos) { + AtomKokkos* atomKK = (AtomKokkos*) atom; +#ifdef LMP_KOKKOS + memory->grow_kokkos(atomKK->k_special,atom->special, + atom->nmax,atom->maxspecial,"atom:special"); +#endif + } else { + memory->destroy(atom->special); + memory->create(atom->special,atom->nmax,atom->maxspecial,"atom:special"); + } - memory->create(atom->special,atom->nmax,atom->maxspecial,"atom:special"); atom->avec->grow_reset(); tagint **special = atom->special; diff --git a/src/thermo.h b/src/thermo.h index 17810932fd..cb0a8950e1 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -352,9 +352,9 @@ E: Thermo custom variable cannot be indexed Self-explanatory. -E: Invalid keyword in thermo_style custom command +E: Unknown keyword in thermo_style custom command -One or more specified keywords are not recognized. +UNDOCUMENTED E: This variable thermo keyword cannot be used between runs @@ -393,4 +393,8 @@ You are using a thermo keyword that requires potentials to have tallied energy, but they didn't on this timestep. See the variable doc page for ideas on how to make this work. +U: Invalid keyword in thermo_style custom command + +One or more specified keywords are not recognized. + */ diff --git a/src/variable.h b/src/variable.h index 703071da65..2ab3fa9693 100644 --- a/src/variable.h +++ b/src/variable.h @@ -166,6 +166,10 @@ E: Atomfile variable could not read values Check the file assigned to the variable. +E: LAMMPS is not built with Python embedded + +UNDOCUMENTED + E: Variable name must be alphanumeric or underscore characters Self-explanatory. @@ -187,6 +191,20 @@ E: Next command must list all universe and uloop variables This is to insure they stay in sync. +E: Variable has circular dependency + +A circular dependency is when variable "a" in used by variable "b" and +variable "b" is also used by varaible "a". Circular dependencies with +longer chains of dependence are also not allowed. + +E: Python variable does not match Python function + +UNDOCUMENTED + +E: Python variable has no function + +UNDOCUMENTED + E: Invalid syntax in variable formula Self-explanatory. @@ -254,12 +272,6 @@ E: Invalid variable name in variable formula Variable name is not recognized. -E: Variable has circular dependency - -A circular dependency is when variable "a" in used by variable "b" and -variable "b" is also used by varaible "a". Circular dependencies with -longer chains of dependence are also not allowed. - E: Invalid variable evaluation in variable formula A variable used in a formula could not be evaluated. @@ -319,6 +331,10 @@ E: Invalid math function in variable formula Self-explanatory. +E: Variable name between brackets must be alphanumeric or underscore characters + +UNDOCUMENTED + E: Non digit character between brackets in variable Self-explantory. @@ -399,6 +415,10 @@ an atom index, which is provided by an atom map. An atom map does not exist (by default) for non-molecular problems. Using the atom_modify map command will force an atom map to be created. +E: Variable atom ID is too large + +UNDOCUMENTED + E: Variable uses atom property that isn't allocated Self-explanatory. @@ -412,13 +432,9 @@ E: Atom vector in equal-style variable formula Atom vectors generate one value per atom which is not allowed in an equal-style variable. -E: Expected floating point parameter in variable definition +E: Too many args in variable function -The quantity being read is a non-numeric value. - -E: Expected integer parameter in variable definition - -The quantity being read is a floating point or non-numeric value. +UNDOCUMENTED E: Invalid Boolean syntax in if command @@ -437,4 +453,12 @@ E: Invalid atom ID in variable file Self-explanatory. +U: Expected floating point parameter in variable definition + +The quantity being read is a non-numeric value. + +U: Expected integer parameter in variable definition + +The quantity being read is a floating point or non-numeric value. + */ diff --git a/src/velocity.h b/src/velocity.h index fb109b449a..21530115cf 100644 --- a/src/velocity.h +++ b/src/velocity.h @@ -140,4 +140,12 @@ E: Fix ID for velocity does not exist Self-explanatory. +E: Cannot use velocity bias command without temp keyword + +UNDOCUMENTED + +E: Velocity temperature ID does calculate a velocity bias + +UNDOCUMENTED + */ diff --git a/src/version.h b/src/version.h index d3e40c8597..9f61924cdc 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "14 Mar 2015" +#define LAMMPS_VERSION "18 Mar 2015" diff --git a/src/write_dump.h b/src/write_dump.h index 7695d2117d..12742be1fc 100644 --- a/src/write_dump.h +++ b/src/write_dump.h @@ -43,7 +43,11 @@ Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. -E: Invalid dump style +E: Unknown dump style + +UNDOCUMENTED + +U: Invalid dump style The choice of dump style is unknown.