Merge pull request #4540 from evoyiatzis/fix-adapt-dihedral
extend fix adapt to treat dihedrals
This commit is contained in:
@ -14,7 +14,7 @@ Syntax
|
|||||||
* adapt = style name of this fix command
|
* adapt = style name of this fix command
|
||||||
* N = adapt simulation settings every this many timesteps
|
* N = adapt simulation settings every this many timesteps
|
||||||
* one or more attribute/arg pairs may be appended
|
* one or more attribute/arg pairs may be appended
|
||||||
* attribute = *pair* or *bond* or *angle* or *improper* or *kspace* or *atom*
|
* attribute = *pair* or *bond* or *angle* or *dihedral* or *improper* or *kspace* or *atom*
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
@ -33,6 +33,11 @@ Syntax
|
|||||||
aparam = parameter to adapt over time
|
aparam = parameter to adapt over time
|
||||||
I = type angle to set parameter for (integer or type label)
|
I = type angle to set parameter for (integer or type label)
|
||||||
v_name = variable with name that calculates value of aparam
|
v_name = variable with name that calculates value of aparam
|
||||||
|
*dihedral* args = dstyle dparam I v_name
|
||||||
|
dstyle = dihedral style name (e.g., quadratic)
|
||||||
|
dparam = parameter to adapt over time
|
||||||
|
I = type dihedral to set parameter for (integer or type label)
|
||||||
|
v_name = variable with name that calculates value of iparam
|
||||||
*improper* args = istyle iparam I v_name
|
*improper* args = istyle iparam I v_name
|
||||||
istyle = improper style name (e.g., cvff)
|
istyle = improper style name (e.g., cvff)
|
||||||
iparam = parameter to adapt over time
|
iparam = parameter to adapt over time
|
||||||
@ -433,6 +438,48 @@ this fix uses to reset theta0 needs to generate values in radians.
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
.. versionadded:: TBD
|
||||||
|
|
||||||
|
The *dihedral* keyword uses the specified variable to change the value of
|
||||||
|
a dihedral coefficient over time, very similar to how the *angle* keyword
|
||||||
|
operates. The only difference is that now a dihedral coefficient for a
|
||||||
|
given dihedral type is adapted.
|
||||||
|
|
||||||
|
A wild-card asterisk can be used in place of or in conjunction with the
|
||||||
|
dihedral type argument to set the coefficients for multiple dihedral types.
|
||||||
|
This takes the form "\*" or "\*n" or "m\*" or "m\*n". If :math:`N` is
|
||||||
|
the number of dihedral 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:`dihedral_style hybrid <dihedral_hybrid>` is used, *dstyle* should be a
|
||||||
|
sub-style name. The dihedral styles that currently work with fix adapt are:
|
||||||
|
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`charmm <dihedral_charmm>` | k,n,d | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`charmmfsw <dihedral_charmm>` | k,n,d | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`class2 <dihedral_class2>` | k1,k2,k3,phi1,phi2,phi3 | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`cosine/squared/restricted <dihedral_cosine_squared_restricted>` | k,phi0 | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`helix <dihedral_helix>` | a,b,c | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`multi/harmonic <dihedral_multi_harmonic>` | a1,a2,a3,a4,a5 | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`opls <dihedral_opls>` | k1,k2,k3,k4 | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
| :doc:`quadratic <dihedral_quadratic>` | k,phi0 | type dihedrals |
|
||||||
|
+------------------------------------------------------------------------+-------------------------+----------------+
|
||||||
|
|
||||||
|
Note that internally, phi0 is stored in radians, so the variable
|
||||||
|
this fix use to reset phi0 needs to generate values in radians.
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
.. versionadded:: 2Apr2025
|
.. versionadded:: 2Apr2025
|
||||||
|
|
||||||
The *improper* keyword uses the specified variable to change the value of
|
The *improper* keyword uses the specified variable to change the value of
|
||||||
|
|||||||
@ -946,3 +946,18 @@ void DihedralClass2::write_data(FILE *fp)
|
|||||||
at_theta0_1[i]*180.0/MY_PI,at_theta0_2[i]*180.0/MY_PI);
|
at_theta0_1[i]*180.0/MY_PI,at_theta0_2[i]*180.0/MY_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralClass2::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "k1") == 0) return (void *) k1;
|
||||||
|
if (strcmp(str, "k2") == 0) return (void *) k2;
|
||||||
|
if (strcmp(str, "k3") == 0) return (void *) k3;
|
||||||
|
if (strcmp(str, "phi1") == 0) return (void *) phi1;
|
||||||
|
if (strcmp(str, "phi2") == 0) return (void *) phi2;
|
||||||
|
if (strcmp(str, "phi3") == 0) return (void *) phi3;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class DihedralClass2 : public Dihedral {
|
|||||||
void write_restart(FILE *) override;
|
void write_restart(FILE *) override;
|
||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *k1, *k2, *k3;
|
double *k1, *k2, *k3;
|
||||||
|
|||||||
@ -393,3 +393,15 @@ void DihedralCosineSquaredRestricted::born_matrix(int nd, int i1, int i2, int i3
|
|||||||
|
|
||||||
du2 = 2 * k[type] * numerator / denominator;
|
du2 = 2 * k[type] * numerator / denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralCosineSquaredRestricted::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "k") == 0) return (void *) k;
|
||||||
|
if (strcmp(str, "phi0") == 0) return (void *) phi0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralCosineSquaredRestricted : public Dihedral {
|
|||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
void born_matrix(int, int, int, int, int, double &, double &) override;
|
void born_matrix(int, int, int, int, int, double &, double &) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *k, *phi0;
|
double *k, *phi0;
|
||||||
|
|||||||
@ -430,3 +430,16 @@ void DihedralHelix::born_matrix(int nd, int i1, int i2, int i3, int i4,
|
|||||||
du2 = -(9.0*bphi[type]*cos(3.0*phi) + cphi[type]*cos(phi + MY_PI4))*siinv*siinv +
|
du2 = -(9.0*bphi[type]*cos(3.0*phi) + cphi[type]*cos(phi + MY_PI4))*siinv*siinv +
|
||||||
(3.0*bphi[type]*sin(3.0*phi) + cphi[type]*sin(phi + MY_PI4))*c*siinv*siinv*siinv;
|
(3.0*bphi[type]*sin(3.0*phi) + cphi[type]*sin(phi + MY_PI4))*c*siinv*siinv*siinv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralHelix::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "a") == 0) return (void *) aphi;
|
||||||
|
if (strcmp(str, "b") == 0) return (void *) bphi;
|
||||||
|
if (strcmp(str, "c") == 0) return (void *) cphi;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralHelix : public Dihedral {
|
|||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
void born_matrix(int, int, int, int, int, double &, double &) override;
|
void born_matrix(int, int, int, int, int, double &, double &) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *aphi, *bphi, *cphi;
|
double *aphi, *bphi, *cphi;
|
||||||
|
|||||||
@ -435,3 +435,15 @@ void DihedralQuadratic::born_matrix(int nd, int i1, int i2, int i3, int i4,
|
|||||||
du = - 2.0 * k[type] * dphi * siinv;
|
du = - 2.0 * k[type] * dphi * siinv;
|
||||||
du2 = 2.0 * k[type] * siinv * siinv * ( 1.0 - dphi * c * siinv) ;
|
du2 = 2.0 * k[type] * siinv * siinv * ( 1.0 - dphi * c * siinv) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralQuadratic::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "k") == 0) return (void *) k;
|
||||||
|
if (strcmp(str, "phi0") == 0) return (void *) phi0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralQuadratic : public Dihedral {
|
|||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
void born_matrix(int, int, int, int, int, double &, double &) override;
|
void born_matrix(int, int, int, int, int, double &, double &) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *k, *phi0;
|
double *k, *phi0;
|
||||||
|
|||||||
@ -432,3 +432,16 @@ void DihedralCharmm::write_data(FILE *fp)
|
|||||||
for (int i = 1; i <= atom->ndihedraltypes; i++)
|
for (int i = 1; i <= atom->ndihedraltypes; i++)
|
||||||
fprintf(fp, "%d %g %d %d %g\n", i, k[i], multiplicity[i], shift[i], weight[i]);
|
fprintf(fp, "%d %g %d %d %g\n", i, k[i], multiplicity[i], shift[i], weight[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralCharmm::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "k") == 0) return (void *) k;
|
||||||
|
if (strcmp(str, "n") == 0) return (void *) multiplicity;
|
||||||
|
if (strcmp(str, "d") == 0) return (void *) shift;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralCharmm : public Dihedral {
|
|||||||
void write_restart(FILE *) override;
|
void write_restart(FILE *) override;
|
||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *k, *weight, *cos_shift, *sin_shift;
|
double *k, *weight, *cos_shift, *sin_shift;
|
||||||
|
|||||||
@ -475,3 +475,16 @@ void DihedralCharmmfsw::write_data(FILE *fp)
|
|||||||
for (int i = 1; i <= atom->ndihedraltypes; i++)
|
for (int i = 1; i <= atom->ndihedraltypes; i++)
|
||||||
fprintf(fp, "%d %g %d %d %g\n", i, k[i], multiplicity[i], shift[i], weight[i]);
|
fprintf(fp, "%d %g %d %d %g\n", i, k[i], multiplicity[i], shift[i], weight[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralCharmmfsw::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "k") == 0) return (void *) k;
|
||||||
|
if (strcmp(str, "n") == 0) return (void *) multiplicity;
|
||||||
|
if (strcmp(str, "d") == 0) return (void *) shift;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralCharmmfsw : public Dihedral {
|
|||||||
void write_restart(FILE *) override;
|
void write_restart(FILE *) override;
|
||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int implicit, weightflag, dihedflag;
|
int implicit, weightflag, dihedflag;
|
||||||
|
|||||||
@ -407,3 +407,19 @@ void DihedralMultiHarmonic::born_matrix(int nd, int i1, int i2, int i3, int i4,
|
|||||||
du = a2[type] + c * (2.0 * a3[type] + c * (3.0 * a4[type] + c * 4.0 * a5[type]));
|
du = a2[type] + c * (2.0 * a3[type] + c * (3.0 * a4[type] + c * 4.0 * a5[type]));
|
||||||
du2 = 2.0 * a3[type] + 6.0 * c * (a4[type] + 2.0 * a5[type] * c);
|
du2 = 2.0 * a3[type] + 6.0 * c * (a4[type] + 2.0 * a5[type] * c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralMultiHarmonic::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "a1") == 0) return (void *) a1;
|
||||||
|
if (strcmp(str, "a2") == 0) return (void *) a2;
|
||||||
|
if (strcmp(str, "a3") == 0) return (void *) a3;
|
||||||
|
if (strcmp(str, "a4") == 0) return (void *) a4;
|
||||||
|
if (strcmp(str, "a5") == 0) return (void *) a5;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralMultiHarmonic : public Dihedral {
|
|||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
void born_matrix(int, int, int, int, int, double &, double &) override;
|
void born_matrix(int, int, int, int, int, double &, double &) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *a1, *a2, *a3, *a4, *a5;
|
double *a1, *a2, *a3, *a4, *a5;
|
||||||
|
|||||||
@ -431,3 +431,17 @@ void DihedralOPLS::born_matrix(int nd, int i1, int i2, int i3, int i4, double &d
|
|||||||
16.0 * k4[type] * si * cos(4.0 * phi) - 4.0 * k4[type] * sin(4.0 * phi)) /
|
16.0 * k4[type] * si * cos(4.0 * phi) - 4.0 * k4[type] * sin(4.0 * phi)) /
|
||||||
(si * si * si);
|
(si * si * si);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return ptr to internal members upon request
|
||||||
|
------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
void *DihedralOPLS::extract(const char *str, int &dim)
|
||||||
|
{
|
||||||
|
dim = 1;
|
||||||
|
if (strcmp(str, "k1") == 0) return (void *) k1;
|
||||||
|
if (strcmp(str, "k2") == 0) return (void *) k2;
|
||||||
|
if (strcmp(str, "k3") == 0) return (void *) k3;
|
||||||
|
if (strcmp(str, "k4") == 0) return (void *) k4;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class DihedralOPLS : public Dihedral {
|
|||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
void write_data(FILE *) override;
|
void write_data(FILE *) override;
|
||||||
void born_matrix(int, int, int, int, int, double &, double &) override;
|
void born_matrix(int, int, int, int, int, double &, double &) override;
|
||||||
|
void *extract(const char *, int &) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double *k1, *k2, *k3, *k4;
|
double *k1, *k2, *k3, *k4;
|
||||||
|
|||||||
@ -33,6 +33,7 @@ Dihedral::Dihedral(LAMMPS *_lmp) : Pointers(_lmp)
|
|||||||
{
|
{
|
||||||
energy = 0.0;
|
energy = 0.0;
|
||||||
writedata = 0;
|
writedata = 0;
|
||||||
|
reinitflag = 1;
|
||||||
|
|
||||||
allocated = 0;
|
allocated = 0;
|
||||||
suffix_flag = Suffix::NONE;
|
suffix_flag = Suffix::NONE;
|
||||||
@ -428,3 +429,15 @@ double Dihedral::memory_usage()
|
|||||||
bytes += (double) comm->nthreads * maxcvatom * 9 * sizeof(double);
|
bytes += (double) comm->nthreads * maxcvatom * 9 * sizeof(double);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
reset all type-based dihedral params via init()
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Dihedral::reinit()
|
||||||
|
{
|
||||||
|
if (!reinitflag)
|
||||||
|
error->all(FLERR, "Fix adapt interface to this dihedral style not supported");
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|||||||
@ -37,6 +37,9 @@ class Dihedral : protected Pointers {
|
|||||||
// CENTROID_AVAIL = different and implemented
|
// CENTROID_AVAIL = different and implemented
|
||||||
// CENTROID_NOTAVAIL = different, not yet implemented
|
// CENTROID_NOTAVAIL = different, not yet implemented
|
||||||
|
|
||||||
|
int reinitflag; // 0 if not compatible with fix adapt
|
||||||
|
// extract() method may still need to be added
|
||||||
|
|
||||||
// KOKKOS host/device flag and data masks
|
// KOKKOS host/device flag and data masks
|
||||||
|
|
||||||
ExecutionSpace execution_space;
|
ExecutionSpace execution_space;
|
||||||
@ -62,6 +65,8 @@ class Dihedral : protected Pointers {
|
|||||||
du = 0.0;
|
du = 0.0;
|
||||||
du2 = 0.0;
|
du2 = 0.0;
|
||||||
}
|
}
|
||||||
|
virtual void *extract(const char *, int &) { return nullptr; }
|
||||||
|
void reinit();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int suffix_flag; // suffix compatibility flag
|
int suffix_flag; // suffix compatibility flag
|
||||||
|
|||||||
@ -326,6 +326,14 @@ void DihedralHybrid::init_style()
|
|||||||
if (styles[m]) styles[m]->init_style();
|
if (styles[m]) styles[m]->init_style();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int DihedralHybrid::check_itype(int itype, char *substyle)
|
||||||
|
{
|
||||||
|
if (strcmp(keywords[map[itype]], substyle) == 0) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
proc 0 writes to restart file
|
proc 0 writes to restart file
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -40,6 +40,8 @@ class DihedralHybrid : public Dihedral {
|
|||||||
void read_restart(FILE *) override;
|
void read_restart(FILE *) override;
|
||||||
double memory_usage() override;
|
double memory_usage() override;
|
||||||
|
|
||||||
|
int check_itype(int, char *);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int *map; // which style each dihedral type points to
|
int *map; // which style each dihedral type points to
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,8 @@
|
|||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
#include "bond.h"
|
#include "bond.h"
|
||||||
#include "bond_hybrid.h"
|
#include "bond_hybrid.h"
|
||||||
|
#include "dihedral.h"
|
||||||
|
#include "dihedral_hybrid.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "fix_store_atom.h"
|
#include "fix_store_atom.h"
|
||||||
@ -43,14 +45,14 @@ using namespace LAMMPS_NS;
|
|||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
using namespace MathConst;
|
using namespace MathConst;
|
||||||
|
|
||||||
enum{PAIR, KSPACE, ATOM, BOND, ANGLE, IMPROPER};
|
enum{PAIR, KSPACE, ATOM, BOND, ANGLE, DIHEDRAL, IMPROPER};
|
||||||
enum{DIAMETER, CHARGE};
|
enum{DIAMETER, CHARGE};
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
|
FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg), nadapt(0), anypair(0), anybond(0), anyangle(0),
|
Fix(lmp, narg, arg), nadapt(0), anypair(0), anybond(0), anyangle(0),
|
||||||
anyimproper(0), id_fix_diam(nullptr), id_fix_chg(nullptr), adapt(nullptr)
|
anydihedral(0), anyimproper(0), id_fix_diam(nullptr), id_fix_chg(nullptr), adapt(nullptr)
|
||||||
{
|
{
|
||||||
if (narg < 5) utils::missing_cmd_args(FLERR,"fix adapt", error);
|
if (narg < 5) utils::missing_cmd_args(FLERR,"fix adapt", error);
|
||||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||||
@ -85,6 +87,10 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt angle", error);
|
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt angle", error);
|
||||||
nadapt++;
|
nadapt++;
|
||||||
iarg += 5;
|
iarg += 5;
|
||||||
|
} else if (strcmp(arg[iarg],"dihedral") == 0) {
|
||||||
|
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt dihedral", error);
|
||||||
|
nadapt++;
|
||||||
|
iarg += 5;
|
||||||
} else if (strcmp(arg[iarg],"improper") == 0) {
|
} else if (strcmp(arg[iarg],"improper") == 0) {
|
||||||
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt improper", error);
|
if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"fix adapt improper", error);
|
||||||
nadapt++;
|
nadapt++;
|
||||||
@ -155,6 +161,19 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
nadapt++;
|
nadapt++;
|
||||||
iarg += 5;
|
iarg += 5;
|
||||||
|
|
||||||
|
} else if (strcmp(arg[iarg],"dihedral") == 0) {
|
||||||
|
adapt[nadapt].which = DIHEDRAL;
|
||||||
|
adapt[nadapt].dihedral = nullptr;
|
||||||
|
adapt[nadapt].dstyle = utils::strdup(arg[iarg+1]);
|
||||||
|
adapt[nadapt].dparam = utils::strdup(arg[iarg+2]);
|
||||||
|
utils::bounds_typelabel(FLERR, arg[iarg+3], 1, atom->ndihedraltypes,
|
||||||
|
adapt[nadapt].ilo, adapt[nadapt].ihi, lmp, Atom::DIHEDRAL);
|
||||||
|
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],"improper") == 0) {
|
} else if (strcmp(arg[iarg],"improper") == 0) {
|
||||||
adapt[nadapt].which = IMPROPER;
|
adapt[nadapt].which = IMPROPER;
|
||||||
adapt[nadapt].improper = nullptr;
|
adapt[nadapt].improper = nullptr;
|
||||||
@ -246,6 +265,12 @@ FixAdapt::FixAdapt(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
// allocate improper style arrays:
|
// allocate improper style arrays:
|
||||||
|
|
||||||
|
n = atom->ndihedraltypes;
|
||||||
|
for (int m = 0; m < nadapt; ++m)
|
||||||
|
if (adapt[m].which == DIHEDRAL) memory->create(adapt[m].vector_orig,n+1,"adapt:vector_orig");
|
||||||
|
|
||||||
|
// allocate improper style arrays:
|
||||||
|
|
||||||
n = atom->nimpropertypes;
|
n = atom->nimpropertypes;
|
||||||
for (int m = 0; m < nadapt; ++m)
|
for (int m = 0; m < nadapt; ++m)
|
||||||
if (adapt[m].which == IMPROPER) memory->create(adapt[m].vector_orig,n+1,"adapt:vector_orig");
|
if (adapt[m].which == IMPROPER) memory->create(adapt[m].vector_orig,n+1,"adapt:vector_orig");
|
||||||
@ -270,6 +295,10 @@ FixAdapt::~FixAdapt()
|
|||||||
delete[] adapt[m].astyle;
|
delete[] adapt[m].astyle;
|
||||||
delete[] adapt[m].aparam;
|
delete[] adapt[m].aparam;
|
||||||
memory->destroy(adapt[m].vector_orig);
|
memory->destroy(adapt[m].vector_orig);
|
||||||
|
} else if (adapt[m].which == DIHEDRAL) {
|
||||||
|
delete[] adapt[m].dstyle;
|
||||||
|
delete[] adapt[m].dparam;
|
||||||
|
memory->destroy(adapt[m].vector_orig);
|
||||||
} else if (adapt[m].which == IMPROPER) {
|
} else if (adapt[m].which == IMPROPER) {
|
||||||
delete[] adapt[m].istyle;
|
delete[] adapt[m].istyle;
|
||||||
delete[] adapt[m].iparam;
|
delete[] adapt[m].iparam;
|
||||||
@ -368,6 +397,7 @@ void FixAdapt::init()
|
|||||||
anypair = 0;
|
anypair = 0;
|
||||||
anybond = 0;
|
anybond = 0;
|
||||||
anyangle = 0;
|
anyangle = 0;
|
||||||
|
anydihedral = 0;
|
||||||
anyimproper = 0;
|
anyimproper = 0;
|
||||||
|
|
||||||
for (int m = 0; m < nadapt; m++) {
|
for (int m = 0; m < nadapt; m++) {
|
||||||
@ -509,6 +539,40 @@ void FixAdapt::init()
|
|||||||
|
|
||||||
delete[] astyle;
|
delete[] astyle;
|
||||||
|
|
||||||
|
} else if (ad->which == DIHEDRAL) {
|
||||||
|
ad->dihedral = nullptr;
|
||||||
|
anydihedral = 1;
|
||||||
|
|
||||||
|
char *dstyle = utils::strdup(ad->dstyle);
|
||||||
|
if (lmp->suffix_enable)
|
||||||
|
ad->dihedral = force->dihedral_match(fmt::format("{}/{}",dstyle,lmp->suffix));
|
||||||
|
|
||||||
|
if (ad->dihedral == nullptr) ad->dihedral = force->dihedral_match(dstyle);
|
||||||
|
if (ad->dihedral == nullptr )
|
||||||
|
error->all(FLERR,"Fix adapt dihedral style {} does not exist", dstyle);
|
||||||
|
|
||||||
|
void *ptr = ad->dihedral->extract(ad->dparam,ad->ddim);
|
||||||
|
|
||||||
|
if (ptr == nullptr)
|
||||||
|
error->all(FLERR,"Fix adapt dihedral style parameter {} not supported", ad->dparam);
|
||||||
|
|
||||||
|
// for dihedral styles, use a vector
|
||||||
|
|
||||||
|
if (ad->ddim == 1) ad->vector = (double *) ptr;
|
||||||
|
|
||||||
|
if (utils::strmatch(force->dihedral_style,"^hybrid")) {
|
||||||
|
auto dihedral = dynamic_cast<DihedralHybrid *>(force->dihedral);
|
||||||
|
if (dihedral) {
|
||||||
|
for (i = ad->ilo; i <= ad->ihi; i++) {
|
||||||
|
if (!dihedral->check_itype(i,dstyle))
|
||||||
|
error->all(FLERR,"Fix adapt type dihedral range is not valid "
|
||||||
|
"for dihedral hybrid sub-style {}", dstyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] dstyle;
|
||||||
|
|
||||||
} else if (ad->which == IMPROPER) {
|
} else if (ad->which == IMPROPER) {
|
||||||
ad->improper = nullptr;
|
ad->improper = nullptr;
|
||||||
anyimproper = 1;
|
anyimproper = 1;
|
||||||
@ -569,7 +633,7 @@ void FixAdapt::init()
|
|||||||
|
|
||||||
if (restart_reset) restart_reset = 0;
|
if (restart_reset) restart_reset = 0;
|
||||||
|
|
||||||
// make copy of original pair/bond/angle/improper array values
|
// make copy of original pair/bond/angle/dihedral/improper array values
|
||||||
|
|
||||||
for (int m = 0; m < nadapt; m++) {
|
for (int m = 0; m < nadapt; m++) {
|
||||||
Adapt *ad = &adapt[m];
|
Adapt *ad = &adapt[m];
|
||||||
@ -588,6 +652,10 @@ void FixAdapt::init()
|
|||||||
for (i = ad->ilo; i <= ad->ihi; ++i )
|
for (i = ad->ilo; i <= ad->ihi; ++i )
|
||||||
ad->vector_orig[i] = ad->vector[i];
|
ad->vector_orig[i] = ad->vector[i];
|
||||||
|
|
||||||
|
} else if (ad->which == DIHEDRAL && ad->ddim == 1) {
|
||||||
|
for (i = ad->ilo; i <= ad->ihi; ++i )
|
||||||
|
ad->vector_orig[i] = ad->vector[i];
|
||||||
|
|
||||||
} else if (ad->which == IMPROPER && ad->idim == 1) {
|
} else if (ad->which == IMPROPER && ad->idim == 1) {
|
||||||
for (i = ad->ilo; i <= ad->ihi; ++i )
|
for (i = ad->ilo; i <= ad->ihi; ++i )
|
||||||
ad->vector_orig[i] = ad->vector[i];
|
ad->vector_orig[i] = ad->vector[i];
|
||||||
@ -710,6 +778,18 @@ void FixAdapt::change_settings()
|
|||||||
ad->vector[i] = value;
|
ad->vector[i] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set dihedral type array values:
|
||||||
|
|
||||||
|
} else if (ad->which == DIHEDRAL) {
|
||||||
|
if (ad->ddim == 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 improper type array values:
|
// set improper type array values:
|
||||||
|
|
||||||
} else if (ad->which == IMPROPER) {
|
} else if (ad->which == IMPROPER) {
|
||||||
@ -797,6 +877,7 @@ void FixAdapt::change_settings()
|
|||||||
if (anypair) force->pair->reinit();
|
if (anypair) force->pair->reinit();
|
||||||
if (anybond) force->bond->reinit();
|
if (anybond) force->bond->reinit();
|
||||||
if (anyangle) force->angle->reinit();
|
if (anyangle) force->angle->reinit();
|
||||||
|
if (anydihedral) force->dihedral->reinit();
|
||||||
if (anyimproper) force->improper->reinit();
|
if (anyimproper) force->improper->reinit();
|
||||||
|
|
||||||
// reset KSpace charges if charges have changed
|
// reset KSpace charges if charges have changed
|
||||||
@ -832,6 +913,12 @@ void FixAdapt::restore_settings()
|
|||||||
ad->vector[i] = ad->vector_orig[i];
|
ad->vector[i] = ad->vector_orig[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (ad->which == DIHEDRAL) {
|
||||||
|
if (ad->ddim == 1) {
|
||||||
|
for (int i = ad->ilo; i <= ad->ihi; i++)
|
||||||
|
ad->vector[i] = ad->vector_orig[i];
|
||||||
|
}
|
||||||
|
|
||||||
} else if (ad->which == IMPROPER) {
|
} else if (ad->which == IMPROPER) {
|
||||||
if (ad->idim == 1) {
|
if (ad->idim == 1) {
|
||||||
for (int i = ad->ilo; i <= ad->ihi; i++)
|
for (int i = ad->ilo; i <= ad->ihi; i++)
|
||||||
@ -878,6 +965,7 @@ void FixAdapt::restore_settings()
|
|||||||
if (anypair) force->pair->reinit();
|
if (anypair) force->pair->reinit();
|
||||||
if (anybond) force->bond->reinit();
|
if (anybond) force->bond->reinit();
|
||||||
if (anyangle) force->angle->reinit();
|
if (anyangle) force->angle->reinit();
|
||||||
|
if (anydihedral) force->dihedral->reinit();
|
||||||
if (anyimproper) force->improper->reinit();
|
if (anyimproper) force->improper->reinit();
|
||||||
if (chgflag && force->kspace) force->kspace->qsum_qsq();
|
if (chgflag && force->kspace) force->kspace->qsum_qsq();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class FixAdapt : public Fix {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int nadapt, resetflag, scaleflag, massflag;
|
int nadapt, resetflag, scaleflag, massflag;
|
||||||
int anypair, anybond, anyangle, anyimproper;
|
int anypair, anybond, anyangle, anydihedral, anyimproper;
|
||||||
int nlevels_respa;
|
int nlevels_respa;
|
||||||
char *id_fix_diam, *id_fix_chg;
|
char *id_fix_diam, *id_fix_chg;
|
||||||
class FixStoreAtom *fix_diam, *fix_chg;
|
class FixStoreAtom *fix_diam, *fix_chg;
|
||||||
@ -57,9 +57,10 @@ class FixAdapt : public Fix {
|
|||||||
char *pstyle, *pparam;
|
char *pstyle, *pparam;
|
||||||
char *bstyle, *bparam;
|
char *bstyle, *bparam;
|
||||||
char *astyle, *aparam;
|
char *astyle, *aparam;
|
||||||
|
char *dstyle, *dparam;
|
||||||
char *istyle, *iparam;
|
char *istyle, *iparam;
|
||||||
int ilo, ihi, jlo, jhi;
|
int ilo, ihi, jlo, jhi;
|
||||||
int pdim, bdim, adim, idim;
|
int pdim, bdim, adim, ddim, idim;
|
||||||
double *scalar, scalar_orig;
|
double *scalar, scalar_orig;
|
||||||
double *vector, *vector_orig;
|
double *vector, *vector_orig;
|
||||||
double **array, **array_orig;
|
double **array, **array_orig;
|
||||||
@ -67,6 +68,7 @@ class FixAdapt : public Fix {
|
|||||||
class Pair *pair;
|
class Pair *pair;
|
||||||
class Bond *bond;
|
class Bond *bond;
|
||||||
class Angle *angle;
|
class Angle *angle;
|
||||||
|
class Dihedral *dihedral;
|
||||||
class Improper *improper;
|
class Improper *improper;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -746,3 +746,44 @@ TEST(DihedralStyle, numdiff)
|
|||||||
cleanup_lammps(lmp, test_config);
|
cleanup_lammps(lmp, test_config);
|
||||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DihedralStyle, extract)
|
||||||
|
{
|
||||||
|
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
|
||||||
|
|
||||||
|
LAMMPS::argv args = {"DihedralStyle", "-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 *dihedral = lmp->force->dihedral;
|
||||||
|
void *ptr = nullptr;
|
||||||
|
int dim = 0;
|
||||||
|
for (auto extract : test_config.extract) {
|
||||||
|
ptr = dihedral->extract(extract.first.c_str(), dim);
|
||||||
|
EXPECT_NE(ptr, nullptr);
|
||||||
|
EXPECT_EQ(dim, extract.second);
|
||||||
|
}
|
||||||
|
ptr = dihedral->extract("does_not_exist", dim);
|
||||||
|
EXPECT_EQ(ptr, nullptr);
|
||||||
|
|
||||||
|
if (!verbose) ::testing::internal::CaptureStdout();
|
||||||
|
cleanup_lammps(lmp, test_config);
|
||||||
|
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||||
|
}
|
||||||
|
|||||||
@ -19,7 +19,10 @@ dihedral_coeff: ! |
|
|||||||
3 56.0 0 110 0.0
|
3 56.0 0 110 0.0
|
||||||
4 23.0 1 180 0.5
|
4 23.0 1 180 0.5
|
||||||
5 19.0 3 90 1.0
|
5 19.0 3 90 1.0
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
k 1
|
||||||
|
n 1
|
||||||
|
d 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 1317.959844120986
|
init_energy: 1317.959844120986
|
||||||
init_stress: ! |2-
|
init_stress: ! |2-
|
||||||
|
|||||||
@ -19,7 +19,10 @@ dihedral_coeff: ! |
|
|||||||
3 56.0 0 110 0.0
|
3 56.0 0 110 0.0
|
||||||
4 23.0 1 180 0.5
|
4 23.0 1 180 0.5
|
||||||
5 19.0 3 90 1.0
|
5 19.0 3 90 1.0
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
k 1
|
||||||
|
n 1
|
||||||
|
d 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 1317.959844120986
|
init_energy: 1317.959844120986
|
||||||
init_stress: ! |2-
|
init_stress: ! |2-
|
||||||
|
|||||||
@ -17,7 +17,13 @@ dihedral_coeff: ! |
|
|||||||
* at 75 42 31 75 42 31 120 50
|
* at 75 42 31 75 42 31 120 50
|
||||||
* aat 75 120 160
|
* aat 75 120 160
|
||||||
* bb13 75 1.4 1.4
|
* bb13 75 1.4 1.4
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
k1 1
|
||||||
|
k2 1
|
||||||
|
k3 1
|
||||||
|
phi1 1
|
||||||
|
phi2 1
|
||||||
|
phi3 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 3355.0074717375933
|
init_energy: 3355.0074717375933
|
||||||
init_stress: ! |2-
|
init_stress: ! |2-
|
||||||
|
|||||||
@ -16,7 +16,9 @@ dihedral_coeff: ! |
|
|||||||
3 15.0 -10.0
|
3 15.0 -10.0
|
||||||
4 12.0 0.0
|
4 12.0 0.0
|
||||||
5 11.0 45.0
|
5 11.0 45.0
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
k 1
|
||||||
|
phi0 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 10643.96352037142
|
init_energy: 10643.96352037142
|
||||||
init_stress: ! |2-
|
init_stress: ! |2-
|
||||||
|
|||||||
@ -16,7 +16,10 @@ dihedral_coeff: ! |
|
|||||||
3 56 10 32
|
3 56 10 32
|
||||||
4 23 80 61
|
4 23 80 61
|
||||||
5 19 90 13
|
5 19 90 13
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
a 1
|
||||||
|
b 1
|
||||||
|
c 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 4634.436545707672
|
init_energy: 4634.436545707672
|
||||||
init_stress: ! |-
|
init_stress: ! |-
|
||||||
|
|||||||
@ -16,7 +16,12 @@ dihedral_coeff: ! |
|
|||||||
3 56 10 32 84 52
|
3 56 10 32 84 52
|
||||||
4 23 80 61 83 74
|
4 23 80 61 83 74
|
||||||
5 19 90 13 15 58
|
5 19 90 13 15 58
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
a1 1
|
||||||
|
a2 1
|
||||||
|
a3 1
|
||||||
|
a4 1
|
||||||
|
a5 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 2854.9857316566695
|
init_energy: 2854.9857316566695
|
||||||
init_stress: ! |2-
|
init_stress: ! |2-
|
||||||
|
|||||||
@ -16,7 +16,11 @@ dihedral_coeff: ! |
|
|||||||
3 56 10 32 84
|
3 56 10 32 84
|
||||||
4 23 80 61 83
|
4 23 80 61 83
|
||||||
5 19 90 13 15
|
5 19 90 13 15
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
k1 1
|
||||||
|
k2 1
|
||||||
|
k3 1
|
||||||
|
k4 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 2260.6834525285753
|
init_energy: 2260.6834525285753
|
||||||
init_stress: ! |-
|
init_stress: ! |-
|
||||||
|
|||||||
@ -17,7 +17,9 @@ dihedral_coeff: ! |
|
|||||||
3 25 100
|
3 25 100
|
||||||
4 35 110
|
4 35 110
|
||||||
5 85 120
|
5 85 120
|
||||||
extract: ! ""
|
extract: ! |
|
||||||
|
k 1
|
||||||
|
phi0 1
|
||||||
natoms: 29
|
natoms: 29
|
||||||
init_energy: 6216.314347066598
|
init_energy: 6216.314347066598
|
||||||
init_stress: ! |2-
|
init_stress: ! |2-
|
||||||
|
|||||||
Reference in New Issue
Block a user