Merge pull request #4467 from evoyiatzis/patch-2
extend fix adapt to treat improper angles
This commit is contained in:
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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: ! |-
|
||||
|
||||
@ -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: ! |-
|
||||
|
||||
@ -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-
|
||||
|
||||
@ -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: ! |-
|
||||
|
||||
@ -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-
|
||||
|
||||
@ -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-
|
||||
|
||||
@ -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-
|
||||
|
||||
@ -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: ! |-
|
||||
|
||||
@ -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: ! |-
|
||||
|
||||
@ -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-
|
||||
|
||||
@ -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-
|
||||
|
||||
Reference in New Issue
Block a user