Merge branch 'develop' into collected-small-changes

This commit is contained in:
Axel Kohlmeyer
2023-10-13 04:59:18 -04:00
15 changed files with 1269 additions and 5 deletions

View File

@ -69,7 +69,7 @@ OPT.
* :doc:`drude/transform/inverse <fix_drude_transform>`
* :doc:`dt/reset (k) <fix_dt_reset>`
* :doc:`edpd/source <fix_dpd_source>`
* :doc:`efield <fix_efield>`
* :doc:`efield (k) <fix_efield>`
* :doc:`efield/tip4p <fix_efield>`
* :doc:`ehex <fix_ehex>`
* :doc:`electrode/conp (i) <fix_electrode>`
@ -233,7 +233,7 @@ OPT.
* :doc:`spring <fix_spring>`
* :doc:`spring/chunk <fix_spring_chunk>`
* :doc:`spring/rg <fix_spring_rg>`
* :doc:`spring/self <fix_spring_self>`
* :doc:`spring/self (k) <fix_spring_self>`
* :doc:`srd <fix_srd>`
* :doc:`store/force <fix_store_force>`
* :doc:`store/state <fix_store_state>`

View File

@ -305,5 +305,5 @@ OPT.
* :doc:`wf/cut <pair_wf_cut>`
* :doc:`ylz <pair_ylz>`
* :doc:`yukawa (gko) <pair_yukawa>`
* :doc:`yukawa/colloid (go) <pair_yukawa_colloid>`
* :doc:`yukawa/colloid (gko) <pair_yukawa_colloid>`
* :doc:`zbl (gko) <pair_zbl>`

View File

@ -1,4 +1,5 @@
.. index:: fix efield
.. index:: fix efield/kk
.. index:: fix efield/tip4p
fix efield command
@ -210,6 +211,12 @@ the iteration count during the minimization.
system (the quantity being minimized), you MUST enable the
:doc:`fix_modify <fix_modify>` *energy* option for this fix.
----------
.. include:: accel_styles.rst
----------
Restrictions
""""""""""""

View File

@ -1,4 +1,5 @@
.. index:: fix spring/self
.. index:: fix spring/self/kk
fix spring/self command
=======================
@ -80,6 +81,12 @@ invoked by the :doc:`minimize <minimize>` command.
you MUST enable the :doc:`fix_modify <fix_modify>` *energy* option for
this fix.
----------
.. include:: accel_styles.rst
----------
Restrictions
""""""""""""
none

View File

