working with library interface

This commit is contained in:
Tom Swinburne
2020-04-14 21:11:32 +02:00
parent 276608738c
commit 6cbd61d929
9 changed files with 2491 additions and 994 deletions

View File

@ -1507,7 +1507,6 @@ void lammps_gather_peratom_fix(void *ptr, char *id, int type, int count, void *d
BEGIN_CAPTURE
{
int i,j,offset;
int ifix = lmp->modify->find_fix(id);
if (ifix < 0) {
lmp->error->warning(FLERR,"lammps_gather_peratom_fix: unknown fix id");
@ -1716,255 +1715,6 @@ void lammps_gather_peratom_fix_subset(void *ptr, char *id, int type, int count,
}
#endif
/* ----------------------------------------------------------------------
scatter the named atom-based entity in data to all atoms
data is ordered by atom ID
requirement for consecutive atom IDs (1 to N)
see scatter_atoms_subset() to scatter data for some (or all) atoms, unordered
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
use count = 3 with "image" for xyz to be packed into single image flag
data = atom-based values in 1d 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 correct length = count*Natoms, as queried by get_natoms()
method:
loop over Natoms, if I own atom ID, set its values from data
------------------------------------------------------------------------- */
#if defined(LAMMPS_BIGBIG)
void lammps_scatter_peratom_fix(void *ptr, char * /*id */, int /*type*/, int /*count*/, void * /*data*/)
{
LAMMPS *lmp = (LAMMPS *) ptr;
BEGIN_CAPTURE
{
lmp->error->all(FLERR,"Library function lammps_scatter_peratom_fix() "
"is not compatible with -DLAMMPS_BIGBIG");
}
END_CAPTURE
}
#else
void lammps_scatter_peratom_fix(void *ptr, char *id, int type, int count, void *data)
{
LAMMPS *lmp = (LAMMPS *) ptr;
BEGIN_CAPTURE
{
int i,j,m,offset;
int ifix = lmp->modify->find_fix(id);
if (ifix < 0) {
lmp->error->warning(FLERR,"lammps_scatter_peratom_fix: unknown fix id");
return;
}
// error if tags are not defined or not consecutive or no atom map
// NOTE: test that name = image or ids is not a 64-bit int in code?
int flag = 0;
if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0)
flag = 1;
if (lmp->atom->natoms > MAXSMALLINT) flag = 1;
if (lmp->atom->map_style == 0) flag = 1;
if (flag) {
if (lmp->comm->me == 0)
lmp->error->warning(FLERR,"Library error in lammps_scatter_peratom_fix");
return;
}
Fix *fix = lmp->modify->fix[ifix];
int natoms = static_cast<int> (lmp->atom->natoms);
if (type == 0) {
int *vector = NULL;
int **array = NULL;
if (count == 1) vector = (int *) fix->vector_atom;
else array = (int **) fix->array_atom;
int *dptr = (int *) data;
if (count == 1) {
for (i = 0; i < natoms; i++)
if ((m = lmp->atom->map(i+1)) >= 0)
vector[m] = dptr[i];
} else {
for (i = 0; i < natoms; i++)
if ((m = lmp->atom->map(i+1)) >= 0) {
offset = count*i;
for (j = 0; j < count; j++)
array[m][j] = dptr[offset++];
}
}
} else {
double *vector = NULL;
double **array = NULL;
if (count == 1) vector = (double *) fix->vector_atom;
else array = (double **) fix->array_atom;
double *dptr = (double *) data;
if (count == 1) {
for (i = 0; i < natoms; i++)
if ((m = lmp->atom->map(i+1)) >= 0)
vector[m] = dptr[i];
} else {
for (i = 0; i < natoms; i++) {
if ((m = lmp->atom->map(i+1)) >= 0) {
offset = count*i;
for (j = 0; j < count; j++)
array[m][j] = dptr[offset++];
}
}
}
}
}
END_CAPTURE
}
#endif
/* ----------------------------------------------------------------------
scatter the named atom-based entity in data to a subset of atoms
data is ordered by provided atom IDs
no requirement for consecutive atom IDs (1 to N)
see scatter_atoms() to scatter data for all atoms, ordered by consecutive IDs
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
use count = 3 with "image" for xyz to be packed into single image flag
ndata = # of atoms in ids and data (could be all atoms)
ids = list of Ndata atom IDs to scatter data to
data = atom-based values in 1d 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 correct length = count*Ndata
method:
loop over Ndata, if I own atom ID, set its values from data
------------------------------------------------------------------------- */
#if defined(LAMMPS_BIGBIG)
void lammps_scatter_peratom_fix_subset(void *ptr, char * /*name */,
int /*type*/, int /*count*/,
int /*ndata*/, int * /*ids*/, void * /*data*/)
{
LAMMPS *lmp = (LAMMPS *) ptr;
BEGIN_CAPTURE
{
lmp->error->all(FLERR,"Library function lammps_scatter_atoms_subset() "
"is not compatible with -DLAMMPS_BIGBIG");
}
END_CAPTURE
}
#else
void lammps_scatter_peratom_fix_subset(void *ptr, char *name,
int type, int count,
int ndata, int *ids, void *data)
{
LAMMPS *lmp = (LAMMPS *) ptr;
BEGIN_CAPTURE
{
int i,j,m,offset;
tagint id;
// error if tags are not defined or no atom map
// NOTE: test that name = image or ids is not a 64-bit int in code?
int flag = 0;
if (lmp->atom->tag_enable == 0) flag = 1;
if (lmp->atom->natoms > MAXSMALLINT) flag = 1;
if (lmp->atom->map_style == 0) flag = 1;
if (flag) {
if (lmp->comm->me == 0)
lmp->error->warning(FLERR,"Library error in lammps_scatter_atoms_subset");
return;
}
void *vptr = lmp->atom->extract(name);
if(vptr == NULL) {
lmp->error->warning(FLERR,
"lammps_scatter_atoms_subset: unknown property name");
return;
}
// 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;
const int imgpack = (count == 3) && (strcmp(name,"image") == 0);
if ((count == 1) || imgpack) vector = (int *) vptr;
else array = (int **) vptr;
int *dptr = (int *) data;
if (count == 1) {
for (i = 0; i < ndata; i++) {
id = ids[i];
if ((m = lmp->atom->map(id)) >= 0)
vector[m] = dptr[i];
}
} else if (imgpack) {
for (i = 0; i < ndata; i++) {
id = ids[i];
if ((m = lmp->atom->map(id)) >= 0) {
offset = count*i;
int image = dptr[offset++] + IMGMAX;
image += (dptr[offset++] + IMGMAX) << IMGBITS;
image += (dptr[offset++] + IMGMAX) << IMG2BITS;
vector[m] = image;
}
}
} else {
for (i = 0; i < ndata; i++) {
id = ids[i];
if ((m = lmp->atom->map(id)) >= 0) {
offset = count*i;
for (j = 0; j < count; j++)
array[m][j] = dptr[offset++];
}
}
}
} else {
double *vector = NULL;
double **array = NULL;
if (count == 1) vector = (double *) vptr;
else array = (double **) vptr;
double *dptr = (double *) data;
if (count == 1) {
for (i = 0; i < ndata; i++) {
id = ids[i];
if ((m = lmp->atom->map(id)) >= 0)
vector[m] = dptr[i];
}
} else {
for (i = 0; i < ndata; i++) {
id = ids[i];
if ((m = lmp->atom->map(id)) >= 0) {
offset = count*i;
for (j = 0; j < count; j++)
array[m][j] = dptr[offset++];
}
}
}
}
}
END_CAPTURE
}
#endif
/* ----------------------------------------------------------------------
create N atoms and assign them to procs based on coords
id = atom IDs (optional, NULL will generate 1 to N)