Merge pull request #4467 from evoyiatzis/patch-2

extend fix adapt to treat improper angles
This commit is contained in:
Axel Kohlmeyer
2025-04-02 12:18:40 -04:00
committed by GitHub
43 changed files with 416 additions and 20 deletions

View File

@ -14,7 +14,7 @@ Syntax
* adapt = style name of this fix command
* N = adapt simulation settings every this many timesteps
* one or more attribute/arg pairs may be appended
* attribute = *pair* or *bond* or *angle* or *kspace* or *atom*
* attribute = *pair* or *bond* or *angle* or *improper* or *kspace* or *atom*
.. parsed-literal::
@ -33,6 +33,11 @@ Syntax
aparam = parameter to adapt over time
I = type angle to set parameter for (integer or type label)
v_name = variable with name that calculates value of aparam
*improper* args = istyle iparam I v_name
istyle = improper style name (e.g., cvff)
iparam = parameter to adapt over time
I = type improper to set parameter for (integer or type label)
v_name = variable with name that calculates value of iparam
*kspace* arg = v_name
v_name = variable with name that calculates scale factor on :math:`k`-space terms
*atom* args = atomparam v_name
@ -428,6 +433,56 @@ this fix uses to reset theta0 needs to generate values in radians.
----------
.. versionadded:: TBD
The *improper* keyword uses the specified variable to change the value of
an improper coefficient over time, very similar to how the *angle* keyword
operates. The only difference is that now an improper coefficient for a
given improper type is adapted.
A wild-card asterisk can be used in place of or in conjunction with the
improper type argument to set the coefficients for multiple improper types.
This takes the form "\*" or "\*n" or "m\*" or "m\*n". If :math:`N` is
the number of improper types, then an asterisk with no numeric values means
all types from 1 to :math:`N`. A leading asterisk means all types from
1 to n (inclusive). A trailing asterisk means all types from m to
:math:`N` (inclusive). A middle asterisk means all types from m to n
(inclusive).
If :doc:`improper_style hybrid <improper_hybrid>` is used, *istyle* should be a
sub-style name. The improper styles that currently work with fix adapt are:
+---------------------------------------------------------+----------------+----------------+
| :doc:`amoeba <improper_amoeba>` | k | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`class2 <improper_class2>` | k,chi0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`cossq <improper_cossq>` | k,chi0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`cvff <improper_cvff>` | k,d,n | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`distance <improper_distance>` | k2,k4 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`distharm <improper_distharm>` | k,d0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`fourier <improper_fourier>` | k,C0,C1,C2 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`harmonic <improper_harmonic>` | k,chi0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`inversion/harmonic <improper_inversion_harmonic>` | k,w0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`ring <improper_ring>` | k,theta0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`umbrella <improper_umbrella>` | k,w0 | type impropers |
+---------------------------------------------------------+----------------+----------------+
| :doc:`sqdistharm <improper_sqdistharm>` | k | type impropers |
+---------------------------------------------------------+----------------+----------------+
Note that internally, chi0 and theta0 are stored in radians, so the variable
this fix use to reset chi0 or theta0 needs to generate values in radians.
----------
The *kspace* keyword used the specified variable as a scale factor on
the energy, forces, virial calculated by whatever :math:`k`-space solver is
defined by the :doc:`kspace_style <kspace_style>` command. If the

View File

@ -337,3 +337,14 @@ void ImproperAmoeba::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp,"%d %g\n",i,k[i]);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperAmoeba::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
return nullptr;
}

View File

@ -34,6 +34,7 @@ class ImproperAmoeba : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
int disable;

View File

@ -843,3 +843,15 @@ void ImproperClass2::write_data(FILE *fp)
aa_theta0_1[i]*180.0/MY_PI,aa_theta0_2[i]*180.0/MY_PI,
aa_theta0_3[i]*180.0/MY_PI);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperClass2::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k0;
if (strcmp(str, "chi0") == 0) return (void *) chi0;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperClass2 : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *k0, *chi0;

View File

@ -309,3 +309,15 @@ void ImproperCossq::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp,"%d %g %g\n",i,k[i],chi[i]/MY_PI*180.0);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperCossq::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
if (strcmp(str, "chi0") == 0) return (void *) chi;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperCossq : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *k, *chi;

View File

