257 lines
8.5 KiB
C++
257 lines
8.5 KiB
C++
/* -*- 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.
|
|
------------------------------------------------------------------------- */
|
|
|
|
#ifndef LMP_KSPACE_H
|
|
#define LMP_KSPACE_H
|
|
|
|
#include "pointers.h" // IWYU pragma: export
|
|
|
|
namespace LAMMPS_NS {
|
|
|
|
class KSpace : protected Pointers {
|
|
friend class ThrOMP;
|
|
friend class FixOMP;
|
|
|
|
public:
|
|
enum {
|
|
REVERSE_RHO,
|
|
REVERSE_RHO_GEOM,
|
|
REVERSE_RHO_ARITH,
|
|
REVERSE_RHO_NONE,
|
|
REVERSE_RHO_GPU,
|
|
REVERSE_RHO_G,
|
|
REVERSE_RHO_A,
|
|
REVERSE_AD,
|
|
REVERSE_AD_PERATOM,
|
|
REVERSE_MU,
|
|
REVERSE_MU_PERATOM
|
|
};
|
|
enum {
|
|
FORWARD_RHO,
|
|
FORWARD_IK,
|
|
FORWARD_AD,
|
|
FORWARD_MU,
|
|
FORWARD_IK_PERATOM,
|
|
FORWARD_AD_PERATOM,
|
|
FORWARD_MU_PERATOM,
|
|
FORWARD_IK_GEOM,
|
|
FORWARD_AD_GEOM,
|
|
FORWARD_IK_PERATOM_GEOM,
|
|
FORWARD_AD_PERATOM_GEOM,
|
|
FORWARD_IK_ARITH,
|
|
FORWARD_AD_ARITH,
|
|
FORWARD_IK_PERATOM_ARITH,
|
|
FORWARD_AD_PERATOM_ARITH,
|
|
FORWARD_IK_NONE,
|
|
FORWARD_AD_NONE,
|
|
FORWARD_IK_PERATOM_NONE,
|
|
FORWARD_AD_PERATOM_NONE,
|
|
FORWARD_IK_G,
|
|
FORWARD_AD_G,
|
|
FORWARD_IK_PERATOM_G,
|
|
FORWARD_AD_PERATOM_G,
|
|
FORWARD_IK_A,
|
|
FORWARD_AD_A,
|
|
FORWARD_IK_PERATOM_A,
|
|
FORWARD_AD_PERATOM_A
|
|
};
|
|
|
|
double energy; // accumulated energies
|
|
double energy_1, energy_6;
|
|
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
|
double *eatom, **vatom; // accumulated per-atom energy/virial
|
|
double e2group; // accumulated group-group energy
|
|
double f2group[3]; // accumulated group-group force
|
|
int triclinic_support; // 1 if supports triclinic geometries
|
|
|
|
int ewaldflag; // 1 if a Ewald solver
|
|
int pppmflag; // 1 if a PPPM solver
|
|
int msmflag; // 1 if a MSM solver
|
|
int dispersionflag; // 1 if a LJ/dispersion solver
|
|
int tip4pflag; // 1 if a TIP4P solver
|
|
int dipoleflag; // 1 if a dipole solver
|
|
int spinflag; // 1 if a spin solver
|
|
int differentiation_flag;
|
|
int neighrequest_flag; // used to avoid obsolete construction
|
|
// of neighbor lists
|
|
int mixflag; // 1 if geometric mixing rules are enforced
|
|
// for LJ coefficients
|
|
bool conp_one_step; // calculate A matrix in one step with pppm
|
|
int slabflag, wireflag;
|
|
int scalar_pressure_flag; // 1 if using MSM fast scalar pressure
|
|
double slab_volfactor, wire_volfactor;
|
|
|
|
int warn_nonneutral; // 0 = error if non-neutral system
|
|
// 1 = warn once if non-neutral system
|
|
// 2 = warn, but already warned
|
|
int warn_nocharge; // 0 = already warned
|
|
// 1 = warn if zero charge
|
|
|
|
int order, order_6, order_allocated;
|
|
double accuracy; // accuracy of KSpace solver (force units)
|
|
double accuracy_absolute; // user-specified accuracy in force units
|
|
double accuracy_relative; // user-specified dimensionless accuracy
|
|
// accuracy = acc_rel * two_charge_force
|
|
double accuracy_real_6; // real space accuracy for
|
|
// dispersion solver (force units)
|
|
double accuracy_kspace_6; // reciprocal space accuracy for
|
|
// dispersion solver (force units)
|
|
int auto_disp_flag; // use automatic parameter generation for pppm/disp
|
|
double two_charge_force; // force in user units of two point
|
|
// charges separated by 1 Angstrom
|
|
|
|
double g_ewald, g_ewald_6;
|
|
int nx_pppm, ny_pppm, nz_pppm; // global FFT grid for Coulombics
|
|
int nx_pppm_6, ny_pppm_6, nz_pppm_6; // global FFT grid for dispersion
|
|
int nx_msm_max, ny_msm_max, nz_msm_max;
|
|
|
|
int group_group_enable; // 1 if style supports group/group calculation
|
|
|
|
int centroidstressflag; // centroid stress compared to two-body stress
|
|
// CENTROID_SAME = same as two-body stress
|
|
// CENTROID_AVAIL = different and implemented
|
|
// CENTROID_NOTAVAIL = different, not yet implemented
|
|
|
|
// KOKKOS host/device flag and data masks
|
|
|
|
ExecutionSpace execution_space;
|
|
unsigned int datamask_read, datamask_modify;
|
|
int copymode;
|
|
|
|
int compute_flag; // 0 if skip compute()
|
|
int fftbench; // 0 if skip FFT timing
|
|
int collective_flag; // 1 if use MPI collectives for FFT/remap
|
|
int stagger_flag; // 1 if using staggered PPPM grids
|
|
|
|
double splittol; // tolerance for when to truncate splitting
|
|
|
|
KSpace(class LAMMPS *);
|
|
~KSpace() override;
|
|
void two_charge();
|
|
void triclinic_check();
|
|
void modify_params(int, char **);
|
|
void *extract(const char *);
|
|
void compute_dummy(int, int);
|
|
|
|
// triclinic
|
|
|
|
void x2lamdaT(double *, double *);
|
|
void lamda2xT(double *, double *);
|
|
void lamda2xvector(double *, double *);
|
|
|
|
// public so can be called by commands that change charge
|
|
|
|
virtual void qsum_qsq(int warning_flag = 1);
|
|
|
|
// general child-class methods
|
|
|
|
virtual void settings(int, char **) {};
|
|
virtual void init() = 0;
|
|
virtual void setup() = 0;
|
|
virtual void reset_grid() {};
|
|
virtual void compute(int, int) = 0;
|
|
virtual void compute_group_group(int, int, int) {};
|
|
|
|
virtual void pack_forward_grid(int, void *, int, int *) {};
|
|
virtual void unpack_forward_grid(int, void *, int, int *) {};
|
|
virtual void pack_reverse_grid(int, void *, int, int *) {};
|
|
virtual void unpack_reverse_grid(int, void *, int, int *) {};
|
|
|
|
virtual int timing(int, double &, double &) { return 0; }
|
|
virtual int timing_1d(int, double &) { return 0; }
|
|
virtual int timing_3d(int, double &) { return 0; }
|
|
|
|
virtual int modify_param(int, char **) { return 0; }
|
|
virtual double memory_usage() { return 0.0; }
|
|
|
|
/* ----------------------------------------------------------------------
|
|
compute gamma for MSM and pair styles
|
|
see Eq 4 from Parallel Computing 35 (2009) 164-177
|
|
------------------------------------------------------------------------- */
|
|
|
|
double gamma(const double &rho) const
|
|
{
|
|
if (rho <= 1.0) {
|
|
const int split_order = order / 2;
|
|
const double rho2 = rho * rho;
|
|
double g = gcons[split_order][0];
|
|
double rho_n = rho2;
|
|
for (int n = 1; n <= split_order; n++) {
|
|
g += gcons[split_order][n] * rho_n;
|
|
rho_n *= rho2;
|
|
}
|
|
return g;
|
|
} else
|
|
return (1.0 / rho);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
compute the derivative of gamma for MSM and pair styles
|
|
see Eq 4 from Parallel Computing 35 (2009) 164-177
|
|
------------------------------------------------------------------------- */
|
|
|
|
double dgamma(const double &rho) const
|
|
{
|
|
if (rho <= 1.0) {
|
|
const int split_order = order / 2;
|
|
const double rho2 = rho * rho;
|
|
double dg = dgcons[split_order][0] * rho;
|
|
double rho_n = rho * rho2;
|
|
for (int n = 1; n < split_order; n++) {
|
|
dg += dgcons[split_order][n] * rho_n;
|
|
rho_n *= rho2;
|
|
}
|
|
return dg;
|
|
} else
|
|
return (-1.0 / rho / rho);
|
|
}
|
|
|
|
double **get_gcons() { return gcons; }
|
|
double **get_dgcons() { return dgcons; }
|
|
|
|
protected:
|
|
int gridflag, gridflag_6;
|
|
int gewaldflag, gewaldflag_6;
|
|
int minorder, overlap_allowed;
|
|
int adjust_cutoff_flag;
|
|
int suffix_flag; // suffix compatibility flag
|
|
bigint natoms_original;
|
|
double scale, qqrd2e;
|
|
double qsum, qsqsum, q2;
|
|
double **gcons, **dgcons; // accumulated per-atom energy/virial
|
|
|
|
int evflag, evflag_atom;
|
|
int eflag_either, eflag_global, eflag_atom;
|
|
int vflag_either, vflag_global, vflag_atom;
|
|
int maxeatom, maxvatom;
|
|
|
|
int kewaldflag; // 1 if kspace range set for Ewald sum
|
|
int kx_ewald, ky_ewald, kz_ewald; // kspace settings for Ewald sum
|
|
|
|
void pair_check();
|
|
void ev_init(int eflag, int vflag, int alloc = 1)
|
|
{
|
|
if (eflag || vflag)
|
|
ev_setup(eflag, vflag, alloc);
|
|
else
|
|
evflag = evflag_atom = eflag_either = eflag_global = eflag_atom = vflag_either =
|
|
vflag_global = vflag_atom = 0;
|
|
}
|
|
void ev_setup(int, int, int alloc = 1);
|
|
double estimate_table_accuracy(double, double);
|
|
};
|
|
|
|
} // namespace LAMMPS_NS
|
|
|
|
#endif
|