@ -1,11 +1,12 @@
.. index:: pair_style yukawa/colloid
.. index:: pair_style yukawa/colloid/gpu
.. index:: pair_style yukawa/colloid/kk
.. index:: pair_style yukawa/colloid/omp
pair_style yukawa/colloid command
=================================
Accelerator Variants: *yukawa/colloid/gpu*, *yukawa/colloid/omp*
Accelerator Variants: *yukawa/colloid/gpu*, *yukawa/colloid/kk*, *yukawa/colloid/omp*
Syntax
""""""
@ -131,6 +132,12 @@ per-type polydispersity is allowed. This means all particles of the
same type must have the same diameter. Each type can have a different
diameter.
----------
.. include:: accel_styles.rst
----------
Related commands
""""""""""""""""

View File

@ -129,6 +129,8 @@ action fix_dt_reset_kokkos.cpp
action fix_dt_reset_kokkos.h
action fix_enforce2d_kokkos.cpp
action fix_enforce2d_kokkos.h
action fix_efield_kokkos.cpp
action fix_efield_kokkos.h
action fix_eos_table_rx_kokkos.cpp fix_eos_table_rx.cpp
action fix_eos_table_rx_kokkos.h fix_eos_table_rx.h
action fix_freeze_kokkos.cpp fix_freeze.cpp
@ -173,6 +175,8 @@ action fix_shake_kokkos.cpp fix_shake.cpp
action fix_shake_kokkos.h fix_shake.h
action fix_shardlow_kokkos.cpp fix_shardlow.cpp
action fix_shardlow_kokkos.h fix_shardlow.h
action fix_spring_self_kokkos.cpp
action fix_spring_self_kokkos.h
action fix_viscous_kokkos.cpp
action fix_viscous_kokkos.h
action fix_wall_gran_kokkos.cpp fix_wall_gran.cpp
@ -363,6 +367,8 @@ action pair_vashishta_kokkos.cpp pair_vashishta.cpp
action pair_vashishta_kokkos.h pair_vashishta.h
action pair_yukawa_kokkos.cpp
action pair_yukawa_kokkos.h
action pair_yukawa_colloid_kokkos.cpp pair_yukawa_colloid.cpp
action pair_yukawa_colloid_kokkos.h pair_yukawa_colloid.h
action pair_zbl_kokkos.cpp
action pair_zbl_kokkos.h
action pppm_kokkos.cpp pppm.cpp

View File

@ -0,0 +1,316 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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: Trung Nguyen (U Chicago)
------------------------------------------------------------------------- */
#include "fix_efield_kokkos.h"
#include "atom_kokkos.h"
#include "update.h"
#include "modify.h"
#include "domain_kokkos.h"
#include "region.h"
#include "input.h"
#include "variable.h"
#include "memory_kokkos.h"
#include "error.h"
#include "atom_masks.h"
#include "kokkos_base.h"
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;
enum{NONE,CONSTANT,EQUAL,ATOM};
/* ---------------------------------------------------------------------- */
template<class DeviceType>
FixEfieldKokkos<DeviceType>::FixEfieldKokkos(LAMMPS *lmp, int narg, char **arg) :
FixEfield(lmp, narg, arg)
{
kokkosable = 1;
atomKK = (AtomKokkos *) atom;
execution_space = ExecutionSpaceFromDevice<DeviceType>::space;
datamask_read = EMPTY_MASK;
datamask_modify = EMPTY_MASK;
memory->destroy(efield);
memoryKK->create_kokkos(k_efield,efield,maxatom,4,"efield:efield");
d_efield = k_efield.view<DeviceType>();
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
FixEfieldKokkos<DeviceType>::~FixEfieldKokkos()
{
if (copymode) return;
memoryKK->destroy_kokkos(k_efield,efield);
efield = nullptr;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixEfieldKokkos<DeviceType>::init()
{
FixEfield::init();
if (utils::strmatch(update->integrate_style,"^respa"))
error->all(FLERR,"Cannot (yet) use respa with Kokkos");
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixEfieldKokkos<DeviceType>::post_force(int /*vflag*/)
{
atomKK->sync(execution_space, X_MASK | F_MASK | Q_MASK | IMAGE_MASK | MASK_MASK);
x = atomKK->k_x.view<DeviceType>();
f = atomKK->k_f.view<DeviceType>();
q = atomKK->k_q.view<DeviceType>();
image = atomKK->k_image.view<DeviceType>();
mask = atomKK->k_mask.view<DeviceType>();
int nlocal = atom->nlocal;
// update region if necessary
if (region) {
if (!utils::strmatch(region->style, "^block"))
error->all(FLERR,"Cannot (yet) use {}-style region with fix efield/kk",region->style);
region->prematch();
DAT::tdual_int_1d k_match = DAT::tdual_int_1d("efield:k_match",nlocal);
KokkosBase* regionKKBase = dynamic_cast<KokkosBase*>(region);
regionKKBase->match_all_kokkos(groupbit,k_match);
k_match.template sync<DeviceType>();
d_match = k_match.template view<DeviceType>();
}
// reallocate sforce array if necessary
if (varflag == ATOM && atom->nmax > maxatom) {
maxatom = atom->nmax;
memoryKK->destroy_kokkos(k_efield,efield);
memoryKK->create_kokkos(k_efield,efield,maxatom,4,"efield:efield");
d_efield = k_efield.view<DeviceType>();
}
fsum[0] = fsum[1] = fsum[2] = fsum[3] = 0.0;
double_4 fsum_kk;
force_flag = 0;
if (varflag == CONSTANT) {
copymode = 1;
// It would be more concise to use the operators below, but there is still an issue with unwrap (TODO below)
//Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagFixEfieldConstant>(0,nlocal),*this,fsum_kk);
{
// local variables for lambda capture
auto prd = Few<double,3>(domain->prd);
auto h = Few<double,6>(domain->h);
auto triclinic = domain->triclinic;
auto l_ex = ex;
auto l_ey = ey;
auto l_ez = ez;
auto l_x = x;
auto l_q = q;
auto l_f = f;
auto l_mask = mask;
auto l_image = image;
auto l_groupbit = groupbit;
Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(const int& i, double_4& fsum_kk) {
if (l_mask[i] & l_groupbit) {
Few<double,3> x_i;
x_i[0] = l_x(i,0);
x_i[1] = l_x(i,1);
x_i[2] = l_x(i,2);
auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,l_image(i));
auto qtmp = l_q(i);
auto fx = qtmp * l_ex;
auto fy = qtmp * l_ey;
auto fz = qtmp * l_ez;
l_f(i,0) += fx;
l_f(i,1) += fy;
l_f(i,2) += fz;
fsum_kk.d0 -= fx * unwrap[0] + fy * unwrap[1] + fz * unwrap[2];
fsum_kk.d1 += fx;
fsum_kk.d2 += fy;
fsum_kk.d3 += fz;
}
},fsum_kk);
}
copymode = 0;
// variable force, wrap with clear/add
} else {
atomKK->sync(Host,ALL_MASK); // this can be removed when variable class is ported to Kokkos
modify->clearstep_compute();
if (xstyle == EQUAL) ex = input->variable->compute_equal(xvar);
else if (xstyle == ATOM)
input->variable->compute_atom(xvar,igroup,&efield[0][0],4,0);
if (ystyle == EQUAL) ey = input->variable->compute_equal(yvar);
else if (ystyle == ATOM)
input->variable->compute_atom(yvar,igroup,&efield[0][1],4,0);
if (zstyle == EQUAL) ez = input->variable->compute_equal(zvar);
else if (zstyle == ATOM)
input->variable->compute_atom(zvar,igroup,&efield[0][2],4,0);
modify->addstep_compute(update->ntimestep + 1);
if (varflag == ATOM) { // this can be removed when variable class is ported to Kokkos
k_efield.modify<LMPHostType>();
k_efield.sync<DeviceType>();
}
copymode = 1;
// It would be more concise to use the operators below, but there is still an issue with unwrap (TODO below)
//Kokkos::parallel_reduce(Kokkos::RangePolicy<DeviceType, TagFixEfieldNonConstant>(0,nlocal),*this,fsum_kk);
{
// local variables for lambda capture
auto prd = Few<double,3>(domain->prd);
auto h = Few<double,6>(domain->h);
auto triclinic = domain->triclinic;
auto l_ex = ex;
auto l_ey = ey;
auto l_ez = ez;
auto l_d_efield = d_efield;
auto l_x = x;
auto l_q = q;
auto l_f = f;
auto l_mask = mask;
auto l_image = image;
auto l_groupbit = groupbit;
auto l_xstyle = xstyle;
auto l_ystyle = ystyle;
auto l_zstyle = zstyle;
Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(const int& i, double_4& fsum_kk) {
if (l_mask[i] & l_groupbit) {
Few<double,3> x_i;
x_i[0] = l_x(i,0);
x_i[1] = l_x(i,1);
x_i[2] = l_x(i,2);
auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,l_image(i));
auto qtmp = l_q(i);
auto fx = qtmp * l_ex;
auto fy = qtmp * l_ey;
auto fz = qtmp * l_ez;
if (l_xstyle == ATOM) l_f(i,0) += qtmp * l_d_efield(i,0);
else if (l_xstyle) l_f(i,0) += fx;
if (l_ystyle == ATOM) l_f(i,1) += qtmp * l_d_efield(i,1);
else if (l_ystyle) l_f(i,1) += fy;
if (l_zstyle == ATOM) l_f(i,2) += qtmp * l_d_efield(i,2);
else if (l_zstyle) l_f(i,2) += fz;
fsum_kk.d0 -= fx * unwrap[0] + fy * unwrap[1] + fz * unwrap[2];
fsum_kk.d1 += fx;
fsum_kk.d2 += fy;
fsum_kk.d3 += fz;
}
},fsum_kk);
}
copymode = 0;
}
atomKK->modified(execution_space, F_MASK);
fsum[0] = fsum_kk.d0;
fsum[1] = fsum_kk.d1;
fsum[2] = fsum_kk.d2;
fsum[3] = fsum_kk.d3;
}
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void FixEfieldKokkos<DeviceType>::operator()(TagFixEfieldConstant, const int &i, double_4& fsum_kk) const {
if (mask[i] & groupbit) {
if (region && !d_match[i]) return;
auto prd = Few<double,3>(domain->prd);
auto h = Few<double,6>(domain->h);
auto triclinic = domain->triclinic;
Few<double,3> x_i;
x_i[0] = x(i,0);
x_i[1] = x(i,1);
x_i[2] = x(i,2);
auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,image(i));
const F_FLOAT qtmp = q(i);
const F_FLOAT fx = qtmp * ex;
const F_FLOAT fy = qtmp * ey;
const F_FLOAT fz = qtmp * ez;
f(i,0) += fx;
f(i,1) += fy;
f(i,2) += fz;
// TODO: access to unwrap below crashes
fsum_kk.d0 -= fx * unwrap[0] + fy * unwrap[1] + fz * unwrap[2];
fsum_kk.d1 += fx;
fsum_kk.d2 += fy;
fsum_kk.d3 += fz;
}
}
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void FixEfieldKokkos<DeviceType>::operator()(TagFixEfieldNonConstant, const int &i, double_4& fsum_kk) const {
auto prd = Few<double,3>(domain->prd);
auto h = Few<double,6>(domain->h);
auto triclinic = domain->triclinic;
if (mask[i] & groupbit) {
if (region && !d_match[i]) return;
Few<double,3> x_i;
x_i[0] = x(i,0);
x_i[1] = x(i,1);
x_i[2] = x(i,2);
auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,image(i));
const F_FLOAT qtmp = q[i];
const F_FLOAT fx = qtmp * ex;
const F_FLOAT fy = qtmp * ey;
const F_FLOAT fz = qtmp * ez;
if (xstyle == ATOM) f(i,0) += d_efield(i,0);
else if (xstyle) f(i,0) += fx;
if (ystyle == ATOM) f(i,1) += d_efield(i,1);
else if (ystyle) f(i,1) += fy;
if (zstyle == ATOM) f(i,2) += d_efield(i,2);
else if (zstyle) f(i,2) += fz;
// TODO: access to unwrap below crashes
fsum_kk.d0 -= fx * unwrap[0] + fy * unwrap[1] + fz * unwrap[2];
fsum_kk.d1 += fx;
fsum_kk.d2 += fy;
fsum_kk.d3 += fz;
}
}
namespace LAMMPS_NS {
template class FixEfieldKokkos<LMPDeviceType>;
#ifdef LMP_KOKKOS_GPU
template class FixEfieldKokkos<LMPHostType>;
#endif
}

View File

@ -0,0 +1,86 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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 FIX_CLASS
// clang-format off
FixStyle(efield/kk,FixEfieldKokkos<LMPDeviceType>);
FixStyle(efield/kk/device,FixEfieldKokkos<LMPDeviceType>);
FixStyle(efield/kk/host,FixEfieldKokkos<LMPHostType>);
// clang-format on
#else
// clang-format off
#ifndef LMP_FIX_EFIELD_KOKKOS_H
#define LMP_FIX_EFIELD_KOKKOS_H
#include "fix_efield.h"
#include "kokkos_type.h"
namespace LAMMPS_NS {
struct e_double_4 {
double d0, d1, d2, d3;
KOKKOS_INLINE_FUNCTION
e_double_4() {
d0 = d1 = d2 = d3 = 0.0;
}
KOKKOS_INLINE_FUNCTION
e_double_4& operator+=(const e_double_4 &rhs) {
d0 += rhs.d0;
d1 += rhs.d1;
d2 += rhs.d2;
d3 += rhs.d3;
return *this;
}
};
typedef e_double_4 double_4;
struct TagFixEfieldConstant{};
struct TagFixEfieldNonConstant{};
template<class DeviceType>
class FixEfieldKokkos : public FixEfield {
public:
typedef DeviceType device_type;
typedef double_4 value_type;
typedef ArrayTypes<DeviceType> AT;
FixEfieldKokkos(class LAMMPS *, int, char **);
~FixEfieldKokkos() override;
void init() override;
void post_force(int) override;
KOKKOS_INLINE_FUNCTION
void operator()(TagFixEfieldConstant, const int&, double_4&) const;
KOKKOS_INLINE_FUNCTION
void operator()(TagFixEfieldNonConstant, const int&, double_4&) const;
private:
DAT::tdual_ffloat_2d k_efield;
typename AT::t_ffloat_2d_randomread d_efield;
typename AT::t_int_1d d_match;
typename AT::t_x_array_randomread x;
typename AT::t_float_1d_randomread q;
typename AT::t_f_array f;
typename AT::t_imageint_1d_randomread image;
typename AT::t_int_1d_randomread mask;
};
}
#endif
#endif

View File

@ -0,0 +1,332 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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: Trung Nguyen (U Chicago)
------------------------------------------------------------------------- */
#include "fix_spring_self_kokkos.h"
#include "atom_kokkos.h"
#include "update.h"
#include "modify.h"
#include "domain_kokkos.h"
#include "region.h"
#include "input.h"
#include "variable.h"
#include "memory_kokkos.h"
#include "error.h"
#include "atom_masks.h"
#include "kokkos_base.h"
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
template<class DeviceType>
FixSpringSelfKokkos<DeviceType>::FixSpringSelfKokkos(LAMMPS *lmp, int narg, char **arg) :
FixSpringSelf(lmp, narg, arg)
{
kokkosable = 1;
exchange_comm_device = 1;
atomKK = (AtomKokkos *) atom;
execution_space = ExecutionSpaceFromDevice<DeviceType>::space;
datamask_read = EMPTY_MASK;
datamask_modify = EMPTY_MASK;
xoriginal_tmp = xoriginal;
xoriginal = nullptr;
int nmax = atom->nmax;
grow_arrays(nmax);
for (int i = 0; i < atom->nlocal; i++) {
k_xoriginal.h_view(i,0) = xoriginal_tmp[i][0];
k_xoriginal.h_view(i,1) = xoriginal_tmp[i][1];
k_xoriginal.h_view(i,2) = xoriginal_tmp[i][2];
}
k_xoriginal.modify_host();
d_count = typename AT::t_int_scalar("spring/self:count");
h_count = Kokkos::create_mirror_view(d_count);
memory->destroy(xoriginal_tmp);
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
FixSpringSelfKokkos<DeviceType>::~FixSpringSelfKokkos()
{
if (copymode) return;
memoryKK->destroy_kokkos(k_xoriginal,xoriginal);
xoriginal = nullptr;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixSpringSelfKokkos<DeviceType>::init()
{
FixSpringSelf::init();
if (utils::strmatch(update->integrate_style,"^respa"))
error->all(FLERR,"Cannot (yet) use respa with Kokkos");
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void FixSpringSelfKokkos<DeviceType>::post_force(int /*vflag*/)
{
atomKK->sync(execution_space, X_MASK | F_MASK | IMAGE_MASK | MASK_MASK);
x = atomKK->k_x.view<DeviceType>();
f = atomKK->k_f.view<DeviceType>();
image = atomKK->k_image.view<DeviceType>();
mask = atomKK->k_mask.view<DeviceType>();
int nlocal = atom->nlocal;
double espring_kk;
k_xoriginal.modify<LMPHostType>();
k_xoriginal.sync<DeviceType>();
copymode = 1;
{
// local variables for lambda capture
auto prd = Few<double,3>(domain->prd);
auto h = Few<double,6>(domain->h);
auto triclinic = domain->triclinic;
auto l_k = k;
auto l_xoriginal = d_xoriginal;
auto l_x = x;
auto l_f = f;
auto l_mask = mask;
auto l_image = image;
auto l_groupbit = groupbit;
auto l_xflag = xflag;
auto l_yflag = yflag;
auto l_zflag = zflag;
Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(const int& i, double& espring_kk) {
if (l_mask[i] & l_groupbit) {
Few<double,3> x_i;
x_i[0] = l_x(i,0);
x_i[1] = l_x(i,1);
x_i[2] = l_x(i,2);
auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,l_image(i));
auto dx = unwrap[0] - l_xoriginal(i, 0);
auto dy = unwrap[1] - l_xoriginal(i, 1);
auto dz = unwrap[2] - l_xoriginal(i, 2);
if (!l_xflag) dx = 0.0;
if (!l_yflag) dy = 0.0;
if (!l_zflag) dz = 0.0;
l_f(i,0) -= l_k*dx;
l_f(i,1) -= l_k*dy;
l_f(i,2) -= l_k*dz;
espring_kk += l_k * (dx*dx + dy*dy + dz*dz);
}
},espring_kk);
}
copymode = 0;
atomKK->modified(execution_space, F_MASK);
espring = 0.5*espring_kk;
}
/* ----------------------------------------------------------------------
allocate local atom-based arrays
------------------------------------------------------------------------- */
template<class DeviceType>
void FixSpringSelfKokkos<DeviceType>::grow_arrays(int nmax)
{
memoryKK->grow_kokkos(k_xoriginal,xoriginal,nmax,"spring/self:xoriginal");
d_xoriginal = k_xoriginal.view<DeviceType>();
}
/* ----------------------------------------------------------------------
copy values within local atom-based arrays
------------------------------------------------------------------------- */
template<class DeviceType>
void FixSpringSelfKokkos<DeviceType>::copy_arrays(int i, int j, int delflag)
{
k_xoriginal.sync_host();
FixSpringSelf::copy_arrays(i,j,delflag);
k_xoriginal.modify_host();
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void FixSpringSelfKokkos<DeviceType>::pack_exchange_item(const int &mysend, int &offset, const bool &final) const
{
const int i = d_exchange_sendlist(mysend);
d_buf[mysend] = nsend + offset;
int m = nsend + offset;
d_buf[m++] = d_xoriginal(i,0);
d_buf[m++] = d_xoriginal(i,1);
d_buf[m++] = d_xoriginal(i,2);
if (mysend == nsend-1) d_count() = m;
offset = m - nsend;
const int j = d_copylist(mysend);
if (j > -1) {
d_xoriginal(i,0) = d_xoriginal(j,0);
d_xoriginal(i,1) = d_xoriginal(j,1);
d_xoriginal(i,2) = d_xoriginal(j,2);
}
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
int FixSpringSelfKokkos<DeviceType>::pack_exchange_kokkos(
const int &nsend, DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d k_exchange_sendlist, DAT::tdual_int_1d k_copylist,
ExecutionSpace space)
{
k_buf.sync<DeviceType>();
k_copylist.sync<DeviceType>();
k_exchange_sendlist.sync<DeviceType>();
d_buf = typename ArrayTypes<DeviceType>::t_xfloat_1d_um(
k_buf.template view<DeviceType>().data(),
k_buf.extent(0)*k_buf.extent(1));
d_copylist = k_copylist.view<DeviceType>();
d_exchange_sendlist = k_exchange_sendlist.view<DeviceType>();
this->nsend = nsend;
k_xoriginal.template sync<DeviceType>();
Kokkos::deep_copy(d_count,0);
copymode = 1;
FixSpringSelfKokkosPackExchangeFunctor<DeviceType> pack_exchange_functor(this);
Kokkos::parallel_scan(nsend,pack_exchange_functor);
copymode = 0;
k_buf.modify<DeviceType>();
if (space == Host) k_buf.sync<LMPHostType>();
else k_buf.sync<LMPDeviceType>();
k_xoriginal.template modify<DeviceType>();
Kokkos::deep_copy(h_count,d_count);
return h_count();
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void FixSpringSelfKokkos<DeviceType>::operator()(TagFixSpringSelfUnpackExchange, const int &i) const
{
int index = d_indices(i);
if (index > -1) {
int m = d_buf[i];
d_xoriginal(index,0) = static_cast<tagint> (d_buf[m++]);
d_xoriginal(index,1) = static_cast<tagint> (d_buf[m++]);
d_xoriginal(index,2) = static_cast<tagint> (d_buf[m++]);
}
}
/* ---------------------------------------------------------------------- */
template <class DeviceType>
void FixSpringSelfKokkos<DeviceType>::unpack_exchange_kokkos(
DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d &k_indices, int nrecv,
ExecutionSpace /*space*/)
{
k_buf.sync<DeviceType>();
k_indices.sync<DeviceType>();
d_buf = typename ArrayTypes<DeviceType>::t_xfloat_1d_um(
k_buf.template view<DeviceType>().data(),
k_buf.extent(0)*k_buf.extent(1));
d_indices = k_indices.view<DeviceType>();
k_xoriginal.template sync<DeviceType>();
copymode = 1;
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType,TagFixSpringSelfUnpackExchange>(0,nrecv),*this);
copymode = 0;
k_xoriginal.template modify<DeviceType>();
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for exchange with another proc
------------------------------------------------------------------------- */
template<class DeviceType>
int FixSpringSelfKokkos<DeviceType>::pack_exchange(int i, double *buf)
{
k_xoriginal.sync_host();
int m = FixSpringSelf::pack_exchange(i,buf);
k_xoriginal.modify_host();
return m;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based arrays from exchange with another proc
------------------------------------------------------------------------- */
template<class DeviceType>
int FixSpringSelfKokkos<DeviceType>::unpack_exchange(int nlocal, double *buf)
{
k_xoriginal.sync_host();
int m = FixSpringSelf::unpack_exchange(nlocal,buf);
k_xoriginal.modify_host();
return m;
}
namespace LAMMPS_NS {
template class FixSpringSelfKokkos<LMPDeviceType>;
#ifdef LMP_KOKKOS_GPU
template class FixSpringSelfKokkos<LMPHostType>;
#endif
}

View File

@ -0,0 +1,108 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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 FIX_CLASS
// clang-format off
FixStyle(spring/self/kk,FixSpringSelfKokkos<LMPDeviceType>);
FixStyle(spring/self/kk/device,FixSpringSelfKokkos<LMPDeviceType>);
FixStyle(spring/self/kk/host,FixSpringSelfKokkos<LMPHostType>);
// clang-format on
#else
// clang-format off
#ifndef LMP_FIX_SPRING_SELF_KOKKOS_H
#define LMP_FIX_SPRING_SELF_KOKKOS_H
#include "fix_spring_self.h"
#include "kokkos_type.h"
#include "kokkos_base.h"
namespace LAMMPS_NS {
struct TagFixSpringSelfUnpackExchange{};
template<class DeviceType>
class FixSpringSelfKokkos : public FixSpringSelf, public KokkosBase {
public:
typedef DeviceType device_type;
typedef double value_type;
typedef ArrayTypes<DeviceType> AT;
FixSpringSelfKokkos(class LAMMPS *, int, char **);
~FixSpringSelfKokkos() override;
void init() override;
void grow_arrays(int) override;
void copy_arrays(int, int, int) override;
void post_force(int) override;
KOKKOS_INLINE_FUNCTION
void pack_exchange_item(const int&, int &, const bool &) const;
KOKKOS_INLINE_FUNCTION
void operator()(TagFixSpringSelfUnpackExchange, const int&) const;
int pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf,
DAT::tdual_int_1d k_sendlist,
DAT::tdual_int_1d k_copylist,
ExecutionSpace space) override;
void unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,
DAT::tdual_int_1d &indices,int nrecv,
ExecutionSpace space) override;
int pack_exchange(int, double *) override;
int unpack_exchange(int, double *) override;
protected:
DAT::tdual_x_array k_xoriginal;
typename AT::t_x_array d_xoriginal;
typename AT::t_x_array_randomread x;
typename AT::t_f_array f;
typename AT::t_imageint_1d_randomread image;
typename AT::t_int_1d_randomread mask;
int nsend;
typename AT::t_int_2d d_sendlist;
typename AT::t_xfloat_1d_um d_buf;
typename AT::t_int_1d d_exchange_sendlist;
typename AT::t_int_1d d_copylist;
typename AT::t_int_1d d_indices;
typename AT::t_int_scalar d_count;
HAT::t_int_scalar h_count;
double **xoriginal_tmp; // original coords of atoms
};
template <class DeviceType>
struct FixSpringSelfKokkosPackExchangeFunctor {
typedef DeviceType device_type;
typedef int value_type;
FixSpringSelfKokkos<DeviceType> c;
FixSpringSelfKokkosPackExchangeFunctor(FixSpringSelfKokkos<DeviceType>* c_ptr):c(*c_ptr) {};
KOKKOS_INLINE_FUNCTION
void operator()(const int &i, int &offset, const bool &final) const {
c.pack_exchange_item(i, offset, final);
}
};
}
#endif
#endif

View File

@ -0,0 +1,270 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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: Trung Nguyen (U Chicago)
------------------------------------------------------------------------- */
#include "pair_yukawa_colloid_kokkos.h"
#include "atom_kokkos.h"
#include "atom_masks.h"
#include "error.h"
#include "force.h"
#include "kokkos.h"
#include "memory_kokkos.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h"
#include "respa.h"
#include "update.h"
#include <cmath>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
template<class DeviceType>
PairYukawaColloidKokkos<DeviceType>::PairYukawaColloidKokkos(LAMMPS *lmp) : PairYukawaColloid(lmp)
{
respa_enable = 0;
kokkosable = 1;
atomKK = (AtomKokkos *) atom;
execution_space = ExecutionSpaceFromDevice<DeviceType>::space;
datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | RADIUS_MASK;
datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
PairYukawaColloidKokkos<DeviceType>::~PairYukawaColloidKokkos()
{
if (copymode) return;
if (allocated) {
memoryKK->destroy_kokkos(k_eatom,eatom);
memoryKK->destroy_kokkos(k_vatom,vatom);
memoryKK->destroy_kokkos(k_cutsq,cutsq);
}
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
template<class DeviceType>
void PairYukawaColloidKokkos<DeviceType>::allocate()
{
PairYukawaColloid::allocate();
int n = atom->ntypes;
memory->destroy(cutsq);
memoryKK->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq");
d_cutsq = k_cutsq.template view<DeviceType>();
k_params = Kokkos::DualView<params_yukawa**,
Kokkos::LayoutRight,DeviceType>(
"PairYukawaColloid::params",n+1,n+1);
params = k_params.template view<DeviceType>();
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
template<class DeviceType>
void PairYukawaColloidKokkos<DeviceType>::init_style()
{
PairYukawaColloid::init_style();
// error if rRESPA with inner levels
if (update->whichflag == 1 && utils::strmatch(update->integrate_style,"^respa")) {
int respa = 0;
if (((Respa *) update->integrate)->level_inner >= 0) respa = 1;
if (((Respa *) update->integrate)->level_middle >= 0) respa = 2;
if (respa)
error->all(FLERR,"Cannot use Kokkos pair style with rRESPA inner/middle");
}
// adjust neighbor list request for KOKKOS
neighflag = lmp->kokkos->neighflag;
auto request = neighbor->find_request(this);
request->set_kokkos_host(std::is_same<DeviceType,LMPHostType>::value &&
!std::is_same<DeviceType,LMPDeviceType>::value);
request->set_kokkos_device(std::is_same<DeviceType,LMPDeviceType>::value);
if (neighflag == FULL) request->enable_full();
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
// Rewrite this.
template<class DeviceType>
double PairYukawaColloidKokkos<DeviceType>::init_one(int i, int j)
{
double cutone = PairYukawaColloid::init_one(i,j);
k_params.h_view(i,j).a = a[i][j];
k_params.h_view(i,j).offset = offset[i][j];
k_params.h_view(i,j).cutsq = cutone*cutone;
k_params.h_view(j,i) = k_params.h_view(i,j);
if (i<MAX_TYPES_STACKPARAMS+1 && j<MAX_TYPES_STACKPARAMS+1) {
m_params[i][j] = m_params[j][i] = k_params.h_view(i,j);
m_cutsq[j][i] = m_cutsq[i][j] = cutone*cutone;
}
k_cutsq.h_view(i,j) = k_cutsq.h_view(j,i) = cutone*cutone;
k_cutsq.template modify<LMPHostType>();
k_params.template modify<LMPHostType>();
return cutone;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void PairYukawaColloidKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
{
eflag = eflag_in;
vflag = vflag_in;
if (neighflag == FULL) no_virial_fdotr_compute = 1;
ev_init(eflag,vflag,0);
// reallocate per-atom arrays if necessary
if (eflag_atom) {
memoryKK->destroy_kokkos(k_eatom,eatom);
memoryKK->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom");
d_eatom = k_eatom.view<DeviceType>();
}
if (vflag_atom) {
memoryKK->destroy_kokkos(k_vatom,vatom);
memoryKK->create_kokkos(k_vatom,vatom,maxvatom,"pair:vatom");
d_vatom = k_vatom.view<DeviceType>();
}
atomKK->sync(execution_space,datamask_read);
k_cutsq.template sync<DeviceType>();
k_params.template sync<DeviceType>();
if (eflag || vflag) atomKK->modified(execution_space,datamask_modify);
else atomKK->modified(execution_space,F_MASK);
x = atomKK->k_x.view<DeviceType>();
c_x = atomKK->k_x.view<DeviceType>();
f = atomKK->k_f.view<DeviceType>();
type = atomKK->k_type.view<DeviceType>();
radius = atomKK->k_radius.view<DeviceType>();
nlocal = atom->nlocal;
nall = atom->nlocal + atom->nghost;
newton_pair = force->newton_pair;
special_lj[0] = force->special_lj[0];
special_lj[1] = force->special_lj[1];
special_lj[2] = force->special_lj[2];
special_lj[3] = force->special_lj[3];
// loop over neighbors of my atoms
EV_FLOAT ev = pair_compute<PairYukawaColloidKokkos<DeviceType>,void >(
this,(NeighListKokkos<DeviceType>*)list);
if (eflag_global) eng_vdwl += 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 (vflag_fdotr) pair_virial_fdotr_compute(this);
if (eflag_atom) {
k_eatom.template modify<DeviceType>();
k_eatom.template sync<LMPHostType>();
}
if (vflag_atom) {
k_vatom.template modify<DeviceType>();
k_vatom.template sync<LMPHostType>();
}
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
template<bool STACKPARAMS, class Specialisation>
KOKKOS_INLINE_FUNCTION
F_FLOAT PairYukawaColloidKokkos<DeviceType>::
compute_fpair(const F_FLOAT& rsq, const int& i, const int&j,
const int& itype, const int& jtype) const {
(void) i;
(void) j;
const F_FLOAT radi = radius[i];
const F_FLOAT radj = radius[j];
const F_FLOAT rr = sqrt(rsq);
// Fetch the params either off the stack or from some mapped memory?
const F_FLOAT aa = STACKPARAMS ? m_params[itype][jtype].a
: params(itype,jtype).a;
// U = a * exp(-kappa*(r-(radi+radj))) / kappa
// f = -dU/dr = a * exp(-kappa*r)
// f/r = a * exp(-kappa*r) / r
const F_FLOAT rinv = 1.0 / rr;
const F_FLOAT screening = exp(-kappa*(rr-(radi+radj)));
const F_FLOAT forceyukawa = aa * screening;
const F_FLOAT fpair = forceyukawa * rinv;
return fpair;
}
template<class DeviceType>
template<bool STACKPARAMS, class Specialisation>
KOKKOS_INLINE_FUNCTION
F_FLOAT PairYukawaColloidKokkos<DeviceType>::
compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j,
const int& itype, const int& jtype) const {
(void) i;
(void) j;
const F_FLOAT radi = radius[i];
const F_FLOAT radj = radius[j];
const F_FLOAT rr = sqrt(rsq);
const F_FLOAT aa = STACKPARAMS ? m_params[itype][jtype].a
: params(itype,jtype).a;
const F_FLOAT offset = STACKPARAMS ? m_params[itype][jtype].offset
: params(itype,jtype).offset;
// U = a * exp(-kappa*(r-(radi+radj))) / kappa
const F_FLOAT rinv = 1.0 / rr;
const F_FLOAT screening = exp(-kappa*(rr-(radi+radj)));
return aa / kappa * screening - offset;
}
namespace LAMMPS_NS {
template class PairYukawaColloidKokkos<LMPDeviceType>;
#ifdef LMP_KOKKOS_GPU
template class PairYukawaColloidKokkos<LMPHostType>;
#endif
}

View File

@ -0,0 +1,121 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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 PAIR_CLASS
// clang-format off
PairStyle(yukawa/colloid/kk,PairYukawaColloidKokkos<LMPDeviceType>);
PairStyle(yukawa/colloid/kk/device,PairYukawaColloidKokkos<LMPDeviceType>);
PairStyle(yukawa/colloid/kk/host,PairYukawaColloidKokkos<LMPHostType>);
// clang-format on
#else
// clang-format off
#ifndef LMP_PAIR_YUKAWA_COLLOID_KOKKOS_H
#define LMP_PAIR_YUKAWA_COLLOID_KOKKOS_H
#include "pair_kokkos.h"
#include "pair_yukawa_colloid.h"
#include "neigh_list_kokkos.h"
namespace LAMMPS_NS {
template<class DeviceType>
class PairYukawaColloidKokkos : public PairYukawaColloid {
public:
enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF};
enum {COUL_FLAG=0};
typedef DeviceType device_type;
typedef ArrayTypes<DeviceType> AT;
PairYukawaColloidKokkos(class LAMMPS *);
~PairYukawaColloidKokkos() override;
void compute(int, int) override;
void init_style() override;
double init_one(int,int) override;
struct params_yukawa {
KOKKOS_INLINE_FUNCTION
params_yukawa() { cutsq=0, a = 0; offset = 0; }
KOKKOS_INLINE_FUNCTION
params_yukawa(int /*i*/) { cutsq=0, a = 0; offset = 0; }
F_FLOAT cutsq, a, offset;
};
protected:
template<bool STACKPARAMS, class Specialisation>
KOKKOS_INLINE_FUNCTION
F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j,
const int& itype, const int& jtype) const;
template<bool STACKPARAMS, class Specialisation>
KOKKOS_INLINE_FUNCTION
F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j,
const int& itype, const int& jtype) const;
template<bool STACKPARAMS, class Specialisation>
KOKKOS_INLINE_FUNCTION
F_FLOAT compute_ecoul(const F_FLOAT& /*rsq*/, const int& /*i*/, const int& /*j*/,
const int& /*itype*/, const int& /*jtype*/) const { return 0; }
Kokkos::DualView<params_yukawa**,Kokkos::LayoutRight,DeviceType> k_params;
typename Kokkos::DualView<params_yukawa**,Kokkos::LayoutRight,DeviceType>::t_dev_const_um params;
params_yukawa m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1];
F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1];
typename AT::t_x_array_randomread x;
typename AT::t_x_array c_x;
typename AT::t_f_array f;
typename AT::t_int_1d_randomread type;
typename AT::t_float_1d_randomread radius;
DAT::tdual_efloat_1d k_eatom;
DAT::tdual_virial_array k_vatom;
typename AT::t_efloat_1d d_eatom;
typename AT::t_virial_array d_vatom;
int newton_pair;
double special_lj[4];
typename AT::tdual_ffloat_2d k_cutsq;
typename AT::t_ffloat_2d d_cutsq;
int neighflag;
int nlocal,nall,eflag,vflag;
void allocate() override;
friend struct PairComputeFunctor<PairYukawaColloidKokkos,FULL,true>;
friend struct PairComputeFunctor<PairYukawaColloidKokkos,HALF,true>;
friend struct PairComputeFunctor<PairYukawaColloidKokkos,HALFTHREAD,true>;
friend struct PairComputeFunctor<PairYukawaColloidKokkos,FULL,false>;
friend struct PairComputeFunctor<PairYukawaColloidKokkos,HALF,false>;
friend struct PairComputeFunctor<PairYukawaColloidKokkos,HALFTHREAD,false>;
friend EV_FLOAT pair_compute_neighlist<PairYukawaColloidKokkos,FULL,void>(
PairYukawaColloidKokkos*,NeighListKokkos<DeviceType>*);
friend EV_FLOAT pair_compute_neighlist<PairYukawaColloidKokkos,HALF,void>(
PairYukawaColloidKokkos*,NeighListKokkos<DeviceType>*);
friend EV_FLOAT pair_compute_neighlist<PairYukawaColloidKokkos,HALFTHREAD,void>(
PairYukawaColloidKokkos*,NeighListKokkos<DeviceType>*);
friend EV_FLOAT pair_compute<PairYukawaColloidKokkos,void>(
PairYukawaColloidKokkos*,NeighListKokkos<DeviceType>*);
friend void pair_virial_fdotr_compute<PairYukawaColloidKokkos>(PairYukawaColloidKokkos*);
};
}
#endif
#endif

View File

@ -129,6 +129,8 @@ FixEfield::FixEfield(LAMMPS *lmp, int narg, char **arg) :
FixEfield::~FixEfield()
{
if (copymode) return;
delete[] xstr;
delete[] ystr;
delete[] zstr;

View File

@ -96,6 +96,8 @@ FixSpringSelf::FixSpringSelf(LAMMPS *lmp, int narg, char **arg) :
FixSpringSelf::~FixSpringSelf()
{
if (copymode) return;
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,Atom::GROW);

View File

@ -47,7 +47,7 @@ class FixSpringSelf : public Fix {
int size_restart(int) override;
int maxsize_restart() override;
private:
protected:
double k, espring;
double **xoriginal; // original coords of atoms
int xflag, yflag, zflag;