@ -268,3 +268,16 @@ void ImproperDistance::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp,"%d %g %g\n",i,k[i],chi[i]);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperDistance::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k2") == 0) return (void *) k;
if (strcmp(str, "k4") == 0) return (void *) chi;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperDistance : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
private:
double *k, *chi;

View File

@ -337,3 +337,17 @@ void ImproperFourier::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp,"%d %g %g %g %g %d\n",i,k[i],C0[i],C1[i],C2[i],all[i]);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperFourier::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
if (strcmp(str, "C0") == 0) return (void *) C0;
if (strcmp(str, "C1") == 0) return (void *) C1;
if (strcmp(str, "C2") == 0) return (void *) C2;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperFourier : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *k, *C0, *C1, *C2;

View File

@ -339,3 +339,16 @@ void ImproperRing::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp,"%d %g %g\n",i,k[i],acos(chi[i])/MY_PI*180.0);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperRing::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
if (strcmp(str, "theta0") == 0) return (void *) chi;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperRing : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *k, *chi;

View File

@ -332,3 +332,15 @@ void ImproperInversionHarmonic::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp,"%d %g %g\n",i,kw[i],w0[i]/MY_PI*180.0);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperInversionHarmonic::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) kw;
if (strcmp(str, "w0") == 0) return (void *) w0;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperInversionHarmonic : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *kw, *w0;

View File

@ -337,3 +337,16 @@ void ImproperCvff::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp, "%d %g %d %d\n", i, k[i], sign[i], multiplicity[i]);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperCvff::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
if (strcmp(str, "d") == 0) return (void *) sign;
if (strcmp(str, "n") == 0) return (void *) multiplicity;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperCvff : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *k;

View File

@ -276,3 +276,15 @@ void ImproperHarmonic::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp, "%d %g %g\n", i, k[i], RAD2DEG * chi[i]);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperHarmonic::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
if (strcmp(str, "chi0") == 0) return (void *) chi;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperHarmonic : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *k, *chi;

View File

@ -322,3 +322,16 @@ void ImproperUmbrella::write_data(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++)
fprintf(fp, "%d %g %g\n", i, kw[i], RAD2DEG * w0[i]);
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperUmbrella::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) kw;
if (strcmp(str, "w0") == 0) return (void *) w0;
return nullptr;
}

View File

