complete region handling refactor

This commit is contained in:
Axel Kohlmeyer
2022-04-16 00:12:43 -04:00
parent cbb4abc55c
commit aa4787f604
39 changed files with 1504 additions and 1664 deletions

View File

@ -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);
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------

View File

@ -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

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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;

View File

@ -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;
}; };

View File

@ -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()
} }
} }
} }

View File

@ -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

View File

@ -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];
} }

View File

@ -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

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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");
} }

View File

@ -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;

View File

@ -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++;
} }

View File

@ -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

View File

@ -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++;
} }

View File

@ -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

View File

@ -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") {

View File

@ -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

View File

@ -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

View File

@ -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]);
} }

View File

@ -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;

View File

@ -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]);
} }

View File

@ -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 &region_creator = (*region_map)[estyle]; RegionCreator &region_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 &region_creator = (*region_map)[estyle]; RegionCreator &region_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 &region_creator = (*region_map)[arg[1]]; RegionCreator &region_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 &reg : 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 &reg : 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

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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 &reg : 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 &reg : 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;

View File

@ -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 &reg : 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) {

View File

@ -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)

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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

View File

@ -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 *);

View File

@ -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"););
} }