diff --git a/src/AMOEBA/pair_amoeba.cpp b/src/AMOEBA/pair_amoeba.cpp index c94faf91a7..ee7e362487 100644 --- a/src/AMOEBA/pair_amoeba.cpp +++ b/src/AMOEBA/pair_amoeba.cpp @@ -831,17 +831,21 @@ void PairAmoeba::init_style() "xyzaxis", "polaxe", "pval"}; int const flag_check[6] = {0, 0, 1, 1, 0, 1}; // correct type (0 int, 1 dbl) int const cols_check[6] = {0, 0, 0, 3, 0, 0}; // xyzaxis 3 cols, all others 0 - int const border_check[6] = {1, 0, 0, 0, 0, 0}; // which types need ghost - int flag, cols, border; + int const ghost_check[6] = {1, 0, 0, 0, 0, 0}; // which types need ghost + int flag, cols, ghost; int index[6]; for (int i = 0; i < 6; i++) { - index[i] = atom->find_custom(names[i], flag, cols, border); + if (ghost_check[i]) { + index[i] = atom->find_custom_ghost(names[i], flag, cols, ghost); + } else { + index[i] = atom->find_custom(names[i], flag, cols); + } std::string err = ""; if (index[i] < 0) err = "was not defined"; else if (flag_check[i] != flag) err = "has the wrong type"; else if (cols_check[i] != cols) err = "has the wrong number of columns"; - else if (border_check[i] && !border) err = "must be set by fix property/atom with ghost yes"; + else if (ghost_check[i] && !ghost) err = "must be set by fix property/atom with ghost yes"; if (err != "") error->all(FLERR,"Pair {} per-atom variable {} {}", mystyle, names[i], err); } diff --git a/src/atom.cpp b/src/atom.cpp index 8ac72e8950..63df04aa14 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -234,6 +234,7 @@ Atom::Atom(LAMMPS *_lmp) : Pointers(_lmp), atom_style(nullptr), avec(nullptr), a darray = nullptr; icols = dcols = nullptr; ivname = dvname = ianame = daname = nullptr; + ivghost = dvghost = iaghost = daghost = nullptr; // initialize atom style and array existence flags @@ -333,6 +334,10 @@ Atom::~Atom() memory->sfree(darray); memory->sfree(icols); memory->sfree(dcols); + memory->destroy(ivghost); + memory->destroy(dvghost); + memory->destroy(iaghost); + memory->destroy(daghost); // delete user-defined molecules @@ -2599,13 +2604,24 @@ void Atom::update_callback(int ifix) if (extra_border[i] > ifix) extra_border[i]--; } +/** \brief Find a custom per-atom property with given name +\verbatim embed:rst + +This function returns the list index of a custom per-atom property +with the name "name", also returning by reference its data type and +number of values per atom. +\endverbatim + * \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix) + * \param &flag Returns data type of property: 0 for int, 1 for double + * \param &cols Returns number of values: 0 for a single value, 1 or more for a vector of values + * \return index of property in the respective list of properties + */ /* ---------------------------------------------------------------------- find custom per-atom vector with name return index if found, -1 if not found lists of names can have NULL entries if previously removed return flag = 0/1 for int/double return cols = 0/N for vector/array where N = # of columns - return border = 0/1 if fix property/atom has "ghost" no/yes ------------------------------------------------------------------------- */ int Atom::find_custom(const char *name, int &flag, int &cols) @@ -2643,10 +2659,30 @@ int Atom::find_custom(const char *name, int &flag, int &cols) return -1; } -int Atom::find_custom(const char *name, int &flag, int &cols, int &border) +/** \brief Find a custom per-atom property with given name and retrieve ghost property +\verbatim embed:rst + +This function returns the list index of a custom per-atom property +with the name "name", also returning by reference its data type, +number of values per atom, and if it is communicated to ghost particles. +Classes rarely need to check on ghost communication and so `find_custom` +is typically preferred to this function. See :doc:`pair amoeba ` +for an example where checking ghost communication is necessary. +\endverbatim + * \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix) + * \param &flag Returns data type of property: 0 for int, 1 for double + * \param &cols Returns number of values: 0 for a single value, 1 or more for a vector of values + * \param &ghost Returns whether property is communicated to ghost atoms: 0 for no, 1 for yes + * \return index of property in the respective list of properties + */ +int Atom::find_custom_ghost(const char *name, int &flag, int &cols, int &ghost) { int i = find_custom(name, flag, cols); - if (i != -1) border = custom_border[flag + (cols) ? 2 : 0][i]; + if (i == -1) return i; + if ((flag == 0) && (cols == 0)) ghost = ivghost[i]; + else if ((flag == 1) && (cols == 0)) ghost = dvghost[i]; + else if ((flag == 0) && (cols == 1)) ghost = iaghost[i]; + else if ((flag == 1) && (cols == 1)) ghost = daghost[i]; return i; } @@ -2660,9 +2696,10 @@ This function is called, e.g. from :doc:`fix property/atom `. * \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix) * \param flag Data type of property: 0 for int, 1 for double * \param cols Number of values: 0 for a single value, 1 or more for a vector of values + * \param ghost Whether property is communicated to ghost atoms: 0 for no, 1 for yes * \return index of property in the respective list of properties */ -int Atom::add_custom(const char *name, int flag, int cols, int border) +int Atom::add_custom(const char *name, int flag, int cols, int ghost) { int index = -1; @@ -2671,6 +2708,8 @@ int Atom::add_custom(const char *name, int flag, int cols, int border) nivector++; ivname = (char **) memory->srealloc(ivname,nivector*sizeof(char *),"atom:ivname"); ivname[index] = utils::strdup(name); + ivghost = (int *) memory->srealloc(ivghost,nivector*sizeof(int),"atom:ivghost"); + ivghost[index] = ghost; ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *),"atom:ivector"); memory->create(ivector[index],nmax,"atom:ivector"); @@ -2679,6 +2718,8 @@ int Atom::add_custom(const char *name, int flag, int cols, int border) ndvector++; dvname = (char **) memory->srealloc(dvname,ndvector*sizeof(char *),"atom:dvname"); dvname[index] = utils::strdup(name); + dvghost = (int *) memory->srealloc(dvghost,ndvector*sizeof(int),"atom:dvghost"); + dvghost[index] = ghost; dvector = (double **) memory->srealloc(dvector,ndvector*sizeof(double *),"atom:dvector"); memory->create(dvector[index],nmax,"atom:dvector"); @@ -2687,6 +2728,8 @@ int Atom::add_custom(const char *name, int flag, int cols, int border) niarray++; ianame = (char **) memory->srealloc(ianame,niarray*sizeof(char *),"atom:ianame"); ianame[index] = utils::strdup(name); + iaghost = (int *) memory->srealloc(iaghost,niarray*sizeof(int),"atom:iaghost"); + iaghost[index] = ghost; iarray = (int ***) memory->srealloc(iarray,niarray*sizeof(int **),"atom:iarray"); memory->create(iarray[index],nmax,cols,"atom:iarray"); icols = (int *) memory->srealloc(icols,niarray*sizeof(int),"atom:icols"); @@ -2697,6 +2740,8 @@ int Atom::add_custom(const char *name, int flag, int cols, int border) ndarray++; daname = (char **) memory->srealloc(daname,ndarray*sizeof(char *),"atom:daname"); daname[index] = utils::strdup(name); + daghost = (int *) memory->srealloc(daghost,ndarray*sizeof(int),"atom:daghost"); + daghost[index] = ghost; darray = (double ***) memory->srealloc(darray,ndarray*sizeof(double **),"atom:darray"); memory->create(darray[index],nmax,cols,"atom:darray"); dcols = (int *) memory->srealloc(dcols,ndarray*sizeof(int),"atom:dcols"); @@ -2705,8 +2750,6 @@ int Atom::add_custom(const char *name, int flag, int cols, int border) if (index < 0) error->all(FLERR,"Invalid call to Atom::add_custom()"); - else - custom_border[flag + (cols) ? 2 : 0].push_back(border); return index; } diff --git a/src/atom.h b/src/atom.h index 6f22ebd160..b515797bb3 100644 --- a/src/atom.h +++ b/src/atom.h @@ -244,7 +244,7 @@ class Atom : protected Pointers { int *icols, *dcols; char **ivname, **dvname, **ianame, **daname; int nivector, ndvector, niarray, ndarray; - std::array, 4> custom_border; + int *ivghost, *dvghost, *iaghost, *daghost; // molecule templates // each template can be a set of consecutive molecules @@ -366,8 +366,8 @@ class Atom : protected Pointers { void update_callback(int); int find_custom(const char *, int &, int &); - int find_custom(const char *, int &, int &, int &); - virtual int add_custom(const char *, int, int, int border = 0); + int find_custom_ghost(const char *, int &, int &, int &); + virtual int add_custom(const char *, int, int, int ghost = 0); virtual void remove_custom(int, int, int); void *extract(const char *);