"stringify" and "vectorize" processing of per-atom attributs in AtomVec classes

This commit is contained in:
Axel Kohlmeyer
2022-04-14 11:06:10 -04:00
parent 1755d06870
commit b16d48aa41
37 changed files with 1596 additions and 1832 deletions

View File

@ -1,4 +1,3 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
@ -19,12 +18,12 @@
#include "error.h"
#include "tokenizer.h"
#include <algorithm>
#include <cstring>
using namespace LAMMPS_NS;
#define NFIELDSTRINGS 12 // # of field strings
enum{ELLIPSOID,LINE,TRIANGLE,BODY}; // also in WriteData
enum { ELLIPSOID, LINE, TRIANGLE, BODY }; // also in WriteData
/* ---------------------------------------------------------------------- */
@ -33,22 +32,16 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp) : AtomVec(lmp)
nstyles = 0;
styles = nullptr;
keywords = nullptr;
fieldstrings = nullptr;
bonus_flag = 0;
nstyles_bonus = 0;
styles_bonus = nullptr;
// these strings will be concatenated from sub-style strings
// field strings will be concatenated from sub-style strings
// fields_data_atom & fields_data_vel start with fields common to all styles
fields_grow = fields_copy = fields_comm = fields_comm_vel = (char *) "";
fields_reverse = fields_border = fields_border_vel = (char *) "";
fields_exchange = fields_restart = fields_create = (char *) "";
fields_data_atom = (char *) "id type x";
fields_data_vel = (char *) "id v";
fields_allocated = 0;
fields_data_atom = {"id", "type", "x"};
fields_data_vel = {"id", "v"};
}
/* ---------------------------------------------------------------------- */
@ -56,28 +49,10 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp) : AtomVec(lmp)
AtomVecHybrid::~AtomVecHybrid()
{
for (int k = 0; k < nstyles; k++) delete styles[k];
delete [] styles;
for (int k = 0; k < nstyles; k++) delete [] keywords[k];
delete [] keywords;
delete [] styles_bonus;
if (!fields_allocated) return;
delete [] fields_grow;
delete [] fields_copy;
delete [] fields_comm;
delete [] fields_comm_vel;
delete [] fields_reverse;
delete [] fields_border;
delete [] fields_border_vel;
delete [] fields_exchange;
delete [] fields_restart;
delete [] fields_create;
delete [] fields_data_atom;
delete [] fields_data_vel;
for (int k = 0; k < nstyles; k++) delete [] fieldstrings[k].fstr;
delete [] fieldstrings;
delete[] styles;
for (int k = 0; k < nstyles; k++) delete[] keywords[k];
delete[] keywords;
delete[] styles_bonus;
}
/* ----------------------------------------------------------------------
@ -92,28 +67,27 @@ void AtomVecHybrid::process_args(int narg, char **arg)
// allocate list of sub-styles as big as possibly needed if no extra args
styles = new AtomVec*[narg];
keywords = new char*[narg];
styles = new AtomVec *[narg];
keywords = new char *[narg];
// allocate each sub-style
// call process_args() with set of args that are not atom style names
// use known_style() to determine which args these are
int i,k,jarg,dummy;
int dummy;
int iarg = 0;
nstyles = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"hybrid") == 0)
error->all(FLERR,"Atom style hybrid cannot have hybrid as an argument");
for (i = 0; i < nstyles; i++)
if (strcmp(arg[iarg],keywords[i]) == 0)
error->all(FLERR,"Atom style hybrid cannot use same atom style twice");
styles[nstyles] = atom->new_avec(arg[iarg],1,dummy);
if (strcmp(arg[iarg], "hybrid") == 0)
error->all(FLERR, "Atom style hybrid cannot have hybrid as an argument");
for (int i = 0; i < nstyles; i++)
if (strcmp(arg[iarg], keywords[i]) == 0)
error->all(FLERR, "Atom style hybrid cannot use same atom style twice");
styles[nstyles] = atom->new_avec(arg[iarg], 1, dummy);
keywords[nstyles] = utils::strdup(arg[iarg]);
jarg = iarg + 1;
int jarg = iarg + 1;
while (jarg < narg && !known_style(arg[jarg])) jarg++;
styles[nstyles]->process_args(jarg-iarg-1,&arg[iarg+1]);
styles[nstyles]->process_args(jarg - iarg - 1, &arg[iarg + 1]);
iarg = jarg;
nstyles++;
}
@ -124,20 +98,19 @@ void AtomVecHybrid::process_args(int narg, char **arg)
molecular = Atom::ATOMIC;
maxexchange = 0;
for (k = 0; k < nstyles; k++) {
for (int k = 0; k < nstyles; k++) {
if ((styles[k]->molecular == Atom::MOLECULAR && molecular == Atom::TEMPLATE) ||
(styles[k]->molecular == Atom::TEMPLATE && molecular == Atom::MOLECULAR))
error->all(FLERR,
"Cannot mix molecular and molecule template atom styles");
molecular = MAX(molecular,styles[k]->molecular);
error->all(FLERR, "Cannot mix molecular and molecule template atom styles");
molecular = MAX(molecular, styles[k]->molecular);
bonds_allow = MAX(bonds_allow,styles[k]->bonds_allow);
angles_allow = MAX(angles_allow,styles[k]->angles_allow);
dihedrals_allow = MAX(dihedrals_allow,styles[k]->dihedrals_allow);
impropers_allow = MAX(impropers_allow,styles[k]->impropers_allow);
mass_type = MAX(mass_type,styles[k]->mass_type);
dipole_type = MAX(dipole_type,styles[k]->dipole_type);
forceclearflag = MAX(forceclearflag,styles[k]->forceclearflag);
bonds_allow = MAX(bonds_allow, styles[k]->bonds_allow);
angles_allow = MAX(angles_allow, styles[k]->angles_allow);
dihedrals_allow = MAX(dihedrals_allow, styles[k]->dihedrals_allow);
impropers_allow = MAX(impropers_allow, styles[k]->impropers_allow);
mass_type = MAX(mass_type, styles[k]->mass_type);
dipole_type = MAX(dipole_type, styles[k]->dipole_type);
forceclearflag = MAX(forceclearflag, styles[k]->forceclearflag);
maxexchange += styles[k]->maxexchange;
if (styles[k]->molecular == Atom::TEMPLATE) onemols = styles[k]->onemols;
@ -148,95 +121,71 @@ void AtomVecHybrid::process_args(int narg, char **arg)
int mass_pertype = 0;
int mass_peratom = 0;
for (k = 0; k < nstyles; k++) {
for (int k = 0; k < nstyles; k++) {
if (styles[k]->mass_type == 0) mass_peratom = 1;
if (styles[k]->mass_type == 1) mass_pertype = 1;
}
if (mass_pertype && mass_peratom && comm->me == 0)
error->warning(FLERR, "Atom style hybrid defines both, per-type "
error->warning(FLERR,
"Atom style hybrid defines both, per-type "
"and per-atom masses; both must be set, but only "
"per-atom masses will be used");
// free allstyles created by build_styles()
for (i = 0; i < nallstyles; i++) delete [] allstyles[i];
delete [] allstyles;
// set field strings from all substyles
fieldstrings = new FieldStrings[nstyles];
for (k = 0; k < nstyles; k++) {
fieldstrings[k].fstr = new char*[NFIELDSTRINGS];
fieldstrings[k].fstr[0] = styles[k]->fields_grow;
fieldstrings[k].fstr[1] = styles[k]->fields_copy;
fieldstrings[k].fstr[2] = styles[k]->fields_comm;
fieldstrings[k].fstr[3] = styles[k]->fields_comm_vel;
fieldstrings[k].fstr[4] = styles[k]->fields_reverse;
fieldstrings[k].fstr[5] = styles[k]->fields_border;
fieldstrings[k].fstr[6] = styles[k]->fields_border_vel;
fieldstrings[k].fstr[7] = styles[k]->fields_exchange;
fieldstrings[k].fstr[8] = styles[k]->fields_restart;
fieldstrings[k].fstr[9] = styles[k]->fields_create;
fieldstrings[k].fstr[10] = styles[k]->fields_data_atom;
fieldstrings[k].fstr[11] = styles[k]->fields_data_vel;
}
for (int i = 0; i < nallstyles; i++) delete[] allstyles[i];
delete[] allstyles;
// merge field strings from all sub-styles
// save concat_grow to check for duplicates of special-case fields
char *concat_grow;;
char *dummyptr = nullptr;
std::vector<std::string> concat_grow;
std::vector<std::string> concat_dummy;
fields_grow = merge_fields(0,fields_grow,1,concat_grow);
fields_copy = merge_fields(1,fields_copy,0,dummyptr);
fields_comm = merge_fields(2,fields_comm,0,dummyptr);
fields_comm_vel = merge_fields(3,fields_comm_vel,0,dummyptr);
fields_reverse = merge_fields(4,fields_reverse,0,dummyptr);
fields_border = merge_fields(5,fields_border,0,dummyptr);
fields_border_vel = merge_fields(6,fields_border_vel,0,dummyptr);
fields_exchange = merge_fields(7,fields_exchange,0,dummyptr);
fields_restart = merge_fields(8,fields_restart,0,dummyptr);
fields_create = merge_fields(9,fields_create,0,dummyptr);
fields_data_atom = merge_fields(10,fields_data_atom,0,dummyptr);
fields_data_vel = merge_fields(11,fields_data_vel,0,dummyptr);
fields_allocated = 1;
for (int k = 0; k < nstyles; k++) {
merge_fields(fields_grow, styles[k]->fields_grow, 1, concat_grow);
merge_fields(fields_copy, styles[k]->fields_copy, 0, concat_dummy);
merge_fields(fields_comm, styles[k]->fields_comm, 0, concat_dummy);
merge_fields(fields_comm_vel, styles[k]->fields_comm_vel, 0, concat_dummy);
merge_fields(fields_reverse, styles[k]->fields_reverse, 0, concat_dummy);
merge_fields(fields_border, styles[k]->fields_border, 0, concat_dummy);
merge_fields(fields_border_vel, styles[k]->fields_border_vel, 0, concat_dummy);
merge_fields(fields_exchange, styles[k]->fields_exchange, 0, concat_dummy);
merge_fields(fields_restart, styles[k]->fields_restart, 0, concat_dummy);
merge_fields(fields_create, styles[k]->fields_create, 0, concat_dummy);
merge_fields(fields_data_atom, styles[k]->fields_data_atom, 0, concat_dummy);
merge_fields(fields_data_vel, styles[k]->fields_data_vel, 0, concat_dummy);
}
// check concat_grow for multiple special-case fields
// may cause issues with style-specific create_atom() and data_atom() methods
// issue warnings if appear in multiple sub-styles
const char *dupfield[] = {"radius","rmass"};
int ndupfield = 2;
char *ptr;
std::vector<std::string> dupfield = {"radius", "rmass"};
for (int idup = 0; idup < ndupfield; idup++) {
auto dup = (char *) dupfield[idup];
ptr = strstr(concat_grow,dup);
if ((ptr && strstr(ptr+1,dup)) && (comm->me == 0))
error->warning(FLERR,fmt::format("Per-atom {} is used in multiple sub-"
"styles; must be used consistently",dup));
for (const auto &idup : dupfield) {
if ((comm->me == 0) && (std::count(concat_grow.begin(), concat_grow.end(), idup) > 1))
error->warning(FLERR,
"Per-atom field {} is used in multiple sub-styles; must be used consistently",
idup);
}
delete [] concat_grow;
// set bonus_flag if any substyle has bonus data
// set nstyles_bonus & styles_bonus
// sum two sizes over contributions from each substyle with bonus data.
nstyles_bonus = 0;
for (k = 0; k < nstyles; k++)
for (int k = 0; k < nstyles; k++)
if (styles[k]->bonus_flag) nstyles_bonus++;
if (nstyles_bonus) {
bonus_flag = 1;
styles_bonus = new AtomVec*[nstyles_bonus];
styles_bonus = new AtomVec *[nstyles_bonus];
nstyles_bonus = 0;
size_forward_bonus = 0;
size_border_bonus = 0;
for (k = 0; k < nstyles; k++) {
for (int k = 0; k < nstyles; k++) {
if (styles[k]->bonus_flag) {
styles_bonus[nstyles_bonus++] = styles[k];
size_forward_bonus += styles[k]->size_forward_bonus;
@ -270,23 +219,21 @@ void AtomVecHybrid::grow_pointers()
void AtomVecHybrid::force_clear(int n, size_t nbytes)
{
for (int k = 0; k < nstyles; k++)
if (styles[k]->forceclearflag) styles[k]->force_clear(n,nbytes);
if (styles[k]->forceclearflag) styles[k]->force_clear(n, nbytes);
}
/* ---------------------------------------------------------------------- */
void AtomVecHybrid::copy_bonus(int i, int j, int delflag)
{
for (int k = 0; k < nstyles_bonus; k++)
styles_bonus[k]->copy_bonus(i,j,delflag);
for (int k = 0; k < nstyles_bonus; k++) styles_bonus[k]->copy_bonus(i, j, delflag);
}
/* ---------------------------------------------------------------------- */
void AtomVecHybrid::clear_bonus()
{
for (int k = 0; k < nstyles_bonus; k++)
styles_bonus[k]->clear_bonus();
for (int k = 0; k < nstyles_bonus; k++) styles_bonus[k]->clear_bonus();
}
/* ---------------------------------------------------------------------- */
@ -294,8 +241,7 @@ void AtomVecHybrid::clear_bonus()
int AtomVecHybrid::pack_comm_bonus(int n, int *list, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->pack_comm_bonus(n,list,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->pack_comm_bonus(n, list, buf);
return m;
}
@ -303,8 +249,7 @@ int AtomVecHybrid::pack_comm_bonus(int n, int *list, double *buf)
void AtomVecHybrid::unpack_comm_bonus(int n, int first, double *buf)
{
for (int k = 0; k < nstyles_bonus; k++)
styles_bonus[k]->unpack_comm_bonus(n,first,buf);
for (int k = 0; k < nstyles_bonus; k++) styles_bonus[k]->unpack_comm_bonus(n, first, buf);
}
/* ---------------------------------------------------------------------- */
@ -312,8 +257,7 @@ void AtomVecHybrid::unpack_comm_bonus(int n, int first, double *buf)
int AtomVecHybrid::pack_border_bonus(int n, int *list, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->pack_border_bonus(n,list,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->pack_border_bonus(n, list, buf);
return m;
}
@ -322,8 +266,7 @@ int AtomVecHybrid::pack_border_bonus(int n, int *list, double *buf)
int AtomVecHybrid::unpack_border_bonus(int n, int first, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->unpack_border_bonus(n,first,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->unpack_border_bonus(n, first, buf);
return m;
}
@ -332,8 +275,7 @@ int AtomVecHybrid::unpack_border_bonus(int n, int first, double *buf)
int AtomVecHybrid::pack_exchange_bonus(int i, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->pack_exchange_bonus(i,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->pack_exchange_bonus(i, buf);
return m;
}
@ -342,8 +284,7 @@ int AtomVecHybrid::pack_exchange_bonus(int i, double *buf)
int AtomVecHybrid::unpack_exchange_bonus(int ilocal, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->unpack_exchange_bonus(ilocal,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->unpack_exchange_bonus(ilocal, buf);
return m;
}
@ -352,8 +293,7 @@ int AtomVecHybrid::unpack_exchange_bonus(int ilocal, double *buf)
int AtomVecHybrid::size_restart_bonus()
{
int n = 0;
for (int k = 0; k < nstyles_bonus; k++)
n += styles_bonus[k]->size_restart_bonus();
for (int k = 0; k < nstyles_bonus; k++) n += styles_bonus[k]->size_restart_bonus();
return n;
}
@ -362,8 +302,7 @@ int AtomVecHybrid::size_restart_bonus()
int AtomVecHybrid::pack_restart_bonus(int i, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->pack_restart_bonus(i,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->pack_restart_bonus(i, buf);
return m;
}
@ -372,8 +311,7 @@ int AtomVecHybrid::pack_restart_bonus(int i, double *buf)
int AtomVecHybrid::unpack_restart_bonus(int ilocal, double *buf)
{
int m = 0;
for (int k = 0; k < nstyles_bonus; k++)
m += styles_bonus[k]->unpack_restart_bonus(ilocal,buf);
for (int k = 0; k < nstyles_bonus; k++) m += styles_bonus[k]->unpack_restart_bonus(ilocal, buf);
return m;
}
@ -382,8 +320,7 @@ int AtomVecHybrid::unpack_restart_bonus(int ilocal, double *buf)
double AtomVecHybrid::memory_usage_bonus()
{
double bytes = 0;
for (int k = 0; k < nstyles_bonus; k++)
bytes += styles_bonus[k]->memory_usage_bonus();
for (int k = 0; k < nstyles_bonus; k++) bytes += styles_bonus[k]->memory_usage_bonus();
return bytes;
}
@ -393,8 +330,7 @@ double AtomVecHybrid::memory_usage_bonus()
void AtomVecHybrid::pack_restart_pre(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->pack_restart_pre(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->pack_restart_pre(ilocal);
}
/* ----------------------------------------------------------------------
@ -403,8 +339,7 @@ void AtomVecHybrid::pack_restart_pre(int ilocal)
void AtomVecHybrid::pack_restart_post(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->pack_restart_post(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->pack_restart_post(ilocal);
}
/* ----------------------------------------------------------------------
@ -413,8 +348,7 @@ void AtomVecHybrid::pack_restart_post(int ilocal)
void AtomVecHybrid::unpack_restart_init(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->unpack_restart_init(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->unpack_restart_init(ilocal);
}
/* ----------------------------------------------------------------------
@ -423,8 +357,7 @@ void AtomVecHybrid::unpack_restart_init(int ilocal)
void AtomVecHybrid::create_atom_post(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->create_atom_post(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->create_atom_post(ilocal);
}
/* ----------------------------------------------------------------------
@ -434,16 +367,15 @@ void AtomVecHybrid::create_atom_post(int ilocal)
void AtomVecHybrid::data_atom_post(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->data_atom_post(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->data_atom_post(ilocal);
}
/* ----------------------------------------------------------------------
modify what AtomVec::data_bonds() just unpacked
or initialize other bond quantities
------------------------------------------------------------------------- */
void AtomVecHybrid::data_bonds_post(int m, int num_bond, tagint atom1,
tagint atom2, tagint id_offset)
void AtomVecHybrid::data_bonds_post(int m, int num_bond, tagint atom1, tagint atom2,
tagint id_offset)
{
for (int k = 0; k < nstyles; k++)
styles[k]->data_bonds_post(m, num_bond, atom1, atom2, id_offset);
@ -455,8 +387,7 @@ void AtomVecHybrid::data_bonds_post(int m, int num_bond, tagint atom1,
void AtomVecHybrid::pack_data_pre(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->pack_data_pre(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->pack_data_pre(ilocal);
}
/* ----------------------------------------------------------------------
@ -465,8 +396,7 @@ void AtomVecHybrid::pack_data_pre(int ilocal)
void AtomVecHybrid::pack_data_post(int ilocal)
{
for (int k = 0; k < nstyles; k++)
styles[k]->pack_data_post(ilocal);
for (int k = 0; k < nstyles; k++) styles[k]->pack_data_post(ilocal);
}
/* ----------------------------------------------------------------------
@ -476,12 +406,12 @@ void AtomVecHybrid::pack_data_post(int ilocal)
int AtomVecHybrid::pack_data_bonus(double *buf, int flag)
{
for (int k = 0; k < nstyles; k++) {
if (flag == ELLIPSOID && strcmp(keywords[k],"ellipsoid") != 0) continue;
if (flag == LINE && strcmp(keywords[k],"line") != 0) continue;
if (flag == TRIANGLE && strcmp(keywords[k],"tri") != 0) continue;
if (flag == BODY && strcmp(keywords[k],"body") != 0) continue;
if (flag == ELLIPSOID && strcmp(keywords[k], "ellipsoid") != 0) continue;
if (flag == LINE && strcmp(keywords[k], "line") != 0) continue;
if (flag == TRIANGLE && strcmp(keywords[k], "tri") != 0) continue;
if (flag == BODY && strcmp(keywords[k], "body") != 0) continue;
return styles[k]->pack_data_bonus(buf,flag);
return styles[k]->pack_data_bonus(buf, flag);
}
return 0;
}
@ -493,12 +423,12 @@ int AtomVecHybrid::pack_data_bonus(double *buf, int flag)
void AtomVecHybrid::write_data_bonus(FILE *fp, int n, double *buf, int flag)
{
for (int k = 0; k < nstyles; k++) {
if (flag == ELLIPSOID && strcmp(keywords[k],"ellipsoid") != 0) continue;
if (flag == LINE && strcmp(keywords[k],"line") != 0) continue;
if (flag == TRIANGLE && strcmp(keywords[k],"tri") != 0) continue;
if (flag == BODY && strcmp(keywords[k],"body") != 0) continue;
if (flag == ELLIPSOID && strcmp(keywords[k], "ellipsoid") != 0) continue;
if (flag == LINE && strcmp(keywords[k], "line") != 0) continue;
if (flag == TRIANGLE && strcmp(keywords[k], "tri") != 0) continue;
if (flag == BODY && strcmp(keywords[k], "body") != 0) continue;
styles[k]->write_data_bonus(fp,n,buf,flag);
styles[k]->write_data_bonus(fp, n, buf, flag);
}
}
@ -508,11 +438,11 @@ void AtomVecHybrid::write_data_bonus(FILE *fp, int n, double *buf, int flag)
return -1 if name is unknown to any sub-styles
------------------------------------------------------------------------- */
int AtomVecHybrid::property_atom(char *name)
int AtomVecHybrid::property_atom(const std::string &name)
{
for (int k = 0; k < nstyles; k++) {
int index = styles[k]->property_atom(name);
if (index >= 0) return index*nstyles + k;
if (index >= 0) return index * nstyles + k;
}
return -1;
}
@ -522,12 +452,11 @@ int AtomVecHybrid::property_atom(char *name)
index maps to data specific to this atom style
------------------------------------------------------------------------- */
void AtomVecHybrid::pack_property_atom(int multiindex, double *buf,
int nvalues, int groupbit)
void AtomVecHybrid::pack_property_atom(int multiindex, double *buf, int nvalues, int groupbit)
{
int k = multiindex % nstyles;
int index = multiindex/nstyles;
styles[k]->pack_property_atom(index,buf,nvalues,groupbit);
int index = multiindex / nstyles;
styles[k]->pack_property_atom(index, buf, nvalues, groupbit);
}
// ----------------------------------------------------------------------
@ -535,48 +464,21 @@ void AtomVecHybrid::pack_property_atom(int multiindex, double *buf,
// ----------------------------------------------------------------------
/* ----------------------------------------------------------------------
merge fields and remove duplicate fields
concat = root + Inum fields string from all substyles
return dedup = concat with duplicate fields removed
merge fields into root vector and remove duplicate fields
if concat_flag set, also return concat (w/ duplicates)
so caller can check for problematic fields, call will free it
so caller can check for problematic fields
------------------------------------------------------------------------- */
char *AtomVecHybrid::merge_fields(int inum, char *root,
int concat_flag, char *&concat_str)
void AtomVecHybrid::merge_fields(std::vector<std::string> &root,
const std::vector<std::string> &fields, int concat_flag,
std::vector<std::string> &concat)
{
// create vector with all words combined
// grow vector with all words combined with dedup and
std::string concat;
if (root) concat += root;
for (int k = 0; k < nstyles; k++) {
if (concat.size() > 0) concat += " ";
concat += fieldstrings[k].fstr[inum];
for (const auto &field : fields) {
if (concat_flag) concat.push_back(field);
if (std::find(root.begin(), root.end(), field) == root.end()) root.push_back(field);
}
if (concat_flag) concat_str = utils::strdup(concat);
// remove duplicate words without changing the order
auto words = Tokenizer(concat, " ").as_vector();
std::vector<std::string> dedup;
for (auto &w : words) {
bool found = false;
for (auto &d : dedup) {
if (w == d) found = true;
}
if (!found) dedup.push_back(w);
}
// create final concatenated, deduped string
concat.clear();
for (auto &d : dedup) {
concat += d;
concat += " ";
}
// remove trailing blank
if (concat.size() > 0) concat.pop_back();
return utils::strdup(concat);
}
/* ----------------------------------------------------------------------
@ -587,19 +489,19 @@ void AtomVecHybrid::build_styles()
{
nallstyles = 0;
#define ATOM_CLASS
#define AtomStyle(key,Class) nallstyles++;
#include "style_atom.h" // IWYU pragma: keep
#define AtomStyle(key, Class) nallstyles++;
#include "style_atom.h" // IWYU pragma: keep
#undef AtomStyle
#undef ATOM_CLASS
allstyles = new char*[nallstyles];
allstyles = new char *[nallstyles];
nallstyles = 0;
#define ATOM_CLASS
#define AtomStyle(key,Class) \
#define AtomStyle(key, Class) \
allstyles[nallstyles] = utils::strdup(#key); \
nallstyles++;
#include "style_atom.h" // IWYU pragma: keep
#include "style_atom.h" // IWYU pragma: keep
#undef AtomStyle
#undef ATOM_CLASS
}
@ -611,6 +513,6 @@ void AtomVecHybrid::build_styles()
int AtomVecHybrid::known_style(char *str)
{
for (int i = 0; i < nallstyles; i++)
if (strcmp(str,allstyles[i]) == 0) return 1;
if (strcmp(str, allstyles[i]) == 0) return 1;
return 0;
}