complete region handling refactor
This commit is contained in:
@ -387,7 +387,7 @@ double LammpsInterface::atom_quantity_conversion(FundamentalAtomQuantity quantit
|
|||||||
|
|
||||||
int LammpsInterface::dimension() const { return lammps_->domain->dimension; }
|
int LammpsInterface::dimension() const { return lammps_->domain->dimension; }
|
||||||
|
|
||||||
int LammpsInterface::nregion() const { return lammps_->domain->nregion; }
|
int LammpsInterface::nregion() const { return lammps_->domain->get_region_list().size(); }
|
||||||
|
|
||||||
void LammpsInterface::box_bounds(double & boxxlo, double & boxxhi,
|
void LammpsInterface::box_bounds(double & boxxlo, double & boxxhi,
|
||||||
double & boxylo, double & boxyhi,
|
double & boxylo, double & boxyhi,
|
||||||
@ -527,14 +527,15 @@ void LammpsInterface::box_periodicity(int & xperiodic,
|
|||||||
zperiodic = lammps_->domain->zperiodic;
|
zperiodic = lammps_->domain->zperiodic;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LammpsInterface::region_id(const char * regionName) const {
|
int LammpsInterface::region_id(const char *regionName) const {
|
||||||
int nregion = this->nregion();
|
auto regions = lammps_->domain->get_region_list();
|
||||||
for (int iregion = 0; iregion < nregion; iregion++) {
|
int iregion = 0;
|
||||||
if (strcmp(regionName, region_name(iregion)) == 0) {
|
for (auto reg : regions) {
|
||||||
|
if (strcmp(regionName, reg->id) == 0) {
|
||||||
return iregion;
|
return iregion;
|
||||||
}
|
}
|
||||||
|
++iregion;
|
||||||
}
|
}
|
||||||
throw ATC_Error("Region has not been defined");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1322,61 +1323,73 @@ int** LammpsInterface::bond_list() const { return lammps_->neighbor->bondlist;
|
|||||||
|
|
||||||
char * LammpsInterface::region_name(int iRegion) const
|
char * LammpsInterface::region_name(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->id;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * LammpsInterface::region_style(int iRegion) const
|
char * LammpsInterface::region_style(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->style;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->style;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_xlo(int iRegion) const
|
double LammpsInterface::region_xlo(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->extent_xlo;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->extent_xlo;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_xhi(int iRegion) const
|
double LammpsInterface::region_xhi(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->extent_xhi;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->extent_xhi;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_ylo(int iRegion) const
|
double LammpsInterface::region_ylo(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->extent_ylo;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->extent_ylo;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_yhi(int iRegion) const
|
double LammpsInterface::region_yhi(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->extent_yhi;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->extent_yhi;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_zlo(int iRegion) const
|
double LammpsInterface::region_zlo(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->extent_zlo;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->extent_zlo;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_zhi(int iRegion) const
|
double LammpsInterface::region_zhi(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->extent_zhi;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->extent_zhi;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_xscale(int iRegion) const
|
double LammpsInterface::region_xscale(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->xscale;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->xscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_yscale(int iRegion) const
|
double LammpsInterface::region_yscale(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->yscale;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->yscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
double LammpsInterface::region_zscale(int iRegion) const
|
double LammpsInterface::region_zscale(int iRegion) const
|
||||||
{
|
{
|
||||||
return lammps_->domain->regions[iRegion]->zscale;
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->zscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LammpsInterface::region_match(int iRegion, double x, double y, double z) const {
|
int LammpsInterface::region_match(int iRegion, double x, double y, double z) const {
|
||||||
return lammps_->domain->regions[iRegion]->match(x,y,z);
|
auto regions = lammps_->domain->get_region_list();
|
||||||
|
return regions[iRegion]->match(x,y,z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|||||||
@ -273,7 +273,7 @@ void DumpCustomADIOS::init_style()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set index and check validity of region
|
// set index and check validity of region
|
||||||
if (idregion && !domain->find_region(idregion))
|
if (idregion && !domain->get_region_by_id(idregion))
|
||||||
error->all(FLERR, "Region {} for dump custom/adios does not exist", idregion);
|
error->all(FLERR, "Region {} for dump custom/adios does not exist", idregion);
|
||||||
|
|
||||||
/* Define the group of variables for the atom style here since it's a fixed
|
/* Define the group of variables for the atom style here since it's a fixed
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -16,7 +15,6 @@
|
|||||||
Contributing author: Andres Jaramillo-Botero (Caltech)
|
Contributing author: Andres Jaramillo-Botero (Caltech)
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
#include "compute_temp_region_eff.h"
|
#include "compute_temp_region_eff.h"
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
@ -33,16 +31,15 @@ using namespace LAMMPS_NS;
|
|||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
ComputeTempRegionEff::ComputeTempRegionEff(LAMMPS *lmp, int narg, char **arg) :
|
ComputeTempRegionEff::ComputeTempRegionEff(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Compute(lmp, narg, arg)
|
Compute(lmp, narg, arg), region(nullptr), idregion(nullptr)
|
||||||
{
|
{
|
||||||
if (!atom->electron_flag)
|
if (!atom->electron_flag)
|
||||||
error->all(FLERR,"Compute temp/region/eff requires atom style electron");
|
error->all(FLERR, "Compute temp/region/eff requires atom style electron");
|
||||||
|
|
||||||
if (narg != 4) error->all(FLERR,"Illegal compute temp/region/eff command");
|
if (narg != 4) error->all(FLERR, "Illegal compute temp/region/eff command");
|
||||||
|
|
||||||
iregion = domain->find_region(arg[3]);
|
region = domain->get_region_by_id(arg[3]);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for compute temp/region/eff does not exist", arg[3]);
|
||||||
error->all(FLERR,"Region ID for compute temp/region/eff does not exist");
|
|
||||||
idregion = utils::strdup(arg[3]);
|
idregion = utils::strdup(arg[3]);
|
||||||
|
|
||||||
scalar_flag = vector_flag = 1;
|
scalar_flag = vector_flag = 1;
|
||||||
@ -61,9 +58,9 @@ ComputeTempRegionEff::ComputeTempRegionEff(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
ComputeTempRegionEff::~ComputeTempRegionEff()
|
ComputeTempRegionEff::~ComputeTempRegionEff()
|
||||||
{
|
{
|
||||||
delete [] idregion;
|
delete[] idregion;
|
||||||
memory->destroy(vbiasall);
|
memory->destroy(vbiasall);
|
||||||
delete [] vector;
|
delete[] vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -72,9 +69,8 @@ void ComputeTempRegionEff::init()
|
|||||||
{
|
{
|
||||||
// set index and check validity of region
|
// set index and check validity of region
|
||||||
|
|
||||||
iregion = domain->find_region(idregion);
|
region = domain->get_region_by_id(idregion);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for compute temp/region/eff does not exist", idregion);
|
||||||
error->all(FLERR,"Region ID for compute temp/region/eff does not exist");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -90,7 +86,7 @@ void ComputeTempRegionEff::setup()
|
|||||||
|
|
||||||
void ComputeTempRegionEff::dof_remove_pre()
|
void ComputeTempRegionEff::dof_remove_pre()
|
||||||
{
|
{
|
||||||
domain->regions[iregion]->prematch();
|
region->prematch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -98,7 +94,7 @@ void ComputeTempRegionEff::dof_remove_pre()
|
|||||||
int ComputeTempRegionEff::dof_remove(int i)
|
int ComputeTempRegionEff::dof_remove(int i)
|
||||||
{
|
{
|
||||||
double *x = atom->x[i];
|
double *x = atom->x[i];
|
||||||
if (domain->regions[iregion]->match(x[0],x[1],x[2])) return 0;
|
if (region->match(x[0], x[1], x[2])) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +112,8 @@ double ComputeTempRegionEff::compute_scalar()
|
|||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
double mefactor = domain->dimension/4.0;
|
double mefactor = domain->dimension / 4.0;
|
||||||
|
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -127,34 +122,35 @@ double ComputeTempRegionEff::compute_scalar()
|
|||||||
|
|
||||||
if (mass) {
|
if (mass) {
|
||||||
for (int i = 0; i < nlocal; i++)
|
for (int i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) {
|
||||||
count++;
|
count++;
|
||||||
t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
|
t += (v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2]) * mass[type[i]];
|
||||||
mass[type[i]];
|
if (abs(spin[i]) == 1) {
|
||||||
if (abs(spin[i])==1) {
|
t += mefactor * mass[type[i]] * ervel[i] * ervel[i];
|
||||||
t += mefactor*mass[type[i]]*ervel[i]*ervel[i];
|
|
||||||
ecount++;
|
ecount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double tarray[2],tarray_all[2];
|
double tarray[2], tarray_all[2];
|
||||||
// Assume 3/2 k T per nucleus
|
// Assume 3/2 k T per nucleus
|
||||||
tarray[0] = count-ecount;
|
tarray[0] = count - ecount;
|
||||||
tarray[1] = t;
|
tarray[1] = t;
|
||||||
MPI_Allreduce(tarray,tarray_all,2,MPI_DOUBLE,MPI_SUM,world);
|
MPI_Allreduce(tarray, tarray_all, 2, MPI_DOUBLE, MPI_SUM, world);
|
||||||
dof = domain->dimension * tarray_all[0] - extra_dof;
|
dof = domain->dimension * tarray_all[0] - extra_dof;
|
||||||
if (dof < 0.0 && tarray_all[0] > 0.0)
|
if (dof < 0.0 && tarray_all[0] > 0.0)
|
||||||
error->all(FLERR,"Temperature compute degrees of freedom < 0");
|
error->all(FLERR, "Temperature compute degrees of freedom < 0");
|
||||||
|
|
||||||
int one = 0;
|
int one = 0;
|
||||||
for (int i = 0; i < nlocal; i++)
|
for (int i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) {
|
||||||
if (abs(spin[i])==1) one++;
|
if (abs(spin[i]) == 1) one++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dof > 0.0) scalar = force->mvv2e * tarray_all[1] / (dof * force->boltz);
|
if (dof > 0.0)
|
||||||
else scalar = 0.0;
|
scalar = force->mvv2e * tarray_all[1] / (dof * force->boltz);
|
||||||
|
else
|
||||||
|
scalar = 0.0;
|
||||||
return scalar;
|
return scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,33 +170,32 @@ void ComputeTempRegionEff::compute_vector()
|
|||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
double mefactor = domain->dimension/4.0;
|
double mefactor = domain->dimension / 4.0;
|
||||||
|
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double massone,t[6];
|
double massone, t[6];
|
||||||
for (i = 0; i < 6; i++) t[i] = 0.0;
|
for (i = 0; i < 6; i++) t[i] = 0.0;
|
||||||
|
|
||||||
for (i = 0; i < nlocal; i++)
|
for (i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
if (mask[i] & groupbit && region->match(x[i][0], x[i][1], x[i][2])) {
|
||||||
massone = mass[type[i]];
|
massone = mass[type[i]];
|
||||||
|
|
||||||
t[0] += massone * v[i][0]*v[i][0];
|
t[0] += massone * v[i][0] * v[i][0];
|
||||||
t[1] += massone * v[i][1]*v[i][1];
|
t[1] += massone * v[i][1] * v[i][1];
|
||||||
t[2] += massone * v[i][2]*v[i][2];
|
t[2] += massone * v[i][2] * v[i][2];
|
||||||
t[3] += massone * v[i][0]*v[i][1];
|
t[3] += massone * v[i][0] * v[i][1];
|
||||||
t[4] += massone * v[i][0]*v[i][2];
|
t[4] += massone * v[i][0] * v[i][2];
|
||||||
t[5] += massone * v[i][1]*v[i][2];
|
t[5] += massone * v[i][1] * v[i][2];
|
||||||
|
|
||||||
if (abs(spin[i])==1) {
|
if (abs(spin[i]) == 1) {
|
||||||
t[0] += mefactor * massone * ervel[i]*ervel[i];
|
t[0] += mefactor * massone * ervel[i] * ervel[i];
|
||||||
t[1] += mefactor * massone * ervel[i]*ervel[i];
|
t[1] += mefactor * massone * ervel[i] * ervel[i];
|
||||||
t[2] += mefactor * massone * ervel[i]*ervel[i];
|
t[2] += mefactor * massone * ervel[i] * ervel[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
|
MPI_Allreduce(t, vector, 6, MPI_DOUBLE, MPI_SUM, world);
|
||||||
for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
|
for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +207,7 @@ void ComputeTempRegionEff::compute_vector()
|
|||||||
void ComputeTempRegionEff::remove_bias(int i, double *v)
|
void ComputeTempRegionEff::remove_bias(int i, double *v)
|
||||||
{
|
{
|
||||||
double *x = atom->x[i];
|
double *x = atom->x[i];
|
||||||
if (domain->regions[iregion]->match(x[0],x[1],x[2]))
|
if (region->match(x[0], x[1], x[2]))
|
||||||
vbias[0] = vbias[1] = vbias[2] = 0.0;
|
vbias[0] = vbias[1] = vbias[2] = 0.0;
|
||||||
else {
|
else {
|
||||||
vbias[0] = v[0];
|
vbias[0] = v[0];
|
||||||
@ -236,14 +231,12 @@ void ComputeTempRegionEff::remove_bias_all()
|
|||||||
if (atom->nmax > maxbias) {
|
if (atom->nmax > maxbias) {
|
||||||
memory->destroy(vbiasall);
|
memory->destroy(vbiasall);
|
||||||
maxbias = atom->nmax;
|
maxbias = atom->nmax;
|
||||||
memory->create(vbiasall,maxbias,3,"temp/region:vbiasall");
|
memory->create(vbiasall, maxbias, 3, "temp/region:vbiasall");
|
||||||
}
|
}
|
||||||
|
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; i++)
|
for (int i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (region->match(x[i][0],x[i][1],x[i][2]))
|
if (region->match(x[i][0], x[i][1], x[i][2]))
|
||||||
vbiasall[i][0] = vbiasall[i][1] = vbiasall[i][2] = 0.0;
|
vbiasall[i][0] = vbiasall[i][1] = vbiasall[i][2] = 0.0;
|
||||||
else {
|
else {
|
||||||
vbiasall[i][0] = v[i][0];
|
vbiasall[i][0] = v[i][0];
|
||||||
@ -289,6 +282,6 @@ void ComputeTempRegionEff::restore_bias_all()
|
|||||||
|
|
||||||
double ComputeTempRegionEff::memory_usage()
|
double ComputeTempRegionEff::memory_usage()
|
||||||
{
|
{
|
||||||
double bytes = (double)maxbias * sizeof(double);
|
double bytes = (double) maxbias * sizeof(double);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class ComputeTempRegionEff : public Compute {
|
|||||||
double memory_usage() override;
|
double memory_usage() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int iregion;
|
class Region *region;
|
||||||
char *idregion;
|
char *idregion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -39,63 +38,53 @@
|
|||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
|
|
||||||
#define MAXLINE 1024
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixElectronStopping::FixElectronStopping(LAMMPS *lmp, int narg, char **arg) :
|
FixElectronStopping::FixElectronStopping(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg)
|
Fix(lmp, narg, arg), elstop_ranges(nullptr), idregion(nullptr), region(nullptr), list(nullptr)
|
||||||
{
|
{
|
||||||
scalar_flag = 1; // Has compute_scalar
|
scalar_flag = 1; // Has compute_scalar
|
||||||
global_freq = 1; // SeLoss computed every step
|
global_freq = 1; // SeLoss computed every step
|
||||||
extscalar = 0; // SeLoss compute_scalar is intensive
|
extscalar = 0; // SeLoss compute_scalar is intensive
|
||||||
nevery = 1; // Run fix every step
|
nevery = 1; // Run fix every step
|
||||||
|
|
||||||
|
|
||||||
// args: 0 = fix ID, 1 = group ID, 2 = "electron/stopping"
|
// args: 0 = fix ID, 1 = group ID, 2 = "electron/stopping"
|
||||||
// 3 = Ecut, 4 = file path
|
// 3 = Ecut, 4 = file path
|
||||||
// optional rest: "region" <region name>
|
// optional rest: "region" <region name>
|
||||||
// "minneigh" <min number of neighbors>
|
// "minneigh" <min number of neighbors>
|
||||||
|
|
||||||
if (narg < 5) error->all(FLERR,
|
if (narg < 5) error->all(FLERR, "Illegal fix electron/stopping command: too few arguments");
|
||||||
"Illegal fix electron/stopping command: too few arguments");
|
|
||||||
|
|
||||||
Ecut = utils::numeric(FLERR, arg[3],false,lmp);
|
Ecut = utils::numeric(FLERR, arg[3], false, lmp);
|
||||||
if (Ecut <= 0.0) error->all(FLERR,
|
if (Ecut <= 0.0) error->all(FLERR, "Illegal fix electron/stopping command: Ecut <= 0");
|
||||||
"Illegal fix electron/stopping command: Ecut <= 0");
|
|
||||||
|
|
||||||
int iarg = 5;
|
int iarg = 5;
|
||||||
iregion = -1;
|
|
||||||
minneigh = 1;
|
minneigh = 1;
|
||||||
bool minneighflag = false;
|
bool minneighflag = false;
|
||||||
|
|
||||||
while (iarg < narg) {
|
while (iarg < narg) {
|
||||||
if (strcmp(arg[iarg], "region") == 0) {
|
if (strcmp(arg[iarg], "region") == 0) {
|
||||||
if (iregion >= 0) error->all(FLERR,
|
if (region) error->all(FLERR, "Illegal fix electron/stopping command: region given twice");
|
||||||
"Illegal fix electron/stopping command: region given twice");
|
if (iarg + 2 > narg)
|
||||||
if (iarg+2 > narg) error->all(FLERR,
|
error->all(FLERR, "Illegal fix electron/stopping command: region name missing");
|
||||||
"Illegal fix electron/stopping command: region name missing");
|
region = domain->get_region_by_id(arg[iarg + 1]);
|
||||||
iregion = domain->find_region(arg[iarg+1]);
|
if (!region)
|
||||||
if (iregion < 0) error->all(FLERR,
|
error->all(FLERR, "Region {} for fix electron/stopping does not exist", arg[iarg + 1]);
|
||||||
"Region ID for fix electron/stopping does not exist");
|
idregion = utils::strdup(arg[iarg + 1]);
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
}
|
} else if (strcmp(arg[iarg], "minneigh") == 0) {
|
||||||
else if (strcmp(arg[iarg], "minneigh") == 0) {
|
if (minneighflag)
|
||||||
if (minneighflag) error->all(FLERR,
|
error->all(FLERR, "Illegal fix electron/stopping command: minneigh given twice");
|
||||||
"Illegal fix electron/stopping command: minneigh given twice");
|
|
||||||
minneighflag = true;
|
minneighflag = true;
|
||||||
if (iarg+2 > narg) error->all(FLERR,
|
if (iarg + 2 > narg)
|
||||||
"Illegal fix electron/stopping command: minneigh number missing");
|
error->all(FLERR, "Illegal fix electron/stopping command: minneigh number missing");
|
||||||
minneigh = utils::inumeric(FLERR, arg[iarg+1],false,lmp);
|
minneigh = utils::inumeric(FLERR, arg[iarg + 1], false, lmp);
|
||||||
if (minneigh < 0) error->all(FLERR,
|
if (minneigh < 0) error->all(FLERR, "Illegal fix electron/stopping command: minneigh < 0");
|
||||||
"Illegal fix electron/stopping command: minneigh < 0");
|
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
}
|
} else
|
||||||
else error->all(FLERR,
|
error->all(FLERR, "Illegal fix electron/stopping command: unknown argument");
|
||||||
"Illegal fix electron/stopping command: unknown argument");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read the input file for energy ranges and stopping powers.
|
// Read the input file for energy ranges and stopping powers.
|
||||||
// First proc 0 reads the file, then bcast to others.
|
// First proc 0 reads the file, then bcast to others.
|
||||||
const int ncol = atom->ntypes + 1;
|
const int ncol = atom->ntypes + 1;
|
||||||
@ -105,13 +94,12 @@ FixElectronStopping::FixElectronStopping(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
read_table(arg[4]);
|
read_table(arg[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MPI_Bcast(&maxlines, 1 , MPI_INT, 0, world);
|
MPI_Bcast(&maxlines, 1, MPI_INT, 0, world);
|
||||||
MPI_Bcast(&table_entries, 1 , MPI_INT, 0, world);
|
MPI_Bcast(&table_entries, 1, MPI_INT, 0, world);
|
||||||
|
|
||||||
if (comm->me != 0)
|
if (comm->me != 0) memory->create(elstop_ranges, ncol, maxlines, "electron/stopping:table");
|
||||||
memory->create(elstop_ranges, ncol, maxlines, "electron/stopping:table");
|
|
||||||
|
|
||||||
MPI_Bcast(&elstop_ranges[0][0], ncol*maxlines, MPI_DOUBLE, 0, world);
|
MPI_Bcast(&elstop_ranges[0][0], ncol * maxlines, MPI_DOUBLE, 0, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -136,6 +124,10 @@ void FixElectronStopping::init()
|
|||||||
{
|
{
|
||||||
SeLoss_sync_flag = 0;
|
SeLoss_sync_flag = 0;
|
||||||
SeLoss = 0.0;
|
SeLoss = 0.0;
|
||||||
|
if (idregion) {
|
||||||
|
region = domain->get_region_by_id(idregion);
|
||||||
|
if (!region) error->all(FLERR, "Region {} for fix electron/stopping does not exist", idregion);
|
||||||
|
}
|
||||||
|
|
||||||
// need an occasional full neighbor list
|
// need an occasional full neighbor list
|
||||||
neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_OCCASIONAL);
|
neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_OCCASIONAL);
|
||||||
@ -176,18 +168,17 @@ void FixElectronStopping::post_force(int /*vflag*/)
|
|||||||
|
|
||||||
int itype = type[i];
|
int itype = type[i];
|
||||||
double massone = (atom->rmass) ? atom->rmass[i] : atom->mass[itype];
|
double massone = (atom->rmass) ? atom->rmass[i] : atom->mass[itype];
|
||||||
double v2 = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
|
double v2 = v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2];
|
||||||
double energy = 0.5 * force->mvv2e * massone * v2;
|
double energy = 0.5 * force->mvv2e * massone * v2;
|
||||||
|
|
||||||
if (energy < Ecut) continue;
|
if (energy < Ecut) continue;
|
||||||
if (energy < elstop_ranges[0][0]) continue;
|
if (energy < elstop_ranges[0][0]) continue;
|
||||||
if (energy > elstop_ranges[0][table_entries - 1]) error->one(FLERR,
|
if (energy > elstop_ranges[0][table_entries - 1])
|
||||||
"Atom kinetic energy too high for fix electron/stopping");
|
error->one(FLERR, "Atom kinetic energy too high for fix electron/stopping");
|
||||||
|
|
||||||
if (iregion >= 0) {
|
if (region) {
|
||||||
// Only apply in the given region
|
// Only apply in the given region
|
||||||
if (domain->regions[iregion]->match(x[i][0], x[i][1], x[i][2]) != 1)
|
if (region->match(x[i][0], x[i][1], x[i][2]) != 1) continue;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary search to find correct energy range
|
// Binary search to find correct energy range
|
||||||
@ -196,8 +187,10 @@ void FixElectronStopping::post_force(int /*vflag*/)
|
|||||||
while (true) {
|
while (true) {
|
||||||
int ihalf = idown + (iup - idown) / 2;
|
int ihalf = idown + (iup - idown) / 2;
|
||||||
if (ihalf == idown) break;
|
if (ihalf == idown) break;
|
||||||
if (elstop_ranges[0][ihalf] < energy) idown = ihalf;
|
if (elstop_ranges[0][ihalf] < energy)
|
||||||
else iup = ihalf;
|
idown = ihalf;
|
||||||
|
else
|
||||||
|
iup = ihalf;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Se_lo = elstop_ranges[itype][idown];
|
double Se_lo = elstop_ranges[itype][idown];
|
||||||
@ -215,7 +208,7 @@ void FixElectronStopping::post_force(int /*vflag*/)
|
|||||||
f[i][1] += v[i][1] * factor;
|
f[i][1] += v[i][1] * factor;
|
||||||
f[i][2] += v[i][2] * factor;
|
f[i][2] += v[i][2] * factor;
|
||||||
|
|
||||||
SeLoss += Se * vabs * dt; // very rough approx
|
SeLoss += Se * vabs * dt; // very rough approx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,19 +247,17 @@ void FixElectronStopping::read_table(const char *file)
|
|||||||
ValueTokenizer values(line);
|
ValueTokenizer values(line);
|
||||||
elstop_ranges[0][nlines] = values.next_double();
|
elstop_ranges[0][nlines] = values.next_double();
|
||||||
if (elstop_ranges[0][nlines] <= oldvalue)
|
if (elstop_ranges[0][nlines] <= oldvalue)
|
||||||
throw TokenizerException("energy values must be positive and in ascending order",line);
|
throw TokenizerException("energy values must be positive and in ascending order", line);
|
||||||
|
|
||||||
oldvalue = elstop_ranges[0][nlines];
|
oldvalue = elstop_ranges[0][nlines];
|
||||||
for (int i = 1; i < ncol; ++i)
|
for (int i = 1; i < ncol; ++i) elstop_ranges[i][nlines] = values.next_double();
|
||||||
elstop_ranges[i][nlines] = values.next_double();
|
|
||||||
|
|
||||||
++nlines;
|
++nlines;
|
||||||
}
|
}
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
error->one(FLERR, "Problem parsing electron stopping data: {}", e.what());
|
error->one(FLERR, "Problem parsing electron stopping data: {}", e.what());
|
||||||
}
|
}
|
||||||
if (nlines == 0)
|
if (nlines == 0) error->one(FLERR, "Did not find any data in electron/stopping table file");
|
||||||
error->one(FLERR, "Did not find any data in electron/stopping table file");
|
|
||||||
|
|
||||||
table_entries = nlines;
|
table_entries = nlines;
|
||||||
}
|
}
|
||||||
@ -281,8 +272,7 @@ void FixElectronStopping::grow_table()
|
|||||||
double **new_array;
|
double **new_array;
|
||||||
memory->create(new_array, ncol, new_maxlines, "electron/stopping:table");
|
memory->create(new_array, ncol, new_maxlines, "electron/stopping:table");
|
||||||
|
|
||||||
for (int i = 0; i < ncol; i++)
|
for (int i = 0; i < ncol; i++) memcpy(new_array[i], elstop_ranges[i], maxlines * sizeof(double));
|
||||||
memcpy(new_array[i], elstop_ranges[i], maxlines*sizeof(double));
|
|
||||||
|
|
||||||
memory->destroy(elstop_ranges);
|
memory->destroy(elstop_ranges);
|
||||||
elstop_ranges = new_array;
|
elstop_ranges = new_array;
|
||||||
|
|||||||
@ -52,8 +52,9 @@ class FixElectronStopping : public Fix {
|
|||||||
double **elstop_ranges; // [ 0][i]: energies
|
double **elstop_ranges; // [ 0][i]: energies
|
||||||
// [>0][i]: stopping powers per type
|
// [>0][i]: stopping powers per type
|
||||||
|
|
||||||
int iregion; // region index if used, else -1
|
char *idregion; // region id
|
||||||
int minneigh; // minimum number of neighbors
|
class Region *region; // region pointer if used, else NULL
|
||||||
|
int minneigh; // minimum number of neighbors
|
||||||
|
|
||||||
class NeighList *list;
|
class NeighList *list;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -28,35 +27,36 @@
|
|||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
|
|
||||||
enum{NONE=-1,X=0,Y=1,Z=2,XYZMASK=3,MINUS=4,PLUS=0};
|
enum { NONE = -1, X = 0, Y = 1, Z = 2, XYZMASK = 3, MINUS = 4, PLUS = 0 };
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixOneWay::FixOneWay(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
|
FixOneWay::FixOneWay(LAMMPS *lmp, int narg, char **arg) :
|
||||||
|
Fix(lmp, narg, arg), region(nullptr), idregion(nullptr)
|
||||||
{
|
{
|
||||||
direction = NONE;
|
direction = NONE;
|
||||||
regionidx = 0;
|
|
||||||
regionstr = nullptr;
|
|
||||||
|
|
||||||
if (narg < 6) error->all(FLERR,"Illegal fix oneway command");
|
if (narg < 6) error->all(FLERR, "Illegal fix oneway command");
|
||||||
|
|
||||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
nevery = utils::inumeric(FLERR, arg[3], false, lmp);
|
||||||
if (nevery < 1) error->all(FLERR,"Illegal fix oneway command");
|
if (nevery < 1) error->all(FLERR, "Illegal fix oneway command");
|
||||||
|
|
||||||
regionstr = utils::strdup(arg[4]);
|
idregion = utils::strdup(arg[4]);
|
||||||
|
if (!domain->get_region_by_id(idregion))
|
||||||
|
error->all(FLERR, "Region {} for fix oneway does not exist", idregion);
|
||||||
|
|
||||||
if (strcmp(arg[5], "x") == 0) direction = X|PLUS;
|
if (strcmp(arg[5], "x") == 0) direction = X | PLUS;
|
||||||
if (strcmp(arg[5], "X") == 0) direction = X|PLUS;
|
if (strcmp(arg[5], "X") == 0) direction = X | PLUS;
|
||||||
if (strcmp(arg[5], "y") == 0) direction = Y|PLUS;
|
if (strcmp(arg[5], "y") == 0) direction = Y | PLUS;
|
||||||
if (strcmp(arg[5], "Y") == 0) direction = Y|PLUS;
|
if (strcmp(arg[5], "Y") == 0) direction = Y | PLUS;
|
||||||
if (strcmp(arg[5], "z") == 0) direction = Z|PLUS;
|
if (strcmp(arg[5], "z") == 0) direction = Z | PLUS;
|
||||||
if (strcmp(arg[5], "Z") == 0) direction = Z|PLUS;
|
if (strcmp(arg[5], "Z") == 0) direction = Z | PLUS;
|
||||||
if (strcmp(arg[5],"-x") == 0) direction = X|MINUS;
|
if (strcmp(arg[5], "-x") == 0) direction = X | MINUS;
|
||||||
if (strcmp(arg[5],"-X") == 0) direction = X|MINUS;
|
if (strcmp(arg[5], "-X") == 0) direction = X | MINUS;
|
||||||
if (strcmp(arg[5],"-y") == 0) direction = Y|MINUS;
|
if (strcmp(arg[5], "-y") == 0) direction = Y | MINUS;
|
||||||
if (strcmp(arg[5],"-Y") == 0) direction = Y|MINUS;
|
if (strcmp(arg[5], "-Y") == 0) direction = Y | MINUS;
|
||||||
if (strcmp(arg[5],"-z") == 0) direction = Z|MINUS;
|
if (strcmp(arg[5], "-z") == 0) direction = Z | MINUS;
|
||||||
if (strcmp(arg[5],"-Z") == 0) direction = Z|MINUS;
|
if (strcmp(arg[5], "-Z") == 0) direction = Z | MINUS;
|
||||||
|
|
||||||
global_freq = nevery;
|
global_freq = nevery;
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ FixOneWay::FixOneWay(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
|
|||||||
|
|
||||||
FixOneWay::~FixOneWay()
|
FixOneWay::~FixOneWay()
|
||||||
{
|
{
|
||||||
delete[] regionstr;
|
delete[] idregion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -79,26 +79,25 @@ int FixOneWay::setmask()
|
|||||||
|
|
||||||
void FixOneWay::init()
|
void FixOneWay::init()
|
||||||
{
|
{
|
||||||
regionidx = domain->find_region(regionstr);
|
region = domain->get_region_by_id(idregion);
|
||||||
if (regionidx < 0)
|
if (!region)
|
||||||
error->all(FLERR,"Region for fix oneway does not exist");
|
error->all(FLERR, "Region {} for fix oneway does not exist", idregion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixOneWay::end_of_step()
|
void FixOneWay::end_of_step()
|
||||||
{
|
{
|
||||||
Region *region = domain->regions[regionidx];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
const int idx = direction & XYZMASK;
|
const int idx = direction & XYZMASK;
|
||||||
const double * const * const x = atom->x;
|
const double *const *const x = atom->x;
|
||||||
double * const * const v = atom->v;
|
double *const *const v = atom->v;
|
||||||
const int *mask = atom->mask;
|
const int *mask = atom->mask;
|
||||||
const int nlocal = atom->nlocal;
|
const int nlocal = atom->nlocal;
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; ++i) {
|
for (int i = 0; i < nlocal; ++i) {
|
||||||
if ((mask[i] & groupbit) && region->match(x[i][0],x[i][1],x[i][2])) {
|
if ((mask[i] & groupbit) && region->match(x[i][0], x[i][1], x[i][2])) {
|
||||||
if (direction & MINUS) {
|
if (direction & MINUS) {
|
||||||
if (v[i][idx] > 0.0) v[i][idx] = -v[i][idx];
|
if (v[i][idx] > 0.0) v[i][idx] = -v[i][idx];
|
||||||
} else {
|
} else {
|
||||||
@ -107,4 +106,3 @@ void FixOneWay::end_of_step()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,8 +34,8 @@ class FixOneWay : public Fix {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int direction;
|
int direction;
|
||||||
int regionidx;
|
class Region *region;
|
||||||
char *regionstr;
|
char *idregion;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LAMMPS_NS
|
} // namespace LAMMPS_NS
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -23,6 +22,7 @@
|
|||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "math_extra.h"
|
#include "math_extra.h"
|
||||||
|
#include "math_special.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "respa.h"
|
#include "respa.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
@ -31,13 +31,14 @@
|
|||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
|
using MathSpecial::powint;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixWallRegionEES::FixWallRegionEES(LAMMPS *lmp, int narg, char **arg) :
|
FixWallRegionEES::FixWallRegionEES(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg)
|
Fix(lmp, narg, arg), idregion(nullptr), region(nullptr)
|
||||||
{
|
{
|
||||||
if (narg != 7) error->all(FLERR,"Illegal fix wall/region/ees command");
|
if (narg != 7) error->all(FLERR, "Illegal fix wall/region/ees command");
|
||||||
|
|
||||||
scalar_flag = 1;
|
scalar_flag = 1;
|
||||||
vector_flag = 1;
|
vector_flag = 1;
|
||||||
@ -49,15 +50,14 @@ FixWallRegionEES::FixWallRegionEES(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
// parse args
|
// parse args
|
||||||
|
|
||||||
iregion = domain->find_region(arg[3]);
|
region = domain->get_region_by_id(arg[3]);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for fix wall/region/ees does not exist", arg[3]);
|
||||||
error->all(FLERR,"Region ID for fix wall/region/ees does not exist");
|
|
||||||
idregion = utils::strdup(arg[3]);
|
idregion = utils::strdup(arg[3]);
|
||||||
epsilon = utils::numeric(FLERR,arg[4],false,lmp);
|
epsilon = utils::numeric(FLERR, arg[4], false, lmp);
|
||||||
sigma = utils::numeric(FLERR,arg[5],false,lmp);
|
sigma = utils::numeric(FLERR, arg[5], false, lmp);
|
||||||
cutoff = utils::numeric(FLERR,arg[6],false,lmp);
|
cutoff = utils::numeric(FLERR, arg[6], false, lmp);
|
||||||
|
|
||||||
if (cutoff <= 0.0) error->all(FLERR,"Fix wall/region/ees cutoff <= 0.0");
|
if (cutoff <= 0.0) error->all(FLERR, "Fix wall/region/ees cutoff <= 0.0");
|
||||||
|
|
||||||
eflag = 0;
|
eflag = 0;
|
||||||
ewall[0] = ewall[1] = ewall[2] = ewall[3] = 0.0;
|
ewall[0] = ewall[1] = ewall[2] = ewall[3] = 0.0;
|
||||||
@ -67,7 +67,7 @@ FixWallRegionEES::FixWallRegionEES(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
FixWallRegionEES::~FixWallRegionEES()
|
FixWallRegionEES::~FixWallRegionEES()
|
||||||
{
|
{
|
||||||
delete [] idregion;
|
delete[] idregion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -87,13 +87,11 @@ void FixWallRegionEES::init()
|
|||||||
{
|
{
|
||||||
// set index and check validity of region
|
// set index and check validity of region
|
||||||
|
|
||||||
iregion = domain->find_region(idregion);
|
region = domain->get_region_by_id(idregion);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for fix wall/region/ees does not exist", idregion);
|
||||||
error->all(FLERR,"Region ID for fix wall/region/ees does not exist");
|
|
||||||
|
|
||||||
avec = dynamic_cast<AtomVecEllipsoid *>( atom->style_match("ellipsoid"));
|
avec = dynamic_cast<AtomVecEllipsoid *>(atom->style_match("ellipsoid"));
|
||||||
if (!avec)
|
if (!avec) error->all(FLERR, "Fix wall/region/ees requires atom style ellipsoid");
|
||||||
error->all(FLERR,"Fix wall/region/ees requires atom style ellipsoid");
|
|
||||||
|
|
||||||
// check that all particles are finite-size ellipsoids
|
// check that all particles are finite-size ellipsoids
|
||||||
// no point particles allowed, spherical is OK
|
// no point particles allowed, spherical is OK
|
||||||
@ -105,33 +103,33 @@ void FixWallRegionEES::init()
|
|||||||
for (int i = 0; i < nlocal; i++)
|
for (int i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & groupbit)
|
if (mask[i] & groupbit)
|
||||||
if (ellipsoid[i] < 0)
|
if (ellipsoid[i] < 0)
|
||||||
error->one(FLERR,"Fix wall/region/ees requires extended particles");
|
error->one(FLERR, "Fix wall/region/ees requires only extended particles");
|
||||||
|
|
||||||
// setup coefficients
|
// setup coefficients
|
||||||
|
|
||||||
coeff1 = ( 2. / 4725. ) * epsilon * pow(sigma,12.0);
|
coeff1 = (2.0 / 4725.0) * epsilon * powint(sigma, 12);
|
||||||
coeff2 = ( 1. / 24. ) * epsilon * pow(sigma,6.0);
|
coeff2 = (1.0 / 24.0) * epsilon * powint(sigma, 6);
|
||||||
coeff3 = ( 2. / 315. ) * epsilon * pow(sigma,12.0);
|
coeff3 = (2.0 / 315.0) * epsilon * powint(sigma, 12);
|
||||||
coeff4 = ( 1. / 3. ) * epsilon * pow(sigma,6.0);
|
coeff4 = (1.0 / 3.0) * epsilon * powint(sigma, 6);
|
||||||
coeff5 = ( 4. / 315. ) * epsilon * pow(sigma,12.0);
|
coeff5 = (4.0 / 315.0) * epsilon * powint(sigma, 12);
|
||||||
coeff6 = ( 1. / 12. ) * epsilon * pow(sigma,6.0);
|
coeff6 = (1.0 / 12.0) * epsilon * powint(sigma, 6);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
||||||
|
if (utils::strmatch(update->integrate_style, "^respa"))
|
||||||
if (utils::strmatch(update->integrate_style,"^respa"))
|
nlevels_respa = (dynamic_cast<Respa *>(update->integrate))->nlevels;
|
||||||
nlevels_respa = (dynamic_cast<Respa *>( update->integrate))->nlevels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixWallRegionEES::setup(int vflag)
|
void FixWallRegionEES::setup(int vflag)
|
||||||
{
|
{
|
||||||
if (utils::strmatch(update->integrate_style,"^verlet"))
|
if (utils::strmatch(update->integrate_style, "^respa")) {
|
||||||
|
auto respa = dynamic_cast<Respa *>(update->integrate);
|
||||||
|
respa->copy_flevel_f(nlevels_respa - 1);
|
||||||
|
post_force_respa(vflag, nlevels_respa - 1, 0);
|
||||||
|
respa->copy_f_flevel(nlevels_respa - 1);
|
||||||
|
} else {
|
||||||
post_force(vflag);
|
post_force(vflag);
|
||||||
else {
|
|
||||||
(dynamic_cast<Respa *>( update->integrate))->copy_flevel_f(nlevels_respa-1);
|
|
||||||
post_force_respa(vflag,nlevels_respa-1,0);
|
|
||||||
(dynamic_cast<Respa *>( update->integrate))->copy_f_flevel(nlevels_respa-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +137,7 @@ void FixWallRegionEES::setup(int vflag)
|
|||||||
|
|
||||||
void FixWallRegionEES::min_setup(int vflag)
|
void FixWallRegionEES::min_setup(int vflag)
|
||||||
{
|
{
|
||||||
post_force(vflag);
|
post_force(vflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -149,8 +147,8 @@ void FixWallRegionEES::post_force(int /*vflag*/)
|
|||||||
//sth is needed here, but I dont know what
|
//sth is needed here, but I dont know what
|
||||||
//that is calculation of sn
|
//that is calculation of sn
|
||||||
|
|
||||||
int i,m,n;
|
int i, m, n;
|
||||||
double rinv,fx,fy,fz,sn,tooclose[3];
|
double rinv, fx, fy, fz, sn, tooclose[3];
|
||||||
|
|
||||||
eflag = 0;
|
eflag = 0;
|
||||||
ewall[0] = ewall[1] = ewall[2] = ewall[3] = 0.0;
|
ewall[0] = ewall[1] = ewall[2] = ewall[3] = 0.0;
|
||||||
@ -165,7 +163,6 @@ void FixWallRegionEES::post_force(int /*vflag*/)
|
|||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
int onflag = 0;
|
int onflag = 0;
|
||||||
@ -176,33 +173,34 @@ void FixWallRegionEES::post_force(int /*vflag*/)
|
|||||||
|
|
||||||
for (i = 0; i < nlocal; i++)
|
for (i = 0; i < nlocal; i++)
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (!region->match(x[i][0],x[i][1],x[i][2])) {
|
if (!region->match(x[i][0], x[i][1], x[i][2])) {
|
||||||
onflag = 1;
|
onflag = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double A[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
|
double A[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
double tempvec[3]= {0,0,0};
|
double tempvec[3] = {0, 0, 0};
|
||||||
double sn2 = 0.0;
|
double sn2 = 0.0;
|
||||||
double nhat[3] = {0,0,0};
|
double nhat[3] = {0, 0, 0};
|
||||||
double* shape = bonus[ellipsoid[i]].shape;;
|
double *shape = bonus[ellipsoid[i]].shape;
|
||||||
MathExtra::quat_to_mat(bonus[ellipsoid[i]].quat,A);
|
;
|
||||||
|
MathExtra::quat_to_mat(bonus[ellipsoid[i]].quat, A);
|
||||||
|
|
||||||
for (int which = 0 ; which < 3; which ++) {//me
|
for (int which = 0; which < 3; which++) { //me
|
||||||
nhat[which]=1;
|
nhat[which] = 1;
|
||||||
nhat[(which+1)%3] = 0 ;
|
nhat[(which + 1) % 3] = 0;
|
||||||
nhat[(which+2)%3] = 0 ;
|
nhat[(which + 2) % 3] = 0;
|
||||||
sn2 = 0 ;
|
sn2 = 0;
|
||||||
MathExtra::transpose_matvec(A,nhat,tempvec);
|
MathExtra::transpose_matvec(A, nhat, tempvec);
|
||||||
for (int k = 0; k<3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
tempvec[k] *= shape[k];
|
tempvec[k] *= shape[k];
|
||||||
sn2 += tempvec[k]*tempvec[k];
|
sn2 += tempvec[k] * tempvec[k];
|
||||||
}
|
}
|
||||||
sn = sqrt(sn2);
|
sn = sqrt(sn2);
|
||||||
tooclose[which] = sn;
|
tooclose[which] = sn;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = region->surface(x[i][0],x[i][1],x[i][2],cutoff);
|
n = region->surface(x[i][0], x[i][1], x[i][2], cutoff);
|
||||||
|
|
||||||
for (m = 0; m < n; m++) {
|
for (m = 0; m < n; m++) {
|
||||||
|
|
||||||
@ -212,12 +210,13 @@ void FixWallRegionEES::post_force(int /*vflag*/)
|
|||||||
} else if (region->contact[m].dely != 0 && region->contact[m].r <= tooclose[1]) {
|
} else if (region->contact[m].dely != 0 && region->contact[m].r <= tooclose[1]) {
|
||||||
onflag = 1;
|
onflag = 1;
|
||||||
continue;
|
continue;
|
||||||
} else if (region->contact[m].delz !=0 && region->contact[m].r <= tooclose[2]) {
|
} else if (region->contact[m].delz != 0 && region->contact[m].r <= tooclose[2]) {
|
||||||
onflag = 1;
|
onflag = 1;
|
||||||
continue;
|
continue;
|
||||||
} else rinv = 1.0/region->contact[m].r;
|
} else
|
||||||
|
rinv = 1.0 / region->contact[m].r;
|
||||||
|
|
||||||
ees(m,i);
|
ees(m, i);
|
||||||
|
|
||||||
ewall[0] += eng;
|
ewall[0] += eng;
|
||||||
fx = fwall * region->contact[m].delx * rinv;
|
fx = fwall * region->contact[m].delx * rinv;
|
||||||
@ -237,15 +236,15 @@ void FixWallRegionEES::post_force(int /*vflag*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onflag) error->one(FLERR,"Particle on or inside surface of region "
|
if (onflag)
|
||||||
"used in fix wall/region/ees");
|
error->one(FLERR, "Particle on or inside surface of region used in fix wall/region/ees");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixWallRegionEES::post_force_respa(int vflag, int ilevel, int /*iloop*/)
|
void FixWallRegionEES::post_force_respa(int vflag, int ilevel, int /*iloop*/)
|
||||||
{
|
{
|
||||||
if (ilevel == nlevels_respa-1) post_force(vflag);
|
if (ilevel == nlevels_respa - 1) post_force(vflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -264,7 +263,7 @@ double FixWallRegionEES::compute_scalar()
|
|||||||
// only sum across procs one time
|
// only sum across procs one time
|
||||||
|
|
||||||
if (eflag == 0) {
|
if (eflag == 0) {
|
||||||
MPI_Allreduce(ewall,ewall_all,4,MPI_DOUBLE,MPI_SUM,world);
|
MPI_Allreduce(ewall, ewall_all, 4, MPI_DOUBLE, MPI_SUM, world);
|
||||||
eflag = 1;
|
eflag = 1;
|
||||||
}
|
}
|
||||||
return ewall_all[0];
|
return ewall_all[0];
|
||||||
@ -279,10 +278,10 @@ double FixWallRegionEES::compute_vector(int n)
|
|||||||
// only sum across procs one time
|
// only sum across procs one time
|
||||||
|
|
||||||
if (eflag == 0) {
|
if (eflag == 0) {
|
||||||
MPI_Allreduce(ewall,ewall_all,4,MPI_DOUBLE,MPI_SUM,world);
|
MPI_Allreduce(ewall, ewall_all, 4, MPI_DOUBLE, MPI_SUM, world);
|
||||||
eflag = 1;
|
eflag = 1;
|
||||||
}
|
}
|
||||||
return ewall_all[n+1];
|
return ewall_all[n + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -292,24 +291,23 @@ double FixWallRegionEES::compute_vector(int n)
|
|||||||
|
|
||||||
void FixWallRegionEES::ees(int m, int i)
|
void FixWallRegionEES::ees(int m, int i)
|
||||||
{
|
{
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double delta, delta2, delta3, delta4, delta5, delta6;
|
double delta, delta2, delta3, delta4, delta5, delta6;
|
||||||
double sigman, sigman2 , sigman3, sigman4, sigman5, sigman6;
|
double sigman, sigman2, sigman3, sigman4, sigman5, sigman6;
|
||||||
double hhss, hhss2, hhss4, hhss7, hhss8; //h^2 - s_n^2
|
double hhss, hhss2, hhss4, hhss7, hhss8; //h^2 - s_n^2
|
||||||
double hps; //h+s_n
|
double hps; //h+s_n
|
||||||
double hms; //h-s_n
|
double hms; //h-s_n
|
||||||
double twall;
|
double twall;
|
||||||
|
|
||||||
double A[3][3], nhat[3], SAn[3], that[3];
|
double A[3][3], nhat[3], SAn[3], that[3];
|
||||||
|
|
||||||
double tempvec[3]= {0,0,0};
|
double tempvec[3] = {0, 0, 0};
|
||||||
double tempvec2[3]= {0,0,0};
|
double tempvec2[3] = {0, 0, 0};
|
||||||
|
|
||||||
double Lx[3][3] = {{0,0,0},{0,0,-1},{0,1,0}};
|
double Lx[3][3] = {{0, 0, 0}, {0, 0, -1}, {0, 1, 0}};
|
||||||
double Ly[3][3] = {{0,0,1},{0,0,0},{-1,0,0}};
|
double Ly[3][3] = {{0, 0, 1}, {0, 0, 0}, {-1, 0, 0}};
|
||||||
double Lz[3][3] = {{0,-1,0},{1,0,0},{0,0,0}};
|
double Lz[3][3] = {{0, -1, 0}, {1, 0, 0}, {0, 0, 0}};
|
||||||
|
|
||||||
nhat[0] = region->contact[m].delx / region->contact[m].r;
|
nhat[0] = region->contact[m].delx / region->contact[m].r;
|
||||||
nhat[1] = region->contact[m].dely / region->contact[m].r;
|
nhat[1] = region->contact[m].dely / region->contact[m].r;
|
||||||
@ -318,14 +316,15 @@ void FixWallRegionEES::ees(int m, int i)
|
|||||||
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
|
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
|
||||||
int *ellipsoid = atom->ellipsoid;
|
int *ellipsoid = atom->ellipsoid;
|
||||||
|
|
||||||
double* shape = bonus[ellipsoid[i]].shape;;
|
double *shape = bonus[ellipsoid[i]].shape;
|
||||||
MathExtra::quat_to_mat(bonus[ellipsoid[i]].quat,A);
|
;
|
||||||
|
MathExtra::quat_to_mat(bonus[ellipsoid[i]].quat, A);
|
||||||
|
|
||||||
sigman2 = 0.0;
|
sigman2 = 0.0;
|
||||||
MathExtra::transpose_matvec(A,nhat,tempvec);
|
MathExtra::transpose_matvec(A, nhat, tempvec);
|
||||||
for (int k = 0; k<3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
tempvec[k] *= shape[k];
|
tempvec[k] *= shape[k];
|
||||||
sigman2 += tempvec[k]*tempvec[k];
|
sigman2 += tempvec[k] * tempvec[k];
|
||||||
SAn[k] = tempvec[k];
|
SAn[k] = tempvec[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,14 +336,14 @@ void FixWallRegionEES::ees(int m, int i)
|
|||||||
sigman5 = sigman4 * sigman;
|
sigman5 = sigman4 * sigman;
|
||||||
sigman6 = sigman3 * sigman3;
|
sigman6 = sigman3 * sigman3;
|
||||||
|
|
||||||
delta2 = delta * delta;
|
delta2 = delta * delta;
|
||||||
delta3 = delta2 * delta;
|
delta3 = delta2 * delta;
|
||||||
delta4 = delta2 * delta2;
|
delta4 = delta2 * delta2;
|
||||||
delta5 = delta3 * delta2;
|
delta5 = delta3 * delta2;
|
||||||
delta6 = delta3 * delta3;
|
delta6 = delta3 * delta3;
|
||||||
|
|
||||||
hhss = delta2 - sigman2;
|
hhss = delta2 - sigman2;
|
||||||
hhss2 = hhss * hhss;
|
hhss2 = hhss * hhss;
|
||||||
hhss4 = hhss2 * hhss2;
|
hhss4 = hhss2 * hhss2;
|
||||||
hhss8 = hhss4 * hhss4;
|
hhss8 = hhss4 * hhss4;
|
||||||
hhss7 = hhss4 * hhss2 * hhss;
|
hhss7 = hhss4 * hhss2 * hhss;
|
||||||
@ -352,31 +351,31 @@ void FixWallRegionEES::ees(int m, int i)
|
|||||||
hps = delta + sigman;
|
hps = delta + sigman;
|
||||||
hms = delta - sigman;
|
hms = delta - sigman;
|
||||||
|
|
||||||
fwall = -1*coeff4/hhss2 + coeff3
|
fwall = -1 * coeff4 / hhss2 +
|
||||||
* (21*delta6 + 63*delta4*sigman2 + 27*delta2*sigman4 + sigman6) / hhss8;
|
coeff3 * (21 * delta6 + 63 * delta4 * sigman2 + 27 * delta2 * sigman4 + sigman6) / hhss8;
|
||||||
|
|
||||||
eng = -1*coeff2 * (4*delta/sigman2/hhss + 2*log(hms/hps)/sigman3) +
|
eng = -1 * coeff2 * (4 * delta / sigman2 / hhss + 2 * log(hms / hps) / sigman3) +
|
||||||
coeff1 * (35*delta5 + 70*delta3*sigman2 + 15*delta*sigman4) / hhss7;
|
coeff1 * (35 * delta5 + 70 * delta3 * sigman2 + 15 * delta * sigman4) / hhss7;
|
||||||
|
|
||||||
twall = coeff6 * (6*delta3/sigman4/hhss2 - 10*delta/sigman2/hhss2
|
twall = coeff6 *
|
||||||
+ 3*log(hms/hps)/sigman5)
|
(6 * delta3 / sigman4 / hhss2 - 10 * delta / sigman2 / hhss2 +
|
||||||
+ coeff5 * (21.*delta5 + 30.*delta3*sigman2 + 5.*delta*sigman4) / hhss8;
|
3 * log(hms / hps) / sigman5) +
|
||||||
|
coeff5 * (21. * delta5 + 30. * delta3 * sigman2 + 5. * delta * sigman4) / hhss8;
|
||||||
|
|
||||||
MathExtra::matvec(Lx,nhat,tempvec);
|
MathExtra::matvec(Lx, nhat, tempvec);
|
||||||
MathExtra::transpose_matvec(A,tempvec,tempvec2);
|
MathExtra::transpose_matvec(A, tempvec, tempvec2);
|
||||||
for (int k = 0; k<3; k++) tempvec2[k] *= shape[k];
|
|
||||||
that[0] = MathExtra::dot3(SAn,tempvec2);
|
|
||||||
|
|
||||||
MathExtra::matvec(Ly,nhat,tempvec);
|
|
||||||
MathExtra::transpose_matvec(A,tempvec,tempvec2);
|
|
||||||
for (int k = 0; k<3; k++) tempvec2[k] *= shape[k];
|
|
||||||
that[1] = MathExtra::dot3(SAn,tempvec2);
|
|
||||||
|
|
||||||
MathExtra::matvec(Lz,nhat,tempvec);
|
|
||||||
MathExtra::transpose_matvec(A,tempvec,tempvec2);
|
|
||||||
for (int k = 0; k < 3; k++) tempvec2[k] *= shape[k];
|
for (int k = 0; k < 3; k++) tempvec2[k] *= shape[k];
|
||||||
that[2] = MathExtra::dot3(SAn,tempvec2);
|
that[0] = MathExtra::dot3(SAn, tempvec2);
|
||||||
|
|
||||||
for (int j = 0; j<3 ; j++)
|
MathExtra::matvec(Ly, nhat, tempvec);
|
||||||
torque[j] = twall * that[j];
|
MathExtra::transpose_matvec(A, tempvec, tempvec2);
|
||||||
|
for (int k = 0; k < 3; k++) tempvec2[k] *= shape[k];
|
||||||
|
that[1] = MathExtra::dot3(SAn, tempvec2);
|
||||||
|
|
||||||
|
MathExtra::matvec(Lz, nhat, tempvec);
|
||||||
|
MathExtra::transpose_matvec(A, tempvec, tempvec2);
|
||||||
|
for (int k = 0; k < 3; k++) tempvec2[k] *= shape[k];
|
||||||
|
that[2] = MathExtra::dot3(SAn, tempvec2);
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++) torque[j] = twall * that[j];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,12 +41,12 @@ class FixWallRegionEES : public Fix {
|
|||||||
private:
|
private:
|
||||||
class AtomVecEllipsoid *avec;
|
class AtomVecEllipsoid *avec;
|
||||||
|
|
||||||
int iregion;
|
|
||||||
double epsilon, sigma, cutoff;
|
double epsilon, sigma, cutoff;
|
||||||
int eflag;
|
int eflag;
|
||||||
double ewall[4], ewall_all[4];
|
double ewall[4], ewall_all[4];
|
||||||
int nlevels_respa;
|
int nlevels_respa;
|
||||||
char *idregion;
|
char *idregion;
|
||||||
|
class Region *region;
|
||||||
|
|
||||||
double coeff1, coeff2, coeff3, coeff4, offset;
|
double coeff1, coeff2, coeff3, coeff4, offset;
|
||||||
double coeff5, coeff6;
|
double coeff5, coeff6;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@ class FixPour : public Fix {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int ninsert, ntype, seed;
|
int ninsert, ntype, seed;
|
||||||
int iregion, mode, idnext, dstyle, npoly, rigidflag, shakeflag;
|
int mode, idnext, dstyle, npoly, rigidflag, shakeflag;
|
||||||
int ignoreflag, ignoreline, ignoretri;
|
int ignoreflag, ignoreline, ignoretri;
|
||||||
double radius_one, radius_max;
|
double radius_one, radius_max;
|
||||||
double radius_lo, radius_hi;
|
double radius_lo, radius_hi;
|
||||||
@ -52,6 +52,8 @@ class FixPour : public Fix {
|
|||||||
double xc, yc, rc;
|
double xc, yc, rc;
|
||||||
double grav;
|
double grav;
|
||||||
char *idrigid, *idshake;
|
char *idrigid, *idshake;
|
||||||
|
char *idregion;
|
||||||
|
class Region *region;
|
||||||
|
|
||||||
class Molecule **onemols;
|
class Molecule **onemols;
|
||||||
int nmol, natom_max;
|
int nmol, natom_max;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -35,21 +34,16 @@ using namespace FixConst;
|
|||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) :
|
FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) :
|
||||||
FixWallGran(lmp, narg, arg), region(nullptr), region_style(nullptr),
|
FixWallGran(lmp, narg, arg), region(nullptr), ncontact(nullptr), walls(nullptr),
|
||||||
ncontact(nullptr),
|
history_many(nullptr), c2r(nullptr)
|
||||||
walls(nullptr), history_many(nullptr), c2r(nullptr)
|
|
||||||
{
|
{
|
||||||
restart_global = 1;
|
restart_global = 1;
|
||||||
motion_resetflag = 0;
|
motion_resetflag = 0;
|
||||||
|
|
||||||
int iregion = domain->find_region(idregion);
|
region = domain->get_region_by_id(idregion);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for fix wall/gran/region does not exist", idregion);
|
||||||
error->all(FLERR,"Region ID for fix wall/gran/region does not exist");
|
|
||||||
region = domain->regions[iregion];
|
|
||||||
region_style = utils::strdup(region->style);
|
|
||||||
nregion = region->nregion;
|
nregion = region->nregion;
|
||||||
|
tmax = region->tmax;
|
||||||
tmax = domain->regions[iregion]->tmax;
|
|
||||||
c2r = new int[tmax];
|
c2r = new int[tmax];
|
||||||
|
|
||||||
// re-allocate atom-based arrays with nshear
|
// re-allocate atom-based arrays with nshear
|
||||||
@ -67,8 +61,7 @@ FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
if (use_history) {
|
if (use_history) {
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
for (int i = 0; i < nlocal; i++)
|
for (int i = 0; i < nlocal; i++) ncontact[i] = 0;
|
||||||
ncontact[i] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +69,8 @@ FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
FixWallGranRegion::~FixWallGranRegion()
|
FixWallGranRegion::~FixWallGranRegion()
|
||||||
{
|
{
|
||||||
delete [] c2r;
|
delete[] c2r;
|
||||||
delete [] region_style;
|
delete[] region_style;
|
||||||
|
|
||||||
memory->destroy(ncontact);
|
memory->destroy(ncontact);
|
||||||
memory->destroy(walls);
|
memory->destroy(walls);
|
||||||
@ -90,25 +83,32 @@ void FixWallGranRegion::init()
|
|||||||
{
|
{
|
||||||
FixWallGran::init();
|
FixWallGran::init();
|
||||||
|
|
||||||
int iregion = domain->find_region(idregion);
|
auto newregion = domain->get_region_by_id(idregion);
|
||||||
if (iregion == -1)
|
if (!newregion) error->all(FLERR, "Region {} for fix wall/gran/region does not exist", idregion);
|
||||||
error->all(FLERR,"Region ID for fix wall/gran/region does not exist");
|
|
||||||
region = domain->regions[iregion];
|
|
||||||
|
|
||||||
// check if region properties changed between runs
|
// check if region properties changed between runs
|
||||||
// reset if restart info was inconsistent
|
// reset if restart info was inconsistent
|
||||||
|
|
||||||
if ((strcmp(idregion,region->id) != 0)
|
if (newregion != region) {
|
||||||
|| (strcmp(region_style,region->style) != 0)
|
region = newregion;
|
||||||
|| (nregion != region->nregion)) {
|
if (comm->me == 0)
|
||||||
error->warning(FLERR,"Region properties for region {} changed between "
|
error->warning(FLERR,
|
||||||
"runs, resetting its motion",idregion);
|
"Region properties for region {} changed between runs, resetting its motion",
|
||||||
|
idregion);
|
||||||
|
nregion = region->nregion;
|
||||||
|
tmax = region->tmax;
|
||||||
|
delete[] c2r;
|
||||||
|
c2r = new int[tmax];
|
||||||
|
region = newregion;
|
||||||
region->reset_vel();
|
region->reset_vel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (motion_resetflag) {
|
if (motion_resetflag) {
|
||||||
error->warning(FLERR,"Region properties for region {} are inconsistent "
|
if (comm->me == 0)
|
||||||
"with restart file, resetting its motion",idregion);
|
error->warning(FLERR,
|
||||||
|
"Region properties for region {} are inconsistent with restart file, "
|
||||||
|
"resetting its motion",
|
||||||
|
idregion);
|
||||||
region->reset_vel();
|
region->reset_vel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,8 +117,8 @@ void FixWallGranRegion::init()
|
|||||||
|
|
||||||
void FixWallGranRegion::post_force(int /*vflag*/)
|
void FixWallGranRegion::post_force(int /*vflag*/)
|
||||||
{
|
{
|
||||||
int i,m,nc,iwall;
|
int i, m, nc, iwall;
|
||||||
double dx,dy,dz,rsq,meff;
|
double dx, dy, dz, rsq, meff;
|
||||||
double vwall[3];
|
double vwall[3];
|
||||||
|
|
||||||
// do not update shear history during setup
|
// do not update shear history during setup
|
||||||
@ -133,17 +133,19 @@ void FixWallGranRegion::post_force(int /*vflag*/)
|
|||||||
|
|
||||||
if (neighbor->ago == 0 && fix_rigid) {
|
if (neighbor->ago == 0 && fix_rigid) {
|
||||||
int tmp;
|
int tmp;
|
||||||
int *body = (int *) fix_rigid->extract("body",tmp);
|
int *body = (int *) fix_rigid->extract("body", tmp);
|
||||||
auto mass_body = (double *) fix_rigid->extract("masstotal",tmp);
|
auto mass_body = (double *) fix_rigid->extract("masstotal", tmp);
|
||||||
if (atom->nmax > nmax) {
|
if (atom->nmax > nmax) {
|
||||||
memory->destroy(mass_rigid);
|
memory->destroy(mass_rigid);
|
||||||
nmax = atom->nmax;
|
nmax = atom->nmax;
|
||||||
memory->create(mass_rigid,nmax,"wall/gran:mass_rigid");
|
memory->create(mass_rigid, nmax, "wall/gran:mass_rigid");
|
||||||
}
|
}
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
for (i = 0; i < nlocal; i++) {
|
for (i = 0; i < nlocal; i++) {
|
||||||
if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]];
|
if (body[i] >= 0)
|
||||||
else mass_rigid[i] = 0.0;
|
mass_rigid[i] = mass_body[body[i]];
|
||||||
|
else
|
||||||
|
mass_rigid[i] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,23 +171,18 @@ void FixWallGranRegion::post_force(int /*vflag*/)
|
|||||||
region->set_velocity();
|
region->set_velocity();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peratom_flag) {
|
if (peratom_flag) { clear_stored_contacts(); }
|
||||||
clear_stored_contacts();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nlocal; i++) {
|
for (i = 0; i < nlocal; i++) {
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (!region->match(x[i][0],x[i][1],x[i][2])) continue;
|
if (!region->match(x[i][0], x[i][1], x[i][2])) continue;
|
||||||
|
|
||||||
if (pairstyle == FixWallGran::GRANULAR && normal_model == FixWallGran::JKR) {
|
if (pairstyle == FixWallGran::GRANULAR && normal_model == FixWallGran::JKR) {
|
||||||
nc = region->surface(x[i][0],x[i][1],x[i][2],
|
nc = region->surface(x[i][0], x[i][1], x[i][2], radius[i] + pulloff_distance(radius[i]));
|
||||||
radius[i]+pulloff_distance(radius[i]));
|
} else {
|
||||||
|
nc = region->surface(x[i][0], x[i][1], x[i][2], radius[i]);
|
||||||
}
|
}
|
||||||
else{
|
if (nc > tmax) error->one(FLERR, "Too many wall/gran/region contacts for one particle");
|
||||||
nc = region->surface(x[i][0],x[i][1],x[i][2],radius[i]);
|
|
||||||
}
|
|
||||||
if (nc > tmax)
|
|
||||||
error->one(FLERR,"Too many wall/gran/region contacts for one particle");
|
|
||||||
|
|
||||||
// shear history maintenance
|
// shear history maintenance
|
||||||
// update ncontact,walls,shear2many for particle I
|
// update ncontact,walls,shear2many for particle I
|
||||||
@ -204,11 +201,11 @@ void FixWallGranRegion::post_force(int /*vflag*/)
|
|||||||
if (ncontact[i] == 0) {
|
if (ncontact[i] == 0) {
|
||||||
ncontact[i] = 1;
|
ncontact[i] = 1;
|
||||||
walls[i][0] = iwall;
|
walls[i][0] = iwall;
|
||||||
for (m = 0; m < size_history; m++)
|
for (m = 0; m < size_history; m++) history_many[i][0][m] = 0.0;
|
||||||
history_many[i][0][m] = 0.0;
|
|
||||||
} else if (ncontact[i] > 1 || iwall != walls[i][0])
|
} else if (ncontact[i] > 1 || iwall != walls[i][0])
|
||||||
update_contacts(i,nc);
|
update_contacts(i, nc);
|
||||||
} else update_contacts(i,nc);
|
} else
|
||||||
|
update_contacts(i, nc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process current contacts
|
// process current contacts
|
||||||
@ -217,12 +214,11 @@ void FixWallGranRegion::post_force(int /*vflag*/)
|
|||||||
// rsq = squared contact distance
|
// rsq = squared contact distance
|
||||||
// xc = contact point
|
// xc = contact point
|
||||||
|
|
||||||
rsq = region->contact[ic].r*region->contact[ic].r;
|
rsq = region->contact[ic].r * region->contact[ic].r;
|
||||||
|
|
||||||
if (pairstyle == FixWallGran::GRANULAR && normal_model == FixWallGran::JKR) {
|
if (pairstyle == FixWallGran::GRANULAR && normal_model == FixWallGran::JKR) {
|
||||||
if (history_many[i][c2r[ic]][0] == 0.0 && rsq > radius[i]*radius[i]) {
|
if (history_many[i][c2r[ic]][0] == 0.0 && rsq > radius[i] * radius[i]) {
|
||||||
for (m = 0; m < size_history; m++)
|
for (m = 0; m < size_history; m++) history_many[i][0][m] = 0.0;
|
||||||
history_many[i][0][m] = 0.0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,20 +252,16 @@ void FixWallGranRegion::post_force(int /*vflag*/)
|
|||||||
contact = nullptr;
|
contact = nullptr;
|
||||||
|
|
||||||
if (pairstyle == FixWallGran::HOOKE)
|
if (pairstyle == FixWallGran::HOOKE)
|
||||||
hooke(rsq,dx,dy,dz,vwall,v[i],f[i],
|
hooke(rsq, dx, dy, dz, vwall, v[i], f[i], omega[i], torque[i], radius[i], meff, contact);
|
||||||
omega[i],torque[i],radius[i],meff, contact);
|
|
||||||
else if (pairstyle == FixWallGran::HOOKE_HISTORY)
|
else if (pairstyle == FixWallGran::HOOKE_HISTORY)
|
||||||
hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i],
|
hooke_history(rsq, dx, dy, dz, vwall, v[i], f[i], omega[i], torque[i], radius[i], meff,
|
||||||
omega[i],torque[i],radius[i],meff,
|
history_many[i][c2r[ic]], contact);
|
||||||
history_many[i][c2r[ic]], contact);
|
|
||||||
else if (pairstyle == FixWallGran::HERTZ_HISTORY)
|
else if (pairstyle == FixWallGran::HERTZ_HISTORY)
|
||||||
hertz_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius,
|
hertz_history(rsq, dx, dy, dz, vwall, region->contact[ic].radius, v[i], f[i], omega[i],
|
||||||
v[i],f[i],omega[i],torque[i],
|
torque[i], radius[i], meff, history_many[i][c2r[ic]], contact);
|
||||||
radius[i],meff,history_many[i][c2r[ic]], contact);
|
|
||||||
else if (pairstyle == FixWallGran::GRANULAR)
|
else if (pairstyle == FixWallGran::GRANULAR)
|
||||||
granular(rsq,dx,dy,dz,vwall,region->contact[ic].radius,
|
granular(rsq, dx, dy, dz, vwall, region->contact[ic].radius, v[i], f[i], omega[i],
|
||||||
v[i],f[i],omega[i],torque[i],
|
torque[i], radius[i], meff, history_many[i][c2r[ic]], contact);
|
||||||
radius[i],meff,history_many[i][c2r[ic]],contact);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,7 +277,7 @@ void FixWallGranRegion::post_force(int /*vflag*/)
|
|||||||
|
|
||||||
void FixWallGranRegion::update_contacts(int i, int nc)
|
void FixWallGranRegion::update_contacts(int i, int nc)
|
||||||
{
|
{
|
||||||
int j,m,iold,nold,ilast,inew,iadd,iwall;
|
int j, m, iold, nold, ilast, inew, iadd, iwall;
|
||||||
|
|
||||||
// loop over old contacts
|
// loop over old contacts
|
||||||
// if not in new contact list:
|
// if not in new contact list:
|
||||||
@ -296,12 +288,12 @@ void FixWallGranRegion::update_contacts(int i, int nc)
|
|||||||
for (m = 0; m < nc; m++)
|
for (m = 0; m < nc; m++)
|
||||||
if (region->contact[m].iwall == walls[i][iold]) break;
|
if (region->contact[m].iwall == walls[i][iold]) break;
|
||||||
if (m >= nc) {
|
if (m >= nc) {
|
||||||
ilast = ncontact[i]-1;
|
ilast = ncontact[i] - 1;
|
||||||
for (j = 0; j < size_history; j++)
|
for (j = 0; j < size_history; j++) history_many[i][iold][j] = history_many[i][ilast][j];
|
||||||
history_many[i][iold][j] = history_many[i][ilast][j];
|
|
||||||
walls[i][iold] = walls[i][ilast];
|
walls[i][iold] = walls[i][ilast];
|
||||||
ncontact[i]--;
|
ncontact[i]--;
|
||||||
} else iold++;
|
} else
|
||||||
|
iold++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop over new contacts
|
// loop over new contacts
|
||||||
@ -315,13 +307,13 @@ void FixWallGranRegion::update_contacts(int i, int nc)
|
|||||||
iwall = region->contact[inew].iwall;
|
iwall = region->contact[inew].iwall;
|
||||||
for (m = 0; m < nold; m++)
|
for (m = 0; m < nold; m++)
|
||||||
if (walls[i][m] == iwall) break;
|
if (walls[i][m] == iwall) break;
|
||||||
if (m < nold) c2r[m] = inew;
|
if (m < nold)
|
||||||
|
c2r[m] = inew;
|
||||||
else {
|
else {
|
||||||
iadd = ncontact[i];
|
iadd = ncontact[i];
|
||||||
|
|
||||||
c2r[iadd] = inew;
|
c2r[iadd] = inew;
|
||||||
for (j = 0; j < size_history; j++)
|
for (j = 0; j < size_history; j++) history_many[i][iadd][j] = 0.0;
|
||||||
history_many[i][iadd][j] = 0.0;
|
|
||||||
walls[i][iadd] = iwall;
|
walls[i][iadd] = iwall;
|
||||||
ncontact[i]++;
|
ncontact[i]++;
|
||||||
}
|
}
|
||||||
@ -336,12 +328,12 @@ double FixWallGranRegion::memory_usage()
|
|||||||
{
|
{
|
||||||
int nmax = atom->nmax;
|
int nmax = atom->nmax;
|
||||||
double bytes = 0.0;
|
double bytes = 0.0;
|
||||||
if (use_history) { // shear history
|
if (use_history) { // shear history
|
||||||
bytes += (double)nmax * sizeof(int); // ncontact
|
bytes += (double) nmax * sizeof(int); // ncontact
|
||||||
bytes += (double)nmax*tmax * sizeof(int); // walls
|
bytes += (double) nmax * tmax * sizeof(int); // walls
|
||||||
bytes += (double)nmax*tmax*size_history * sizeof(double); // history_many
|
bytes += (double) nmax * tmax * size_history * sizeof(double); // history_many
|
||||||
}
|
}
|
||||||
if (fix_rigid) bytes += (double)nmax * sizeof(int); // mass_rigid
|
if (fix_rigid) bytes += (double) nmax * sizeof(int); // mass_rigid
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,12 +344,11 @@ double FixWallGranRegion::memory_usage()
|
|||||||
void FixWallGranRegion::grow_arrays(int nmax)
|
void FixWallGranRegion::grow_arrays(int nmax)
|
||||||
{
|
{
|
||||||
if (use_history) {
|
if (use_history) {
|
||||||
memory->grow(ncontact,nmax,"fix_wall_gran:ncontact");
|
memory->grow(ncontact, nmax, "fix_wall_gran:ncontact");
|
||||||
memory->grow(walls,nmax,tmax,"fix_wall_gran:walls");
|
memory->grow(walls, nmax, tmax, "fix_wall_gran:walls");
|
||||||
memory->grow(history_many,nmax,tmax,size_history,"fix_wall_gran:history_many");
|
memory->grow(history_many, nmax, tmax, size_history, "fix_wall_gran:history_many");
|
||||||
}
|
}
|
||||||
if (peratom_flag)
|
if (peratom_flag) memory->grow(array_atom, nmax, size_peratom_cols, "fix_wall_gran:array_atom");
|
||||||
memory->grow(array_atom,nmax,size_peratom_cols,"fix_wall_gran:array_atom");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -366,21 +357,19 @@ void FixWallGranRegion::grow_arrays(int nmax)
|
|||||||
|
|
||||||
void FixWallGranRegion::copy_arrays(int i, int j, int /*delflag*/)
|
void FixWallGranRegion::copy_arrays(int i, int j, int /*delflag*/)
|
||||||
{
|
{
|
||||||
int m,n,iwall;
|
int m, n, iwall;
|
||||||
|
|
||||||
if (use_history) {
|
if (use_history) {
|
||||||
n = ncontact[i];
|
n = ncontact[i];
|
||||||
for (iwall = 0; iwall < n; iwall++) {
|
for (iwall = 0; iwall < n; iwall++) {
|
||||||
walls[j][iwall] = walls[i][iwall];
|
walls[j][iwall] = walls[i][iwall];
|
||||||
for (m = 0; m < size_history; m++)
|
for (m = 0; m < size_history; m++) history_many[j][iwall][m] = history_many[i][iwall][m];
|
||||||
history_many[j][iwall][m] = history_many[i][iwall][m];
|
|
||||||
}
|
}
|
||||||
ncontact[j] = ncontact[i];
|
ncontact[j] = ncontact[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peratom_flag) {
|
if (peratom_flag) {
|
||||||
for (int m = 0; m < size_peratom_cols; m++)
|
for (int m = 0; m < size_peratom_cols; m++) array_atom[j][m] = array_atom[i][m];
|
||||||
array_atom[j][m] = array_atom[i][m];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,11 +379,9 @@ void FixWallGranRegion::copy_arrays(int i, int j, int /*delflag*/)
|
|||||||
|
|
||||||
void FixWallGranRegion::set_arrays(int i)
|
void FixWallGranRegion::set_arrays(int i)
|
||||||
{
|
{
|
||||||
if (use_history)
|
if (use_history) ncontact[i] = 0;
|
||||||
ncontact[i] = 0;
|
|
||||||
if (peratom_flag) {
|
if (peratom_flag) {
|
||||||
for (int m = 0; m < size_peratom_cols; m++)
|
for (int m = 0; m < size_peratom_cols; m++) array_atom[i][m] = 0;
|
||||||
array_atom[i][m] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,13 +399,11 @@ int FixWallGranRegion::pack_exchange(int i, double *buf)
|
|||||||
buf[n++] = ubuf(count).d;
|
buf[n++] = ubuf(count).d;
|
||||||
for (int iwall = 0; iwall < count; iwall++) {
|
for (int iwall = 0; iwall < count; iwall++) {
|
||||||
buf[n++] = ubuf(walls[i][iwall]).d;
|
buf[n++] = ubuf(walls[i][iwall]).d;
|
||||||
for (m = 0; m < size_history; m++)
|
for (m = 0; m < size_history; m++) buf[n++] = history_many[i][iwall][m];
|
||||||
buf[n++] = history_many[i][iwall][m];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (peratom_flag) {
|
if (peratom_flag) {
|
||||||
for (int m = 0; m < size_peratom_cols; m++)
|
for (int m = 0; m < size_peratom_cols; m++) buf[n++] = array_atom[i][m];
|
||||||
buf[n++] = array_atom[i][m];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
@ -432,19 +417,16 @@ int FixWallGranRegion::unpack_exchange(int nlocal, double *buf)
|
|||||||
{
|
{
|
||||||
int m;
|
int m;
|
||||||
|
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if (use_history) {
|
if (use_history) {
|
||||||
int count = ncontact[nlocal] = (int) ubuf(buf[n++]).i;
|
int count = ncontact[nlocal] = (int) ubuf(buf[n++]).i;
|
||||||
for (int iwall = 0; iwall < count; iwall++) {
|
for (int iwall = 0; iwall < count; iwall++) {
|
||||||
walls[nlocal][iwall] = (int) ubuf(buf[n++]).i;
|
walls[nlocal][iwall] = (int) ubuf(buf[n++]).i;
|
||||||
for (m = 0; m < size_history; m++)
|
for (m = 0; m < size_history; m++) history_many[nlocal][iwall][m] = buf[n++];
|
||||||
history_many[nlocal][iwall][m] = buf[n++];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (peratom_flag) {
|
if (peratom_flag) {
|
||||||
for (int m = 0; m < size_peratom_cols; m++)
|
for (int m = 0; m < size_peratom_cols; m++) array_atom[nlocal][m] = buf[n++];
|
||||||
array_atom[nlocal][m] = buf[n++];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
@ -466,8 +448,7 @@ int FixWallGranRegion::pack_restart(int i, double *buf)
|
|||||||
buf[n++] = ubuf(count).d;
|
buf[n++] = ubuf(count).d;
|
||||||
for (int iwall = 0; iwall < count; iwall++) {
|
for (int iwall = 0; iwall < count; iwall++) {
|
||||||
buf[n++] = ubuf(walls[i][iwall]).d;
|
buf[n++] = ubuf(walls[i][iwall]).d;
|
||||||
for (m = 0; m < size_history; m++)
|
for (m = 0; m < size_history; m++) buf[n++] = history_many[i][iwall][m];
|
||||||
buf[n++] = history_many[i][iwall][m];
|
|
||||||
}
|
}
|
||||||
// pack buf[0] this way because other fixes unpack it
|
// pack buf[0] this way because other fixes unpack it
|
||||||
buf[0] = n;
|
buf[0] = n;
|
||||||
@ -490,14 +471,13 @@ void FixWallGranRegion::unpack_restart(int nlocal, int nth)
|
|||||||
// unpack the Nth first values this way because other fixes pack them
|
// unpack the Nth first values this way because other fixes pack them
|
||||||
|
|
||||||
int m = 0;
|
int m = 0;
|
||||||
for (int i = 0; i < nth; i++) m += static_cast<int> (extra[nlocal][m]);
|
for (int i = 0; i < nth; i++) m += static_cast<int>(extra[nlocal][m]);
|
||||||
m++;
|
m++;
|
||||||
|
|
||||||
int count = ncontact[nlocal] = (int) ubuf(extra[nlocal][m++]).i;
|
int count = ncontact[nlocal] = (int) ubuf(extra[nlocal][m++]).i;
|
||||||
for (int iwall = 0; iwall < count; iwall++) {
|
for (int iwall = 0; iwall < count; iwall++) {
|
||||||
walls[nlocal][iwall] = (int) ubuf(extra[nlocal][m++]).i;
|
walls[nlocal][iwall] = (int) ubuf(extra[nlocal][m++]).i;
|
||||||
for (k = 0; k < size_history; k++)
|
for (k = 0; k < size_history; k++) history_many[nlocal][iwall][k] = extra[nlocal][m++];
|
||||||
history_many[nlocal][iwall][k] = extra[nlocal][m++];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +488,7 @@ void FixWallGranRegion::unpack_restart(int nlocal, int nth)
|
|||||||
int FixWallGranRegion::maxsize_restart()
|
int FixWallGranRegion::maxsize_restart()
|
||||||
{
|
{
|
||||||
if (!use_history) return 0;
|
if (!use_history) return 0;
|
||||||
return 2 + tmax*(size_history+1);
|
return 2 + tmax * (size_history + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -518,7 +498,7 @@ int FixWallGranRegion::maxsize_restart()
|
|||||||
int FixWallGranRegion::size_restart(int nlocal)
|
int FixWallGranRegion::size_restart(int nlocal)
|
||||||
{
|
{
|
||||||
if (!use_history) return 0;
|
if (!use_history) return 0;
|
||||||
return 2 + ncontact[nlocal]*(size_history+1);
|
return 2 + ncontact[nlocal] * (size_history + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -530,7 +510,7 @@ void FixWallGranRegion::write_restart(FILE *fp)
|
|||||||
if (comm->me) return;
|
if (comm->me) return;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
region->length_restart_string(len);
|
region->length_restart_string(len);
|
||||||
fwrite(&len, sizeof(int),1,fp);
|
fwrite(&len, sizeof(int), 1, fp);
|
||||||
region->write_restart(fp);
|
region->write_restart(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,5 +521,5 @@ void FixWallGranRegion::write_restart(FILE *fp)
|
|||||||
void FixWallGranRegion::restart(char *buf)
|
void FixWallGranRegion::restart(char *buf)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if (!region->restart(buf,n)) motion_resetflag = 1;
|
if (!region->restart(buf, n)) motion_resetflag = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* *** Smooth Mach Dynamics ***
|
* *** Smooth Mach Dynamics ***
|
||||||
@ -41,320 +40,297 @@
|
|||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
|
|
||||||
enum {
|
enum { NONE, CONSTANT, EQUAL, ATOM };
|
||||||
NONE, CONSTANT, EQUAL, ATOM
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixSMDSetVel::FixSMDSetVel(LAMMPS *lmp, int narg, char **arg) :
|
FixSMDSetVel::FixSMDSetVel(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg) {
|
Fix(lmp, narg, arg), xstr(nullptr), ystr(nullptr), zstr(nullptr), idregion(nullptr),
|
||||||
if (narg < 6)
|
region(nullptr), sforce(nullptr)
|
||||||
error->all(FLERR, "Illegal fix setvelocity command");
|
{
|
||||||
|
if (narg < 6) error->all(FLERR, "Illegal fix setvelocity command");
|
||||||
|
|
||||||
dynamic_group_allow = 1;
|
dynamic_group_allow = 1;
|
||||||
vector_flag = 1;
|
vector_flag = 1;
|
||||||
size_vector = 3;
|
size_vector = 3;
|
||||||
global_freq = 1;
|
global_freq = 1;
|
||||||
extvector = 1;
|
extvector = 1;
|
||||||
|
|
||||||
xstr = ystr = zstr = nullptr;
|
if (strstr(arg[3], "v_") == arg[3]) {
|
||||||
|
xstr = utils::strdup(&arg[3][2]);
|
||||||
|
} else if (strcmp(arg[3], "NULL") == 0) {
|
||||||
|
xstyle = NONE;
|
||||||
|
} else {
|
||||||
|
xvalue = utils::numeric(FLERR, arg[3], false, lmp);
|
||||||
|
xstyle = CONSTANT;
|
||||||
|
}
|
||||||
|
if (strstr(arg[4], "v_") == arg[4]) {
|
||||||
|
ystr = utils::strdup(&arg[4][2]);
|
||||||
|
} else if (strcmp(arg[4], "NULL") == 0) {
|
||||||
|
ystyle = NONE;
|
||||||
|
} else {
|
||||||
|
yvalue = utils::numeric(FLERR, arg[4], false, lmp);
|
||||||
|
ystyle = CONSTANT;
|
||||||
|
}
|
||||||
|
if (strstr(arg[5], "v_") == arg[5]) {
|
||||||
|
zstr = utils::strdup(&arg[5][2]);
|
||||||
|
} else if (strcmp(arg[5], "NULL") == 0) {
|
||||||
|
zstyle = NONE;
|
||||||
|
} else {
|
||||||
|
zvalue = utils::numeric(FLERR, arg[5], false, lmp);
|
||||||
|
zstyle = CONSTANT;
|
||||||
|
}
|
||||||
|
|
||||||
if (strstr(arg[3], "v_") == arg[3]) {
|
// optional args
|
||||||
xstr = utils::strdup( &arg[3][2]);
|
|
||||||
} else if (strcmp(arg[3], "NULL") == 0) {
|
|
||||||
xstyle = NONE;
|
|
||||||
} else {
|
|
||||||
xvalue = utils::numeric(FLERR, arg[3],false,lmp);
|
|
||||||
xstyle = CONSTANT;
|
|
||||||
}
|
|
||||||
if (strstr(arg[4], "v_") == arg[4]) {
|
|
||||||
ystr = utils::strdup( &arg[4][2]);
|
|
||||||
} else if (strcmp(arg[4], "NULL") == 0) {
|
|
||||||
ystyle = NONE;
|
|
||||||
} else {
|
|
||||||
yvalue = utils::numeric(FLERR, arg[4],false,lmp);
|
|
||||||
ystyle = CONSTANT;
|
|
||||||
}
|
|
||||||
if (strstr(arg[5], "v_") == arg[5]) {
|
|
||||||
zstr = utils::strdup( &arg[5][2]);
|
|
||||||
} else if (strcmp(arg[5], "NULL") == 0) {
|
|
||||||
zstyle = NONE;
|
|
||||||
} else {
|
|
||||||
zvalue = utils::numeric(FLERR, arg[5],false,lmp);
|
|
||||||
zstyle = CONSTANT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional args
|
int iarg = 6;
|
||||||
|
while (iarg < narg) {
|
||||||
|
if (strcmp(arg[iarg], "region") == 0) {
|
||||||
|
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix setvelocity command");
|
||||||
|
region = domain->get_region_by_id(arg[iarg + 1]);
|
||||||
|
if (!region) error->all(FLERR, "Region {} for fix setvelocity does not exist", arg[iarg + 1]);
|
||||||
|
idregion = utils::strdup(arg[iarg + 1]);
|
||||||
|
iarg += 2;
|
||||||
|
} else
|
||||||
|
error->all(FLERR, "Illegal fix setvelocity command");
|
||||||
|
}
|
||||||
|
|
||||||
iregion = -1;
|
force_flag = 0;
|
||||||
idregion = nullptr;
|
foriginal[0] = foriginal[1] = foriginal[2] = 0.0;
|
||||||
|
|
||||||
int iarg = 6;
|
maxatom = atom->nmax;
|
||||||
while (iarg < narg) {
|
memory->create(sforce, maxatom, 3, "setvelocity:sforce");
|
||||||
if (strcmp(arg[iarg], "region") == 0) {
|
|
||||||
if (iarg + 2 > narg)
|
|
||||||
error->all(FLERR, "Illegal fix setvelocity command");
|
|
||||||
iregion = domain->find_region(arg[iarg + 1]);
|
|
||||||
if (iregion == -1)
|
|
||||||
error->all(FLERR, "Region ID for fix setvelocity does not exist");
|
|
||||||
idregion = utils::strdup( arg[iarg + 1]);
|
|
||||||
iarg += 2;
|
|
||||||
} else
|
|
||||||
error->all(FLERR, "Illegal fix setvelocity command");
|
|
||||||
}
|
|
||||||
|
|
||||||
force_flag = 0;
|
|
||||||
foriginal[0] = foriginal[1] = foriginal[2] = 0.0;
|
|
||||||
|
|
||||||
maxatom = atom->nmax;
|
|
||||||
memory->create(sforce, maxatom, 3, "setvelocity:sforce");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixSMDSetVel::~FixSMDSetVel() {
|
FixSMDSetVel::~FixSMDSetVel()
|
||||||
delete[] xstr;
|
{
|
||||||
delete[] ystr;
|
delete[] xstr;
|
||||||
delete[] zstr;
|
delete[] ystr;
|
||||||
delete[] idregion;
|
delete[] zstr;
|
||||||
memory->destroy(sforce);
|
delete[] idregion;
|
||||||
|
memory->destroy(sforce);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
int FixSMDSetVel::setmask() {
|
int FixSMDSetVel::setmask()
|
||||||
int mask = 0;
|
{
|
||||||
//mask |= INITIAL_INTEGRATE;
|
int mask = 0;
|
||||||
mask |= POST_FORCE;
|
mask |= POST_FORCE;
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixSMDSetVel::init() {
|
void FixSMDSetVel::init()
|
||||||
// check variables
|
{
|
||||||
|
// check variables
|
||||||
|
|
||||||
if (xstr) {
|
if (xstr) {
|
||||||
xvar = input->variable->find(xstr);
|
xvar = input->variable->find(xstr);
|
||||||
if (xvar < 0)
|
if (xvar < 0) error->all(FLERR, "Variable name for fix setvelocity does not exist");
|
||||||
error->all(FLERR, "Variable name for fix setvelocity does not exist");
|
if (input->variable->equalstyle(xvar))
|
||||||
if (input->variable->equalstyle(xvar))
|
xstyle = EQUAL;
|
||||||
xstyle = EQUAL;
|
else if (input->variable->atomstyle(xvar))
|
||||||
else if (input->variable->atomstyle(xvar))
|
xstyle = ATOM;
|
||||||
xstyle = ATOM;
|
else
|
||||||
else
|
error->all(FLERR, "Variable for fix setvelocity is invalid style");
|
||||||
error->all(FLERR, "Variable for fix setvelocity is invalid style");
|
}
|
||||||
}
|
if (ystr) {
|
||||||
if (ystr) {
|
yvar = input->variable->find(ystr);
|
||||||
yvar = input->variable->find(ystr);
|
if (yvar < 0) error->all(FLERR, "Variable name for fix setvelocity does not exist");
|
||||||
if (yvar < 0)
|
if (input->variable->equalstyle(yvar))
|
||||||
error->all(FLERR, "Variable name for fix setvelocity does not exist");
|
ystyle = EQUAL;
|
||||||
if (input->variable->equalstyle(yvar))
|
else if (input->variable->atomstyle(yvar))
|
||||||
ystyle = EQUAL;
|
ystyle = ATOM;
|
||||||
else if (input->variable->atomstyle(yvar))
|
else
|
||||||
ystyle = ATOM;
|
error->all(FLERR, "Variable for fix setvelocity is invalid style");
|
||||||
else
|
}
|
||||||
error->all(FLERR, "Variable for fix setvelocity is invalid style");
|
if (zstr) {
|
||||||
}
|
zvar = input->variable->find(zstr);
|
||||||
if (zstr) {
|
if (zvar < 0) error->all(FLERR, "Variable name for fix setvelocity does not exist");
|
||||||
zvar = input->variable->find(zstr);
|
if (input->variable->equalstyle(zvar))
|
||||||
if (zvar < 0)
|
zstyle = EQUAL;
|
||||||
error->all(FLERR, "Variable name for fix setvelocity does not exist");
|
else if (input->variable->atomstyle(zvar))
|
||||||
if (input->variable->equalstyle(zvar))
|
zstyle = ATOM;
|
||||||
zstyle = EQUAL;
|
else
|
||||||
else if (input->variable->atomstyle(zvar))
|
error->all(FLERR, "Variable for fix setvelocity is invalid style");
|
||||||
zstyle = ATOM;
|
}
|
||||||
else
|
|
||||||
error->all(FLERR, "Variable for fix setvelocity is invalid style");
|
|
||||||
}
|
|
||||||
|
|
||||||
// set index and check validity of region
|
// set index and check validity of region
|
||||||
|
|
||||||
if (iregion >= 0) {
|
if (idregion) {
|
||||||
iregion = domain->find_region(idregion);
|
region = domain->get_region_by_id(idregion);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for fix setvelocity does not exist", idregion);
|
||||||
error->all(FLERR, "Region ID for fix setvelocity does not exist");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM)
|
if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM)
|
||||||
varflag = ATOM;
|
varflag = ATOM;
|
||||||
else if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL)
|
else if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL)
|
||||||
varflag = EQUAL;
|
varflag = EQUAL;
|
||||||
else
|
else
|
||||||
varflag = CONSTANT;
|
varflag = CONSTANT;
|
||||||
|
|
||||||
// cannot use non-zero forces for a minimization since no energy is integrated
|
// cannot use non-zero forces for a minimization since no energy is integrated
|
||||||
// use fix addforce instead
|
// use fix addforce instead
|
||||||
|
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
if (update->whichflag == 2) {
|
if (update->whichflag == 2) {
|
||||||
if (xstyle == EQUAL || xstyle == ATOM)
|
if (xstyle == EQUAL || xstyle == ATOM) flag = 1;
|
||||||
flag = 1;
|
if (ystyle == EQUAL || ystyle == ATOM) flag = 1;
|
||||||
if (ystyle == EQUAL || ystyle == ATOM)
|
if (zstyle == EQUAL || zstyle == ATOM) flag = 1;
|
||||||
flag = 1;
|
if (xstyle == CONSTANT && xvalue != 0.0) flag = 1;
|
||||||
if (zstyle == EQUAL || zstyle == ATOM)
|
if (ystyle == CONSTANT && yvalue != 0.0) flag = 1;
|
||||||
flag = 1;
|
if (zstyle == CONSTANT && zvalue != 0.0) flag = 1;
|
||||||
if (xstyle == CONSTANT && xvalue != 0.0)
|
}
|
||||||
flag = 1;
|
if (flag) error->all(FLERR, "Cannot use non-zero forces in an energy minimization");
|
||||||
if (ystyle == CONSTANT && yvalue != 0.0)
|
|
||||||
flag = 1;
|
|
||||||
if (zstyle == CONSTANT && zvalue != 0.0)
|
|
||||||
flag = 1;
|
|
||||||
}
|
|
||||||
if (flag)
|
|
||||||
error->all(FLERR, "Cannot use non-zero forces in an energy minimization");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixSMDSetVel::setup(int vflag) {
|
void FixSMDSetVel::setup(int vflag)
|
||||||
if (utils::strmatch(update->integrate_style,"^verlet"))
|
{
|
||||||
post_force(vflag);
|
if (utils::strmatch(update->integrate_style, "^verlet"))
|
||||||
else
|
post_force(vflag);
|
||||||
error->all(FLERR,"Fix smd/setvel does not support RESPA");
|
else
|
||||||
|
error->all(FLERR, "Fix smd/setvel does not support RESPA");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixSMDSetVel::min_setup(int vflag) {
|
void FixSMDSetVel::min_setup(int vflag)
|
||||||
post_force(vflag);
|
{
|
||||||
|
post_force(vflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
//void FixSMDSetVel::initial_integrate(int vflag) {
|
void FixSMDSetVel::post_force(int /*vflag*/)
|
||||||
void FixSMDSetVel::post_force(int /*vflag*/) {
|
{
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
double **f = atom->f;
|
double **f = atom->f;
|
||||||
double **v = atom->v;
|
double **v = atom->v;
|
||||||
double **vest = atom->vest;
|
double **vest = atom->vest;
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
// update region if necessary
|
// update region if necessary
|
||||||
|
|
||||||
Region *region = nullptr;
|
if (region) region->prematch();
|
||||||
if (iregion >= 0) {
|
|
||||||
region = domain->regions[iregion];
|
// reallocate sforce array if necessary
|
||||||
region->prematch();
|
|
||||||
|
if (varflag == ATOM && atom->nmax > maxatom) {
|
||||||
|
maxatom = atom->nmax;
|
||||||
|
memory->destroy(sforce);
|
||||||
|
memory->create(sforce, maxatom, 3, "setvelocity:sforce");
|
||||||
|
}
|
||||||
|
|
||||||
|
foriginal[0] = foriginal[1] = foriginal[2] = 0.0;
|
||||||
|
force_flag = 0;
|
||||||
|
|
||||||
|
if (varflag == CONSTANT) {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit) {
|
||||||
|
if (region && !region->match(x[i][0], x[i][1], x[i][2])) continue;
|
||||||
|
foriginal[0] += f[i][0];
|
||||||
|
foriginal[1] += f[i][1];
|
||||||
|
foriginal[2] += f[i][2];
|
||||||
|
if (xstyle) {
|
||||||
|
v[i][0] = xvalue;
|
||||||
|
vest[i][0] = xvalue;
|
||||||
|
f[i][0] = 0.0;
|
||||||
|
}
|
||||||
|
if (ystyle) {
|
||||||
|
v[i][1] = yvalue;
|
||||||
|
vest[i][1] = yvalue;
|
||||||
|
f[i][1] = 0.0;
|
||||||
|
}
|
||||||
|
if (zstyle) {
|
||||||
|
v[i][2] = zvalue;
|
||||||
|
vest[i][2] = zvalue;
|
||||||
|
f[i][2] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// variable force, wrap with clear/add
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
modify->clearstep_compute();
|
||||||
|
|
||||||
|
if (xstyle == EQUAL)
|
||||||
|
xvalue = input->variable->compute_equal(xvar);
|
||||||
|
else if (xstyle == ATOM)
|
||||||
|
input->variable->compute_atom(xvar, igroup, &sforce[0][0], 3, 0);
|
||||||
|
if (ystyle == EQUAL)
|
||||||
|
yvalue = input->variable->compute_equal(yvar);
|
||||||
|
else if (ystyle == ATOM)
|
||||||
|
input->variable->compute_atom(yvar, igroup, &sforce[0][1], 3, 0);
|
||||||
|
if (zstyle == EQUAL)
|
||||||
|
zvalue = input->variable->compute_equal(zvar);
|
||||||
|
else if (zstyle == ATOM)
|
||||||
|
input->variable->compute_atom(zvar, igroup, &sforce[0][2], 3, 0);
|
||||||
|
|
||||||
|
modify->addstep_compute(update->ntimestep + 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit) {
|
||||||
|
if (region && !region->match(x[i][0], x[i][1], x[i][2])) continue;
|
||||||
|
foriginal[0] += f[i][0];
|
||||||
|
foriginal[1] += f[i][1];
|
||||||
|
foriginal[2] += f[i][2];
|
||||||
|
if (xstyle == ATOM) {
|
||||||
|
vest[i][0] = v[i][0] = sforce[i][0];
|
||||||
|
f[i][0] = 0.0;
|
||||||
|
} else if (xstyle) {
|
||||||
|
vest[i][0] = v[i][0] = xvalue;
|
||||||
|
f[i][0] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reallocate sforce array if necessary
|
if (ystyle == ATOM) {
|
||||||
|
vest[i][1] = v[i][1] = sforce[i][1];
|
||||||
if (varflag == ATOM && atom->nmax > maxatom) {
|
f[i][1] = 0.0;
|
||||||
maxatom = atom->nmax;
|
} else if (ystyle) {
|
||||||
memory->destroy(sforce);
|
vest[i][1] = v[i][1] = yvalue;
|
||||||
memory->create(sforce, maxatom, 3, "setvelocity:sforce");
|
f[i][1] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
foriginal[0] = foriginal[1] = foriginal[2] = 0.0;
|
if (zstyle == ATOM) {
|
||||||
force_flag = 0;
|
vest[i][2] = v[i][2] = sforce[i][2];
|
||||||
|
f[i][2] = 0.0;
|
||||||
if (varflag == CONSTANT) {
|
} else if (zstyle) {
|
||||||
for (int i = 0; i < nlocal; i++)
|
vest[i][2] = v[i][2] = zvalue;
|
||||||
if (mask[i] & groupbit) {
|
f[i][2] = 0.0;
|
||||||
if (region && !region->match(x[i][0], x[i][1], x[i][2]))
|
|
||||||
continue;
|
|
||||||
foriginal[0] += f[i][0];
|
|
||||||
foriginal[1] += f[i][1];
|
|
||||||
foriginal[2] += f[i][2];
|
|
||||||
if (xstyle) {
|
|
||||||
v[i][0] = xvalue;
|
|
||||||
vest[i][0] = xvalue;
|
|
||||||
f[i][0] = 0.0;
|
|
||||||
}
|
|
||||||
if (ystyle) {
|
|
||||||
v[i][1] = yvalue;
|
|
||||||
vest[i][1] = yvalue;
|
|
||||||
f[i][1] = 0.0;
|
|
||||||
}
|
|
||||||
if (zstyle) {
|
|
||||||
v[i][2] = zvalue;
|
|
||||||
vest[i][2] = zvalue;
|
|
||||||
f[i][2] = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// variable force, wrap with clear/add
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
modify->clearstep_compute();
|
|
||||||
|
|
||||||
if (xstyle == EQUAL)
|
|
||||||
xvalue = input->variable->compute_equal(xvar);
|
|
||||||
else if (xstyle == ATOM)
|
|
||||||
input->variable->compute_atom(xvar, igroup, &sforce[0][0], 3, 0);
|
|
||||||
if (ystyle == EQUAL)
|
|
||||||
yvalue = input->variable->compute_equal(yvar);
|
|
||||||
else if (ystyle == ATOM)
|
|
||||||
input->variable->compute_atom(yvar, igroup, &sforce[0][1], 3, 0);
|
|
||||||
if (zstyle == EQUAL)
|
|
||||||
zvalue = input->variable->compute_equal(zvar);
|
|
||||||
else if (zstyle == ATOM)
|
|
||||||
input->variable->compute_atom(zvar, igroup, &sforce[0][2], 3, 0);
|
|
||||||
|
|
||||||
modify->addstep_compute(update->ntimestep + 1);
|
|
||||||
|
|
||||||
//printf("setting velocity at timestep %d\n", update->ntimestep);
|
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; i++)
|
|
||||||
if (mask[i] & groupbit) {
|
|
||||||
if (region && !region->match(x[i][0], x[i][1], x[i][2]))
|
|
||||||
continue;
|
|
||||||
foriginal[0] += f[i][0];
|
|
||||||
foriginal[1] += f[i][1];
|
|
||||||
foriginal[2] += f[i][2];
|
|
||||||
if (xstyle == ATOM) {
|
|
||||||
vest[i][0] = v[i][0] = sforce[i][0];
|
|
||||||
f[i][0] = 0.0;
|
|
||||||
} else if (xstyle) {
|
|
||||||
vest[i][0] = v[i][0] = xvalue;
|
|
||||||
f[i][0] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ystyle == ATOM) {
|
|
||||||
vest[i][1] = v[i][1] = sforce[i][1];
|
|
||||||
f[i][1] = 0.0;
|
|
||||||
} else if (ystyle) {
|
|
||||||
vest[i][1] = v[i][1] = yvalue;
|
|
||||||
f[i][1] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zstyle == ATOM) {
|
|
||||||
vest[i][2] = v[i][2] = sforce[i][2];
|
|
||||||
f[i][2] = 0.0;
|
|
||||||
} else if (zstyle) {
|
|
||||||
vest[i][2] = v[i][2] = zvalue;
|
|
||||||
f[i][2] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
return components of total force on fix group before force was changed
|
return components of total force on fix group before force was changed
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
double FixSMDSetVel::compute_vector(int n) {
|
double FixSMDSetVel::compute_vector(int n)
|
||||||
// only sum across procs one time
|
{
|
||||||
|
// only sum across procs one time
|
||||||
|
|
||||||
if (force_flag == 0) {
|
if (force_flag == 0) {
|
||||||
MPI_Allreduce(foriginal, foriginal_all, 3, MPI_DOUBLE, MPI_SUM, world);
|
MPI_Allreduce(foriginal, foriginal_all, 3, MPI_DOUBLE, MPI_SUM, world);
|
||||||
force_flag = 1;
|
force_flag = 1;
|
||||||
}
|
}
|
||||||
return foriginal_all[n];
|
return foriginal_all[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
memory usage of local atom-based array
|
memory usage of local atom-based array
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
double FixSMDSetVel::memory_usage() {
|
double FixSMDSetVel::memory_usage()
|
||||||
double bytes = 0.0;
|
{
|
||||||
if (varflag == ATOM)
|
double bytes = 0.0;
|
||||||
bytes = atom->nmax * 3 * sizeof(double);
|
if (varflag == ATOM) bytes = atom->nmax * 3 * sizeof(double);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,9 +50,10 @@ class FixSMDSetVel : public Fix {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
double xvalue, yvalue, zvalue;
|
double xvalue, yvalue, zvalue;
|
||||||
int varflag, iregion;
|
int varflag;
|
||||||
char *xstr, *ystr, *zstr;
|
char *xstr, *ystr, *zstr;
|
||||||
char *idregion;
|
char *idregion;
|
||||||
|
class Region *region;
|
||||||
int xvar, yvar, zvar, xstyle, ystyle, zstyle;
|
int xvar, yvar, zvar, xstyle, ystyle, zstyle;
|
||||||
double foriginal[3], foriginal_all[3];
|
double foriginal[3], foriginal_all[3];
|
||||||
int force_flag;
|
int force_flag;
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -40,9 +39,9 @@
|
|||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
@ -51,13 +50,12 @@ using namespace FixConst;
|
|||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixAtomSwap::FixAtomSwap(LAMMPS *lmp, int narg, char **arg) :
|
FixAtomSwap::FixAtomSwap(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg),
|
Fix(lmp, narg, arg), region(nullptr), idregion(nullptr), type_list(nullptr), mu(nullptr),
|
||||||
idregion(nullptr), type_list(nullptr), mu(nullptr), qtype(nullptr),
|
qtype(nullptr), sqrt_mass_ratio(nullptr), local_swap_iatom_list(nullptr),
|
||||||
sqrt_mass_ratio(nullptr), local_swap_iatom_list(nullptr),
|
local_swap_jatom_list(nullptr), local_swap_atom_list(nullptr), random_equal(nullptr),
|
||||||
local_swap_jatom_list(nullptr), local_swap_atom_list(nullptr),
|
random_unequal(nullptr), c_pe(nullptr)
|
||||||
random_equal(nullptr), random_unequal(nullptr), c_pe(nullptr)
|
|
||||||
{
|
{
|
||||||
if (narg < 10) error->all(FLERR,"Illegal fix atom/swap command");
|
if (narg < 10) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
|
|
||||||
dynamic_group_allow = 1;
|
dynamic_group_allow = 1;
|
||||||
|
|
||||||
@ -70,33 +68,33 @@ FixAtomSwap::FixAtomSwap(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
// required args
|
// required args
|
||||||
|
|
||||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
nevery = utils::inumeric(FLERR, arg[3], false, lmp);
|
||||||
ncycles = utils::inumeric(FLERR,arg[4],false,lmp);
|
ncycles = utils::inumeric(FLERR, arg[4], false, lmp);
|
||||||
seed = utils::inumeric(FLERR,arg[5],false,lmp);
|
seed = utils::inumeric(FLERR, arg[5], false, lmp);
|
||||||
double temperature = utils::numeric(FLERR,arg[6],false,lmp);
|
double temperature = utils::numeric(FLERR, arg[6], false, lmp);
|
||||||
|
|
||||||
if (nevery <= 0) error->all(FLERR,"Illegal fix atom/swap command");
|
if (nevery <= 0) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
if (ncycles < 0) error->all(FLERR,"Illegal fix atom/swap command");
|
if (ncycles < 0) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
if (seed <= 0) error->all(FLERR,"Illegal fix atom/swap command");
|
if (seed <= 0) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
if (temperature <= 0.0) error->all(FLERR,"Illegal fix atom/swap command");
|
if (temperature <= 0.0) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
|
|
||||||
beta = 1.0/(force->boltz*temperature);
|
beta = 1.0 / (force->boltz * temperature);
|
||||||
|
|
||||||
memory->create(type_list,atom->ntypes,"atom/swap:type_list");
|
memory->create(type_list, atom->ntypes, "atom/swap:type_list");
|
||||||
memory->create(mu,atom->ntypes+1,"atom/swap:mu");
|
memory->create(mu, atom->ntypes + 1, "atom/swap:mu");
|
||||||
for (int i = 1; i <= atom->ntypes; i++) mu[i] = 0.0;
|
for (int i = 1; i <= atom->ntypes; i++) mu[i] = 0.0;
|
||||||
|
|
||||||
// read options from end of input line
|
// read options from end of input line
|
||||||
|
|
||||||
options(narg-7,&arg[7]);
|
options(narg - 7, &arg[7]);
|
||||||
|
|
||||||
// random number generator, same for all procs
|
// random number generator, same for all procs
|
||||||
|
|
||||||
random_equal = new RanPark(lmp,seed);
|
random_equal = new RanPark(lmp, seed);
|
||||||
|
|
||||||
// random number generator, not the same for all procs
|
// random number generator, not the same for all procs
|
||||||
|
|
||||||
random_unequal = new RanPark(lmp,seed);
|
random_unequal = new RanPark(lmp, seed);
|
||||||
|
|
||||||
// set up reneighboring
|
// set up reneighboring
|
||||||
|
|
||||||
@ -115,9 +113,10 @@ FixAtomSwap::FixAtomSwap(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
// set comm size needed by this Fix
|
// set comm size needed by this Fix
|
||||||
|
|
||||||
if (atom->q_flag) comm_forward = 2;
|
if (atom->q_flag)
|
||||||
else comm_forward = 1;
|
comm_forward = 2;
|
||||||
|
else
|
||||||
|
comm_forward = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -130,7 +129,7 @@ FixAtomSwap::~FixAtomSwap()
|
|||||||
memory->destroy(sqrt_mass_ratio);
|
memory->destroy(sqrt_mass_ratio);
|
||||||
memory->destroy(local_swap_iatom_list);
|
memory->destroy(local_swap_iatom_list);
|
||||||
memory->destroy(local_swap_jatom_list);
|
memory->destroy(local_swap_jatom_list);
|
||||||
if (regionflag) delete [] idregion;
|
delete[] idregion;
|
||||||
delete random_equal;
|
delete random_equal;
|
||||||
delete random_unequal;
|
delete random_unequal;
|
||||||
}
|
}
|
||||||
@ -141,54 +140,51 @@ FixAtomSwap::~FixAtomSwap()
|
|||||||
|
|
||||||
void FixAtomSwap::options(int narg, char **arg)
|
void FixAtomSwap::options(int narg, char **arg)
|
||||||
{
|
{
|
||||||
if (narg < 0) error->all(FLERR,"Illegal fix atom/swap command");
|
if (narg < 0) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
|
|
||||||
regionflag = 0;
|
|
||||||
ke_flag = 1;
|
ke_flag = 1;
|
||||||
semi_grand_flag = 0;
|
semi_grand_flag = 0;
|
||||||
nswaptypes = 0;
|
nswaptypes = 0;
|
||||||
nmutypes = 0;
|
nmutypes = 0;
|
||||||
iregion = -1;
|
|
||||||
|
|
||||||
int iarg = 0;
|
int iarg = 0;
|
||||||
while (iarg < narg) {
|
while (iarg < narg) {
|
||||||
if (strcmp(arg[iarg],"region") == 0) {
|
if (strcmp(arg[iarg], "region") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix atom/swap command");
|
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
iregion = domain->find_region(arg[iarg+1]);
|
region = domain->get_region_by_id(arg[iarg + 1]);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for fix atom/swap does not exist", arg[iarg + 1]);
|
||||||
error->all(FLERR,"Region ID for fix atom/swap does not exist");
|
idregion = utils::strdup(arg[iarg + 1]);
|
||||||
idregion = utils::strdup(arg[iarg+1]);
|
|
||||||
regionflag = 1;
|
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else if (strcmp(arg[iarg],"ke") == 0) {
|
} else if (strcmp(arg[iarg], "ke") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix atom/swap command");
|
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
ke_flag = utils::logical(FLERR,arg[iarg+1],false,lmp);
|
ke_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else if (strcmp(arg[iarg],"semi-grand") == 0) {
|
} else if (strcmp(arg[iarg], "semi-grand") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix atom/swap command");
|
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
semi_grand_flag = utils::logical(FLERR,arg[iarg+1],false,lmp);
|
semi_grand_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else if (strcmp(arg[iarg],"types") == 0) {
|
} else if (strcmp(arg[iarg], "types") == 0) {
|
||||||
if (iarg+3 > narg) error->all(FLERR,"Illegal fix atom/swap command");
|
if (iarg + 3 > narg) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
iarg++;
|
iarg++;
|
||||||
while (iarg < narg) {
|
while (iarg < narg) {
|
||||||
if (isalpha(arg[iarg][0])) break;
|
if (isalpha(arg[iarg][0])) break;
|
||||||
if (nswaptypes >= atom->ntypes) error->all(FLERR,"Illegal fix atom/swap command");
|
if (nswaptypes >= atom->ntypes) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
type_list[nswaptypes] = utils::numeric(FLERR,arg[iarg],false,lmp);
|
type_list[nswaptypes] = utils::numeric(FLERR, arg[iarg], false, lmp);
|
||||||
nswaptypes++;
|
nswaptypes++;
|
||||||
iarg++;
|
iarg++;
|
||||||
}
|
}
|
||||||
} else if (strcmp(arg[iarg],"mu") == 0) {
|
} else if (strcmp(arg[iarg], "mu") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix atom/swap command");
|
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
iarg++;
|
iarg++;
|
||||||
while (iarg < narg) {
|
while (iarg < narg) {
|
||||||
if (isalpha(arg[iarg][0])) break;
|
if (isalpha(arg[iarg][0])) break;
|
||||||
nmutypes++;
|
nmutypes++;
|
||||||
if (nmutypes > atom->ntypes) error->all(FLERR,"Illegal fix atom/swap command");
|
if (nmutypes > atom->ntypes) error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
mu[nmutypes] = utils::numeric(FLERR,arg[iarg],false,lmp);
|
mu[nmutypes] = utils::numeric(FLERR, arg[iarg], false, lmp);
|
||||||
iarg++;
|
iarg++;
|
||||||
}
|
}
|
||||||
} else error->all(FLERR,"Illegal fix atom/swap command");
|
} else
|
||||||
|
error->all(FLERR, "Illegal fix atom/swap command");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,36 +201,40 @@ int FixAtomSwap::setmask()
|
|||||||
|
|
||||||
void FixAtomSwap::init()
|
void FixAtomSwap::init()
|
||||||
{
|
{
|
||||||
auto id_pe = (char *) "thermo_pe";
|
c_pe = modify->get_compute_by_id("thermo_pe");
|
||||||
int ipe = modify->find_compute(id_pe);
|
|
||||||
c_pe = modify->compute[ipe];
|
|
||||||
|
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
|
|
||||||
if (nswaptypes < 2)
|
if (nswaptypes < 2) error->all(FLERR, "Must specify at least 2 types in fix atom/swap command");
|
||||||
error->all(FLERR,"Must specify at least 2 types in fix atom/swap command");
|
|
||||||
|
|
||||||
if (semi_grand_flag) {
|
if (semi_grand_flag) {
|
||||||
if (nswaptypes != nmutypes)
|
if (nswaptypes != nmutypes)
|
||||||
error->all(FLERR,"Need nswaptypes mu values in fix atom/swap command");
|
error->all(FLERR, "Need nswaptypes mu values in fix atom/swap command");
|
||||||
} else {
|
} else {
|
||||||
if (nswaptypes != 2)
|
if (nswaptypes != 2)
|
||||||
error->all(FLERR,"Only 2 types allowed when not using semi-grand in fix atom/swap command");
|
error->all(FLERR, "Only 2 types allowed when not using semi-grand in fix atom/swap command");
|
||||||
if (nmutypes != 0)
|
if (nmutypes != 0)
|
||||||
error->all(FLERR,"Mu not allowed when not using semi-grand in fix atom/swap command");
|
error->all(FLERR, "Mu not allowed when not using semi-grand in fix atom/swap command");
|
||||||
|
}
|
||||||
|
|
||||||
|
// set index and check validity of region
|
||||||
|
|
||||||
|
if (idregion) {
|
||||||
|
region = domain->get_region_by_id(idregion);
|
||||||
|
if (!region) error->all(FLERR, "Region {} for fix setforce does not exist", idregion);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int iswaptype = 0; iswaptype < nswaptypes; iswaptype++)
|
for (int iswaptype = 0; iswaptype < nswaptypes; iswaptype++)
|
||||||
if (type_list[iswaptype] <= 0 || type_list[iswaptype] > atom->ntypes)
|
if (type_list[iswaptype] <= 0 || type_list[iswaptype] > atom->ntypes)
|
||||||
error->all(FLERR,"Invalid atom type in fix atom/swap command");
|
error->all(FLERR, "Invalid atom type in fix atom/swap command");
|
||||||
|
|
||||||
// this is only required for non-semi-grand
|
// this is only required for non-semi-grand
|
||||||
// in which case, nswaptypes = 2
|
// in which case, nswaptypes = 2
|
||||||
|
|
||||||
if (atom->q_flag && !semi_grand_flag) {
|
if (atom->q_flag && !semi_grand_flag) {
|
||||||
double qmax,qmin;
|
double qmax, qmin;
|
||||||
int firstall,first;
|
int firstall, first;
|
||||||
memory->create(qtype,nswaptypes,"atom/swap:qtype");
|
memory->create(qtype, nswaptypes, "atom/swap:qtype");
|
||||||
for (int iswaptype = 0; iswaptype < nswaptypes; iswaptype++) {
|
for (int iswaptype = 0; iswaptype < nswaptypes; iswaptype++) {
|
||||||
first = 1;
|
first = 1;
|
||||||
for (int i = 0; i < atom->nlocal; i++) {
|
for (int i = 0; i < atom->nlocal; i++) {
|
||||||
@ -244,24 +244,26 @@ void FixAtomSwap::init()
|
|||||||
qtype[iswaptype] = atom->q[i];
|
qtype[iswaptype] = atom->q[i];
|
||||||
first = 0;
|
first = 0;
|
||||||
} else if (qtype[iswaptype] != atom->q[i])
|
} else if (qtype[iswaptype] != atom->q[i])
|
||||||
error->one(FLERR,"All atoms of a swapped type must have the same charge.");
|
error->one(FLERR, "All atoms of a swapped type must have the same charge.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MPI_Allreduce(&first,&firstall,1,MPI_INT,MPI_MIN,world);
|
MPI_Allreduce(&first, &firstall, 1, MPI_INT, MPI_MIN, world);
|
||||||
if (firstall) error->all(FLERR,"At least one atom of each swapped type must be present to define charges.");
|
if (firstall)
|
||||||
|
error->all(FLERR,
|
||||||
|
"At least one atom of each swapped type must be present to define charges.");
|
||||||
if (first) qtype[iswaptype] = -DBL_MAX;
|
if (first) qtype[iswaptype] = -DBL_MAX;
|
||||||
MPI_Allreduce(&qtype[iswaptype],&qmax,1,MPI_DOUBLE,MPI_MAX,world);
|
MPI_Allreduce(&qtype[iswaptype], &qmax, 1, MPI_DOUBLE, MPI_MAX, world);
|
||||||
if (first) qtype[iswaptype] = DBL_MAX;
|
if (first) qtype[iswaptype] = DBL_MAX;
|
||||||
MPI_Allreduce(&qtype[iswaptype],&qmin,1,MPI_DOUBLE,MPI_MIN,world);
|
MPI_Allreduce(&qtype[iswaptype], &qmin, 1, MPI_DOUBLE, MPI_MIN, world);
|
||||||
if (qmax != qmin) error->all(FLERR,"All atoms of a swapped type must have same charge.");
|
if (qmax != qmin) error->all(FLERR, "All atoms of a swapped type must have same charge.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memory->create(sqrt_mass_ratio,atom->ntypes+1,atom->ntypes+1,"atom/swap:sqrt_mass_ratio");
|
memory->create(sqrt_mass_ratio, atom->ntypes + 1, atom->ntypes + 1, "atom/swap:sqrt_mass_ratio");
|
||||||
for (int itype = 1; itype <= atom->ntypes; itype++)
|
for (int itype = 1; itype <= atom->ntypes; itype++)
|
||||||
for (int jtype = 1; jtype <= atom->ntypes; jtype++)
|
for (int jtype = 1; jtype <= atom->ntypes; jtype++)
|
||||||
sqrt_mass_ratio[itype][jtype] = sqrt(atom->mass[itype]/atom->mass[jtype]);
|
sqrt_mass_ratio[itype][jtype] = sqrt(atom->mass[itype] / atom->mass[jtype]);
|
||||||
|
|
||||||
// check to see if itype and jtype cutoffs are the same
|
// check to see if itype and jtype cutoffs are the same
|
||||||
// if not, reneighboring will be needed between swaps
|
// if not, reneighboring will be needed between swaps
|
||||||
@ -286,10 +288,9 @@ void FixAtomSwap::init()
|
|||||||
if ((mask[i] == groupbit) && (mask[i] && firstgroupbit)) flag = 1;
|
if ((mask[i] == groupbit) && (mask[i] && firstgroupbit)) flag = 1;
|
||||||
|
|
||||||
int flagall;
|
int flagall;
|
||||||
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
|
MPI_Allreduce(&flag, &flagall, 1, MPI_INT, MPI_SUM, world);
|
||||||
|
|
||||||
if (flagall)
|
if (flagall) error->all(FLERR, "Cannot do atom/swap on atoms in atom_modify first group");
|
||||||
error->all(FLERR,"Cannot do atom/swap on atoms in atom_modify first group");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +310,7 @@ void FixAtomSwap::pre_exchange()
|
|||||||
domain->pbc();
|
domain->pbc();
|
||||||
comm->exchange();
|
comm->exchange();
|
||||||
comm->borders();
|
comm->borders();
|
||||||
if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
|
if (domain->triclinic) domain->lamda2x(atom->nlocal + atom->nghost);
|
||||||
if (modify->n_pre_neighbor) modify->pre_neighbor();
|
if (modify->n_pre_neighbor) modify->pre_neighbor();
|
||||||
neighbor->build(1);
|
neighbor->build(1);
|
||||||
|
|
||||||
@ -353,14 +354,14 @@ int FixAtomSwap::attempt_semi_grand()
|
|||||||
|
|
||||||
// pick a random atom and perform swap
|
// pick a random atom and perform swap
|
||||||
|
|
||||||
int itype,jtype,jswaptype;
|
int itype, jtype, jswaptype;
|
||||||
int i = pick_semi_grand_atom();
|
int i = pick_semi_grand_atom();
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
jswaptype = static_cast<int> (nswaptypes*random_unequal->uniform());
|
jswaptype = static_cast<int>(nswaptypes * random_unequal->uniform());
|
||||||
jtype = type_list[jswaptype];
|
jtype = type_list[jswaptype];
|
||||||
itype = atom->type[i];
|
itype = atom->type[i];
|
||||||
while (itype == jtype) {
|
while (itype == jtype) {
|
||||||
jswaptype = static_cast<int> (nswaptypes*random_unequal->uniform());
|
jswaptype = static_cast<int>(nswaptypes * random_unequal->uniform());
|
||||||
jtype = type_list[jswaptype];
|
jtype = type_list[jswaptype];
|
||||||
}
|
}
|
||||||
atom->type[i] = jtype;
|
atom->type[i] = jtype;
|
||||||
@ -374,7 +375,7 @@ int FixAtomSwap::attempt_semi_grand()
|
|||||||
if (domain->triclinic) domain->x2lamda(atom->nlocal);
|
if (domain->triclinic) domain->x2lamda(atom->nlocal);
|
||||||
comm->exchange();
|
comm->exchange();
|
||||||
comm->borders();
|
comm->borders();
|
||||||
if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
|
if (domain->triclinic) domain->lamda2x(atom->nlocal + atom->nghost);
|
||||||
if (modify->n_pre_neighbor) modify->pre_neighbor();
|
if (modify->n_pre_neighbor) modify->pre_neighbor();
|
||||||
neighbor->build(1);
|
neighbor->build(1);
|
||||||
} else {
|
} else {
|
||||||
@ -389,11 +390,11 @@ int FixAtomSwap::attempt_semi_grand()
|
|||||||
int success = 0;
|
int success = 0;
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
if (random_unequal->uniform() <
|
if (random_unequal->uniform() <
|
||||||
exp(beta*(energy_before - energy_after
|
exp(beta * (energy_before - energy_after + mu[jtype] - mu[itype])))
|
||||||
+ mu[jtype] - mu[itype]))) success = 1;
|
success = 1;
|
||||||
|
|
||||||
int success_all = 0;
|
int success_all = 0;
|
||||||
MPI_Allreduce(&success,&success_all,1,MPI_INT,MPI_MAX,world);
|
MPI_Allreduce(&success, &success_all, 1, MPI_INT, MPI_MAX, world);
|
||||||
|
|
||||||
// swap accepted, return 1
|
// swap accepted, return 1
|
||||||
|
|
||||||
@ -460,7 +461,7 @@ int FixAtomSwap::attempt_swap()
|
|||||||
domain->pbc();
|
domain->pbc();
|
||||||
comm->exchange();
|
comm->exchange();
|
||||||
comm->borders();
|
comm->borders();
|
||||||
if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
|
if (domain->triclinic) domain->lamda2x(atom->nlocal + atom->nghost);
|
||||||
if (modify->n_pre_neighbor) modify->pre_neighbor();
|
if (modify->n_pre_neighbor) modify->pre_neighbor();
|
||||||
neighbor->build(1);
|
neighbor->build(1);
|
||||||
} else {
|
} else {
|
||||||
@ -474,8 +475,7 @@ int FixAtomSwap::attempt_swap()
|
|||||||
// swap accepted, return 1
|
// swap accepted, return 1
|
||||||
// if ke_flag, rescale atom velocities
|
// if ke_flag, rescale atom velocities
|
||||||
|
|
||||||
if (random_equal->uniform() <
|
if (random_equal->uniform() < exp(beta * (energy_before - energy_after))) {
|
||||||
exp(beta*(energy_before - energy_after))) {
|
|
||||||
update_swap_atoms_list();
|
update_swap_atoms_list();
|
||||||
if (ke_flag) {
|
if (ke_flag) {
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
@ -521,16 +521,16 @@ double FixAtomSwap::energy_full()
|
|||||||
|
|
||||||
if (modify->n_pre_force) modify->pre_force(vflag);
|
if (modify->n_pre_force) modify->pre_force(vflag);
|
||||||
|
|
||||||
if (force->pair) force->pair->compute(eflag,vflag);
|
if (force->pair) force->pair->compute(eflag, vflag);
|
||||||
|
|
||||||
if (atom->molecular != Atom::ATOMIC) {
|
if (atom->molecular != Atom::ATOMIC) {
|
||||||
if (force->bond) force->bond->compute(eflag,vflag);
|
if (force->bond) force->bond->compute(eflag, vflag);
|
||||||
if (force->angle) force->angle->compute(eflag,vflag);
|
if (force->angle) force->angle->compute(eflag, vflag);
|
||||||
if (force->dihedral) force->dihedral->compute(eflag,vflag);
|
if (force->dihedral) force->dihedral->compute(eflag, vflag);
|
||||||
if (force->improper) force->improper->compute(eflag,vflag);
|
if (force->improper) force->improper->compute(eflag, vflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force->kspace) force->kspace->compute(eflag,vflag);
|
if (force->kspace) force->kspace->compute(eflag, vflag);
|
||||||
|
|
||||||
if (modify->n_post_force) modify->post_force(vflag);
|
if (modify->n_post_force) modify->post_force(vflag);
|
||||||
|
|
||||||
@ -546,9 +546,8 @@ double FixAtomSwap::energy_full()
|
|||||||
int FixAtomSwap::pick_semi_grand_atom()
|
int FixAtomSwap::pick_semi_grand_atom()
|
||||||
{
|
{
|
||||||
int i = -1;
|
int i = -1;
|
||||||
int iwhichglobal = static_cast<int> (nswap*random_equal->uniform());
|
int iwhichglobal = static_cast<int>(nswap * random_equal->uniform());
|
||||||
if ((iwhichglobal >= nswap_before) &&
|
if ((iwhichglobal >= nswap_before) && (iwhichglobal < nswap_before + nswap_local)) {
|
||||||
(iwhichglobal < nswap_before + nswap_local)) {
|
|
||||||
int iwhichlocal = iwhichglobal - nswap_before;
|
int iwhichlocal = iwhichglobal - nswap_before;
|
||||||
i = local_swap_atom_list[iwhichlocal];
|
i = local_swap_atom_list[iwhichlocal];
|
||||||
}
|
}
|
||||||
@ -562,9 +561,8 @@ int FixAtomSwap::pick_semi_grand_atom()
|
|||||||
int FixAtomSwap::pick_i_swap_atom()
|
int FixAtomSwap::pick_i_swap_atom()
|
||||||
{
|
{
|
||||||
int i = -1;
|
int i = -1;
|
||||||
int iwhichglobal = static_cast<int> (niswap*random_equal->uniform());
|
int iwhichglobal = static_cast<int>(niswap * random_equal->uniform());
|
||||||
if ((iwhichglobal >= niswap_before) &&
|
if ((iwhichglobal >= niswap_before) && (iwhichglobal < niswap_before + niswap_local)) {
|
||||||
(iwhichglobal < niswap_before + niswap_local)) {
|
|
||||||
int iwhichlocal = iwhichglobal - niswap_before;
|
int iwhichlocal = iwhichglobal - niswap_before;
|
||||||
i = local_swap_iatom_list[iwhichlocal];
|
i = local_swap_iatom_list[iwhichlocal];
|
||||||
}
|
}
|
||||||
@ -578,9 +576,8 @@ int FixAtomSwap::pick_i_swap_atom()
|
|||||||
int FixAtomSwap::pick_j_swap_atom()
|
int FixAtomSwap::pick_j_swap_atom()
|
||||||
{
|
{
|
||||||
int j = -1;
|
int j = -1;
|
||||||
int jwhichglobal = static_cast<int> (njswap*random_equal->uniform());
|
int jwhichglobal = static_cast<int>(njswap * random_equal->uniform());
|
||||||
if ((jwhichglobal >= njswap_before) &&
|
if ((jwhichglobal >= njswap_before) && (jwhichglobal < njswap_before + njswap_local)) {
|
||||||
(jwhichglobal < njswap_before + njswap_local)) {
|
|
||||||
int jwhichlocal = jwhichglobal - njswap_before;
|
int jwhichlocal = jwhichglobal - njswap_before;
|
||||||
j = local_swap_jatom_list[jwhichlocal];
|
j = local_swap_jatom_list[jwhichlocal];
|
||||||
}
|
}
|
||||||
@ -600,16 +597,15 @@ void FixAtomSwap::update_semi_grand_atoms_list()
|
|||||||
if (atom->nmax > atom_swap_nmax) {
|
if (atom->nmax > atom_swap_nmax) {
|
||||||
memory->sfree(local_swap_atom_list);
|
memory->sfree(local_swap_atom_list);
|
||||||
atom_swap_nmax = atom->nmax;
|
atom_swap_nmax = atom->nmax;
|
||||||
local_swap_atom_list = (int *) memory->smalloc(atom_swap_nmax*sizeof(int),
|
local_swap_atom_list =
|
||||||
"MCSWAP:local_swap_atom_list");
|
(int *) memory->smalloc(atom_swap_nmax * sizeof(int), "MCSWAP:local_swap_atom_list");
|
||||||
}
|
}
|
||||||
|
|
||||||
nswap_local = 0;
|
nswap_local = 0;
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]) == 1) {
|
if (region->match(x[i][0], x[i][1], x[i][2]) == 1) {
|
||||||
if (atom->mask[i] & groupbit) {
|
if (atom->mask[i] & groupbit) {
|
||||||
int itype = atom->type[i];
|
int itype = atom->type[i];
|
||||||
int iswaptype;
|
int iswaptype;
|
||||||
@ -625,23 +621,22 @@ void FixAtomSwap::update_semi_grand_atoms_list()
|
|||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (atom->mask[i] & groupbit) {
|
if (atom->mask[i] & groupbit) {
|
||||||
int itype = atom->type[i];
|
int itype = atom->type[i];
|
||||||
int iswaptype;
|
int iswaptype;
|
||||||
for (iswaptype = 0; iswaptype < nswaptypes; iswaptype++)
|
for (iswaptype = 0; iswaptype < nswaptypes; iswaptype++)
|
||||||
if (itype == type_list[iswaptype]) break;
|
if (itype == type_list[iswaptype]) break;
|
||||||
if (iswaptype == nswaptypes) continue;
|
if (iswaptype == nswaptypes) continue;
|
||||||
local_swap_atom_list[nswap_local] = i;
|
local_swap_atom_list[nswap_local] = i;
|
||||||
nswap_local++;
|
nswap_local++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MPI_Allreduce(&nswap_local,&nswap,1,MPI_INT,MPI_SUM,world);
|
MPI_Allreduce(&nswap_local, &nswap, 1, MPI_INT, MPI_SUM, world);
|
||||||
MPI_Scan(&nswap_local,&nswap_before,1,MPI_INT,MPI_SUM,world);
|
MPI_Scan(&nswap_local, &nswap_before, 1, MPI_INT, MPI_SUM, world);
|
||||||
nswap_before -= nswap_local;
|
nswap_before -= nswap_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
update the list of gas atoms
|
update the list of gas atoms
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -656,24 +651,24 @@ void FixAtomSwap::update_swap_atoms_list()
|
|||||||
memory->sfree(local_swap_iatom_list);
|
memory->sfree(local_swap_iatom_list);
|
||||||
memory->sfree(local_swap_jatom_list);
|
memory->sfree(local_swap_jatom_list);
|
||||||
atom_swap_nmax = atom->nmax;
|
atom_swap_nmax = atom->nmax;
|
||||||
local_swap_iatom_list = (int *) memory->smalloc(atom_swap_nmax*sizeof(int),
|
local_swap_iatom_list =
|
||||||
"MCSWAP:local_swap_iatom_list");
|
(int *) memory->smalloc(atom_swap_nmax * sizeof(int), "MCSWAP:local_swap_iatom_list");
|
||||||
local_swap_jatom_list = (int *) memory->smalloc(atom_swap_nmax*sizeof(int),
|
local_swap_jatom_list =
|
||||||
"MCSWAP:local_swap_jatom_list");
|
(int *) memory->smalloc(atom_swap_nmax * sizeof(int), "MCSWAP:local_swap_jatom_list");
|
||||||
}
|
}
|
||||||
|
|
||||||
niswap_local = 0;
|
niswap_local = 0;
|
||||||
njswap_local = 0;
|
njswap_local = 0;
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]) == 1) {
|
if (region->match(x[i][0], x[i][1], x[i][2]) == 1) {
|
||||||
if (atom->mask[i] & groupbit) {
|
if (atom->mask[i] & groupbit) {
|
||||||
if (type[i] == type_list[0]) {
|
if (type[i] == type_list[0]) {
|
||||||
local_swap_iatom_list[niswap_local] = i;
|
local_swap_iatom_list[niswap_local] = i;
|
||||||
niswap_local++;
|
niswap_local++;
|
||||||
} else if (type[i] == type_list[1]) {
|
} else if (type[i] == type_list[1]) {
|
||||||
local_swap_jatom_list[njswap_local] = i;
|
local_swap_jatom_list[njswap_local] = i;
|
||||||
njswap_local++;
|
njswap_local++;
|
||||||
}
|
}
|
||||||
@ -684,10 +679,10 @@ void FixAtomSwap::update_swap_atoms_list()
|
|||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (atom->mask[i] & groupbit) {
|
if (atom->mask[i] & groupbit) {
|
||||||
if (type[i] == type_list[0]) {
|
if (type[i] == type_list[0]) {
|
||||||
local_swap_iatom_list[niswap_local] = i;
|
local_swap_iatom_list[niswap_local] = i;
|
||||||
niswap_local++;
|
niswap_local++;
|
||||||
} else if (type[i] == type_list[1]) {
|
} else if (type[i] == type_list[1]) {
|
||||||
local_swap_jatom_list[njswap_local] = i;
|
local_swap_jatom_list[njswap_local] = i;
|
||||||
njswap_local++;
|
njswap_local++;
|
||||||
}
|
}
|
||||||
@ -695,12 +690,12 @@ void FixAtomSwap::update_swap_atoms_list()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MPI_Allreduce(&niswap_local,&niswap,1,MPI_INT,MPI_SUM,world);
|
MPI_Allreduce(&niswap_local, &niswap, 1, MPI_INT, MPI_SUM, world);
|
||||||
MPI_Scan(&niswap_local,&niswap_before,1,MPI_INT,MPI_SUM,world);
|
MPI_Scan(&niswap_local, &niswap_before, 1, MPI_INT, MPI_SUM, world);
|
||||||
niswap_before -= niswap_local;
|
niswap_before -= niswap_local;
|
||||||
|
|
||||||
MPI_Allreduce(&njswap_local,&njswap,1,MPI_INT,MPI_SUM,world);
|
MPI_Allreduce(&njswap_local, &njswap, 1, MPI_INT, MPI_SUM, world);
|
||||||
MPI_Scan(&njswap_local,&njswap_before,1,MPI_INT,MPI_SUM,world);
|
MPI_Scan(&njswap_local, &njswap_before, 1, MPI_INT, MPI_SUM, world);
|
||||||
njswap_before -= njswap_local;
|
njswap_before -= njswap_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,7 +703,7 @@ void FixAtomSwap::update_swap_atoms_list()
|
|||||||
|
|
||||||
int FixAtomSwap::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/)
|
int FixAtomSwap::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag*/, int * /*pbc*/)
|
||||||
{
|
{
|
||||||
int i,j,m;
|
int i, j, m;
|
||||||
|
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
double *q = atom->q;
|
double *q = atom->q;
|
||||||
@ -735,7 +730,7 @@ int FixAtomSwap::pack_forward_comm(int n, int *list, double *buf, int /*pbc_flag
|
|||||||
|
|
||||||
void FixAtomSwap::unpack_forward_comm(int n, int first, double *buf)
|
void FixAtomSwap::unpack_forward_comm(int n, int first, double *buf)
|
||||||
{
|
{
|
||||||
int i,m,last;
|
int i, m, last;
|
||||||
|
|
||||||
int *type = atom->type;
|
int *type = atom->type;
|
||||||
double *q = atom->q;
|
double *q = atom->q;
|
||||||
@ -745,12 +740,11 @@ void FixAtomSwap::unpack_forward_comm(int n, int first, double *buf)
|
|||||||
|
|
||||||
if (atom->q_flag) {
|
if (atom->q_flag) {
|
||||||
for (i = first; i < last; i++) {
|
for (i = first; i < last; i++) {
|
||||||
type[i] = static_cast<int> (buf[m++]);
|
type[i] = static_cast<int>(buf[m++]);
|
||||||
q[i] = buf[m++];
|
q[i] = buf[m++];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = first; i < last; i++)
|
for (i = first; i < last; i++) type[i] = static_cast<int>(buf[m++]);
|
||||||
type[i] = static_cast<int> (buf[m++]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +765,7 @@ double FixAtomSwap::compute_vector(int n)
|
|||||||
|
|
||||||
double FixAtomSwap::memory_usage()
|
double FixAtomSwap::memory_usage()
|
||||||
{
|
{
|
||||||
double bytes = (double)atom_swap_nmax * sizeof(int);
|
double bytes = (double) atom_swap_nmax * sizeof(int);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,8 +786,8 @@ void FixAtomSwap::write_restart(FILE *fp)
|
|||||||
|
|
||||||
if (comm->me == 0) {
|
if (comm->me == 0) {
|
||||||
int size = n * sizeof(double);
|
int size = n * sizeof(double);
|
||||||
fwrite(&size,sizeof(int),1,fp);
|
fwrite(&size, sizeof(int), 1, fp);
|
||||||
fwrite(list,sizeof(double),n,fp);
|
fwrite(list, sizeof(double), n, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,10 +800,10 @@ void FixAtomSwap::restart(char *buf)
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
auto list = (double *) buf;
|
auto list = (double *) buf;
|
||||||
|
|
||||||
seed = static_cast<int> (list[n++]);
|
seed = static_cast<int>(list[n++]);
|
||||||
random_equal->reset(seed);
|
random_equal->reset(seed);
|
||||||
|
|
||||||
seed = static_cast<int> (list[n++]);
|
seed = static_cast<int>(list[n++]);
|
||||||
random_unequal->reset(seed);
|
random_unequal->reset(seed);
|
||||||
|
|
||||||
next_reneighbor = (bigint) ubuf(list[n++]).i;
|
next_reneighbor = (bigint) ubuf(list[n++]).i;
|
||||||
@ -819,5 +813,5 @@ void FixAtomSwap::restart(char *buf)
|
|||||||
|
|
||||||
bigint ntimestep_restart = (bigint) ubuf(list[n++]).i;
|
bigint ntimestep_restart = (bigint) ubuf(list[n++]).i;
|
||||||
if (ntimestep_restart != update->ntimestep)
|
if (ntimestep_restart != update->ntimestep)
|
||||||
error->all(FLERR,"Must not reset timestep when restarting fix atom/swap");
|
error->all(FLERR, "Must not reset timestep when restarting fix atom/swap");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,8 +49,7 @@ class FixAtomSwap : public Fix {
|
|||||||
int nswap; // # of swap atoms on all procs
|
int nswap; // # of swap atoms on all procs
|
||||||
int nswap_local; // # of swap atoms on this proc
|
int nswap_local; // # of swap atoms on this proc
|
||||||
int nswap_before; // # of swap atoms on procs < this proc
|
int nswap_before; // # of swap atoms on procs < this proc
|
||||||
int regionflag; // 0 = anywhere in box, 1 = specific region
|
class Region *region; // swap region
|
||||||
int iregion; // swap region
|
|
||||||
char *idregion; // swap region id
|
char *idregion; // swap region id
|
||||||
|
|
||||||
int nswaptypes, nmutypes;
|
int nswaptypes, nmutypes;
|
||||||
|
|||||||
@ -68,7 +68,7 @@ enum{NONE,MOVEATOM,MOVEMOL}; // movemode
|
|||||||
|
|
||||||
FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) :
|
FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg),
|
Fix(lmp, narg, arg),
|
||||||
idregion(nullptr), full_flag(false), ngroups(0), groupstrings(nullptr), ngrouptypes(0),
|
region(nullptr), idregion(nullptr), full_flag(false), groupstrings(nullptr),
|
||||||
grouptypestrings(nullptr), grouptypebits(nullptr), grouptypes(nullptr), local_gas_list(nullptr),
|
grouptypestrings(nullptr), grouptypebits(nullptr), grouptypes(nullptr), local_gas_list(nullptr),
|
||||||
molcoords(nullptr), molq(nullptr), molimage(nullptr), random_equal(nullptr), random_unequal(nullptr),
|
molcoords(nullptr), molq(nullptr), molimage(nullptr), random_equal(nullptr), random_unequal(nullptr),
|
||||||
fixrigid(nullptr), fixshake(nullptr), idrigid(nullptr), idshake(nullptr)
|
fixrigid(nullptr), fixshake(nullptr), idrigid(nullptr), idshake(nullptr)
|
||||||
@ -87,6 +87,9 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
restart_global = 1;
|
restart_global = 1;
|
||||||
time_depend = 1;
|
time_depend = 1;
|
||||||
|
|
||||||
|
ngroups = 0;
|
||||||
|
ngrouptypes = 0;
|
||||||
|
|
||||||
// required args
|
// required args
|
||||||
|
|
||||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||||
@ -122,18 +125,18 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
region_xlo = region_xhi = region_ylo = region_yhi =
|
region_xlo = region_xhi = region_ylo = region_yhi =
|
||||||
region_zlo = region_zhi = 0.0;
|
region_zlo = region_zhi = 0.0;
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
if (domain->regions[iregion]->bboxflag == 0)
|
if (region->bboxflag == 0)
|
||||||
error->all(FLERR,"Fix gcmc region does not support a bounding box");
|
error->all(FLERR,"Fix gcmc region does not support a bounding box");
|
||||||
if (domain->regions[iregion]->dynamic_check())
|
if (region->dynamic_check())
|
||||||
error->all(FLERR,"Fix gcmc region cannot be dynamic");
|
error->all(FLERR,"Fix gcmc region cannot be dynamic");
|
||||||
|
|
||||||
region_xlo = domain->regions[iregion]->extent_xlo;
|
region_xlo = region->extent_xlo;
|
||||||
region_xhi = domain->regions[iregion]->extent_xhi;
|
region_xhi = region->extent_xhi;
|
||||||
region_ylo = domain->regions[iregion]->extent_ylo;
|
region_ylo = region->extent_ylo;
|
||||||
region_yhi = domain->regions[iregion]->extent_yhi;
|
region_yhi = region->extent_yhi;
|
||||||
region_zlo = domain->regions[iregion]->extent_zlo;
|
region_zlo = region->extent_zlo;
|
||||||
region_zhi = domain->regions[iregion]->extent_zhi;
|
region_zhi = region->extent_zhi;
|
||||||
|
|
||||||
if (region_xlo < domain->boxlo[0] || region_xhi > domain->boxhi[0] ||
|
if (region_xlo < domain->boxlo[0] || region_xhi > domain->boxhi[0] ||
|
||||||
region_ylo < domain->boxlo[1] || region_yhi > domain->boxhi[1] ||
|
region_ylo < domain->boxlo[1] || region_yhi > domain->boxhi[1] ||
|
||||||
@ -149,15 +152,14 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
if (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) != 0)
|
if (region->match(coord[0],coord[1],coord[2]) != 0)
|
||||||
inside++;
|
inside++;
|
||||||
}
|
}
|
||||||
|
|
||||||
double max_region_volume = (region_xhi - region_xlo)*
|
double max_region_volume = (region_xhi - region_xlo) *
|
||||||
(region_yhi - region_ylo)*(region_zhi - region_zlo);
|
(region_yhi - region_ylo) * (region_zhi - region_zlo);
|
||||||
|
|
||||||
region_volume = max_region_volume*static_cast<double> (inside)/
|
region_volume = max_region_volume * static_cast<double>(inside) / static_cast<double>(attempts);
|
||||||
static_cast<double> (attempts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// error check and further setup for exchmode = EXCHMOL
|
// error check and further setup for exchmode = EXCHMOL
|
||||||
@ -241,8 +243,6 @@ void FixGCMC::options(int narg, char **arg)
|
|||||||
pmolrotate = 0.0;
|
pmolrotate = 0.0;
|
||||||
pmctot = 0.0;
|
pmctot = 0.0;
|
||||||
max_rotation_angle = 10*MY_PI/180;
|
max_rotation_angle = 10*MY_PI/180;
|
||||||
regionflag = 0;
|
|
||||||
iregion = -1;
|
|
||||||
region_volume = 0;
|
region_volume = 0;
|
||||||
max_region_attempts = 1000;
|
max_region_attempts = 1000;
|
||||||
molecule_group = 0;
|
molecule_group = 0;
|
||||||
@ -300,11 +300,10 @@ void FixGCMC::options(int narg, char **arg)
|
|||||||
iarg += 4;
|
iarg += 4;
|
||||||
} else if (strcmp(arg[iarg],"region") == 0) {
|
} else if (strcmp(arg[iarg],"region") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix gcmc command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix gcmc command");
|
||||||
iregion = domain->find_region(arg[iarg+1]);
|
region = domain->get_region_by_id(arg[iarg+1]);
|
||||||
if (iregion == -1)
|
if (!region)
|
||||||
error->all(FLERR,"Region ID for fix gcmc does not exist");
|
error->all(FLERR,"Region {} for fix gcmc does not exist",arg[iarg+1]);
|
||||||
idregion = utils::strdup(arg[iarg+1]);
|
idregion = utils::strdup(arg[iarg+1]);
|
||||||
regionflag = 1;
|
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else if (strcmp(arg[iarg],"maxangle") == 0) {
|
} else if (strcmp(arg[iarg],"maxangle") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix gcmc command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix gcmc command");
|
||||||
@ -397,7 +396,7 @@ void FixGCMC::options(int narg, char **arg)
|
|||||||
|
|
||||||
FixGCMC::~FixGCMC()
|
FixGCMC::~FixGCMC()
|
||||||
{
|
{
|
||||||
if (regionflag) delete [] idregion;
|
delete[] idregion;
|
||||||
delete random_equal;
|
delete random_equal;
|
||||||
delete random_unequal;
|
delete random_unequal;
|
||||||
|
|
||||||
@ -406,12 +405,12 @@ FixGCMC::~FixGCMC()
|
|||||||
memory->destroy(molq);
|
memory->destroy(molq);
|
||||||
memory->destroy(molimage);
|
memory->destroy(molimage);
|
||||||
|
|
||||||
delete [] idrigid;
|
delete[] idrigid;
|
||||||
delete [] idshake;
|
delete[] idshake;
|
||||||
|
|
||||||
if (ngroups > 0) {
|
if (ngroups > 0) {
|
||||||
for (int igroup = 0; igroup < ngroups; igroup++)
|
for (int igroup = 0; igroup < ngroups; igroup++)
|
||||||
delete [] groupstrings[igroup];
|
delete[] groupstrings[igroup];
|
||||||
memory->sfree(groupstrings);
|
memory->sfree(groupstrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +418,7 @@ FixGCMC::~FixGCMC()
|
|||||||
memory->destroy(grouptypes);
|
memory->destroy(grouptypes);
|
||||||
memory->destroy(grouptypebits);
|
memory->destroy(grouptypebits);
|
||||||
for (int igroup = 0; igroup < ngrouptypes; igroup++)
|
for (int igroup = 0; igroup < ngrouptypes; igroup++)
|
||||||
delete [] grouptypestrings[igroup];
|
delete[] grouptypestrings[igroup];
|
||||||
memory->sfree(grouptypestrings);
|
memory->sfree(grouptypestrings);
|
||||||
}
|
}
|
||||||
if (full_flag && group) {
|
if (full_flag && group) {
|
||||||
@ -443,6 +442,13 @@ int FixGCMC::setmask()
|
|||||||
void FixGCMC::init()
|
void FixGCMC::init()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// set index and check validity of region
|
||||||
|
|
||||||
|
if (idregion) {
|
||||||
|
region = domain->get_region_by_id(idregion);
|
||||||
|
if (!region) error->all(FLERR, "Region {} for fix gcmc does not exist", idregion);
|
||||||
|
}
|
||||||
|
|
||||||
triclinic = domain->triclinic;
|
triclinic = domain->triclinic;
|
||||||
|
|
||||||
// set probabilities for MC moves
|
// set probabilities for MC moves
|
||||||
@ -719,7 +725,7 @@ void FixGCMC::pre_exchange()
|
|||||||
subhi = domain->subhi;
|
subhi = domain->subhi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regionflag) volume = region_volume;
|
if (region) volume = region_volume;
|
||||||
else volume = domain->xprd * domain->yprd * domain->zprd;
|
else volume = domain->xprd * domain->yprd * domain->zprd;
|
||||||
|
|
||||||
if (triclinic) domain->x2lamda(atom->nlocal);
|
if (triclinic) domain->x2lamda(atom->nlocal);
|
||||||
@ -801,8 +807,7 @@ void FixGCMC::attempt_atomic_translation()
|
|||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
double energy_before = energy(i,ngcmc_type,-1,x[i]);
|
double energy_before = energy(i,ngcmc_type,-1,x[i]);
|
||||||
if (overlap_flag && energy_before > MAXENERGYTEST)
|
if (overlap_flag && energy_before > MAXENERGYTEST)
|
||||||
error->warning(FLERR,"Energy of old configuration in "
|
error->warning(FLERR,"Energy of old configuration in fix gcmc is > MAXENERGYTEST.");
|
||||||
"fix gcmc is > MAXENERGYTEST.");
|
|
||||||
double rsq = 1.1;
|
double rsq = 1.1;
|
||||||
double rx,ry,rz;
|
double rx,ry,rz;
|
||||||
rx = ry = rz = 0.0;
|
rx = ry = rz = 0.0;
|
||||||
@ -816,8 +821,8 @@ void FixGCMC::attempt_atomic_translation()
|
|||||||
coord[0] = x[i][0] + displace*rx;
|
coord[0] = x[i][0] + displace*rx;
|
||||||
coord[1] = x[i][1] + displace*ry;
|
coord[1] = x[i][1] + displace*ry;
|
||||||
coord[2] = x[i][2] + displace*rz;
|
coord[2] = x[i][2] + displace*rz;
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
rsq = 1.1;
|
rsq = 1.1;
|
||||||
while (rsq > 1.0) {
|
while (rsq > 1.0) {
|
||||||
rx = 2*random_unequal->uniform() - 1.0;
|
rx = 2*random_unequal->uniform() - 1.0;
|
||||||
@ -913,12 +918,12 @@ void FixGCMC::attempt_atomic_insertion()
|
|||||||
// pick coordinates for insertion point
|
// pick coordinates for insertion point
|
||||||
|
|
||||||
double coord[3];
|
double coord[3];
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
@ -1043,7 +1048,7 @@ void FixGCMC::attempt_molecule_translation()
|
|||||||
com_displace[1] = displace*ry;
|
com_displace[1] = displace*ry;
|
||||||
com_displace[2] = displace*rz;
|
com_displace[2] = displace*rz;
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
for (int i = 0; i < atom->nlocal; i++) {
|
for (int i = 0; i < atom->nlocal; i++) {
|
||||||
if (atom->molecule[i] == translation_molecule) {
|
if (atom->molecule[i] == translation_molecule) {
|
||||||
@ -1058,7 +1063,7 @@ void FixGCMC::attempt_molecule_translation()
|
|||||||
coord[0] = com[0] + displace*rx;
|
coord[0] = com[0] + displace*rx;
|
||||||
coord[1] = com[1] + displace*ry;
|
coord[1] = com[1] + displace*ry;
|
||||||
coord[2] = com[2] + displace*rz;
|
coord[2] = com[2] + displace*rz;
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
rsq = 1.1;
|
rsq = 1.1;
|
||||||
while (rsq > 1.0) {
|
while (rsq > 1.0) {
|
||||||
rx = 2*random_equal->uniform() - 1.0;
|
rx = 2*random_equal->uniform() - 1.0;
|
||||||
@ -1266,7 +1271,7 @@ void FixGCMC::attempt_molecule_insertion()
|
|||||||
if (ngas >= max_ngas) return;
|
if (ngas >= max_ngas) return;
|
||||||
|
|
||||||
double com_coord[3];
|
double com_coord[3];
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -1274,7 +1279,7 @@ void FixGCMC::attempt_molecule_insertion()
|
|||||||
(region_yhi-region_ylo);
|
(region_yhi-region_ylo);
|
||||||
com_coord[2] = region_zlo + random_equal->uniform() *
|
com_coord[2] = region_zlo + random_equal->uniform() *
|
||||||
(region_zhi-region_zlo);
|
(region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(com_coord[0],com_coord[1],
|
while (region->match(com_coord[0],com_coord[1],
|
||||||
com_coord[2]) == 0) {
|
com_coord[2]) == 0) {
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -1485,8 +1490,8 @@ void FixGCMC::attempt_atomic_translation_full()
|
|||||||
coord[0] = x[i][0] + displace*rx;
|
coord[0] = x[i][0] + displace*rx;
|
||||||
coord[1] = x[i][1] + displace*ry;
|
coord[1] = x[i][1] + displace*ry;
|
||||||
coord[2] = x[i][2] + displace*rz;
|
coord[2] = x[i][2] + displace*rz;
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
rsq = 1.1;
|
rsq = 1.1;
|
||||||
while (rsq > 1.0) {
|
while (rsq > 1.0) {
|
||||||
rx = 2*random_unequal->uniform() - 1.0;
|
rx = 2*random_unequal->uniform() - 1.0;
|
||||||
@ -1602,12 +1607,12 @@ void FixGCMC::attempt_atomic_insertion_full()
|
|||||||
double energy_before = energy_stored;
|
double energy_before = energy_stored;
|
||||||
|
|
||||||
double coord[3];
|
double coord[3];
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
@ -1726,7 +1731,7 @@ void FixGCMC::attempt_molecule_translation_full()
|
|||||||
com_displace[1] = displace*ry;
|
com_displace[1] = displace*ry;
|
||||||
com_displace[2] = displace*rz;
|
com_displace[2] = displace*rz;
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int *mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
for (int i = 0; i < atom->nlocal; i++) {
|
for (int i = 0; i < atom->nlocal; i++) {
|
||||||
if (atom->molecule[i] == translation_molecule) {
|
if (atom->molecule[i] == translation_molecule) {
|
||||||
@ -1741,7 +1746,7 @@ void FixGCMC::attempt_molecule_translation_full()
|
|||||||
coord[0] = com[0] + displace*rx;
|
coord[0] = com[0] + displace*rx;
|
||||||
coord[1] = com[1] + displace*ry;
|
coord[1] = com[1] + displace*ry;
|
||||||
coord[2] = com[2] + displace*rz;
|
coord[2] = com[2] + displace*rz;
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
rsq = 1.1;
|
rsq = 1.1;
|
||||||
while (rsq > 1.0) {
|
while (rsq > 1.0) {
|
||||||
rx = 2*random_equal->uniform() - 1.0;
|
rx = 2*random_equal->uniform() - 1.0;
|
||||||
@ -1998,7 +2003,7 @@ void FixGCMC::attempt_molecule_insertion_full()
|
|||||||
int nlocalprev = atom->nlocal;
|
int nlocalprev = atom->nlocal;
|
||||||
|
|
||||||
double com_coord[3];
|
double com_coord[3];
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -2006,7 +2011,7 @@ void FixGCMC::attempt_molecule_insertion_full()
|
|||||||
(region_yhi-region_ylo);
|
(region_yhi-region_ylo);
|
||||||
com_coord[2] = region_zlo + random_equal->uniform() *
|
com_coord[2] = region_zlo + random_equal->uniform() *
|
||||||
(region_zhi-region_zlo);
|
(region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(com_coord[0],com_coord[1],
|
while (region->match(com_coord[0],com_coord[1],
|
||||||
com_coord[2]) == 0) {
|
com_coord[2]) == 0) {
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -2408,7 +2413,7 @@ void FixGCMC::update_gas_atoms_list()
|
|||||||
|
|
||||||
ngas_local = 0;
|
ngas_local = 0;
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
|
|
||||||
if (exchmode == EXCHMOL || movemode == MOVEMOL) {
|
if (exchmode == EXCHMOL || movemode == MOVEMOL) {
|
||||||
|
|
||||||
@ -2441,7 +2446,7 @@ void FixGCMC::update_gas_atoms_list()
|
|||||||
|
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (domain->regions[iregion]->match(comx[molecule[i]],
|
if (region->match(comx[molecule[i]],
|
||||||
comy[molecule[i]],comz[molecule[i]]) == 1) {
|
comy[molecule[i]],comz[molecule[i]]) == 1) {
|
||||||
local_gas_list[ngas_local] = i;
|
local_gas_list[ngas_local] = i;
|
||||||
ngas_local++;
|
ngas_local++;
|
||||||
@ -2454,7 +2459,7 @@ void FixGCMC::update_gas_atoms_list()
|
|||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]) == 1) {
|
if (region->match(x[i][0],x[i][1],x[i][2]) == 1) {
|
||||||
local_gas_list[ngas_local] = i;
|
local_gas_list[ngas_local] = i;
|
||||||
ngas_local++;
|
ngas_local++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,17 +65,16 @@ class FixGCMC : public Fix {
|
|||||||
int ngcmc_type, nevery, seed;
|
int ngcmc_type, nevery, seed;
|
||||||
int ncycles, nexchanges, nmcmoves;
|
int ncycles, nexchanges, nmcmoves;
|
||||||
double patomtrans, pmoltrans, pmolrotate, pmctot;
|
double patomtrans, pmoltrans, pmolrotate, pmctot;
|
||||||
int ngas; // # of gas atoms on all procs
|
int ngas; // # of gas atoms on all procs
|
||||||
int ngas_local; // # of gas atoms on this proc
|
int ngas_local; // # of gas atoms on this proc
|
||||||
int ngas_before; // # of gas atoms on procs < this proc
|
int ngas_before; // # of gas atoms on procs < this proc
|
||||||
int exchmode; // exchange ATOM or MOLECULE
|
int exchmode; // exchange ATOM or MOLECULE
|
||||||
int movemode; // move ATOM or MOLECULE
|
int movemode; // move ATOM or MOLECULE
|
||||||
int regionflag; // 0 = anywhere in box, 1 = specific region
|
class Region *region; // gcmc region
|
||||||
int iregion; // gcmc region
|
char *idregion; // gcmc region id
|
||||||
char *idregion; // gcmc region id
|
bool pressure_flag; // true if user specified reservoir pressure
|
||||||
bool pressure_flag; // true if user specified reservoir pressure
|
bool charge_flag; // true if user specified atomic charge
|
||||||
bool charge_flag; // true if user specified atomic charge
|
bool full_flag; // true if doing full system energy calculations
|
||||||
bool full_flag; // true if doing full system energy calculations
|
|
||||||
|
|
||||||
int natoms_per_molecule; // number of atoms in each inserted molecule
|
int natoms_per_molecule; // number of atoms in each inserted molecule
|
||||||
int nmaxmolatoms; // number of atoms allocated for molecule arrays
|
int nmaxmolatoms; // number of atoms allocated for molecule arrays
|
||||||
|
|||||||
@ -46,7 +46,6 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
using namespace MathConst;
|
using namespace MathConst;
|
||||||
@ -59,8 +58,8 @@ enum{EXCHATOM,EXCHMOL}; // exchmode
|
|||||||
|
|
||||||
FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) :
|
FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg),
|
Fix(lmp, narg, arg),
|
||||||
idregion(nullptr), full_flag(false), local_gas_list(nullptr), molcoords(nullptr),
|
region(nullptr), idregion(nullptr), full_flag(false), local_gas_list(nullptr),
|
||||||
molq(nullptr), molimage(nullptr), random_equal(nullptr)
|
molcoords(nullptr),molq(nullptr), molimage(nullptr), random_equal(nullptr)
|
||||||
{
|
{
|
||||||
if (narg < 8) error->all(FLERR,"Illegal fix widom command");
|
if (narg < 8) error->all(FLERR,"Illegal fix widom command");
|
||||||
|
|
||||||
@ -76,8 +75,6 @@ FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
restart_global = 1;
|
restart_global = 1;
|
||||||
time_depend = 1;
|
time_depend = 1;
|
||||||
|
|
||||||
//ave_widom_chemical_potential = 0;
|
|
||||||
|
|
||||||
// required args
|
// required args
|
||||||
|
|
||||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||||
@ -104,18 +101,18 @@ FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
|
|
||||||
region_xlo = region_xhi = region_ylo = region_yhi =
|
region_xlo = region_xhi = region_ylo = region_yhi =
|
||||||
region_zlo = region_zhi = 0.0;
|
region_zlo = region_zhi = 0.0;
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
if (domain->regions[iregion]->bboxflag == 0)
|
if (region->bboxflag == 0)
|
||||||
error->all(FLERR,"Fix widom region does not support a bounding box");
|
error->all(FLERR,"Fix widom region does not support a bounding box");
|
||||||
if (domain->regions[iregion]->dynamic_check())
|
if (region->dynamic_check())
|
||||||
error->all(FLERR,"Fix widom region cannot be dynamic");
|
error->all(FLERR,"Fix widom region cannot be dynamic");
|
||||||
|
|
||||||
region_xlo = domain->regions[iregion]->extent_xlo;
|
region_xlo = region->extent_xlo;
|
||||||
region_xhi = domain->regions[iregion]->extent_xhi;
|
region_xhi = region->extent_xhi;
|
||||||
region_ylo = domain->regions[iregion]->extent_ylo;
|
region_ylo = region->extent_ylo;
|
||||||
region_yhi = domain->regions[iregion]->extent_yhi;
|
region_yhi = region->extent_yhi;
|
||||||
region_zlo = domain->regions[iregion]->extent_zlo;
|
region_zlo = region->extent_zlo;
|
||||||
region_zhi = domain->regions[iregion]->extent_zhi;
|
region_zhi = region->extent_zhi;
|
||||||
|
|
||||||
if (region_xlo < domain->boxlo[0] || region_xhi > domain->boxhi[0] ||
|
if (region_xlo < domain->boxlo[0] || region_xhi > domain->boxhi[0] ||
|
||||||
region_ylo < domain->boxlo[1] || region_yhi > domain->boxhi[1] ||
|
region_ylo < domain->boxlo[1] || region_yhi > domain->boxhi[1] ||
|
||||||
@ -131,15 +128,14 @@ FixWidom::FixWidom(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
if (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) != 0)
|
if (region->match(coord[0],coord[1],coord[2]) != 0)
|
||||||
inside++;
|
inside++;
|
||||||
}
|
}
|
||||||
|
|
||||||
double max_region_volume = (region_xhi - region_xlo)*
|
double max_region_volume = (region_xhi - region_xlo) *
|
||||||
(region_yhi - region_ylo)*(region_zhi - region_zlo);
|
(region_yhi - region_ylo) * (region_zhi - region_zlo);
|
||||||
|
|
||||||
region_volume = max_region_volume*static_cast<double> (inside)/
|
region_volume = max_region_volume * static_cast<double>(inside) / static_cast<double>(attempts);
|
||||||
static_cast<double> (attempts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// error check and further setup for exchmode = EXCHMOL
|
// error check and further setup for exchmode = EXCHMOL
|
||||||
@ -191,8 +187,6 @@ void FixWidom::options(int narg, char **arg)
|
|||||||
// defaults
|
// defaults
|
||||||
|
|
||||||
exchmode = EXCHATOM;
|
exchmode = EXCHATOM;
|
||||||
regionflag = 0;
|
|
||||||
iregion = -1;
|
|
||||||
region_volume = 0;
|
region_volume = 0;
|
||||||
max_region_attempts = 1000;
|
max_region_attempts = 1000;
|
||||||
molecule_group = 0;
|
molecule_group = 0;
|
||||||
@ -221,11 +215,10 @@ void FixWidom::options(int narg, char **arg)
|
|||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else if (strcmp(arg[iarg],"region") == 0) {
|
} else if (strcmp(arg[iarg],"region") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix widom command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix widom command");
|
||||||
iregion = domain->find_region(arg[iarg+1]);
|
region = domain->get_region_by_id(arg[iarg+1]);
|
||||||
if (iregion == -1)
|
if (!region)
|
||||||
error->all(FLERR,"Region ID for fix widom does not exist");
|
error->all(FLERR,"Region {} for fix widom does not exist",arg[iarg+1]);
|
||||||
idregion = utils::strdup(arg[iarg+1]);
|
idregion = utils::strdup(arg[iarg+1]);
|
||||||
regionflag = 1;
|
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
} else if (strcmp(arg[iarg],"charge") == 0) {
|
} else if (strcmp(arg[iarg],"charge") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix widom command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix widom command");
|
||||||
@ -247,7 +240,7 @@ void FixWidom::options(int narg, char **arg)
|
|||||||
|
|
||||||
FixWidom::~FixWidom()
|
FixWidom::~FixWidom()
|
||||||
{
|
{
|
||||||
if (regionflag) delete [] idregion;
|
delete[] idregion;
|
||||||
delete random_equal;
|
delete random_equal;
|
||||||
|
|
||||||
memory->destroy(local_gas_list);
|
memory->destroy(local_gas_list);
|
||||||
@ -271,11 +264,18 @@ int FixWidom::setmask()
|
|||||||
void FixWidom::init()
|
void FixWidom::init()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// set index and check validity of region
|
||||||
|
|
||||||
|
if (idregion) {
|
||||||
|
region = domain->get_region_by_id(idregion);
|
||||||
|
if (!region) error->all(FLERR, "Region {} for fix widom does not exist", idregion);
|
||||||
|
}
|
||||||
|
|
||||||
triclinic = domain->triclinic;
|
triclinic = domain->triclinic;
|
||||||
|
|
||||||
ave_widom_chemical_potential = 0;
|
ave_widom_chemical_potential = 0;
|
||||||
|
|
||||||
if (regionflag) volume = region_volume;
|
if (region) volume = region_volume;
|
||||||
else volume = domain->xprd * domain->yprd * domain->zprd;
|
else volume = domain->xprd * domain->yprd * domain->zprd;
|
||||||
|
|
||||||
// decide whether to switch to the full_energy option
|
// decide whether to switch to the full_energy option
|
||||||
@ -283,8 +283,8 @@ void FixWidom::init()
|
|||||||
if ((force->kspace) ||
|
if ((force->kspace) ||
|
||||||
(force->pair == nullptr) ||
|
(force->pair == nullptr) ||
|
||||||
(force->pair->single_enable == 0) ||
|
(force->pair->single_enable == 0) ||
|
||||||
(force->pair_match("hybrid",0)) ||
|
(force->pair_match("^hybrid",0)) ||
|
||||||
(force->pair_match("eam",0)) ||
|
(force->pair_match("^eam",0)) ||
|
||||||
(force->pair->tail_flag)) {
|
(force->pair->tail_flag)) {
|
||||||
full_flag = true;
|
full_flag = true;
|
||||||
if (comm->me == 0)
|
if (comm->me == 0)
|
||||||
@ -434,7 +434,7 @@ void FixWidom::pre_exchange()
|
|||||||
subhi = domain->subhi;
|
subhi = domain->subhi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regionflag) volume = region_volume;
|
if (region) volume = region_volume;
|
||||||
else volume = domain->xprd * domain->yprd * domain->zprd;
|
else volume = domain->xprd * domain->yprd * domain->zprd;
|
||||||
|
|
||||||
if (triclinic) domain->x2lamda(atom->nlocal);
|
if (triclinic) domain->x2lamda(atom->nlocal);
|
||||||
@ -486,12 +486,12 @@ void FixWidom::attempt_atomic_insertion()
|
|||||||
|
|
||||||
// pick coordinates for insertion point
|
// pick coordinates for insertion point
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
@ -562,7 +562,7 @@ void FixWidom::attempt_molecule_insertion()
|
|||||||
|
|
||||||
for (int imove = 0; imove < ninsertions; imove++) {
|
for (int imove = 0; imove < ninsertions; imove++) {
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -570,7 +570,7 @@ void FixWidom::attempt_molecule_insertion()
|
|||||||
(region_yhi-region_ylo);
|
(region_yhi-region_ylo);
|
||||||
com_coord[2] = region_zlo + random_equal->uniform() *
|
com_coord[2] = region_zlo + random_equal->uniform() *
|
||||||
(region_zhi-region_zlo);
|
(region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(com_coord[0],com_coord[1],
|
while (region->match(com_coord[0],com_coord[1],
|
||||||
com_coord[2]) == 0) {
|
com_coord[2]) == 0) {
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -688,12 +688,12 @@ void FixWidom::attempt_atomic_insertion_full()
|
|||||||
|
|
||||||
for (int imove = 0; imove < ninsertions; imove++) {
|
for (int imove = 0; imove < ninsertions; imove++) {
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
|
while (region->match(coord[0],coord[1],coord[2]) == 0) {
|
||||||
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
coord[0] = region_xlo + random_equal->uniform() * (region_xhi-region_xlo);
|
||||||
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
coord[1] = region_ylo + random_equal->uniform() * (region_yhi-region_ylo);
|
||||||
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
coord[2] = region_zlo + random_equal->uniform() * (region_zhi-region_zlo);
|
||||||
@ -801,7 +801,7 @@ void FixWidom::attempt_molecule_insertion_full()
|
|||||||
|
|
||||||
for (int imove = 0; imove < ninsertions; imove++) {
|
for (int imove = 0; imove < ninsertions; imove++) {
|
||||||
double com_coord[3];
|
double com_coord[3];
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
int region_attempt = 0;
|
int region_attempt = 0;
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -809,7 +809,7 @@ void FixWidom::attempt_molecule_insertion_full()
|
|||||||
(region_yhi-region_ylo);
|
(region_yhi-region_ylo);
|
||||||
com_coord[2] = region_zlo + random_equal->uniform() *
|
com_coord[2] = region_zlo + random_equal->uniform() *
|
||||||
(region_zhi-region_zlo);
|
(region_zhi-region_zlo);
|
||||||
while (domain->regions[iregion]->match(com_coord[0],com_coord[1],
|
while (region->match(com_coord[0],com_coord[1],
|
||||||
com_coord[2]) == 0) {
|
com_coord[2]) == 0) {
|
||||||
com_coord[0] = region_xlo + random_equal->uniform() *
|
com_coord[0] = region_xlo + random_equal->uniform() *
|
||||||
(region_xhi-region_xlo);
|
(region_xhi-region_xlo);
|
||||||
@ -1081,7 +1081,7 @@ void FixWidom::update_gas_atoms_list()
|
|||||||
|
|
||||||
ngas_local = 0;
|
ngas_local = 0;
|
||||||
|
|
||||||
if (regionflag) {
|
if (region) {
|
||||||
|
|
||||||
if (exchmode == EXCHMOL) {
|
if (exchmode == EXCHMOL) {
|
||||||
|
|
||||||
@ -1114,7 +1114,7 @@ void FixWidom::update_gas_atoms_list()
|
|||||||
|
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (domain->regions[iregion]->match(comx[molecule[i]],
|
if (region->match(comx[molecule[i]],
|
||||||
comy[molecule[i]],comz[molecule[i]]) == 1) {
|
comy[molecule[i]],comz[molecule[i]]) == 1) {
|
||||||
local_gas_list[ngas_local] = i;
|
local_gas_list[ngas_local] = i;
|
||||||
ngas_local++;
|
ngas_local++;
|
||||||
@ -1127,7 +1127,7 @@ void FixWidom::update_gas_atoms_list()
|
|||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (mask[i] & groupbit) {
|
if (mask[i] & groupbit) {
|
||||||
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]) == 1) {
|
if (region->match(x[i][0],x[i][1],x[i][2]) == 1) {
|
||||||
local_gas_list[ngas_local] = i;
|
local_gas_list[ngas_local] = i;
|
||||||
ngas_local++;
|
ngas_local++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,15 +53,14 @@ class FixWidom : public Fix {
|
|||||||
int exclusion_group, exclusion_group_bit;
|
int exclusion_group, exclusion_group_bit;
|
||||||
int nwidom_type, nevery, seed;
|
int nwidom_type, nevery, seed;
|
||||||
int ninsertions;
|
int ninsertions;
|
||||||
int ngas; // # of gas atoms on all procs
|
int ngas; // # of gas atoms on all procs
|
||||||
int ngas_local; // # of gas atoms on this proc
|
int ngas_local; // # of gas atoms on this proc
|
||||||
int exchmode; // exchange ATOM or MOLECULE
|
int exchmode; // exchange ATOM or MOLECULE
|
||||||
int movemode; // move ATOM or MOLECULE
|
int movemode; // move ATOM or MOLECULE
|
||||||
int regionflag; // 0 = anywhere in box, 1 = specific region
|
class Region *region; // widom region
|
||||||
int iregion; // widom region
|
char *idregion; // widom region id
|
||||||
char *idregion; // widom region id
|
bool charge_flag; // true if user specified atomic charge
|
||||||
bool charge_flag; // true if user specified atomic charge
|
bool full_flag; // true if doing full system energy calculations
|
||||||
bool full_flag; // true if doing full system energy calculations
|
|
||||||
|
|
||||||
int natoms_per_molecule; // number of atoms in each inserted molecule
|
int natoms_per_molecule; // number of atoms in each inserted molecule
|
||||||
int nmaxmolatoms; // number of atoms allocated for molecule arrays
|
int nmaxmolatoms; // number of atoms allocated for molecule arrays
|
||||||
|
|||||||
@ -389,7 +389,7 @@ void plugin_unload(const char *style, const char *name, LAMMPS *lmp)
|
|||||||
if (found != region_map->end()) region_map->erase(name);
|
if (found != region_map->end()) region_map->erase(name);
|
||||||
|
|
||||||
for (auto iregion : lmp->domain->get_region_by_style(name))
|
for (auto iregion : lmp->domain->get_region_by_style(name))
|
||||||
lmp->domain->delete_region(iregion->id);
|
lmp->domain->delete_region(iregion);
|
||||||
|
|
||||||
} else if (pstyle == "command") {
|
} else if (pstyle == "command") {
|
||||||
|
|
||||||
|
|||||||
@ -155,12 +155,11 @@ void Hyper::command(int narg, char **arg)
|
|||||||
|
|
||||||
// cannot use hyper with time-dependent fixes or regions
|
// cannot use hyper with time-dependent fixes or regions
|
||||||
|
|
||||||
for (int i = 0; i < modify->nfix; i++)
|
for (auto ifix : modify->get_fix_list())
|
||||||
if (modify->fix[i]->time_depend)
|
if (ifix->time_depend) error->all(FLERR,"Cannot use hyper with a time-dependent fix defined");
|
||||||
error->all(FLERR,"Cannot use hyper with a time-dependent fix defined");
|
|
||||||
|
|
||||||
for (int i = 0; i < domain->nregion; i++)
|
for (auto reg : domain->get_region_list())
|
||||||
if (domain->regions[i]->dynamic_check())
|
if (reg->dynamic_check())
|
||||||
error->all(FLERR,"Cannot use hyper with a time-dependent region defined");
|
error->all(FLERR,"Cannot use hyper with a time-dependent region defined");
|
||||||
|
|
||||||
// perform hyperdynamics simulation
|
// perform hyperdynamics simulation
|
||||||
|
|||||||
@ -229,12 +229,11 @@ void PRD::command(int narg, char **arg)
|
|||||||
|
|
||||||
// cannot use PRD with time-dependent fixes or regions
|
// cannot use PRD with time-dependent fixes or regions
|
||||||
|
|
||||||
for (int i = 0; i < modify->nfix; i++)
|
for (auto ifix : modify->get_fix_list())
|
||||||
if (modify->fix[i]->time_depend)
|
if (ifix->time_depend) error->all(FLERR,"Cannot use PRD with a time-dependent fix defined");
|
||||||
error->all(FLERR,"Cannot use PRD with a time-dependent fix defined");
|
|
||||||
|
|
||||||
for (int i = 0; i < domain->nregion; i++)
|
for (auto reg : domain->get_region_list())
|
||||||
if (domain->regions[i]->dynamic_check())
|
if (reg->dynamic_check())
|
||||||
error->all(FLERR,"Cannot use PRD with a time-dependent region defined");
|
error->all(FLERR,"Cannot use PRD with a time-dependent region defined");
|
||||||
|
|
||||||
// perform PRD simulation
|
// perform PRD simulation
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// clang-format off
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
https://www.lammps.org/, Sandia National Laboratories
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
@ -43,18 +42,18 @@
|
|||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using namespace FixConst;
|
using namespace FixConst;
|
||||||
|
|
||||||
enum{CONSTANT,EQUAL,ATOM};
|
enum { CONSTANT, EQUAL, ATOM };
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixEHEX::FixEHEX(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
|
FixEHEX::FixEHEX(LAMMPS *lmp, int narg, char **arg) :
|
||||||
idregion(nullptr), x(nullptr), f(nullptr), v(nullptr),
|
Fix(lmp, narg, arg), region(nullptr), idregion(nullptr), x(nullptr), f(nullptr), v(nullptr),
|
||||||
mass(nullptr), rmass(nullptr), type(nullptr), scalingmask(nullptr)
|
mass(nullptr), rmass(nullptr), type(nullptr), scalingmask(nullptr)
|
||||||
{
|
{
|
||||||
MPI_Comm_rank(world, &me);
|
MPI_Comm_rank(world, &me);
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (narg < 4) error->all(FLERR,"Illegal fix ehex command: wrong number of parameters ");
|
if (narg < 4) error->all(FLERR, "Illegal fix ehex command: wrong number of parameters ");
|
||||||
|
|
||||||
scalar_flag = 1;
|
scalar_flag = 1;
|
||||||
global_freq = 1;
|
global_freq = 1;
|
||||||
@ -62,18 +61,16 @@ FixEHEX::FixEHEX(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
|
|||||||
|
|
||||||
// apply fix every nevery timesteps
|
// apply fix every nevery timesteps
|
||||||
|
|
||||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
nevery = utils::inumeric(FLERR, arg[3], false, lmp);
|
||||||
|
|
||||||
if (nevery <= 0) error->all(FLERR,"Illegal fix ehex command");
|
if (nevery <= 0) error->all(FLERR, "Illegal fix ehex command");
|
||||||
|
|
||||||
// heat flux into the reservoir
|
// heat flux into the reservoir
|
||||||
|
|
||||||
heat_input = utils::numeric(FLERR,arg[4],false,lmp);
|
heat_input = utils::numeric(FLERR, arg[4], false, lmp);
|
||||||
|
|
||||||
// optional args
|
// optional args
|
||||||
|
|
||||||
iregion = -1;
|
|
||||||
|
|
||||||
// NOTE: constraints are deactivated by default
|
// NOTE: constraints are deactivated by default
|
||||||
|
|
||||||
constraints = 0;
|
constraints = 0;
|
||||||
@ -89,12 +86,12 @@ FixEHEX::FixEHEX(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
|
|||||||
int iarg = 5;
|
int iarg = 5;
|
||||||
while (iarg < narg) {
|
while (iarg < narg) {
|
||||||
|
|
||||||
if (strcmp(arg[iarg],"region") == 0) {
|
if (strcmp(arg[iarg], "region") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ehex command: wrong number of parameters ");
|
if (iarg + 2 > narg)
|
||||||
iregion = domain->find_region(arg[iarg+1]);
|
error->all(FLERR, "Illegal fix ehex command: wrong number of parameters ");
|
||||||
if (iregion == -1)
|
region = domain->get_region_by_id(arg[iarg + 1]);
|
||||||
error->all(FLERR,"Region ID for fix ehex does not exist");
|
if (!region) error->all(FLERR, "Region {} for fix ehex does not exist", arg[iarg + 1]);
|
||||||
idregion = utils::strdup(arg[iarg+1]);
|
idregion = utils::strdup(arg[iarg + 1]);
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,10 +112,9 @@ FixEHEX::FixEHEX(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
|
|||||||
// don't apply a coordinate correction if this keyword is specified
|
// don't apply a coordinate correction if this keyword is specified
|
||||||
|
|
||||||
else if (strcmp(arg[iarg], "hex") == 0) {
|
else if (strcmp(arg[iarg], "hex") == 0) {
|
||||||
hex = 1;
|
hex = 1;
|
||||||
iarg+= 1;
|
iarg += 1;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
error->all(FLERR, "Illegal fix ehex keyword ");
|
error->all(FLERR, "Illegal fix ehex keyword ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,28 +124,25 @@ FixEHEX::FixEHEX(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
|
|||||||
error->all(FLERR, "You can only use the keyword 'com' together with the keyword 'constrain' ");
|
error->all(FLERR, "You can only use the keyword 'com' together with the keyword 'constrain' ");
|
||||||
|
|
||||||
scale = 1.0;
|
scale = 1.0;
|
||||||
scalingmask = nullptr;
|
scalingmask = nullptr;
|
||||||
FixEHEX::grow_arrays(atom->nmax);
|
FixEHEX::grow_arrays(atom->nmax);
|
||||||
atom->add_callback(Atom::GROW);
|
atom->add_callback(Atom::GROW);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixEHEX::grow_arrays(int nmax) {
|
void FixEHEX::grow_arrays(int nmax)
|
||||||
memory->grow(scalingmask, nmax,"ehex:scalingmask");
|
{
|
||||||
|
memory->grow(scalingmask, nmax, "ehex:scalingmask");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
FixEHEX::~FixEHEX()
|
FixEHEX::~FixEHEX()
|
||||||
{
|
{
|
||||||
atom->delete_callback(id,Atom::GROW);
|
atom->delete_callback(id, Atom::GROW);
|
||||||
delete [] idregion;
|
delete[] idregion;
|
||||||
memory->destroy(scalingmask);
|
memory->destroy(scalingmask);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
@ -167,16 +160,14 @@ void FixEHEX::init()
|
|||||||
{
|
{
|
||||||
// set index and check validity of region
|
// set index and check validity of region
|
||||||
|
|
||||||
if (iregion >= 0) {
|
if (idregion) {
|
||||||
iregion = domain->find_region(idregion);
|
region = domain->get_region_by_id(idregion);
|
||||||
if (iregion == -1)
|
if (!region) error->all(FLERR, "Region {} for fix ehex does not exist",idregion);
|
||||||
error->all(FLERR,"Region ID for fix ehex does not exist");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cannot have 0 atoms in group
|
// cannot have 0 atoms in group
|
||||||
|
|
||||||
if (group->count(igroup) == 0)
|
if (group->count(igroup) == 0) error->all(FLERR, "Fix ehex group has no atoms");
|
||||||
error->all(FLERR,"Fix ehex group has no atoms");
|
|
||||||
|
|
||||||
fshake = nullptr;
|
fshake = nullptr;
|
||||||
if (constraints) {
|
if (constraints) {
|
||||||
@ -194,30 +185,29 @@ void FixEHEX::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cnt_shake > 1)
|
if (cnt_shake > 1)
|
||||||
error->all(FLERR,"Multiple instances of fix shake/rattle detected (not supported yet)");
|
error->all(FLERR, "Multiple instances of fix shake/rattle detected (not supported yet)");
|
||||||
else if (cnt_shake == 1) {
|
else if (cnt_shake == 1) {
|
||||||
fshake = (dynamic_cast<FixShake*>( modify->fix[id_shake]));
|
fshake = (dynamic_cast<FixShake *>(modify->fix[id_shake]));
|
||||||
}
|
} else if (cnt_shake == 0)
|
||||||
else if (cnt_shake == 0)
|
error->all(
|
||||||
error->all(FLERR, "Fix ehex was configured with keyword constrain, but shake/rattle was not defined");
|
FLERR,
|
||||||
|
"Fix ehex was configured with keyword constrain, but shake/rattle was not defined");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void FixEHEX::end_of_step()
|
||||||
void FixEHEX::end_of_step() {
|
{
|
||||||
// store local pointers
|
// store local pointers
|
||||||
|
|
||||||
x = atom->x;
|
x = atom->x;
|
||||||
f = atom->f;
|
f = atom->f;
|
||||||
v = atom->v;
|
v = atom->v;
|
||||||
mass = atom->mass;
|
mass = atom->mass;
|
||||||
rmass = atom->rmass;
|
rmass = atom->rmass;
|
||||||
type = atom->type;
|
type = atom->type;
|
||||||
nlocal = atom->nlocal;
|
nlocal = atom->nlocal;
|
||||||
|
|
||||||
// determine which sites are to be rescaled
|
// determine which sites are to be rescaled
|
||||||
|
|
||||||
@ -229,20 +219,18 @@ void FixEHEX::end_of_step() {
|
|||||||
|
|
||||||
// if required use shake/rattle to correct coordinates and velocities
|
// if required use shake/rattle to correct coordinates and velocities
|
||||||
|
|
||||||
if (constraints && fshake)
|
if (constraints && fshake) fshake->shake_end_of_step(0);
|
||||||
fshake->shake_end_of_step(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
Iterate over all atoms, rescale the velocities and apply coordinate
|
Iterate over all atoms, rescale the velocities and apply coordinate
|
||||||
corrections.
|
corrections.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixEHEX::rescale() {
|
void FixEHEX::rescale()
|
||||||
|
{
|
||||||
double Kr, Ke, escale;
|
double Kr, Ke, escale;
|
||||||
double vsub[3],vcm[3], sfr[3];
|
double vsub[3], vcm[3], sfr[3];
|
||||||
double mi;
|
double mi;
|
||||||
double dt;
|
double dt;
|
||||||
double F, mr, epsr_ik, sfvr, eta_ik;
|
double F, mr, epsr_ik, sfvr, eta_ik;
|
||||||
@ -255,54 +243,54 @@ void FixEHEX::rescale() {
|
|||||||
|
|
||||||
// heat flux into the reservoir
|
// heat flux into the reservoir
|
||||||
|
|
||||||
F = heat_input * force->ftm2v * nevery;
|
F = heat_input * force->ftm2v * nevery;
|
||||||
|
|
||||||
// total mass
|
// total mass
|
||||||
|
|
||||||
mr = masstotal;
|
mr = masstotal;
|
||||||
|
|
||||||
// energy scaling factor
|
// energy scaling factor
|
||||||
|
|
||||||
escale = 1. + (F*dt)/Kr;
|
escale = 1. + (F * dt) / Kr;
|
||||||
|
|
||||||
// safety check for kinetic energy
|
// safety check for kinetic energy
|
||||||
|
|
||||||
if (escale < 0.0) error->all(FLERR,"Fix ehex kinetic energy went negative");
|
if (escale < 0.0) error->all(FLERR, "Fix ehex kinetic energy went negative");
|
||||||
|
|
||||||
scale = sqrt(escale);
|
scale = sqrt(escale);
|
||||||
vsub[0] = (scale-1.0) * vcm[0];
|
vsub[0] = (scale - 1.0) * vcm[0];
|
||||||
vsub[1] = (scale-1.0) * vcm[1];
|
vsub[1] = (scale - 1.0) * vcm[1];
|
||||||
vsub[2] = (scale-1.0) * vcm[2];
|
vsub[2] = (scale - 1.0) * vcm[2];
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
|
|
||||||
if (scalingmask[i]) {
|
if (scalingmask[i]) {
|
||||||
|
|
||||||
mi = (rmass) ? rmass[i] : mass[type[i]];
|
mi = (rmass) ? rmass[i] : mass[type[i]];
|
||||||
|
|
||||||
for (int k=0; k<3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
|
|
||||||
// apply coordinate correction unless running in hex mode
|
// apply coordinate correction unless running in hex mode
|
||||||
|
|
||||||
if (!hex) {
|
if (!hex) {
|
||||||
|
|
||||||
// epsr_ik implements Eq. (20) in the paper
|
// epsr_ik implements Eq. (20) in the paper
|
||||||
|
|
||||||
eta_ik = mi * F/(2.*Kr) * (v[i][k] - vcm[k]);
|
eta_ik = mi * F / (2. * Kr) * (v[i][k] - vcm[k]);
|
||||||
epsr_ik = eta_ik / (mi*Kr) * (F/48. + sfvr/6.*force->ftm2v) - F/(12.*Kr) * (f[i][k]/mi - sfr[k]/mr)*force->ftm2v;
|
epsr_ik = eta_ik / (mi * Kr) * (F / 48. + sfvr / 6. * force->ftm2v) -
|
||||||
|
F / (12. * Kr) * (f[i][k] / mi - sfr[k] / mr) * force->ftm2v;
|
||||||
|
|
||||||
x[i][k] -= dt*dt*dt * epsr_ik;
|
x[i][k] -= dt * dt * dt * epsr_ik;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rescale the velocity
|
// rescale the velocity
|
||||||
|
|
||||||
v[i][k] = scale*v[i][k] - vsub[k];
|
v[i][k] = scale * v[i][k] - vsub[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
double FixEHEX::compute_scalar()
|
double FixEHEX::compute_scalar()
|
||||||
@ -317,17 +305,17 @@ double FixEHEX::compute_scalar()
|
|||||||
double FixEHEX::memory_usage()
|
double FixEHEX::memory_usage()
|
||||||
{
|
{
|
||||||
double bytes = 0.0;
|
double bytes = 0.0;
|
||||||
bytes += (double)atom->nmax * sizeof(double);
|
bytes += (double) atom->nmax * sizeof(double);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
Update the array scalingmask depending on which individual atoms
|
Update the array scalingmask depending on which individual atoms
|
||||||
will be rescaled or not.
|
will be rescaled or not.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixEHEX::update_scalingmask() {
|
void FixEHEX::update_scalingmask()
|
||||||
|
{
|
||||||
int m;
|
int m;
|
||||||
int lid;
|
int lid;
|
||||||
bool stat;
|
bool stat;
|
||||||
@ -335,11 +323,7 @@ void FixEHEX::update_scalingmask() {
|
|||||||
|
|
||||||
// prematch region
|
// prematch region
|
||||||
|
|
||||||
Region *region = nullptr;
|
if (region) region->prematch();
|
||||||
if (iregion >= 0) {
|
|
||||||
region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// only rescale molecules whose center of mass if fully contained in the region
|
// only rescale molecules whose center of mass if fully contained in the region
|
||||||
|
|
||||||
@ -347,28 +331,33 @@ void FixEHEX::update_scalingmask() {
|
|||||||
|
|
||||||
// loop over all clusters
|
// loop over all clusters
|
||||||
|
|
||||||
for (int i=0; i < fshake->nlist; i++) {
|
for (int i = 0; i < fshake->nlist; i++) {
|
||||||
|
|
||||||
// cluster id
|
// cluster id
|
||||||
|
|
||||||
m = fshake->list[i];
|
m = fshake->list[i];
|
||||||
|
|
||||||
// check if the centre of mass of the cluster is inside the region
|
// check if the centre of mass of the cluster is inside the region
|
||||||
// if region == nullptr, just check the group information of all sites
|
// if region == nullptr, just check the group information of all sites
|
||||||
|
|
||||||
if (fshake->shake_flag[m] == 1) nsites = 3;
|
if (fshake->shake_flag[m] == 1)
|
||||||
else if (fshake->shake_flag[m] == 2) nsites = 2;
|
nsites = 3;
|
||||||
else if (fshake->shake_flag[m] == 3) nsites = 3;
|
else if (fshake->shake_flag[m] == 2)
|
||||||
else if (fshake->shake_flag[m] == 4) nsites = 4;
|
nsites = 2;
|
||||||
else nsites = 0;
|
else if (fshake->shake_flag[m] == 3)
|
||||||
|
nsites = 3;
|
||||||
|
else if (fshake->shake_flag[m] == 4)
|
||||||
|
nsites = 4;
|
||||||
|
else
|
||||||
|
nsites = 0;
|
||||||
|
|
||||||
if (nsites == 0) {
|
if (nsites == 0) {
|
||||||
error->all(FLERR,"Internal error: shake_flag[m] has to be between 1 and 4 for m in nlist");
|
error->all(FLERR, "Internal error: shake_flag[m] has to be between 1 and 4 for m in nlist");
|
||||||
}
|
}
|
||||||
|
|
||||||
stat = check_cluster(fshake->shake_atom[m], nsites, region);
|
stat = check_cluster(fshake->shake_atom[m], nsites, region);
|
||||||
|
|
||||||
for (int l=0; l < nsites; l++) {
|
for (int l = 0; l < nsites; l++) {
|
||||||
lid = atom->map(fshake->shake_atom[m][l]);
|
lid = atom->map(fshake->shake_atom[m][l]);
|
||||||
scalingmask[lid] = stat;
|
scalingmask[lid] = stat;
|
||||||
}
|
}
|
||||||
@ -376,9 +365,8 @@ void FixEHEX::update_scalingmask() {
|
|||||||
|
|
||||||
// check atoms that do not belong to any cluster
|
// check atoms that do not belong to any cluster
|
||||||
|
|
||||||
for (int i=0; i<atom->nlocal; i++) {
|
for (int i = 0; i < atom->nlocal; i++) {
|
||||||
if (fshake->shake_flag[i] == 0)
|
if (fshake->shake_flag[i] == 0) scalingmask[i] = rescale_atom(i, region);
|
||||||
scalingmask[i] = rescale_atom(i,region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -386,41 +374,39 @@ void FixEHEX::update_scalingmask() {
|
|||||||
// no clusters, just individual sites (e.g. monatomic system or flexible molecules)
|
// no clusters, just individual sites (e.g. monatomic system or flexible molecules)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
for (int i=0; i<atom->nlocal; i++)
|
for (int i = 0; i < atom->nlocal; i++) scalingmask[i] = rescale_atom(i, region);
|
||||||
scalingmask[i] = rescale_atom(i,region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
Check if the centre of mass of the cluster to be constrained is
|
Check if the centre of mass of the cluster to be constrained is
|
||||||
inside the region.
|
inside the region.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
bool FixEHEX::check_cluster(tagint *shake_atom, int n, Region * region) {
|
bool FixEHEX::check_cluster(tagint *shake_atom, int n, Region *region)
|
||||||
|
{
|
||||||
|
|
||||||
// IMPORTANT NOTE: If any site of the cluster belongs to a group
|
// IMPORTANT NOTE: If any site of the cluster belongs to a group
|
||||||
// which should not be rescaled than all of the sites
|
// which should not be rescaled than all of the sites
|
||||||
// will be ignored!
|
// will be ignored!
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
double * rmass = atom->rmass;
|
double *rmass = atom->rmass;
|
||||||
double * mass = atom->mass;
|
double *mass = atom->mass;
|
||||||
int * type = atom->type;
|
int *type = atom->type;
|
||||||
int * mask = atom->mask;
|
int *mask = atom->mask;
|
||||||
double xcom[3], xtemp[3];
|
double xcom[3], xtemp[3];
|
||||||
double mcluster, mi;
|
double mcluster, mi;
|
||||||
bool stat;
|
bool stat;
|
||||||
int lid[4];
|
int lid[4];
|
||||||
|
|
||||||
// accumulate mass and centre of mass position
|
// accumulate mass and centre of mass position
|
||||||
|
|
||||||
stat = true;
|
stat = true;
|
||||||
xcom[0] = 0.;
|
xcom[0] = 0.;
|
||||||
xcom[1] = 0.;
|
xcom[1] = 0.;
|
||||||
xcom[2] = 0.;
|
xcom[2] = 0.;
|
||||||
mcluster = 0;
|
mcluster = 0;
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
|
|
||||||
@ -432,26 +418,24 @@ bool FixEHEX::check_cluster(tagint *shake_atom, int n, Region * region) {
|
|||||||
|
|
||||||
stat = stat && (mask[lid[i]] & groupbit);
|
stat = stat && (mask[lid[i]] & groupbit);
|
||||||
|
|
||||||
if (region && stat) {
|
if (region && stat) {
|
||||||
|
|
||||||
// check if reduced mass is used
|
// check if reduced mass is used
|
||||||
|
|
||||||
mi = (rmass) ? rmass[lid[i]] : mass[type[lid[i]]];
|
mi = (rmass) ? rmass[lid[i]] : mass[type[lid[i]]];
|
||||||
mcluster += mi;
|
mcluster += mi;
|
||||||
|
|
||||||
// accumulate centre of mass
|
// accumulate centre of mass
|
||||||
// NOTE: you can either use unwrapped coordinates or take site x[lid[0]] as reference,
|
// NOTE: you can either use unwrapped coordinates or take site x[lid[0]] as reference,
|
||||||
// i.e. reconstruct the molecule around this site and calculate the com.
|
// i.e. reconstruct the molecule around this site and calculate the com.
|
||||||
|
|
||||||
for (int k=0; k<3; k++)
|
for (int k = 0; k < 3; k++) xtemp[k] = x[lid[i]][k] - x[lid[0]][k];
|
||||||
xtemp[k] = x[lid[i]][k] - x[lid[0]][k];
|
|
||||||
|
|
||||||
// take into account pbc
|
// take into account pbc
|
||||||
|
|
||||||
domain->minimum_image(xtemp);
|
domain->minimum_image(xtemp);
|
||||||
|
|
||||||
for (int k=0; k<3; k++)
|
for (int k = 0; k < 3; k++) xcom[k] += mi * (x[lid[0]][k] + xtemp[k]);
|
||||||
xcom[k] += mi * (x[lid[0]][k] + xtemp[k]) ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,14 +445,11 @@ bool FixEHEX::check_cluster(tagint *shake_atom, int n, Region * region) {
|
|||||||
|
|
||||||
// check mass
|
// check mass
|
||||||
|
|
||||||
if (mcluster < 1.e-14) {
|
if (mcluster < 1.e-14) { error->all(FLERR, "Fix ehex shake cluster has almost zero mass."); }
|
||||||
error->all(FLERR, "Fix ehex shake cluster has almost zero mass.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// divide by total mass
|
// divide by total mass
|
||||||
|
|
||||||
for (int k=0; k<3; k++)
|
for (int k = 0; k < 3; k++) xcom[k] = xcom[k] / mcluster;
|
||||||
xcom[k] = xcom[k]/mcluster;
|
|
||||||
|
|
||||||
// apply periodic boundary conditions (centre of mass could be outside the box)
|
// apply periodic boundary conditions (centre of mass could be outside the box)
|
||||||
// and check if molecule is inside the region
|
// and check if molecule is inside the region
|
||||||
@ -480,12 +461,12 @@ bool FixEHEX::check_cluster(tagint *shake_atom, int n, Region * region) {
|
|||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
Check if atom i has the correct group and is inside the region.
|
Check if atom i has the correct group and is inside the region.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
bool FixEHEX::rescale_atom(int i, Region*region) {
|
bool FixEHEX::rescale_atom(int i, Region *region)
|
||||||
|
{
|
||||||
bool stat;
|
bool stat;
|
||||||
double x_r[3];
|
double x_r[3];
|
||||||
|
|
||||||
@ -505,7 +486,7 @@ bool FixEHEX::rescale_atom(int i, Region*region) {
|
|||||||
|
|
||||||
// check if the atom is in the group/region
|
// check if the atom is in the group/region
|
||||||
|
|
||||||
stat = stat && region->match(x_r[0],x_r[1],x_r[2]);
|
stat = stat && region->match(x_r[0], x_r[1], x_r[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
@ -516,102 +497,101 @@ bool FixEHEX::rescale_atom(int i, Region*region) {
|
|||||||
(e.g. com velocity, kinetic energy, total mass,...)
|
(e.g. com velocity, kinetic energy, total mass,...)
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void FixEHEX::com_properties(double * vr, double * sfr, double *sfvr, double *K, double *Kr, double *mr) {
|
void FixEHEX::com_properties(double *vr, double *sfr, double *sfvr, double *K, double *Kr,
|
||||||
double ** f = atom->f;
|
double *mr)
|
||||||
double ** v = atom->v;
|
{
|
||||||
int nlocal = atom->nlocal;
|
double **f = atom->f;
|
||||||
double *rmass= atom->rmass;
|
double **v = atom->v;
|
||||||
double *mass = atom->mass;
|
int nlocal = atom->nlocal;
|
||||||
int *type = atom->type;
|
double *rmass = atom->rmass;
|
||||||
double l_vr[3];
|
double *mass = atom->mass;
|
||||||
double l_mr;
|
int *type = atom->type;
|
||||||
double l_sfr[3];
|
double l_vr[3];
|
||||||
double l_sfvr;
|
double l_mr;
|
||||||
double l_K;
|
double l_sfr[3];
|
||||||
double mi;
|
double l_sfvr;
|
||||||
double l_buf[9];
|
double l_K;
|
||||||
double buf[9];
|
double mi;
|
||||||
|
double l_buf[9];
|
||||||
|
double buf[9];
|
||||||
|
|
||||||
// calculate partial sums
|
// calculate partial sums
|
||||||
|
|
||||||
l_vr[0] = l_vr[1] = l_vr[2] = 0;
|
l_vr[0] = l_vr[1] = l_vr[2] = 0;
|
||||||
l_sfr[0] = l_sfr[1] = l_sfr[2] = 0;
|
l_sfr[0] = l_sfr[1] = l_sfr[2] = 0;
|
||||||
l_sfvr = 0;
|
l_sfvr = 0;
|
||||||
l_mr = 0;
|
l_mr = 0;
|
||||||
l_K = 0;
|
l_K = 0;
|
||||||
|
|
||||||
for (int i = 0; i < nlocal; i++) {
|
for (int i = 0; i < nlocal; i++) {
|
||||||
if (scalingmask[i]) {
|
if (scalingmask[i]) {
|
||||||
|
|
||||||
// check if reduced mass is used
|
// check if reduced mass is used
|
||||||
|
|
||||||
mi = (rmass) ? rmass[i] : mass[type[i]];
|
mi = (rmass) ? rmass[i] : mass[type[i]];
|
||||||
|
|
||||||
// accumulate total mass
|
// accumulate total mass
|
||||||
|
|
||||||
l_mr += mi;
|
l_mr += mi;
|
||||||
|
|
||||||
// accumulate kinetic energy
|
// accumulate kinetic energy
|
||||||
|
|
||||||
l_K += mi/2. * (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]);
|
l_K += mi / 2. * (v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2]);
|
||||||
|
|
||||||
// sum_j f_j * v_j
|
// sum_j f_j * v_j
|
||||||
|
|
||||||
l_sfvr += f[i][0]*v[i][0] + f[i][1]*v[i][1] + f[i][2]*v[i][2];
|
l_sfvr += f[i][0] * v[i][0] + f[i][1] * v[i][1] + f[i][2] * v[i][2];
|
||||||
|
|
||||||
// accumulate com velocity and sum of forces
|
// accumulate com velocity and sum of forces
|
||||||
|
|
||||||
for (int k=0; k<3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
l_vr[k] += mi * v[i][k];
|
l_vr[k] += mi * v[i][k];
|
||||||
l_sfr[k]+= f[i][k];
|
l_sfr[k] += f[i][k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduce sums
|
// reduce sums
|
||||||
|
|
||||||
l_buf[0] = l_vr[0];
|
l_buf[0] = l_vr[0];
|
||||||
l_buf[1] = l_vr[1];
|
l_buf[1] = l_vr[1];
|
||||||
l_buf[2] = l_vr[2];
|
l_buf[2] = l_vr[2];
|
||||||
l_buf[3] = l_K;
|
l_buf[3] = l_K;
|
||||||
l_buf[4] = l_mr;
|
l_buf[4] = l_mr;
|
||||||
l_buf[5] = l_sfr[0];
|
l_buf[5] = l_sfr[0];
|
||||||
l_buf[6] = l_sfr[1];
|
l_buf[6] = l_sfr[1];
|
||||||
l_buf[7] = l_sfr[2];
|
l_buf[7] = l_sfr[2];
|
||||||
l_buf[8] = l_sfvr;
|
l_buf[8] = l_sfvr;
|
||||||
|
|
||||||
MPI_Allreduce(l_buf, buf, 9, MPI_DOUBLE, MPI_SUM, world);
|
MPI_Allreduce(l_buf, buf, 9, MPI_DOUBLE, MPI_SUM, world);
|
||||||
|
|
||||||
// total mass of region
|
// total mass of region
|
||||||
|
|
||||||
*mr = buf[4];
|
*mr = buf[4];
|
||||||
|
|
||||||
if (*mr < 1.e-14) {
|
if (*mr < 1.e-14) { error->all(FLERR, "Fix ehex error mass of region is close to zero"); }
|
||||||
error->all(FLERR, "Fix ehex error mass of region is close to zero");
|
|
||||||
}
|
|
||||||
|
|
||||||
// total kinetic energy of region
|
// total kinetic energy of region
|
||||||
|
|
||||||
*K = buf[3];
|
*K = buf[3];
|
||||||
|
|
||||||
// centre of mass velocity of region
|
// centre of mass velocity of region
|
||||||
|
|
||||||
vr[0] = buf[0]/(*mr);
|
vr[0] = buf[0] / (*mr);
|
||||||
vr[1] = buf[1]/(*mr);
|
vr[1] = buf[1] / (*mr);
|
||||||
vr[2] = buf[2]/(*mr);
|
vr[2] = buf[2] / (*mr);
|
||||||
|
|
||||||
// sum of forces
|
// sum of forces
|
||||||
|
|
||||||
sfr[0] = buf[5];
|
sfr[0] = buf[5];
|
||||||
sfr[1] = buf[6];
|
sfr[1] = buf[6];
|
||||||
sfr[2] = buf[7];
|
sfr[2] = buf[7];
|
||||||
|
|
||||||
// calculate non-translational kinetic energy
|
// calculate non-translational kinetic energy
|
||||||
|
|
||||||
*Kr = *K - 0.5* (*mr) * (vr[0]*vr[0]+vr[1]*vr[1]+vr[2]*vr[2]);
|
*Kr = *K - 0.5 * (*mr) * (vr[0] * vr[0] + vr[1] * vr[1] + vr[2] * vr[2]);
|
||||||
|
|
||||||
// calculate sum_j f_j * (v_j - v_r) = sum_j f_j * v_j - v_r * sum_j f_j
|
// calculate sum_j f_j * (v_j - v_r) = sum_j f_j * v_j - v_r * sum_j f_j
|
||||||
|
|
||||||
*sfvr = buf[8] - (vr[0]*sfr[0] + vr[1]*sfr[1] + vr[2]*sfr[2]);
|
*sfvr = buf[8] - (vr[0] * sfr[0] + vr[1] * sfr[1] + vr[2] * sfr[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,10 +43,10 @@ class FixEHEX : public Fix {
|
|||||||
bool check_cluster(tagint *shake_atom, int n, class Region *region);
|
bool check_cluster(tagint *shake_atom, int n, class Region *region);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int iregion;
|
|
||||||
double heat_input;
|
double heat_input;
|
||||||
double masstotal;
|
double masstotal;
|
||||||
double scale;
|
double scale;
|
||||||
|
class Region *region;
|
||||||
char *idregion;
|
char *idregion;
|
||||||
int me;
|
int me;
|
||||||
|
|
||||||
|
|||||||
@ -246,12 +246,11 @@ void DumpVTK::init_style()
|
|||||||
else if (flag && cols) custom_flag[i] = DARRAY;
|
else if (flag && cols) custom_flag[i] = DARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set index and check validity of region
|
// check validity of region
|
||||||
|
|
||||||
if (iregion >= 0) {
|
if (idregion) {
|
||||||
iregion = domain->find_region(idregion);
|
if (!domain->get_region_by_id(idregion))
|
||||||
if (iregion == -1)
|
error->all(FLERR,"Region {} for dump vtk does not exist",idregion);
|
||||||
error->all(FLERR,"Region ID for dump vtk does not exist");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,8 +334,8 @@ int DumpVTK::count()
|
|||||||
|
|
||||||
// un-choose if not in region
|
// un-choose if not in region
|
||||||
|
|
||||||
if (iregion >= 0) {
|
auto region = domain->get_region_by_id(idregion);
|
||||||
Region *region = domain->regions[iregion];
|
if (region) {
|
||||||
region->prematch();
|
region->prematch();
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
for (i = 0; i < nlocal; i++)
|
for (i = 0; i < nlocal; i++)
|
||||||
@ -2054,11 +2053,12 @@ int DumpVTK::modify_param(int narg, char **arg)
|
|||||||
{
|
{
|
||||||
if (strcmp(arg[0],"region") == 0) {
|
if (strcmp(arg[0],"region") == 0) {
|
||||||
if (narg < 2) error->all(FLERR,"Illegal dump_modify command");
|
if (narg < 2) error->all(FLERR,"Illegal dump_modify command");
|
||||||
if (strcmp(arg[1],"none") == 0) iregion = -1;
|
if (strcmp(arg[1],"none") == 0) {
|
||||||
else {
|
delete[] idregion;
|
||||||
iregion = domain->find_region(arg[1]);
|
idregion = nullptr;
|
||||||
if (iregion == -1)
|
} else {
|
||||||
error->all(FLERR,"Dump_modify region ID {} does not exist",arg[1]);
|
if (!domain->get_region_by_id(arg[1]))
|
||||||
|
error->all(FLERR,"Dump_modify region {} does not exist",arg[1]);
|
||||||
delete[] idregion;
|
delete[] idregion;
|
||||||
idregion = utils::strdup(arg[1]);
|
idregion = utils::strdup(arg[1]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,9 +106,6 @@ Domain::Domain(LAMMPS *lmp) : Pointers(lmp)
|
|||||||
set_lattice(2,args);
|
set_lattice(2,args);
|
||||||
delete [] args;
|
delete [] args;
|
||||||
|
|
||||||
nregion = maxregion = 0;
|
|
||||||
regions = nullptr;
|
|
||||||
|
|
||||||
copymode = 0;
|
copymode = 0;
|
||||||
|
|
||||||
region_map = new RegionCreatorMap();
|
region_map = new RegionCreatorMap();
|
||||||
@ -128,10 +125,8 @@ Domain::~Domain()
|
|||||||
{
|
{
|
||||||
if (copymode) return;
|
if (copymode) return;
|
||||||
|
|
||||||
|
region_list.clear();
|
||||||
delete lattice;
|
delete lattice;
|
||||||
for (int i = 0; i < nregion; i++) delete regions[i];
|
|
||||||
memory->sfree(regions);
|
|
||||||
|
|
||||||
delete region_map;
|
delete region_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +189,7 @@ void Domain::init()
|
|||||||
|
|
||||||
// region inits
|
// region inits
|
||||||
|
|
||||||
for (int i = 0; i < nregion; i++) regions[i]->init();
|
for (auto reg : region_list) reg->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -1758,88 +1753,67 @@ void Domain::add_region(int narg, char **arg)
|
|||||||
if (strcmp(arg[1],"none") == 0)
|
if (strcmp(arg[1],"none") == 0)
|
||||||
error->all(FLERR,"Unrecognized region style 'none'");
|
error->all(FLERR,"Unrecognized region style 'none'");
|
||||||
|
|
||||||
if (find_region(arg[0]) >= 0) error->all(FLERR,"Reuse of region ID");
|
if (get_region_by_id(arg[0])) error->all(FLERR,"Reuse of region ID {}", arg[0]);
|
||||||
|
|
||||||
// extend Region list if necessary
|
|
||||||
|
|
||||||
if (nregion == maxregion) {
|
|
||||||
maxregion += DELTAREGION;
|
|
||||||
regions = (Region **)
|
|
||||||
memory->srealloc(regions,maxregion*sizeof(Region *),"domain:regions");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the Region
|
// create the Region
|
||||||
|
Region *newregion = nullptr;
|
||||||
|
|
||||||
if (lmp->suffix_enable) {
|
if (lmp->suffix_enable) {
|
||||||
if (lmp->suffix) {
|
if (lmp->suffix) {
|
||||||
std::string estyle = std::string(arg[1]) + "/" + lmp->suffix;
|
std::string estyle = std::string(arg[1]) + "/" + lmp->suffix;
|
||||||
if (region_map->find(estyle) != region_map->end()) {
|
if (region_map->find(estyle) != region_map->end()) {
|
||||||
RegionCreator ®ion_creator = (*region_map)[estyle];
|
RegionCreator ®ion_creator = (*region_map)[estyle];
|
||||||
regions[nregion] = region_creator(lmp, narg, arg);
|
newregion = region_creator(lmp, narg, arg);
|
||||||
regions[nregion]->init();
|
|
||||||
nregion++;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lmp->suffix2) {
|
if (!newregion && lmp->suffix2) {
|
||||||
std::string estyle = std::string(arg[1]) + "/" + lmp->suffix2;
|
std::string estyle = std::string(arg[1]) + "/" + lmp->suffix2;
|
||||||
if (region_map->find(estyle) != region_map->end()) {
|
if (region_map->find(estyle) != region_map->end()) {
|
||||||
RegionCreator ®ion_creator = (*region_map)[estyle];
|
RegionCreator ®ion_creator = (*region_map)[estyle];
|
||||||
regions[nregion] = region_creator(lmp, narg, arg);
|
newregion = region_creator(lmp, narg, arg);
|
||||||
regions[nregion]->init();
|
|
||||||
nregion++;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region_map->find(arg[1]) != region_map->end()) {
|
if (!newregion && (region_map->find(arg[1]) != region_map->end())) {
|
||||||
RegionCreator ®ion_creator = (*region_map)[arg[1]];
|
RegionCreator ®ion_creator = (*region_map)[arg[1]];
|
||||||
regions[nregion] = region_creator(lmp, narg, arg);
|
newregion = region_creator(lmp, narg, arg);
|
||||||
} else error->all(FLERR,utils::check_packages_for_style("region",arg[1],lmp));
|
}
|
||||||
|
|
||||||
|
if (!newregion)
|
||||||
|
error->all(FLERR,utils::check_packages_for_style("region",arg[1],lmp));
|
||||||
|
|
||||||
// initialize any region variables via init()
|
// initialize any region variables via init()
|
||||||
// in case region is used between runs, e.g. to print a variable
|
// in case region is used between runs, e.g. to print a variable
|
||||||
|
|
||||||
regions[nregion]->init();
|
newregion->init();
|
||||||
nregion++;
|
region_list.push_back(newregion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
delete a region
|
delete a region
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Domain::delete_region(int iregion)
|
void Domain::delete_region(Region *reg)
|
||||||
{
|
{
|
||||||
if ((iregion < 0) || (iregion >= nregion)) return;
|
if (!reg) return;
|
||||||
|
|
||||||
// delete and move other Regions down in list one slot
|
// delete and move other Regions down in list one slot
|
||||||
|
bool match = false;
|
||||||
delete regions[iregion];
|
for (std::size_t i = 0; i < region_list.size(); ++i) {
|
||||||
for (int i = iregion+1; i < nregion; ++i)
|
if (match) region_list[i-1] = region_list[i];
|
||||||
regions[i-1] = regions[i];
|
if (reg == region_list[i]) match = true;
|
||||||
nregion--;
|
}
|
||||||
|
delete reg;
|
||||||
|
region_list.resize(region_list.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Domain::delete_region(const std::string &id)
|
void Domain::delete_region(const std::string &id)
|
||||||
{
|
{
|
||||||
int iregion = find_region(id);
|
auto reg = get_region_by_id(id);
|
||||||
if (iregion == -1) error->all(FLERR,"Delete region ID does not exist");
|
if (!reg) error->all(FLERR,"Delete region {} does not exist", id);
|
||||||
|
delete_region(reg);
|
||||||
delete_region(iregion);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
return region index if name matches existing region ID
|
|
||||||
return -1 if no such region
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
int Domain::find_region(const std::string &name) const
|
|
||||||
{
|
|
||||||
for (int iregion = 0; iregion < nregion; iregion++)
|
|
||||||
if (name == regions[iregion]->id) return iregion;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -1849,8 +1823,8 @@ int Domain::find_region(const std::string &name) const
|
|||||||
|
|
||||||
Region *Domain::get_region_by_id(const std::string &name) const
|
Region *Domain::get_region_by_id(const std::string &name) const
|
||||||
{
|
{
|
||||||
for (int iregion = 0; iregion < nregion; iregion++)
|
for (auto ® : region_list)
|
||||||
if (name == regions[iregion]->id) return regions[iregion];
|
if (name == reg->id) return reg;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1864,12 +1838,21 @@ const std::vector<Region *> Domain::get_region_by_style(const std::string &name)
|
|||||||
std::vector<Region *> matches;
|
std::vector<Region *> matches;
|
||||||
if (name.empty()) return matches;
|
if (name.empty()) return matches;
|
||||||
|
|
||||||
for (int iregion = 0; iregion < nregion; iregion++)
|
for (auto ® : region_list)
|
||||||
if (name == regions[iregion]->style) matches.push_back(regions[iregion]);
|
if (name == reg->style) matches.push_back(reg);
|
||||||
|
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return list of fixes as vector
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
const std::vector<Region *> &Domain::get_region_list()
|
||||||
|
{
|
||||||
|
return region_list;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
(re)set boundary settings
|
(re)set boundary settings
|
||||||
flag = 0, called from the input script
|
flag = 0, called from the input script
|
||||||
|
|||||||
10
src/domain.h
10
src/domain.h
@ -17,6 +17,7 @@
|
|||||||
#include "pointers.h"
|
#include "pointers.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
@ -98,10 +99,6 @@ class Domain : protected Pointers {
|
|||||||
|
|
||||||
class Lattice *lattice; // user-defined lattice
|
class Lattice *lattice; // user-defined lattice
|
||||||
|
|
||||||
int nregion; // # of defined Regions
|
|
||||||
int maxregion; // max # list can hold
|
|
||||||
Region **regions; // list of defined Regions
|
|
||||||
|
|
||||||
int copymode;
|
int copymode;
|
||||||
enum { NO_REMAP, X_REMAP, V_REMAP };
|
enum { NO_REMAP, X_REMAP, V_REMAP };
|
||||||
|
|
||||||
@ -137,11 +134,11 @@ class Domain : protected Pointers {
|
|||||||
|
|
||||||
void set_lattice(int, char **);
|
void set_lattice(int, char **);
|
||||||
void add_region(int, char **);
|
void add_region(int, char **);
|
||||||
void delete_region(int);
|
void delete_region(Region *);
|
||||||
void delete_region(const std::string &);
|
void delete_region(const std::string &);
|
||||||
int find_region(const std::string &) const;
|
|
||||||
Region *get_region_by_id(const std::string &) const;
|
Region *get_region_by_id(const std::string &) const;
|
||||||
const std::vector<Region *> get_region_by_style(const std::string &) const;
|
const std::vector<Region *> get_region_by_style(const std::string &) const;
|
||||||
|
const std::vector<Region *> &get_region_list();
|
||||||
void set_boundary(int, char **, int);
|
void set_boundary(int, char **, int);
|
||||||
void set_box(int, char **);
|
void set_box(int, char **);
|
||||||
void print_box(const std::string &);
|
void print_box(const std::string &);
|
||||||
@ -175,6 +172,7 @@ class Domain : protected Pointers {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
double small[3]; // fractions of box lengths
|
double small[3]; // fractions of box lengths
|
||||||
|
std::vector<Region *> region_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LAMMPS_NS
|
} // namespace LAMMPS_NS
|
||||||
|
|||||||
@ -40,8 +40,8 @@
|
|||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
#define MAX_GROUP 32
|
static constexpr int MAX_GROUP = 32;
|
||||||
#define EPSILON 1.0e-6
|
static constexpr double EPSILON = 1.0e-6;
|
||||||
|
|
||||||
enum{NONE,TYPE,MOLECULE,ID};
|
enum{NONE,TYPE,MOLECULE,ID};
|
||||||
enum{LT,LE,GT,GE,EQ,NEQ,BETWEEN};
|
enum{LT,LE,GT,GE,EQ,NEQ,BETWEEN};
|
||||||
@ -176,13 +176,13 @@ void Group::assign(int narg, char **arg)
|
|||||||
|
|
||||||
if (narg != 3) error->all(FLERR,"Illegal group command");
|
if (narg != 3) error->all(FLERR,"Illegal group command");
|
||||||
|
|
||||||
int iregion = domain->find_region(arg[2]);
|
auto region = domain->get_region_by_id(arg[2]);
|
||||||
if (iregion == -1) error->all(FLERR,"Group region ID does not exist");
|
if (!region) error->all(FLERR,"Group region {} does not exist", arg[2]);
|
||||||
domain->regions[iregion]->init();
|
region->init();
|
||||||
domain->regions[iregion]->prematch();
|
region->prematch();
|
||||||
|
|
||||||
for (i = 0; i < nlocal; i++)
|
for (i = 0; i < nlocal; i++)
|
||||||
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
|
if (region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
mask[i] |= bit;
|
mask[i] |= bit;
|
||||||
|
|
||||||
// create an empty group
|
// create an empty group
|
||||||
@ -813,15 +813,6 @@ bigint Group::count(int igroup, Region *region)
|
|||||||
return nall;
|
return nall;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
count atoms in group and region
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
bigint Group::count(int igroup, int iregion)
|
|
||||||
{
|
|
||||||
return count(igroup, domain->regions[iregion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total mass of group of atoms
|
compute the total mass of group of atoms
|
||||||
use either per-type mass or per-atom rmass
|
use either per-type mass or per-atom rmass
|
||||||
@ -886,16 +877,6 @@ double Group::mass(int igroup, Region *region)
|
|||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
compute the total mass of group of atoms in region
|
|
||||||
use either per-type mass or per-atom rmass
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
double Group::mass(int igroup, int iregion)
|
|
||||||
{
|
|
||||||
return mass(igroup, domain->regions[iregion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total charge of group of atoms
|
compute the total charge of group of atoms
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -921,10 +902,9 @@ double Group::charge(int igroup)
|
|||||||
compute the total charge of group of atoms in region
|
compute the total charge of group of atoms in region
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
double Group::charge(int igroup, int iregion)
|
double Group::charge(int igroup, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
@ -990,10 +970,9 @@ void Group::bounds(int igroup, double *minmax)
|
|||||||
periodic images are not considered, so atoms are NOT unwrapped
|
periodic images are not considered, so atoms are NOT unwrapped
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Group::bounds(int igroup, double *minmax, int iregion)
|
void Group::bounds(int igroup, double *minmax, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double extent[6];
|
double extent[6];
|
||||||
@ -1090,10 +1069,9 @@ void Group::xcm(int igroup, double masstotal, double *cm)
|
|||||||
must unwrap atoms to compute center-of-mass correctly
|
must unwrap atoms to compute center-of-mass correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Group::xcm(int igroup, double masstotal, double *cm, int iregion)
|
void Group::xcm(int igroup, double masstotal, double *cm, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
@ -1232,17 +1210,6 @@ void Group::vcm(int igroup, double masstotal, double *cm, Region *region)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
compute the center-of-mass velocity of group of atoms in region
|
|
||||||
masstotal = total mass
|
|
||||||
return center-of-mass velocity in cm[]
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void Group::vcm(int igroup, double masstotal, double *cm, int iregion)
|
|
||||||
{
|
|
||||||
vcm(igroup, masstotal, cm, domain->regions[iregion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total force on group of atoms
|
compute the total force on group of atoms
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -1272,10 +1239,9 @@ void Group::fcm(int igroup, double *cm)
|
|||||||
compute the total force on group of atoms in region
|
compute the total force on group of atoms in region
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Group::fcm(int igroup, double *cm, int iregion)
|
void Group::fcm(int igroup, double *cm, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
@ -1368,15 +1334,6 @@ double Group::ke(int igroup, Region *region)
|
|||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
compute the total kinetic energy of group of atoms in region and return it
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
double Group::ke(int igroup, int iregion)
|
|
||||||
{
|
|
||||||
return ke(igroup, domain->regions[iregion]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the radius-of-gyration of group of atoms
|
compute the radius-of-gyration of group of atoms
|
||||||
around center-of-mass cm
|
around center-of-mass cm
|
||||||
@ -1422,10 +1379,9 @@ double Group::gyration(int igroup, double masstotal, double *cm)
|
|||||||
must unwrap atoms to compute Rg correctly
|
must unwrap atoms to compute Rg correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
double Group::gyration(int igroup, double masstotal, double *cm, int iregion)
|
double Group::gyration(int igroup, double masstotal, double *cm, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
@ -1504,10 +1460,9 @@ void Group::angmom(int igroup, double *cm, double *lmom)
|
|||||||
must unwrap atoms to compute L correctly
|
must unwrap atoms to compute L correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Group::angmom(int igroup, double *cm, double *lmom, int iregion)
|
void Group::angmom(int igroup, double *cm, double *lmom, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
@ -1583,10 +1538,9 @@ void Group::torque(int igroup, double *cm, double *tq)
|
|||||||
must unwrap atoms to compute T correctly
|
must unwrap atoms to compute T correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Group::torque(int igroup, double *cm, double *tq, int iregion)
|
void Group::torque(int igroup, double *cm, double *tq, Region *region)
|
||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
@ -1669,12 +1623,11 @@ void Group::inertia(int igroup, double *cm, double itensor[3][3])
|
|||||||
must unwrap atoms to compute itensor correctly
|
must unwrap atoms to compute itensor correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Group::inertia(int igroup, double *cm, double itensor[3][3], int iregion)
|
void Group::inertia(int igroup, double *cm, double itensor[3][3], Region *region)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
|
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
Region *region = domain->regions[iregion];
|
|
||||||
region->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
|
|||||||
20
src/group.h
20
src/group.h
@ -41,33 +41,29 @@ class Group : protected Pointers {
|
|||||||
|
|
||||||
bigint count_all(); // count atoms in group all
|
bigint count_all(); // count atoms in group all
|
||||||
bigint count(int); // count atoms in group
|
bigint count(int); // count atoms in group
|
||||||
bigint count(int, int); // count atoms in group & region
|
|
||||||
bigint count(int, Region *); // count atoms in group & region
|
bigint count(int, Region *); // count atoms in group & region
|
||||||
double mass(int); // total mass of atoms in group
|
double mass(int); // total mass of atoms in group
|
||||||
double mass(int, int);
|
|
||||||
double mass(int, Region *);
|
double mass(int, Region *);
|
||||||
double charge(int); // total charge of atoms in group
|
double charge(int); // total charge of atoms in group
|
||||||
double charge(int, int);
|
double charge(int, Region *);
|
||||||
void bounds(int, double *); // bounds of atoms in group
|
void bounds(int, double *); // bounds of atoms in group
|
||||||
void bounds(int, double *, int);
|
void bounds(int, double *, Region *);
|
||||||
void xcm(int, double, double *); // center-of-mass coords of group
|
void xcm(int, double, double *); // center-of-mass coords of group
|
||||||
void xcm(int, double, double *, int);
|
void xcm(int, double, double *, Region *);
|
||||||
void vcm(int, double, double *); // center-of-mass velocity of group
|
void vcm(int, double, double *); // center-of-mass velocity of group
|
||||||
void vcm(int, double, double *, int);
|
|
||||||
void vcm(int, double, double *, Region *);
|
void vcm(int, double, double *, Region *);
|
||||||
void fcm(int, double *); // total force on group
|
void fcm(int, double *); // total force on group
|
||||||
void fcm(int, double *, int);
|
void fcm(int, double *, Region *);
|
||||||
double ke(int); // kinetic energy of group
|
double ke(int); // kinetic energy of group
|
||||||
double ke(int, int);
|
|
||||||
double ke(int, Region *);
|
double ke(int, Region *);
|
||||||
double gyration(int, double, double *); // radius-of-gyration of group
|
double gyration(int, double, double *); // radius-of-gyration of group
|
||||||
double gyration(int, double, double *, int);
|
double gyration(int, double, double *, Region *);
|
||||||
void angmom(int, double *, double *); // angular momentum of group
|
void angmom(int, double *, double *); // angular momentum of group
|
||||||
void angmom(int, double *, double *, int);
|
void angmom(int, double *, double *, Region *);
|
||||||
void torque(int, double *, double *); // torque on group
|
void torque(int, double *, double *); // torque on group
|
||||||
void torque(int, double *, double *, int);
|
void torque(int, double *, double *, Region *);
|
||||||
void inertia(int, double *, double[3][3]); // inertia tensor
|
void inertia(int, double *, double[3][3]); // inertia tensor
|
||||||
void inertia(int, double *, double[3][3], int);
|
void inertia(int, double *, double[3][3], Region *);
|
||||||
void omega(double *, double[3][3], double *); // angular velocity
|
void omega(double *, double[3][3], double *); // angular velocity
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
26
src/info.cpp
26
src/info.cpp
@ -546,19 +546,17 @@ void Info::command(int narg, char **arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & REGIONS) {
|
if (flags & REGIONS) {
|
||||||
int nreg = domain->nregion;
|
|
||||||
Region **regs = domain->regions;
|
|
||||||
fputs("\nRegion information:\n",out);
|
fputs("\nRegion information:\n",out);
|
||||||
for (int i=0; i < nreg; ++i) {
|
int i=0;
|
||||||
|
for (auto ® : domain->get_region_list()) {
|
||||||
fmt::print(out,"Region[{:3d}]: {:16} style = {:16} side = {}\n",
|
fmt::print(out,"Region[{:3d}]: {:16} style = {:16} side = {}\n",
|
||||||
i, std::string(regs[i]->id)+',',
|
i, std::string(reg->id)+',', std::string(reg->style)+',',
|
||||||
std::string(regs[i]->style)+',',
|
reg->interior ? "in" : "out");
|
||||||
regs[i]->interior ? "in" : "out");
|
if (reg->bboxflag)
|
||||||
if (regs[i]->bboxflag)
|
|
||||||
fmt::print(out," Boundary: lo {:.8} {:.8} {:.8} hi {:.8} {:.8} {:.8}\n",
|
fmt::print(out," Boundary: lo {:.8} {:.8} {:.8} hi {:.8} {:.8} {:.8}\n",
|
||||||
regs[i]->extent_xlo, regs[i]->extent_ylo,
|
reg->extent_xlo, reg->extent_ylo,
|
||||||
regs[i]->extent_zlo, regs[i]->extent_xhi,
|
reg->extent_zlo, reg->extent_xhi,
|
||||||
regs[i]->extent_yhi, regs[i]->extent_zhi);
|
reg->extent_yhi, reg->extent_zhi);
|
||||||
else fputs(" No Boundary\n",out);
|
else fputs(" No Boundary\n",out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -916,12 +914,8 @@ bool Info::is_defined(const char *category, const char *name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (strcmp(category,"region") == 0) {
|
} else if (strcmp(category,"region") == 0) {
|
||||||
int nreg = domain->nregion;
|
for (auto ® : domain->get_region_list())
|
||||||
Region **regs = domain->regions;
|
if (strcmp(reg->id,name) == 0) return true;
|
||||||
for (int i=0; i < nreg; ++i) {
|
|
||||||
if (strcmp(regs[i]->id,name) == 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (strcmp(category,"variable") == 0) {
|
} else if (strcmp(category,"variable") == 0) {
|
||||||
int nvar = input->variable->nvar;
|
int nvar = input->variable->nvar;
|
||||||
char **names = input->variable->names;
|
char **names = input->variable->names;
|
||||||
|
|||||||
@ -4772,10 +4772,8 @@ int lammps_has_id(void *handle, const char *category, const char *name) {
|
|||||||
if (strcmp(name,molecule[i]->id) == 0) return 1;
|
if (strcmp(name,molecule[i]->id) == 0) return 1;
|
||||||
}
|
}
|
||||||
} else if (strcmp(category,"region") == 0) {
|
} else if (strcmp(category,"region") == 0) {
|
||||||
int nregion = lmp->domain->nregion;
|
for (auto ® : lmp->domain->get_region_list()) {
|
||||||
Region **region = lmp->domain->regions;
|
if (strcmp(name,reg->id) == 0) return 1;
|
||||||
for (int i=0; i < nregion; ++i) {
|
|
||||||
if (strcmp(name,region[i]->id) == 0) return 1;
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(category,"variable") == 0) {
|
} else if (strcmp(category,"variable") == 0) {
|
||||||
int nvariable = lmp->input->variable->nvar;
|
int nvariable = lmp->input->variable->nvar;
|
||||||
@ -4818,7 +4816,7 @@ int lammps_id_count(void *handle, const char *category) {
|
|||||||
} else if (strcmp(category,"molecule") == 0) {
|
} else if (strcmp(category,"molecule") == 0) {
|
||||||
return lmp->atom->nmolecule;
|
return lmp->atom->nmolecule;
|
||||||
} else if (strcmp(category,"region") == 0) {
|
} else if (strcmp(category,"region") == 0) {
|
||||||
return lmp->domain->nregion;
|
return lmp->domain->get_region_list().size();
|
||||||
} else if (strcmp(category,"variable") == 0) {
|
} else if (strcmp(category,"variable") == 0) {
|
||||||
return lmp->input->variable->nvar;
|
return lmp->input->variable->nvar;
|
||||||
}
|
}
|
||||||
@ -4848,8 +4846,7 @@ set to an empty string, otherwise 1.
|
|||||||
* \param buf_size size of the provided string buffer
|
* \param buf_size size of the provided string buffer
|
||||||
* \return 1 if successful, otherwise 0
|
* \return 1 if successful, otherwise 0
|
||||||
*/
|
*/
|
||||||
int lammps_id_name(void *handle, const char *category, int idx,
|
int lammps_id_name(void *handle, const char *category, int idx, char *buffer, int buf_size) {
|
||||||
char *buffer, int buf_size) {
|
|
||||||
auto lmp = (LAMMPS *) handle;
|
auto lmp = (LAMMPS *) handle;
|
||||||
|
|
||||||
if (strcmp(category,"compute") == 0) {
|
if (strcmp(category,"compute") == 0) {
|
||||||
@ -4878,8 +4875,9 @@ int lammps_id_name(void *handle, const char *category, int idx,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (strcmp(category,"region") == 0) {
|
} else if (strcmp(category,"region") == 0) {
|
||||||
if ((idx >=0) && (idx < lmp->domain->nregion)) {
|
auto regions = lmp->domain->get_region_list();
|
||||||
strncpy(buffer, lmp->domain->regions[idx]->id, buf_size);
|
if ((idx >=0) && (idx < (int) regions.size())) {
|
||||||
|
strncpy(buffer, regions[idx]->id, buf_size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (strcmp(category,"variable") == 0) {
|
} else if (strcmp(category,"variable") == 0) {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ namespace MathConst {
|
|||||||
static constexpr double MY_2PI = 6.28318530717958647692; // 2pi
|
static constexpr double MY_2PI = 6.28318530717958647692; // 2pi
|
||||||
static constexpr double MY_3PI = 9.42477796076937971538; // 3pi
|
static constexpr double MY_3PI = 9.42477796076937971538; // 3pi
|
||||||
static constexpr double MY_4PI = 12.56637061435917295384; // 4pi
|
static constexpr double MY_4PI = 12.56637061435917295384; // 4pi
|
||||||
|
static constexpr double MY_4PI3 = 4.18879020478639098461; // 4/3pi
|
||||||
static constexpr double MY_PI2 = 1.57079632679489661923; // pi/2
|
static constexpr double MY_PI2 = 1.57079632679489661923; // pi/2
|
||||||
static constexpr double MY_PI4 = 0.78539816339744830962; // pi/4
|
static constexpr double MY_PI4 = 0.78539816339744830962; // pi/4
|
||||||
static constexpr double MY_PIS = 1.77245385090551602729; // sqrt(pi)
|
static constexpr double MY_PIS = 1.77245385090551602729; // sqrt(pi)
|
||||||
|
|||||||
@ -859,7 +859,7 @@ Fix *Modify::add_fix(int narg, char **arg, int trysuffix)
|
|||||||
fix[ifix]->style = utils::strdup(estyle);
|
fix[ifix]->style = utils::strdup(estyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fix[ifix] == nullptr && lmp->suffix2) {
|
if ((fix[ifix] == nullptr) && lmp->suffix2) {
|
||||||
std::string estyle = arg[2] + std::string("/") + lmp->suffix2;
|
std::string estyle = arg[2] + std::string("/") + lmp->suffix2;
|
||||||
if (fix_map->find(estyle) != fix_map->end()) {
|
if (fix_map->find(estyle) != fix_map->end()) {
|
||||||
FixCreator &fix_creator = (*fix_map)[estyle];
|
FixCreator &fix_creator = (*fix_map)[estyle];
|
||||||
@ -870,7 +870,7 @@ Fix *Modify::add_fix(int narg, char **arg, int trysuffix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fix[ifix] == nullptr && fix_map->find(arg[2]) != fix_map->end()) {
|
if ((fix[ifix] == nullptr) && (fix_map->find(arg[2]) != fix_map->end())) {
|
||||||
FixCreator &fix_creator = (*fix_map)[arg[2]];
|
FixCreator &fix_creator = (*fix_map)[arg[2]];
|
||||||
fix[ifix] = fix_creator(lmp, narg, arg);
|
fix[ifix] = fix_creator(lmp, narg, arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -700,13 +700,13 @@ void Set::selection(int n)
|
|||||||
else select[i] = 0;
|
else select[i] = 0;
|
||||||
|
|
||||||
} else if (style == REGION_SELECT) {
|
} else if (style == REGION_SELECT) {
|
||||||
int iregion = domain->find_region(id);
|
auto region = domain->get_region_by_id(id);
|
||||||
if (iregion == -1) error->all(FLERR,"Set region ID does not exist");
|
if (!region) error->all(FLERR,"Set region {} does not exist", id);
|
||||||
domain->regions[iregion]->prematch();
|
region->prematch();
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
|
if (region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
select[i] = 1;
|
select[i] = 1;
|
||||||
else select[i] = 0;
|
else select[i] = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
144
src/variable.cpp
144
src/variable.cpp
@ -3043,18 +3043,18 @@ double Variable::eval_tree(Tree *tree, int i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tree->type == GMASK) {
|
if (tree->type == GMASK) {
|
||||||
if (atom->mask[i] & tree->ivalue1) return 1.0;
|
if (atom->mask[i] & tree->ivalue) return 1.0;
|
||||||
else return 0.0;
|
else return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->type == RMASK) {
|
if (tree->type == RMASK) {
|
||||||
if (domain->regions[tree->ivalue1]->match(atom->x[i][0], atom->x[i][1], atom->x[i][2])) return 1.0;
|
if (tree->region->match(atom->x[i][0], atom->x[i][1], atom->x[i][2])) return 1.0;
|
||||||
else return 0.0;
|
else return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->type == GRMASK) {
|
if (tree->type == GRMASK) {
|
||||||
if ((atom->mask[i] & tree->ivalue1) &&
|
if ((atom->mask[i] & tree->ivalue) &&
|
||||||
(domain->regions[tree->ivalue2]->match(atom->x[i][0], atom->x[i][1], atom->x[i][2]))) return 1.0;
|
(tree->region->match(atom->x[i][0], atom->x[i][1], atom->x[i][2]))) return 1.0;
|
||||||
else return 0.0;
|
else return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3664,32 +3664,31 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
|
|
||||||
int igroup = group->find(args[0]);
|
int igroup = group->find(args[0]);
|
||||||
if (igroup == -1) {
|
if (igroup == -1) {
|
||||||
std::string mesg = "Group ID '";
|
const auto errmesg = fmt::format("Group {} in variable formula does not exist", args[0]);
|
||||||
mesg += args[0];
|
print_var_error(FLERR, errmesg, ivar);
|
||||||
mesg += "' in variable formula does not exist";
|
|
||||||
print_var_error(FLERR,mesg,ivar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// match word to group function
|
// match word to group function
|
||||||
|
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
const auto group_errmesg = fmt::format("Invalid {}() function in variable formula", word);
|
||||||
|
|
||||||
if (strcmp(word,"count") == 0) {
|
if (strcmp(word,"count") == 0) {
|
||||||
if (narg == 1) value = group->count(igroup);
|
if (narg == 1) value = group->count(igroup);
|
||||||
else if (narg == 2)
|
else if (narg == 2)
|
||||||
value = group->count(igroup,region_function(args[1],ivar));
|
value = group->count(igroup,region_function(args[1],ivar));
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"mass") == 0) {
|
} else if (strcmp(word,"mass") == 0) {
|
||||||
if (narg == 1) value = group->mass(igroup);
|
if (narg == 1) value = group->mass(igroup);
|
||||||
else if (narg == 2) value = group->mass(igroup,region_function(args[1],ivar));
|
else if (narg == 2) value = group->mass(igroup,region_function(args[1],ivar));
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"charge") == 0) {
|
} else if (strcmp(word,"charge") == 0) {
|
||||||
if (narg == 1) value = group->charge(igroup);
|
if (narg == 1) value = group->charge(igroup);
|
||||||
else if (narg == 2)
|
else if (narg == 2)
|
||||||
value = group->charge(igroup,region_function(args[1],ivar));
|
value = group->charge(igroup,region_function(args[1],ivar));
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"xcm") == 0) {
|
} else if (strcmp(word,"xcm") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3698,14 +3697,14 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
double masstotal = group->mass(igroup);
|
double masstotal = group->mass(igroup);
|
||||||
group->xcm(igroup,masstotal,xcm);
|
group->xcm(igroup,masstotal,xcm);
|
||||||
} else if (narg == 3) {
|
} else if (narg == 3) {
|
||||||
int iregion = region_function(args[2],ivar);
|
auto region = region_function(args[2],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->xcm(igroup,masstotal,xcm,iregion);
|
group->xcm(igroup,masstotal,xcm,region);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"x") == 0) value = xcm[0];
|
if (strcmp(args[1],"x") == 0) value = xcm[0];
|
||||||
else if (strcmp(args[1],"y") == 0) value = xcm[1];
|
else if (strcmp(args[1],"y") == 0) value = xcm[1];
|
||||||
else if (strcmp(args[1],"z") == 0) value = xcm[2];
|
else if (strcmp(args[1],"z") == 0) value = xcm[2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"vcm") == 0) {
|
} else if (strcmp(word,"vcm") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3714,38 +3713,38 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
double masstotal = group->mass(igroup);
|
double masstotal = group->mass(igroup);
|
||||||
group->vcm(igroup,masstotal,vcm);
|
group->vcm(igroup,masstotal,vcm);
|
||||||
} else if (narg == 3) {
|
} else if (narg == 3) {
|
||||||
int iregion = region_function(args[2],ivar);
|
auto region = region_function(args[2],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->vcm(igroup,masstotal,vcm,iregion);
|
group->vcm(igroup,masstotal,vcm,region);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"x") == 0) value = vcm[0];
|
if (strcmp(args[1],"x") == 0) value = vcm[0];
|
||||||
else if (strcmp(args[1],"y") == 0) value = vcm[1];
|
else if (strcmp(args[1],"y") == 0) value = vcm[1];
|
||||||
else if (strcmp(args[1],"z") == 0) value = vcm[2];
|
else if (strcmp(args[1],"z") == 0) value = vcm[2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"fcm") == 0) {
|
} else if (strcmp(word,"fcm") == 0) {
|
||||||
double fcm[3];
|
double fcm[3];
|
||||||
if (narg == 2) group->fcm(igroup,fcm);
|
if (narg == 2) group->fcm(igroup,fcm);
|
||||||
else if (narg == 3) group->fcm(igroup,fcm,region_function(args[2],ivar));
|
else if (narg == 3) group->fcm(igroup,fcm,region_function(args[2],ivar));
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"x") == 0) value = fcm[0];
|
if (strcmp(args[1],"x") == 0) value = fcm[0];
|
||||||
else if (strcmp(args[1],"y") == 0) value = fcm[1];
|
else if (strcmp(args[1],"y") == 0) value = fcm[1];
|
||||||
else if (strcmp(args[1],"z") == 0) value = fcm[2];
|
else if (strcmp(args[1],"z") == 0) value = fcm[2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"bound") == 0) {
|
} else if (strcmp(word,"bound") == 0) {
|
||||||
double minmax[6];
|
double minmax[6];
|
||||||
if (narg == 2) group->bounds(igroup,minmax);
|
if (narg == 2) group->bounds(igroup,minmax);
|
||||||
else if (narg == 3)
|
else if (narg == 3)
|
||||||
group->bounds(igroup,minmax,region_function(args[2],ivar));
|
group->bounds(igroup,minmax,region_function(args[2],ivar));
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"xmin") == 0) value = minmax[0];
|
if (strcmp(args[1],"xmin") == 0) value = minmax[0];
|
||||||
else if (strcmp(args[1],"xmax") == 0) value = minmax[1];
|
else if (strcmp(args[1],"xmax") == 0) value = minmax[1];
|
||||||
else if (strcmp(args[1],"ymin") == 0) value = minmax[2];
|
else if (strcmp(args[1],"ymin") == 0) value = minmax[2];
|
||||||
else if (strcmp(args[1],"ymax") == 0) value = minmax[3];
|
else if (strcmp(args[1],"ymax") == 0) value = minmax[3];
|
||||||
else if (strcmp(args[1],"zmin") == 0) value = minmax[4];
|
else if (strcmp(args[1],"zmin") == 0) value = minmax[4];
|
||||||
else if (strcmp(args[1],"zmax") == 0) value = minmax[5];
|
else if (strcmp(args[1],"zmax") == 0) value = minmax[5];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"gyration") == 0) {
|
} else if (strcmp(word,"gyration") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3755,16 +3754,16 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
group->xcm(igroup,masstotal,xcm);
|
group->xcm(igroup,masstotal,xcm);
|
||||||
value = group->gyration(igroup,masstotal,xcm);
|
value = group->gyration(igroup,masstotal,xcm);
|
||||||
} else if (narg == 2) {
|
} else if (narg == 2) {
|
||||||
int iregion = region_function(args[1],ivar);
|
auto region = region_function(args[1],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->xcm(igroup,masstotal,xcm,iregion);
|
group->xcm(igroup,masstotal,xcm,region);
|
||||||
value = group->gyration(igroup,masstotal,xcm,iregion);
|
value = group->gyration(igroup,masstotal,xcm,region);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"ke") == 0) {
|
} else if (strcmp(word,"ke") == 0) {
|
||||||
if (narg == 1) value = group->ke(igroup);
|
if (narg == 1) value = group->ke(igroup);
|
||||||
else if (narg == 2) value = group->ke(igroup,region_function(args[1],ivar));
|
else if (narg == 2) value = group->ke(igroup,region_function(args[1],ivar));
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"angmom") == 0) {
|
} else if (strcmp(word,"angmom") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3774,15 +3773,15 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
group->xcm(igroup,masstotal,xcm);
|
group->xcm(igroup,masstotal,xcm);
|
||||||
group->angmom(igroup,xcm,lmom);
|
group->angmom(igroup,xcm,lmom);
|
||||||
} else if (narg == 3) {
|
} else if (narg == 3) {
|
||||||
int iregion = region_function(args[2],ivar);
|
auto region = region_function(args[2],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->xcm(igroup,masstotal,xcm,iregion);
|
group->xcm(igroup,masstotal,xcm,region);
|
||||||
group->angmom(igroup,xcm,lmom,iregion);
|
group->angmom(igroup,xcm,lmom,region);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"x") == 0) value = lmom[0];
|
if (strcmp(args[1],"x") == 0) value = lmom[0];
|
||||||
else if (strcmp(args[1],"y") == 0) value = lmom[1];
|
else if (strcmp(args[1],"y") == 0) value = lmom[1];
|
||||||
else if (strcmp(args[1],"z") == 0) value = lmom[2];
|
else if (strcmp(args[1],"z") == 0) value = lmom[2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"torque") == 0) {
|
} else if (strcmp(word,"torque") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3792,15 +3791,15 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
group->xcm(igroup,masstotal,xcm);
|
group->xcm(igroup,masstotal,xcm);
|
||||||
group->torque(igroup,xcm,tq);
|
group->torque(igroup,xcm,tq);
|
||||||
} else if (narg == 3) {
|
} else if (narg == 3) {
|
||||||
int iregion = region_function(args[2],ivar);
|
auto region = region_function(args[2],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->xcm(igroup,masstotal,xcm,iregion);
|
group->xcm(igroup,masstotal,xcm,region);
|
||||||
group->torque(igroup,xcm,tq,iregion);
|
group->torque(igroup,xcm,tq,region);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"x") == 0) value = tq[0];
|
if (strcmp(args[1],"x") == 0) value = tq[0];
|
||||||
else if (strcmp(args[1],"y") == 0) value = tq[1];
|
else if (strcmp(args[1],"y") == 0) value = tq[1];
|
||||||
else if (strcmp(args[1],"z") == 0) value = tq[2];
|
else if (strcmp(args[1],"z") == 0) value = tq[2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"inertia") == 0) {
|
} else if (strcmp(word,"inertia") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3810,18 +3809,18 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
group->xcm(igroup,masstotal,xcm);
|
group->xcm(igroup,masstotal,xcm);
|
||||||
group->inertia(igroup,xcm,inertia);
|
group->inertia(igroup,xcm,inertia);
|
||||||
} else if (narg == 3) {
|
} else if (narg == 3) {
|
||||||
int iregion = region_function(args[2],ivar);
|
auto region = region_function(args[2],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->xcm(igroup,masstotal,xcm,iregion);
|
group->xcm(igroup,masstotal,xcm,region);
|
||||||
group->inertia(igroup,xcm,inertia,iregion);
|
group->inertia(igroup,xcm,inertia,region);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"xx") == 0) value = inertia[0][0];
|
if (strcmp(args[1],"xx") == 0) value = inertia[0][0];
|
||||||
else if (strcmp(args[1],"yy") == 0) value = inertia[1][1];
|
else if (strcmp(args[1],"yy") == 0) value = inertia[1][1];
|
||||||
else if (strcmp(args[1],"zz") == 0) value = inertia[2][2];
|
else if (strcmp(args[1],"zz") == 0) value = inertia[2][2];
|
||||||
else if (strcmp(args[1],"xy") == 0) value = inertia[0][1];
|
else if (strcmp(args[1],"xy") == 0) value = inertia[0][1];
|
||||||
else if (strcmp(args[1],"yz") == 0) value = inertia[1][2];
|
else if (strcmp(args[1],"yz") == 0) value = inertia[1][2];
|
||||||
else if (strcmp(args[1],"xz") == 0) value = inertia[0][2];
|
else if (strcmp(args[1],"xz") == 0) value = inertia[0][2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
|
|
||||||
} else if (strcmp(word,"omega") == 0) {
|
} else if (strcmp(word,"omega") == 0) {
|
||||||
atom->check_mass(FLERR);
|
atom->check_mass(FLERR);
|
||||||
@ -3833,17 +3832,17 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
group->inertia(igroup,xcm,inertia);
|
group->inertia(igroup,xcm,inertia);
|
||||||
group->omega(angmom,inertia,omega);
|
group->omega(angmom,inertia,omega);
|
||||||
} else if (narg == 3) {
|
} else if (narg == 3) {
|
||||||
int iregion = region_function(args[2],ivar);
|
auto region = region_function(args[2],ivar);
|
||||||
double masstotal = group->mass(igroup,iregion);
|
double masstotal = group->mass(igroup,region);
|
||||||
group->xcm(igroup,masstotal,xcm,iregion);
|
group->xcm(igroup,masstotal,xcm,region);
|
||||||
group->angmom(igroup,xcm,angmom,iregion);
|
group->angmom(igroup,xcm,angmom,region);
|
||||||
group->inertia(igroup,xcm,inertia,iregion);
|
group->inertia(igroup,xcm,inertia,region);
|
||||||
group->omega(angmom,inertia,omega);
|
group->omega(angmom,inertia,omega);
|
||||||
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
} else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
if (strcmp(args[1],"x") == 0) value = omega[0];
|
if (strcmp(args[1],"x") == 0) value = omega[0];
|
||||||
else if (strcmp(args[1],"y") == 0) value = omega[1];
|
else if (strcmp(args[1],"y") == 0) value = omega[1];
|
||||||
else if (strcmp(args[1],"z") == 0) value = omega[2];
|
else if (strcmp(args[1],"z") == 0) value = omega[2];
|
||||||
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
|
else print_var_error(FLERR,group_errmesg,ivar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete stored args
|
// delete stored args
|
||||||
@ -3864,21 +3863,16 @@ int Variable::group_function(char *word, char *contents, Tree **tree, Tree **tre
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Variable::region_function(char *id, int ivar)
|
Region *Variable::region_function(char *id, int ivar)
|
||||||
{
|
{
|
||||||
int iregion = domain->find_region(id);
|
auto region = domain->get_region_by_id(id);
|
||||||
if (iregion == -1) {
|
if (!region)
|
||||||
std::string mesg = "Region ID '";
|
print_var_error(FLERR, fmt::format("Region {} in variable formula does not exist", id), ivar);
|
||||||
mesg += id;
|
|
||||||
mesg += "' in variable formula does not exist";
|
|
||||||
print_var_error(FLERR,mesg,ivar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// init region in case sub-regions have been deleted
|
// init region in case sub-regions have been deleted
|
||||||
|
|
||||||
domain->regions[iregion]->init();
|
region->init();
|
||||||
|
return region;
|
||||||
return iregion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -4149,7 +4143,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
|||||||
|
|
||||||
auto newtree = new Tree();
|
auto newtree = new Tree();
|
||||||
newtree->type = GMASK;
|
newtree->type = GMASK;
|
||||||
newtree->ivalue1 = group->bitmask[igroup];
|
newtree->ivalue = group->bitmask[igroup];
|
||||||
treestack[ntreestack++] = newtree;
|
treestack[ntreestack++] = newtree;
|
||||||
|
|
||||||
} else if (strcmp(word,"rmask") == 0) {
|
} else if (strcmp(word,"rmask") == 0) {
|
||||||
@ -4158,12 +4152,12 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
|||||||
if (narg != 1)
|
if (narg != 1)
|
||||||
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
|
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
|
||||||
|
|
||||||
int iregion = region_function(args[0],ivar);
|
auto region = region_function(args[0],ivar);
|
||||||
domain->regions[iregion]->prematch();
|
region->prematch();
|
||||||
|
|
||||||
auto newtree = new Tree();
|
auto newtree = new Tree();
|
||||||
newtree->type = RMASK;
|
newtree->type = RMASK;
|
||||||
newtree->ivalue1 = iregion;
|
newtree->region = region;
|
||||||
treestack[ntreestack++] = newtree;
|
treestack[ntreestack++] = newtree;
|
||||||
|
|
||||||
} else if (strcmp(word,"grmask") == 0) {
|
} else if (strcmp(word,"grmask") == 0) {
|
||||||
@ -4175,13 +4169,13 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
|||||||
int igroup = group->find(args[0]);
|
int igroup = group->find(args[0]);
|
||||||
if (igroup == -1)
|
if (igroup == -1)
|
||||||
print_var_error(FLERR,"Group ID in variable formula does not exist",ivar);
|
print_var_error(FLERR,"Group ID in variable formula does not exist",ivar);
|
||||||
int iregion = region_function(args[1],ivar);
|
auto region = region_function(args[1],ivar);
|
||||||
domain->regions[iregion]->prematch();
|
region->prematch();
|
||||||
|
|
||||||
auto newtree = new Tree();
|
auto newtree = new Tree();
|
||||||
newtree->type = GRMASK;
|
newtree->type = GRMASK;
|
||||||
newtree->ivalue1 = group->bitmask[igroup];
|
newtree->ivalue = group->bitmask[igroup];
|
||||||
newtree->ivalue2 = iregion;
|
newtree->region = region;
|
||||||
treestack[ntreestack++] = newtree;
|
treestack[ntreestack++] = newtree;
|
||||||
|
|
||||||
// special function for file-style or atomfile-style variables
|
// special function for file-style or atomfile-style variables
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include "pointers.h"
|
#include "pointers.h"
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
class Region;
|
||||||
|
|
||||||
class Variable : protected Pointers {
|
class Variable : protected Pointers {
|
||||||
friend class Info;
|
friend class Info;
|
||||||
@ -110,14 +111,15 @@ class Variable : protected Pointers {
|
|||||||
int nvector; // length of array for vector-style variable
|
int nvector; // length of array for vector-style variable
|
||||||
int nstride; // stride between atoms if array is a 2d array
|
int nstride; // stride between atoms if array is a 2d array
|
||||||
int selfalloc; // 1 if array is allocated here, else 0
|
int selfalloc; // 1 if array is allocated here, else 0
|
||||||
int ivalue1, ivalue2; // extra values needed for gmask,rmask,grmask
|
int ivalue; // extra value needed for gmask, grmask
|
||||||
int nextra; // # of additional args beyond first 2
|
int nextra; // # of additional args beyond first 2
|
||||||
|
Region *region; // region pointer for rmask, grmask
|
||||||
Tree *first, *second; // ptrs further down tree for first 2 args
|
Tree *first, *second; // ptrs further down tree for first 2 args
|
||||||
Tree **extra; // ptrs further down tree for nextra args
|
Tree **extra; // ptrs further down tree for nextra args
|
||||||
|
|
||||||
Tree() :
|
Tree() :
|
||||||
array(nullptr), iarray(nullptr), barray(nullptr), selfalloc(0), ivalue1(0), ivalue2(0),
|
array(nullptr), iarray(nullptr), barray(nullptr), selfalloc(0), ivalue(0),
|
||||||
nextra(0), first(nullptr), second(nullptr), extra(nullptr)
|
nextra(0), region(nullptr), first(nullptr), second(nullptr), extra(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -135,7 +137,7 @@ class Variable : protected Pointers {
|
|||||||
int find_matching_paren(char *, int, char *&, int);
|
int find_matching_paren(char *, int, char *&, int);
|
||||||
int math_function(char *, char *, Tree **, Tree **, int &, double *, int &, int);
|
int math_function(char *, char *, Tree **, Tree **, int &, double *, int &, int);
|
||||||
int group_function(char *, char *, Tree **, Tree **, int &, double *, int &, int);
|
int group_function(char *, char *, Tree **, Tree **, int &, double *, int &, int);
|
||||||
int region_function(char *, int);
|
Region *region_function(char *, int);
|
||||||
int special_function(char *, char *, Tree **, Tree **, int &, double *, int &, int);
|
int special_function(char *, char *, Tree **, Tree **, int &, double *, int &, int);
|
||||||
void peratom2global(int, char *, double *, int, tagint, Tree **, Tree **, int &, double *, int &);
|
void peratom2global(int, char *, double *, int, tagint, Tree **, Tree **, int &, double *, int &);
|
||||||
int is_atom_vector(char *);
|
int is_atom_vector(char *);
|
||||||
|
|||||||
@ -151,7 +151,8 @@ TEST_F(GroupTest, RegionClear)
|
|||||||
ASSERT_EQ(group->count_all(), lmp->atom->natoms);
|
ASSERT_EQ(group->count_all(), lmp->atom->natoms);
|
||||||
|
|
||||||
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three region left xxx"););
|
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three region left xxx"););
|
||||||
TEST_FAILURE(".*ERROR: Group region ID does not exist.*", command("group four region dummy"););
|
TEST_FAILURE(".*ERROR: Group region dummy does not exist.*",
|
||||||
|
command("group four region dummy"););
|
||||||
|
|
||||||
BEGIN_HIDE_OUTPUT();
|
BEGIN_HIDE_OUTPUT();
|
||||||
command("group one clear");
|
command("group one clear");
|
||||||
@ -196,8 +197,8 @@ TEST_F(GroupTest, SelectRestart)
|
|||||||
ASSERT_EQ(group->count(group->find("four")), 32);
|
ASSERT_EQ(group->count(group->find("four")), 32);
|
||||||
ASSERT_EQ(group->count(group->find("five")), 16);
|
ASSERT_EQ(group->count(group->find("five")), 16);
|
||||||
ASSERT_EQ(group->count(group->find("six")), 8);
|
ASSERT_EQ(group->count(group->find("six")), 8);
|
||||||
ASSERT_EQ(group->count(group->find("half"), domain->find_region("top")), 8);
|
ASSERT_EQ(group->count(group->find("half"), domain->get_region_by_id("top")), 8);
|
||||||
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->find_region("top")), 8.0);
|
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->get_region_by_id("top")), 8.0);
|
||||||
|
|
||||||
BEGIN_HIDE_OUTPUT();
|
BEGIN_HIDE_OUTPUT();
|
||||||
command("write_restart group.restart");
|
command("write_restart group.restart");
|
||||||
@ -243,9 +244,9 @@ TEST_F(GroupTest, Molecular)
|
|||||||
ASSERT_EQ(group->count(group->find("two")), 16);
|
ASSERT_EQ(group->count(group->find("two")), 16);
|
||||||
ASSERT_EQ(group->count(group->find("three")), 15);
|
ASSERT_EQ(group->count(group->find("three")), 15);
|
||||||
ASSERT_DOUBLE_EQ(group->mass(group->find("half")), 40);
|
ASSERT_DOUBLE_EQ(group->mass(group->find("half")), 40);
|
||||||
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->find_region("top")), 10);
|
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->get_region_by_id("top")), 10);
|
||||||
ASSERT_NEAR(group->charge(group->find("top")), 0, 1.0e-14);
|
ASSERT_NEAR(group->charge(group->find("top")), 0, 1.0e-14);
|
||||||
ASSERT_NEAR(group->charge(group->find("right"), domain->find_region("top")), 0, 1.0e-14);
|
ASSERT_NEAR(group->charge(group->find("right"), domain->get_region_by_id("top")), 0, 1.0e-14);
|
||||||
|
|
||||||
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three include xxx"););
|
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three include xxx"););
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user