@ -33,6 +33,7 @@ class ImproperUmbrella : public Improper {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void *extract(const char *, int &) override;
protected:
double *kw, *w0, *C;

View File

@ -226,12 +226,9 @@ void ImproperDistHarm::coeff(int narg, char **arg)
double k_one = utils::numeric(FLERR,arg[1],false,lmp);
double chi_one = utils::numeric(FLERR,arg[2],false,lmp);
// convert chi from degrees to radians
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
//chi[i] = chi_one/180.0 * PI;
chi[i] = chi_one;
setflag[i] = 1;
count++;
@ -267,3 +264,15 @@ void ImproperDistHarm::read_restart(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperDistHarm::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
if (strcmp(str, "d0") == 0) return (void *) chi;
return nullptr;
}

View File

@ -32,6 +32,7 @@ class ImproperDistHarm : public Improper {
void coeff(int, char **) override;
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void *extract(const char *, int &) override;
private:
double *k, *chi;

View File

@ -267,3 +267,14 @@ void ImproperSQDistHarm::read_restart(FILE *fp)
for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
return ptr to internal members upon request
------------------------------------------------------------------------ */
void *ImproperSQDistHarm::extract(const char *str, int &dim)
{
dim = 1;
if (strcmp(str, "k") == 0) return (void *) k;
return nullptr;
}

View File

@ -32,6 +32,7 @@ class ImproperSQDistHarm : public Improper {
void coeff(int, char **) override;
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void *extract(const char *, int &) override;
private:
double *k, *chi;

View File

@ -24,6 +24,8 @@
#include "fix_store_atom.h"
#include "force.h"
#include "group.h"
#include "improper.h"
#include "improper_hybrid.h"
#include "input.h"
#include "kspace.h"
#include "math_const.h"
@ -41,14 +43,14 @@ using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
enum{PAIR, KSPACE, ATOM, BOND, ANGLE};
enum{PAIR, KSPACE, ATOM, BOND, ANGLE, IMPROPER};
enum{DIAMETER, CHARGE};
/* ---------------------------------------------------------------------- */
FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), nadapt(0), anypair(0), anybond(0), anyangle(0),
id_fix_diam(nullptr), id_fix_chg(nullptr), adapt(nullptr)
anyimproper(0), id_fix_diam(nullptr), id_fix_chg(nullptr), adapt(nullptr)
{
if (narg < 5) utils::missing_cmd_args(FLERR,"fix adapt", error);
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
@ -83,6 +85,10 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt angle", error);
nadapt++;
iarg += 5;
} else if (strcmp(arg[iarg],"improper") == 0) {
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt improper", error);
nadapt++;
iarg += 5;
} else break;
}
@ -149,6 +155,19 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
nadapt++;
iarg += 5;
} else if (strcmp(arg[iarg],"improper") == 0) {
adapt[nadapt].which = IMPROPER;
adapt[nadapt].improper = nullptr;
adapt[nadapt].istyle = utils::strdup(arg[iarg+1]);
adapt[nadapt].iparam = utils::strdup(arg[iarg+2]);
utils::bounds_typelabel(FLERR, arg[iarg+3], 1, atom->nimpropertypes,
adapt[nadapt].ilo, adapt[nadapt].ihi, lmp, Atom::IMPROPER);
if (utils::strmatch(arg[iarg+4],"^v_")) {
adapt[nadapt].var = utils::strdup(arg[iarg+4]+2);
} else error->all(FLERR,"Argument #{} must be variable not {}", iarg+5, arg[iarg+4]);
nadapt++;
iarg += 5;
} else if (strcmp(arg[iarg],"kspace") == 0) {
adapt[nadapt].which = KSPACE;
if (utils::strmatch(arg[iarg+1],"^v_")) {
@ -224,6 +243,13 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
n = atom->nangletypes;
for (int m = 0; m < nadapt; ++m)
if (adapt[m].which == ANGLE) memory->create(adapt[m].vector_orig,n+1,"adapt:vector_orig");
// allocate improper style arrays:
n = atom->nimpropertypes;
for (int m = 0; m < nadapt; ++m)
if (adapt[m].which == IMPROPER) memory->create(adapt[m].vector_orig,n+1,"adapt:vector_orig");
}
/* ---------------------------------------------------------------------- */
@ -244,6 +270,10 @@ FixAdapt::~FixAdapt()
delete[] adapt[m].astyle;
delete[] adapt[m].aparam;
memory->destroy(adapt[m].vector_orig);
} else if (adapt[m].which == IMPROPER) {
delete[] adapt[m].istyle;
delete[] adapt[m].iparam;
memory->destroy(adapt[m].vector_orig);
}
}
delete[] adapt;
@ -338,6 +368,7 @@ void FixAdapt::init()
anypair = 0;
anybond = 0;
anyangle = 0;
anyimproper = 0;
for (int m = 0; m < nadapt; m++) {
Adapt *ad = &adapt[m];
@ -478,6 +509,40 @@ void FixAdapt::init()
delete[] astyle;
} else if (ad->which == IMPROPER) {
ad->improper = nullptr;
anyimproper = 1;
char *istyle = utils::strdup(ad->istyle);
if (lmp->suffix_enable)
ad->improper = force->improper_match(fmt::format("{}/{}",istyle,lmp->suffix));
if (ad->improper == nullptr) ad->improper = force->improper_match(istyle);
if (ad->improper == nullptr )
error->all(FLERR,"Fix adapt improper style {} does not exist", istyle);
void *ptr = ad->improper->extract(ad->iparam,ad->idim);
if (ptr == nullptr)
error->all(FLERR,"Fix adapt improper style parameter {} not supported", ad->iparam);
// for improper styles, use a vector
if (ad->idim == 1) ad->vector = (double *) ptr;
if (utils::strmatch(force->improper_style,"^hybrid")) {
auto improper = dynamic_cast<ImproperHybrid *>(force->improper);
if (improper) {
for (i = ad->ilo; i <= ad->ihi; i++) {
if (!improper->check_itype(i,istyle))
error->all(FLERR,"Fix adapt type improper range is not valid "
"for improper hybrid sub-style {}", istyle);
}
}
}
delete[] istyle;
} else if (ad->which == KSPACE) {
if (force->kspace == nullptr)
error->all(FLERR, Error::NOLASTLINE,
@ -504,7 +569,7 @@ void FixAdapt::init()
if (restart_reset) restart_reset = 0;
// make copy of original pair/bond/angle array values
// make copy of original pair/bond/angle/improper array values
for (int m = 0; m < nadapt; m++) {
Adapt *ad = &adapt[m];
@ -522,6 +587,10 @@ void FixAdapt::init()
} else if (ad->which == ANGLE && ad->adim == 1) {
for (i = ad->ilo; i <= ad->ihi; ++i )
ad->vector_orig[i] = ad->vector[i];
} else if (ad->which == IMPROPER && ad->idim == 1) {
for (i = ad->ilo; i <= ad->ihi; ++i )
ad->vector_orig[i] = ad->vector[i];
}
}
@ -641,6 +710,18 @@ void FixAdapt::change_settings()
ad->vector[i] = value;
}
// set improper type array values:
} else if (ad->which == IMPROPER) {
if (ad->idim == 1) {
if (scaleflag)
for (i = ad->ilo; i <= ad->ihi; ++i )
ad->vector[i] = value*ad->vector_orig[i];
else
for (i = ad->ilo; i <= ad->ihi; ++i )
ad->vector[i] = value;
}
// set kspace scale factor
} else if (ad->which == KSPACE) {
@ -716,6 +797,7 @@ void FixAdapt::change_settings()
if (anypair) force->pair->reinit();
if (anybond) force->bond->reinit();
if (anyangle) force->angle->reinit();
if (anyimproper) force->improper->reinit();
// reset KSpace charges if charges have changed
@ -750,6 +832,12 @@ void FixAdapt::restore_settings()
ad->vector[i] = ad->vector_orig[i];
}
} else if (ad->which == IMPROPER) {
if (ad->idim == 1) {
for (int i = ad->ilo; i <= ad->ihi; i++)
ad->vector[i] = ad->vector_orig[i];
}
} else if (ad->which == KSPACE) {
*kspace_scale = 1.0;
@ -790,6 +878,7 @@ void FixAdapt::restore_settings()
if (anypair) force->pair->reinit();
if (anybond) force->bond->reinit();
if (anyangle) force->angle->reinit();
if (anyimproper) force->improper->reinit();
if (chgflag && force->kspace) force->kspace->qsum_qsq();
}

