Hi,
I am trying to add some functions to library.cpp. I am wondering why in library.cpp you guys always put two dimension pointers from lammps into one dimension pointers. Like when coordinates are got from lammps in the function below, x is a two dimension like x[0][0],x[0][1],x[0][2],x[1][0],x[1][1],x[1][2],x[2][0],… But one dimension copy is used to store x by expand the two dimension pointers x. I think it should be easier to just use two dimension maybe **copy do the same job. I am not really familiar with c++/c. The command line “ lmp->memory->create(copy,countnatoms,“lib/gather:copy”);” is creating vector copy if I think it right. I also find a template **create which is able to create a 2-d array in memory.h. So why not creat a 2-d copy instead of 1-d copy? Is there any reason?
Thank you.
Below is one function in library.cpp.
/* ----------------------------------------------------------------------
gather the named atom-based entity across all processors
name = desired quantity, e.g. x or charge
type = 0 for integer values, 1 for double values
count = # of per-atom values, e.g. 1 for type or charge, 3 for x or f
return atom-based values in data, ordered by count, then by atom ID
e.g. x[0][0],x[0][1],x[0][2],x[1][0],x[1][1],x[1][2],x[2][0],…
data must be pre-allocated by caller to correct length
------------------------------------------------------------------------- */
void lammps_gather_atoms(void *ptr, char *name,
int type, int count, void *data)
{
LAMMPS *lmp = (LAMMPS *) ptr;
// error if tags are not defined or not consecutive
int flag = 0;
if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) flag = 1;
if (lmp->atom->natoms > MAXSMALLINT) flag = 1;
if (flag && lmp->comm->me == 0) {
lmp->error->warning(FLERR,“Library error in lammps_gather_atoms”);
return;
}
int natoms = static_cast (lmp->atom->natoms);
int i,j,offset;
void *vptr = lmp->atom->extract(name);
// copy = Natom length vector of per-atom values
// use atom ID to insert each atom’s values into copy
// MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID
if (type == 0) {
int *vector = NULL;
int **array = NULL;
if (count == 1) vector = (int *) vptr;
else array = (int **) vptr;
int *copy;
lmp->memory->create(copy,count*natoms,“lib/gather:copy”);
for (i = 0; i < count*natoms; i++) copy[i] = 0;
int *tag = lmp->atom->tag;
int nlocal = lmp->atom->nlocal;
if (count == 1)
for (i = 0; i < nlocal; i++)
copy[tag[i]-1] = vector[i];
else
for (i = 0; i < nlocal; i++) {
offset = count*(tag[i]-1);
for (j = 0; j < count; j++)
copy[offset++] = array[i][j];
}
MPI_Allreduce(copy,data,count*natoms,MPI_INT,MPI_SUM,lmp->world);
lmp->memory->destroy(copy);
} else {
double *vector = NULL;
double **array = NULL;
if (count == 1) vector = (double *) vptr;
else array = (double **) vptr;
double *copy;
lmp->memory->create(copy,count*natoms,“lib/gather:copy”);
for (i = 0; i < count*natoms; i++) copy[i] = 0.0;
int *tag = lmp->atom->tag;
int nlocal = lmp->atom->nlocal;
if (count == 1) {
for (i = 0; i < nlocal; i++)
copy[tag[i]-1] = vector[i];
} else {
for (i = 0; i < nlocal; i++) {
offset = count*(tag[i]-1);
for (j = 0; j < count; j++)
copy[offset++] = array[i][j];
}
}
MPI_Allreduce(copy,data,count*natoms,MPI_DOUBLE,MPI_SUM,lmp->world);
lmp->memory->destroy(copy);
}
}