Merge pull request #3093 from Bibobu/Elastic_stress
Add compute born/matrix command to compute elastic stress
This commit is contained in:
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@ -453,6 +453,8 @@
|
||||
/compute_basal_atom.h
|
||||
/compute_body_local.cpp
|
||||
/compute_body_local.h
|
||||
/compute_born_matrix.cpp
|
||||
/compute_born_matrix.h
|
||||
/compute_cnp_atom.cpp
|
||||
/compute_cnp_atom.h
|
||||
/compute_damage_atom.cpp
|
||||
|
||||
1224
src/EXTRA-COMPUTE/compute_born_matrix.cpp
Normal file
1224
src/EXTRA-COMPUTE/compute_born_matrix.cpp
Normal file
File diff suppressed because it is too large
Load Diff
97
src/EXTRA-COMPUTE/compute_born_matrix.h
Normal file
97
src/EXTRA-COMPUTE/compute_born_matrix.h
Normal file
@ -0,0 +1,97 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://www.lammps.org/, 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 Authors : Germain Clavier (TUe), Aidan Thompson (Sandia)
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef COMPUTE_CLASS
|
||||
// clang-format off
|
||||
ComputeStyle(born/matrix,ComputeBornMatrix);
|
||||
// clang-format on
|
||||
#else
|
||||
|
||||
#ifndef LMP_COMPUTE_BORN_MATRIX_H
|
||||
#define LMP_COMPUTE_BORN_MATRIX_H
|
||||
|
||||
#include "compute.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class ComputeBornMatrix : public Compute {
|
||||
public:
|
||||
ComputeBornMatrix(class LAMMPS *, int, char **);
|
||||
~ComputeBornMatrix() override;
|
||||
void init() override;
|
||||
void init_list(int, class NeighList *) override;
|
||||
void compute_vector() override;
|
||||
double memory_usage() override;
|
||||
|
||||
private:
|
||||
// Born matrix contributions
|
||||
|
||||
void compute_pairs(); // pair and manybody
|
||||
void compute_bonds(); // bonds
|
||||
void compute_angles(); // angles
|
||||
void compute_dihedrals(); // dihedrals
|
||||
void compute_numdiff(); // stress virial finite differences
|
||||
void displace_atoms(int, int, double); // displace atoms
|
||||
void force_clear(int); // zero out force array
|
||||
void update_virial(); // recalculate the virial
|
||||
void restore_atoms(int, int); // restore atom positions
|
||||
void virial_addon(); // restore atom positions
|
||||
void reallocate(); // grow the atom arrays
|
||||
|
||||
int me; // process rank
|
||||
int nvalues; // length of elastic tensor
|
||||
int numflag; // 1 if using finite differences
|
||||
double numdelta; // size of finite strain
|
||||
int maxatom; // allocated size of atom arrays
|
||||
|
||||
int pairflag, bondflag, angleflag;
|
||||
int dihedflag, impflag, kspaceflag;
|
||||
|
||||
double *values_local, *values_global;
|
||||
double pos, pos1, dt, nktv2p, ftm2v;
|
||||
class NeighList *list;
|
||||
|
||||
char *id_virial; // name of virial compute
|
||||
class Compute *compute_virial; // pointer to virial compute
|
||||
|
||||
static constexpr int NDIR_VIRIAL = 6; // dimension of virial and strain vectors
|
||||
static constexpr int NXYZ_VIRIAL = 3; // number of Cartesian coordinates
|
||||
int revalbe[NDIR_VIRIAL][NDIR_VIRIAL];
|
||||
int virialVtoV[NDIR_VIRIAL];
|
||||
double **temp_x; // original coords
|
||||
double **temp_f; // original forces
|
||||
double fixedpoint[NXYZ_VIRIAL]; // displacement field origin
|
||||
int dirlist[NDIR_VIRIAL][2]; // strain cartesian indices
|
||||
};
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ERROR/WARNING messages:
|
||||
|
||||
E: 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: ... style does not support compute born/matrix
|
||||
|
||||
Some component of the force field (pair, bond, angle...) does not provide
|
||||
a function to return the Born term contribution.
|
||||
*/
|
||||
@ -25,6 +25,7 @@
|
||||
#include "force.h"
|
||||
#include "memory.h"
|
||||
#include "neighbor.h"
|
||||
#include "domain.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -39,6 +40,7 @@ DihedralNHarmonic::DihedralNHarmonic(LAMMPS *lmp) : Dihedral(lmp)
|
||||
{
|
||||
writedata = 1;
|
||||
a = nullptr;
|
||||
born_matrix_enable = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -336,3 +338,64 @@ void DihedralNHarmonic::write_data(FILE *fp)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------*/
|
||||
|
||||
void DihedralNHarmonic::born_matrix(int nd, int i1, int i2, int i3, int i4,
|
||||
double &dudih, double &du2dih) {
|
||||
int i,type;
|
||||
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
|
||||
double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
|
||||
double c,s,kf;
|
||||
|
||||
int **dihedrallist = neighbor->dihedrallist;
|
||||
double **x = atom->x;
|
||||
|
||||
int ndihedrallist = neighbor->ndihedrallist;
|
||||
type = dihedrallist[nd][4];
|
||||
|
||||
vb1x = x[i1][0] - x[i2][0];
|
||||
vb1y = x[i1][1] - x[i2][1];
|
||||
vb1z = x[i1][2] - x[i2][2];
|
||||
|
||||
vb2x = x[i3][0] - x[i2][0];
|
||||
vb2y = x[i3][1] - x[i2][1];
|
||||
vb2z = x[i3][2] - x[i2][2];
|
||||
|
||||
vb2xm = -vb2x;
|
||||
vb2ym = -vb2y;
|
||||
vb2zm = -vb2z;
|
||||
|
||||
vb3x = x[i4][0] - x[i3][0];
|
||||
vb3y = x[i4][1] - x[i3][1];
|
||||
vb3z = x[i4][2] - x[i3][2];
|
||||
|
||||
// c,s calculation
|
||||
|
||||
ax = vb1y*vb2zm - vb1z*vb2ym;
|
||||
ay = vb1z*vb2xm - vb1x*vb2zm;
|
||||
az = vb1x*vb2ym - vb1y*vb2xm;
|
||||
bx = vb3y*vb2zm - vb3z*vb2ym;
|
||||
by = vb3z*vb2xm - vb3x*vb2zm;
|
||||
bz = vb3x*vb2ym - vb3y*vb2xm;
|
||||
|
||||
rasq = ax*ax + ay*ay + az*az;
|
||||
rbsq = bx*bx + by*by + bz*bz;
|
||||
|
||||
ra2inv = rb2inv = 0.0;
|
||||
if (rasq > 0) ra2inv = 1.0/rasq;
|
||||
if (rbsq > 0) rb2inv = 1.0/rbsq;
|
||||
rabinv = sqrt(ra2inv*rb2inv);
|
||||
|
||||
c = (ax*bx + ay*by + az*bz)*rabinv;
|
||||
|
||||
dudih = 0.0;
|
||||
du2dih = 0.0;
|
||||
for (i = 1; i < nterms[type]; i++) {
|
||||
dudih += this->a[type][i]*i*pow(c,i-1);
|
||||
}
|
||||
|
||||
for (i = 2; i < nterms[type]; i++) {
|
||||
du2dih += this->a[type][i]*i*(i-1)*pow(c, i-2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ class DihedralNHarmonic : public Dihedral {
|
||||
void write_restart(FILE *) override;
|
||||
void read_restart(FILE *) override;
|
||||
void write_data(FILE *) override;
|
||||
void born_matrix(int /*dtype*/, int, int, int, int, double&, double&) override;
|
||||
|
||||
protected:
|
||||
int *nterms;
|
||||
|
||||
@ -29,7 +29,10 @@ using MathConst::MY_PI;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
AngleCosine::AngleCosine(LAMMPS *_lmp) : Angle(_lmp) {}
|
||||
AngleCosine::AngleCosine(LAMMPS *_lmp) : Angle(_lmp)
|
||||
{
|
||||
born_matrix_enable = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -235,6 +238,14 @@ double AngleCosine::single(int type, int i1, int i2, int i3)
|
||||
return k[type] * (1.0 + c);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void AngleCosine::born_matrix(int type, int i1, int i2, int i3, double &du, double &du2)
|
||||
{
|
||||
du2 = 0;
|
||||
du = k[type];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return ptr to internal members upon request
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
@ -35,6 +35,7 @@ class AngleCosine : public Angle {
|
||||
void read_restart(FILE *) override;
|
||||
void write_data(FILE *) override;
|
||||
double single(int, int, int, int) override;
|
||||
void born_matrix(int type, int i1, int i2, int i3, double& du, double& du2) override;
|
||||
void *extract(const char *, int &) override;
|
||||
|
||||
protected:
|
||||
|
||||
@ -38,6 +38,7 @@ AngleCosineSquared::AngleCosineSquared(LAMMPS *_lmp) : Angle(_lmp)
|
||||
{
|
||||
k = nullptr;
|
||||
theta0 = nullptr;
|
||||
born_matrix_enable = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -262,3 +263,32 @@ double AngleCosineSquared::single(int type, int i1, int i2, int i3)
|
||||
double tk = k[type] * dcostheta;
|
||||
return tk * dcostheta;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void AngleCosineSquared::born_matrix(int type, int i1, int i2, int i3, double& du, double& du2)
|
||||
{
|
||||
double **x = atom->x;
|
||||
|
||||
double delx1 = x[i1][0] - x[i2][0];
|
||||
double dely1 = x[i1][1] - x[i2][1];
|
||||
double delz1 = x[i1][2] - x[i2][2];
|
||||
domain->minimum_image(delx1,dely1,delz1);
|
||||
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
|
||||
|
||||
double delx2 = x[i3][0] - x[i2][0];
|
||||
double dely2 = x[i3][1] - x[i2][1];
|
||||
double delz2 = x[i3][2] - x[i2][2];
|
||||
domain->minimum_image(delx2,dely2,delz2);
|
||||
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
|
||||
|
||||
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
|
||||
c /= r1*r2;
|
||||
if (c > 1.0) c = 1.0;
|
||||
if (c < -1.0) c = -1.0;
|
||||
|
||||
double dcostheta = c - cos(theta0[type]);
|
||||
double tk = k[type] * dcostheta;
|
||||
du2 = 2*k[type];
|
||||
du = du2*dcostheta;
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ class AngleCosineSquared : public Angle {
|
||||
void read_restart(FILE *) override;
|
||||
void write_data(FILE *) override;
|
||||
double single(int, int, int, int) override;
|
||||
void born_matrix(int type, int i1, int i2, int i3, double& du, double& du2) override;
|
||||
|
||||
protected:
|
||||
double *k, *theta0;
|
||||
|
||||
@ -27,7 +27,10 @@ using namespace LAMMPS_NS;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
BondHarmonic::BondHarmonic(LAMMPS *_lmp) : Bond(_lmp) {}
|
||||
BondHarmonic::BondHarmonic(LAMMPS *_lmp) : Bond(_lmp)
|
||||
{
|
||||
born_matrix_enable = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -197,6 +200,20 @@ double BondHarmonic::single(int type, double rsq, int /*i*/, int /*j*/, double &
|
||||
return rk * dr;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void BondHarmonic::born_matrix(int type, double rsq, int /*i*/, int /*j*/,
|
||||
double &du, double& du2)
|
||||
{
|
||||
double r = sqrt(rsq);
|
||||
double dr = r - r0[type];
|
||||
du2 = 0.0;
|
||||
du = 0.0;
|
||||
du2 = 2*k[type];
|
||||
if (r > 0.0) du = du2*dr;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return ptr to internal members upon request
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
@ -35,6 +35,7 @@ class BondHarmonic : public Bond {
|
||||
void read_restart(FILE *) override;
|
||||
void write_data(FILE *) override;
|
||||
double single(int, double, int, int, double &) override;
|
||||
void born_matrix(int, double, int, int, double &, double &) override;
|
||||
void *extract(const char *, int &) override;
|
||||
|
||||
protected:
|
||||
|
||||
@ -34,6 +34,7 @@ Angle::Angle(LAMMPS *_lmp) : Pointers(_lmp)
|
||||
|
||||
allocated = 0;
|
||||
suffix_flag = Suffix::NONE;
|
||||
born_matrix_enable = 0;
|
||||
|
||||
maxeatom = maxvatom = maxcvatom = 0;
|
||||
eatom = nullptr;
|
||||
|
||||
@ -26,6 +26,7 @@ class Angle : protected Pointers {
|
||||
int allocated;
|
||||
int *setflag;
|
||||
int writedata; // 1 if writes coeffs to data file
|
||||
int born_matrix_enable;
|
||||
double energy; // accumulated energies
|
||||
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
||||
double *eatom, **vatom; // accumulated per-atom energy/virial
|
||||
@ -59,6 +60,11 @@ class Angle : protected Pointers {
|
||||
virtual void read_restart_settings(FILE *){};
|
||||
virtual void write_data(FILE *) {}
|
||||
virtual double single(int, int, int, int) = 0;
|
||||
virtual void born_matrix(int/*atype*/, int/*at1*/, int/*at2*/, int/*at3*/, double& du, double& du2)
|
||||
{
|
||||
du = 0.0;
|
||||
du2 = 0.0;
|
||||
}
|
||||
virtual double memory_usage();
|
||||
virtual void *extract(const char *, int &) { return nullptr; }
|
||||
void reinit();
|
||||
|
||||
@ -49,6 +49,7 @@ Bond::Bond(LAMMPS *_lmp) : Pointers(_lmp)
|
||||
|
||||
allocated = 0;
|
||||
suffix_flag = Suffix::NONE;
|
||||
born_matrix_enable = 0;
|
||||
partial_flag = 0;
|
||||
|
||||
maxeatom = maxvatom = 0;
|
||||
|
||||
@ -33,6 +33,8 @@ class Bond : protected Pointers {
|
||||
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
||||
double *eatom, **vatom; // accumulated per-atom energy/virial
|
||||
|
||||
int born_matrix_enable;
|
||||
|
||||
int comm_forward; // size of forward communication (0 if none)
|
||||
int comm_reverse; // size of reverse communication (0 if none)
|
||||
int comm_reverse_off; // size of reverse comm even if newton off
|
||||
@ -69,6 +71,12 @@ class Bond : protected Pointers {
|
||||
virtual int pack_reverse_comm(int, int, double *) {return 0;}
|
||||
virtual void unpack_reverse_comm(int, int *, double *) {}
|
||||
|
||||
virtual void born_matrix(int/*btype*/, double/*rsq*/, int/*at1*/, int/*at2*/, double& du, double& du2)
|
||||
{
|
||||
du = 0.0;
|
||||
du2 = 0.0;
|
||||
}
|
||||
|
||||
void write_file(int, char **);
|
||||
|
||||
protected:
|
||||
|
||||
@ -184,7 +184,7 @@ void ComputeClusterAtom::compute_peratom()
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int ComputeClusterAtom::pack_forward_comm(int n, int *list, double *buf,
|
||||
int ComputeClusterAtom::pack_forward_comm(int n, int *list, double *buf,
|
||||
int /*pbc_flag*/, int * /*pbc*/)
|
||||
{
|
||||
int i, j, m;
|
||||
|
||||
@ -311,7 +311,7 @@ void ComputeCoordAtom::compute_peratom()
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int ComputeCoordAtom::pack_forward_comm(int n, int *list, double *buf,
|
||||
int ComputeCoordAtom::pack_forward_comm(int n, int *list, double *buf,
|
||||
int /*pbc_flag*/, int * /*pbc*/)
|
||||
{
|
||||
int i, m = 0, j;
|
||||
|
||||
@ -35,6 +35,7 @@ Dihedral::Dihedral(LAMMPS *_lmp) : Pointers(_lmp)
|
||||
|
||||
allocated = 0;
|
||||
suffix_flag = Suffix::NONE;
|
||||
born_matrix_enable = 0;
|
||||
|
||||
maxeatom = maxvatom = maxcvatom = 0;
|
||||
eatom = nullptr;
|
||||
|
||||
@ -26,6 +26,7 @@ class Dihedral : protected Pointers {
|
||||
int allocated;
|
||||
int *setflag;
|
||||
int writedata; // 1 if writes coeffs to data file
|
||||
int born_matrix_enable;
|
||||
double energy; // accumulated energy
|
||||
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
||||
double *eatom, **vatom; // accumulated per-atom energy/virial
|
||||
@ -55,6 +56,11 @@ class Dihedral : protected Pointers {
|
||||
virtual void read_restart_settings(FILE *){};
|
||||
virtual void write_data(FILE *) {}
|
||||
virtual double memory_usage();
|
||||
virtual void born_matrix(int/*dtype*/, int/*at1*/, int/*at2*/, int/*at3*/, int /*at4*/, double& du, double& du2)
|
||||
{
|
||||
du = 0.0;
|
||||
du2 = 0.0;
|
||||
}
|
||||
|
||||
protected:
|
||||
int suffix_flag; // suffix compatibility flag
|
||||
|
||||
@ -182,7 +182,7 @@ void FixGroup::set_group()
|
||||
|
||||
// invoke atom-style variable if defined
|
||||
// NOTE: after variable invocation could reset invoked computes to not-invoked
|
||||
// this would avoid an issue where other post-force fixes
|
||||
// this would avoid an issue where other post-force fixes
|
||||
// change the compute result since it will not be re-invoked at end-of-step,
|
||||
// e.g. if compute pe/atom includes pe contributions from fixes
|
||||
|
||||
@ -237,7 +237,7 @@ void FixGroup::set_group()
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int FixGroup::pack_forward_comm(int n, int *list, double *buf,
|
||||
int FixGroup::pack_forward_comm(int n, int *list, double *buf,
|
||||
int /*pbc_flag*/, int * /*pbc*/)
|
||||
{
|
||||
int i, j, m;
|
||||
@ -261,9 +261,9 @@ void FixGroup::unpack_forward_comm(int n, int first, double *buf)
|
||||
|
||||
m = 0;
|
||||
last = first + n;
|
||||
|
||||
|
||||
int *mask = atom->mask;
|
||||
|
||||
|
||||
for (i = first; i < last; i++) mask[i] = (int) ubuf(buf[m++]).i;
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ Improper::Improper(LAMMPS *_lmp) : Pointers(_lmp)
|
||||
|
||||
allocated = 0;
|
||||
suffix_flag = Suffix::NONE;
|
||||
born_matrix_enable = 0;
|
||||
|
||||
maxeatom = maxvatom = maxcvatom = 0;
|
||||
eatom = nullptr;
|
||||
|
||||
@ -26,6 +26,7 @@ class Improper : protected Pointers {
|
||||
int allocated;
|
||||
int *setflag;
|
||||
int writedata; // 1 if writes coeffs to data file
|
||||
int born_matrix_enable;
|
||||
double energy; // accumulated energies
|
||||
double virial[6]; // accumulated virial: xx,yy,zz,xy,xz,yz
|
||||
double *eatom, **vatom; // accumulated per-atom energy/virial
|
||||
@ -55,6 +56,11 @@ class Improper : protected Pointers {
|
||||
virtual void read_restart_settings(FILE *){};
|
||||
virtual void write_data(FILE *) {}
|
||||
virtual double memory_usage();
|
||||
virtual void born_matrix(int/*dtype*/, int/*at1*/, int/*at2*/, int/*at3*/, int /*at4*/, double& du, double& du2)
|
||||
{
|
||||
du = 0.0;
|
||||
du2 = 0.0;
|
||||
}
|
||||
|
||||
protected:
|
||||
int suffix_flag; // suffix compatibility flag
|
||||
|
||||
@ -457,12 +457,12 @@ void Modify::pre_reverse(int eflag, int vflag)
|
||||
void Modify::post_force(int vflag)
|
||||
{
|
||||
if (n_post_force_group) {
|
||||
for (int i = 0; i < n_post_force_group; i++)
|
||||
for (int i = 0; i < n_post_force_group; i++)
|
||||
fix[list_post_force_group[i]]->post_force(vflag);
|
||||
}
|
||||
|
||||
if (n_post_force) {
|
||||
for (int i = 0; i < n_post_force; i++)
|
||||
for (int i = 0; i < n_post_force; i++)
|
||||
fix[list_post_force[i]]->post_force(vflag);
|
||||
}
|
||||
}
|
||||
@ -610,7 +610,7 @@ void Modify::pre_force_respa(int vflag, int ilevel, int iloop)
|
||||
void Modify::post_force_respa(int vflag, int ilevel, int iloop)
|
||||
{
|
||||
if (n_post_force_group) {
|
||||
for (int i = 0; i < n_post_force_group; i++)
|
||||
for (int i = 0; i < n_post_force_group; i++)
|
||||
fix[list_post_force_group[i]]->post_force_respa(vflag, ilevel, iloop);
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +58,7 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp)
|
||||
comm_forward = comm_reverse = comm_reverse_off = 0;
|
||||
|
||||
single_enable = 1;
|
||||
born_matrix_enable = 0;
|
||||
single_hessian_enable = 0;
|
||||
restartinfo = 1;
|
||||
respa_enable = 0;
|
||||
|
||||
@ -52,6 +52,7 @@ class Pair : protected Pointers {
|
||||
int comm_reverse_off; // size of reverse comm even if newton off
|
||||
|
||||
int single_enable; // 1 if single() routine exists
|
||||
int born_matrix_enable; // 1 if born_matrix() routine exists
|
||||
int single_hessian_enable; // 1 if single_hessian() routine exists
|
||||
int restartinfo; // 1 if pair style writes restart info
|
||||
int respa_enable; // 1 if inner/middle/outer rRESPA routines
|
||||
@ -169,6 +170,12 @@ class Pair : protected Pointers {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
virtual void born_matrix(int /*i*/, int /*j*/, int /*itype*/, int /*jtype*/, double /*rsq*/,
|
||||
double /*factor_coul*/, double /*factor_lj*/, double &du, double &du2)
|
||||
{
|
||||
du = du2 = 0.0;
|
||||
}
|
||||
|
||||
virtual void settings(int, char **) = 0;
|
||||
virtual void coeff(int, char **) = 0;
|
||||
|
||||
|
||||
@ -391,6 +391,7 @@ void PairHybrid::flags()
|
||||
// single_enable = 1 if all sub-styles are set
|
||||
// respa_enable = 1 if all sub-styles are set
|
||||
// manybody_flag = 1 if any sub-style is set
|
||||
// born_matrix_enable = 1 if all sub-styles are set
|
||||
// no_virial_fdotr_compute = 1 if any sub-style is set
|
||||
// ghostneigh = 1 if any sub-style is set
|
||||
// ewaldflag, pppmflag, msmflag, dipoleflag, dispersionflag, tip4pflag = 1
|
||||
@ -401,11 +402,13 @@ void PairHybrid::flags()
|
||||
compute_flag = 0;
|
||||
respa_enable = 0;
|
||||
restartinfo = 0;
|
||||
born_matrix_enable = 0;
|
||||
|
||||
for (m = 0; m < nstyles; m++) {
|
||||
if (styles[m]->single_enable) ++single_enable;
|
||||
if (styles[m]->respa_enable) ++respa_enable;
|
||||
if (styles[m]->restartinfo) ++restartinfo;
|
||||
if (styles[m]->born_matrix_enable) ++born_matrix_enable;
|
||||
if (styles[m]->manybody_flag) manybody_flag = 1;
|
||||
if (styles[m]->no_virial_fdotr_compute) no_virial_fdotr_compute = 1;
|
||||
if (styles[m]->ghostneigh) ghostneigh = 1;
|
||||
@ -422,6 +425,7 @@ void PairHybrid::flags()
|
||||
single_enable = (single_enable == nstyles) ? 1 : 0;
|
||||
respa_enable = (respa_enable == nstyles) ? 1 : 0;
|
||||
restartinfo = (restartinfo == nstyles) ? 1 : 0;
|
||||
born_matrix_enable = (born_matrix_enable == nstyles) ? 1 : 0;
|
||||
init_svector();
|
||||
|
||||
// set centroidstressflag for pair hybrid
|
||||
@ -867,6 +871,40 @@ double PairHybrid::single(int i, int j, int itype, int jtype,
|
||||
return esum;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
call sub-style to compute born matrix interaction
|
||||
error if sub-style does not support born_matrix call
|
||||
since overlay could have multiple sub-styles, sum results explicitly
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairHybrid::born_matrix(int i, int j, int itype, int jtype, double rsq,
|
||||
double factor_coul, double factor_lj,
|
||||
double &dupair, double &du2pair)
|
||||
{
|
||||
if (nmap[itype][jtype] == 0)
|
||||
error->one(FLERR,"Invoked pair born_matrix on pair style none");
|
||||
|
||||
double du, du2;
|
||||
dupair = du2pair = 0.0;
|
||||
|
||||
for (int m = 0; m < nmap[itype][jtype]; m++) {
|
||||
if (rsq < styles[map[itype][jtype][m]]->cutsq[itype][jtype]) {
|
||||
if (styles[map[itype][jtype][m]]->born_matrix_enable == 0)
|
||||
error->one(FLERR,"Pair hybrid sub-style does not support born_matrix call");
|
||||
|
||||
if ((special_lj[map[itype][jtype][m]] != nullptr) ||
|
||||
(special_coul[map[itype][jtype][m]] != nullptr))
|
||||
error->one(FLERR,"Pair hybrid born_matrix calls do not support"
|
||||
" per sub-style special bond values");
|
||||
|
||||
du = du2 = 0.0;
|
||||
styles[map[itype][jtype][m]]->born_matrix(i,j,itype,jtype,rsq,factor_coul,factor_lj,du,du2);
|
||||
dupair += du;
|
||||
du2pair += du2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
copy Pair::svector data
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -49,6 +49,8 @@ class PairHybrid : public Pair {
|
||||
void write_restart(FILE *) override;
|
||||
void read_restart(FILE *) override;
|
||||
double single(int, int, int, int, double, double, double, double &) override;
|
||||
void born_matrix(int, int, int, int, double, double, double, double &, double &) override;
|
||||
|
||||
void modify_params(int narg, char **arg) override;
|
||||
double memory_usage() override;
|
||||
|
||||
|
||||
@ -413,7 +413,7 @@ double PairHybridScaled::single(int i, int j, int itype, int jtype, double rsq,
|
||||
(special_coul[map[itype][jtype][m]] != nullptr))
|
||||
error->one(FLERR, "Pair hybrid single() does not support per sub-style special_bond");
|
||||
|
||||
scale = scaleval[map[itype][jtype][m]];
|
||||
double scale = scaleval[map[itype][jtype][m]];
|
||||
esum += scale * pstyle->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fone);
|
||||
fforce += scale * fone;
|
||||
}
|
||||
@ -423,6 +423,57 @@ double PairHybridScaled::single(int i, int j, int itype, int jtype, double rsq,
|
||||
return esum;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
call sub-style to compute born matrix interaction
|
||||
error if sub-style does not support born_matrix call
|
||||
since overlay could have multiple sub-styles, sum results explicitly
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairHybridScaled::born_matrix(int i, int j, int itype, int jtype, double rsq,
|
||||
double factor_coul, double factor_lj,
|
||||
double &dupair, double &du2pair)
|
||||
{
|
||||
if (nmap[itype][jtype] == 0) error->one(FLERR, "Invoked pair born_matrix on pair style none");
|
||||
|
||||
// update scale values from variables where needed
|
||||
|
||||
const int nvars = scalevars.size();
|
||||
if (nvars > 0) {
|
||||
double *vals = new double[nvars];
|
||||
for (int k = 0; k < nvars; ++k) {
|
||||
int m = input->variable->find(scalevars[k].c_str());
|
||||
if (m < 0)
|
||||
error->all(FLERR, "Variable '{}' not found when updating scale factors", scalevars[k]);
|
||||
vals[k] = input->variable->compute_equal(m);
|
||||
}
|
||||
for (int k = 0; k < nstyles; ++k) {
|
||||
if (scaleidx[k] >= 0) scaleval[k] = vals[scaleidx[k]];
|
||||
}
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
double du, du2, scale;
|
||||
dupair = du2pair = scale = 0.0;
|
||||
|
||||
for (int m = 0; m < nmap[itype][jtype]; m++) {
|
||||
auto pstyle = styles[map[itype][jtype][m]];
|
||||
if (rsq < pstyle->cutsq[itype][jtype]) {
|
||||
if (pstyle->born_matrix_enable == 0)
|
||||
error->one(FLERR, "Pair hybrid sub-style does not support born_matrix call");
|
||||
|
||||
if ((special_lj[map[itype][jtype][m]] != nullptr) ||
|
||||
(special_coul[map[itype][jtype][m]] != nullptr))
|
||||
error->one(FLERR, "Pair hybrid born_matrix() does not support per sub-style special_bond");
|
||||
|
||||
du = du2 = 0.0;
|
||||
scale = scaleval[map[itype][jtype][m]];
|
||||
pstyle->born_matrix(i, j, itype, jtype, rsq, factor_coul, factor_lj, du, du2);
|
||||
dupair += scale*du;
|
||||
du2pair += scale*du2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set coeffs for one or more type pairs
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -38,6 +38,7 @@ class PairHybridScaled : public PairHybrid {
|
||||
void write_restart(FILE *) override;
|
||||
void read_restart(FILE *) override;
|
||||
double single(int, int, int, int, double, double, double, double &) override;
|
||||
void born_matrix(int, int, int, int, double, double, double, double &, double &) override;
|
||||
|
||||
void init_svector() override;
|
||||
void copy_svector(int, int) override;
|
||||
|
||||
@ -39,6 +39,7 @@ using namespace MathConst;
|
||||
PairLJCut::PairLJCut(LAMMPS *lmp) : Pair(lmp)
|
||||
{
|
||||
respa_enable = 1;
|
||||
born_matrix_enable = 1;
|
||||
writedata = 1;
|
||||
}
|
||||
|
||||
@ -672,6 +673,28 @@ double PairLJCut::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq,
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairLJCut::born_matrix(int /*i*/, int /*j*/, int itype, int jtype, double rsq,
|
||||
double /*factor_coul*/, double factor_lj,
|
||||
double &dupair, double &du2pair)
|
||||
{
|
||||
double rinv,r2inv,r6inv,du,du2;
|
||||
|
||||
r2inv = 1.0/rsq;
|
||||
rinv = sqrt(r2inv);
|
||||
r6inv = r2inv*r2inv*r2inv;
|
||||
|
||||
// Reminder: lj1 = 48*e*s^12, lj2 = 24*e*s^6
|
||||
// so dupair = -forcelj/r = -fforce*r (forcelj from single method)
|
||||
|
||||
du = r6inv * rinv * (lj2[itype][jtype] - lj1[itype][jtype]*r6inv);
|
||||
du2 = r6inv * r2inv * (13*lj1[itype][jtype]*r6inv - 7*lj2[itype][jtype]);
|
||||
|
||||
dupair = factor_lj*du;
|
||||
du2pair = factor_lj*du2;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void *PairLJCut::extract(const char *str, int &dim)
|
||||
{
|
||||
dim = 2;
|
||||
|
||||
@ -40,6 +40,7 @@ class PairLJCut : public Pair {
|
||||
void write_data(FILE *) override;
|
||||
void write_data_all(FILE *) override;
|
||||
double single(int, int, int, int, double, double, double, double &) override;
|
||||
void born_matrix(int, int, int, int, double, double, double, double &, double &) override;
|
||||
void *extract(const char *, int &) override;
|
||||
|
||||
void compute_inner() override;
|
||||
|
||||
@ -704,7 +704,7 @@ void Respa::recurse(int ilevel)
|
||||
timer->stamp(Timer::COMM);
|
||||
}
|
||||
timer->stamp();
|
||||
if (modify->n_post_force_respa_any)
|
||||
if (modify->n_post_force_respa_any)
|
||||
modify->post_force_respa(vflag, ilevel, iloop);
|
||||
modify->final_integrate_respa(ilevel, iloop);
|
||||
timer->stamp(Timer::MODIFY);
|
||||
|
||||
Reference in New Issue
Block a user