View File

@ -44,7 +44,7 @@ class FixAdapt : public Fix {
private:
int nadapt, resetflag, scaleflag, massflag;
int anypair, anybond, anyangle;
int anypair, anybond, anyangle, anyimproper;
int nlevels_respa;
char *id_fix_diam, *id_fix_chg;
class FixStoreAtom *fix_diam, *fix_chg;
@ -57,8 +57,9 @@ class FixAdapt : public Fix {
char *pstyle, *pparam;
char *bstyle, *bparam;
char *astyle, *aparam;
char *istyle, *iparam;
int ilo, ihi, jlo, jhi;
int pdim, bdim, adim;
int pdim, bdim, adim, idim;
double *scalar, scalar_orig;
double *vector, *vector_orig;
double **array, **array_orig;
@ -66,6 +67,7 @@ class FixAdapt : public Fix {
class Pair *pair;
class Bond *bond;
class Angle *angle;
class Improper *improper;
};
Adapt *adapt;

View File

@ -31,6 +31,7 @@ Improper::Improper(LAMMPS *_lmp) : Pointers(_lmp)
{
energy = 0.0;
writedata = 0;
reinitflag = 1;
for (int i = 0; i < 4; i++) symmatoms[i] = 0;
allocated = 0;
@ -427,3 +428,15 @@ double Improper::memory_usage()
bytes += (double) comm->nthreads * maxvatom * 6 * sizeof(double);
return bytes;
}
/* -----------------------------------------------------------------------
reset all type-based improper params via init()
-------------------------------------------------------------------------- */
void Improper::reinit()
{
if (!reinitflag)
error->all(FLERR, "Fix adapt interface to this improper style not supported");
init();
}

View File

@ -37,6 +37,9 @@ class Improper : protected Pointers {
// CENTROID_AVAIL = different and implemented
// CENTROID_NOTAVAIL = different, not yet implemented
int reinitflag; // 0 if not compatible with fix adapt
// extract() method may still need to be added
int symmatoms[4]; // symmetry atom(s) of improper style
// value of 0: interchangable atoms
// value of 1: central atom
@ -67,6 +70,8 @@ class Improper : protected Pointers {
du = 0.0;
du2 = 0.0;
}
virtual void *extract(const char *, int &) { return nullptr; }
void reinit();
protected:
int suffix_flag; // suffix compatibility flag

View File

@ -320,6 +320,14 @@ void ImproperHybrid::init_style()
if (styles[m]) styles[m]->init_style();
}
/* ---------------------------------------------------------------------- */
int ImproperHybrid::check_itype(int itype, char *substyle)
{
if (strcmp(keywords[map[itype]], substyle) == 0) return 1;
return 0;
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */

View File

@ -40,6 +40,8 @@ class ImproperHybrid : public Improper {
void read_restart(FILE *) override;
double memory_usage() override;
int check_itype(int, char *);
protected:
int *map; // which style each improper type points to

View File

@ -720,3 +720,44 @@ TEST(ImproperStyle, numdiff)
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
}
TEST(ImproperStyle, extract)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"};
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
for (auto prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
auto *improper = lmp->force->improper;
void *ptr = nullptr;
int dim = 0;
for (auto extract : test_config.extract) {
ptr = improper->extract(extract.first.c_str(), dim);
EXPECT_NE(ptr, nullptr);
EXPECT_EQ(dim, extract.second);
}
ptr = improper->extract("does_not_exist", dim);
EXPECT_EQ(ptr, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
}

View File

@ -14,7 +14,9 @@ improper_coeff: ! |
1 75.0 169
2 45.0 10
* aa 75 42 31 125.4 130.01 115.06
extract: ! ""
extract: ! |
k 1
chi0 1
natoms: 29
init_energy: 1375.7372366975192
init_stress: ! |-

View File

@ -13,7 +13,9 @@ improper_style: cossq
improper_coeff: ! |
1 75.0 120.2
2 45.0 59.5
extract: ! ""
extract: ! |
k 1
chi0 1
natoms: 29
init_energy: 47.901206451962224
init_stress: ! |-

View File

@ -13,7 +13,10 @@ improper_style: cvff
improper_coeff: ! |
1 75.0 -1 5
2 45.0 +1 2
extract: ! ""
extract: ! |
k 1
d 1
n 1
natoms: 29
init_energy: 89.33266688553577
init_stress: ! |2-

View File

@ -13,7 +13,9 @@ improper_style: distance
improper_coeff: ! |
1 75.0 120.2
2 45.0 59.5
extract: ! ""
extract: ! |
k2 1
k4 1
natoms: 29
init_energy: 0.0747454910197192
init_stress: ! |-

View File

@ -13,7 +13,9 @@ improper_style: distharm
improper_coeff: ! |
1 75.0 5.5
2 45.0 6.2
extract: ! ""
extract: ! |
k 1
d0 1
natoms: 29
init_energy: 3973.601605432119
init_stress: ! |2-

View File

@ -13,7 +13,11 @@ improper_style: fourier
improper_coeff: ! |
1 75.0 0.9 0.2 0.3 1
2 45.0 0.5 0.1 0.8 0
extract: ! ""
extract: ! |
k 1
C0 1
C1 1
C2 1
natoms: 29
init_energy: 376.7915390602297
init_stress: ! |2-

View File

@ -13,7 +13,9 @@ improper_style: harmonic
improper_coeff: ! |
1 75.0 120.2
2 45.0 59.5
extract: ! ""
extract: ! |
k 1
chi0 1
natoms: 29
init_energy: 369.34096479618404
init_stress: ! |2-

View File

@ -13,7 +13,9 @@ improper_style: inversion/harmonic
improper_coeff: ! |
1 75.0 0.1
2 45.0 1.0
extract: ! ""
extract: ! |
k 1
w0 1
natoms: 29
init_energy: 0.35230115027159387
init_stress: ! |-

View File

@ -13,7 +13,9 @@ improper_style: ring
improper_coeff: ! |
1 75.0 120.2
2 45.0 59.5
extract: ! ""
extract: ! |
k 1
theta0 1
natoms: 29
init_energy: 31535.23771704055
init_stress: ! |-

View File

@ -13,7 +13,8 @@ improper_style: sqdistharm
improper_coeff: ! |
1 75.0 5.5
2 45.0 6.2
extract: ! ""
extract: ! |
k 1
natoms: 29
init_energy: 3997.62616072489
init_stress: ! |2-

View File

@ -13,7 +13,9 @@ improper_style: umbrella
improper_coeff: ! |
1 75.0 120.2
2 45.0 59.5
extract: ! ""
extract: ! |
k 1
w0 1
natoms: 29
init_energy: 120.51735030260785
init_stress: ! |2-