support for reset_box and create_atom commands

This commit is contained in:
Steve Plimpton
2021-09-09 17:16:33 -06:00
parent 6193ebaba7
commit 1e26fe2d6f
2 changed files with 165 additions and 85 deletions

View File

@ -52,6 +52,10 @@ enum{DEFAULT,MD,OPT}; // top-level MDI engine mode
enum{TYPE,CHARGE,MASS,COORD,VELOCITY,FORCE};
// stages of CREATE_ATOM commands
enum{CREATE_ATOM,CREATE_ID,CREATE_TYPE,CREATE_X,CREATE_V,CREATE_IMAGE,CREATE_GO};
/* ----------------------------------------------------------------------
mdi command: engine
NOTE: may later have other MDI command variants?
@ -164,6 +168,9 @@ void MDIEngine2::mdi_engine(int narg, char **arg)
ibuf1 = ibuf1all = nullptr;
maxbuf = 0;
nbytes = -1;
create_atoms_flag = 0;
// define MDI commands that LAMMPS engine recognizes
mdi_commands();
@ -442,8 +449,8 @@ int MDIEngine2::execute_command(const char *command, MDI_Comm mdicomm)
// custom LAMMPS commands
// -------------------------------------------------------
} else if (strcmp(command, "LENGTH") == 0) {
length_command();
} else if (strcmp(command, "NBYTES") == 0) {
nbytes_command();
} else if (strcmp(command, "COMMAND") == 0) {
single_command();
} else if (strcmp(command, "COMMANDS") == 0) {
@ -455,7 +462,19 @@ int MDIEngine2::execute_command(const char *command, MDI_Comm mdicomm)
} else if (strcmp(command, "RESET_BOX") == 0) {
reset_box();
} else if (strcmp(command, "CREATE_ATOM") == 0) {
create_atoms();
create_atoms(CREATE_ATOM);
} else if (strcmp(command, "CREATE_ID") == 0) {
create_atoms(CREATE_ID);
} else if (strcmp(command, "CREATE_TYPE") == 0) {
create_atoms(CREATE_TYPE);
} else if (strcmp(command, "CREATE_X") == 0) {
create_atoms(CREATE_X);
} else if (strcmp(command, "CREATE_V") == 0) {
create_atoms(CREATE_V);
} else if (strcmp(command, "CREATE_IMG") == 0) {
create_atoms(CREATE_IMAGE);
} else if (strcmp(command, "CREATE_GO") == 0) {
create_atoms(CREATE_GO);
} else if (strcmp(command, "<PRESSURE") == 0) {
send_pressure();
} else if (strcmp(command, "<PTENSOR") == 0) {
@ -618,13 +637,19 @@ void MDIEngine2::mdi_commands()
// max length for a command is current 11 chars in MDI
// ------------------------------------
MDI_Register_command("@DEFAULT", "LENGTH");
MDI_Register_command("@DEFAULT", "NBYTES");
MDI_Register_command("@DEFAULT", "COMMAND");
MDI_Register_command("@DEFAULT", "COMMANDS");
MDI_Register_command("@DEFAULT", "INFILE");
MDI_Register_command("@DEFAULT", "EVAL");
MDI_Register_command("@DEFAULT", "RESET_BOX");
MDI_Register_command("@DEFAULT", "CREATE_ATOM");
MDI_Register_command("@DEFAULT", "CREATE_ID");
MDI_Register_command("@DEFAULT", "CREATE_TYPE");
MDI_Register_command("@DEFAULT", "CREATE_X");
MDI_Register_command("@DEFAULT", "CREATE_V");
MDI_Register_command("@DEFAULT", "CREATE_IMG");
MDI_Register_command("@DEFAULT", "CREATE_GO");
MDI_Register_command("@DEFAULT", "<KE");
MDI_Register_command("@DEFAULT", "<PE");
MDI_Register_command("@DEFAULT", "<PRESSURE");
@ -1211,31 +1236,33 @@ void MDIEngine2::receive_celldispl()
// ----------------------------------------------------------------------
/* ----------------------------------------------------------------------
LENGTH command
store received value in length_param
NBYTES command
store received value in nbytes
for use by a subsequent command, e.g. ones that send strings
---------------------------------------------------------------------- */
void MDIEngine2::length_command()
void MDIEngine2::nbytes_command()
{
int ierr = MDI_Recv(&length_param,1,MDI_INT,mdicomm);
if (ierr) error->all(FLERR,"MDI: LENGTH data");
MPI_Bcast(&length_param,1,MPI_INT,0,world);
int ierr = MDI_Recv(&nbytes,1,MDI_INT,mdicomm);
if (ierr) error->all(FLERR,"MDI: NBYTES data");
MPI_Bcast(&nbytes,1,MPI_INT,0,world);
}
/* ----------------------------------------------------------------------
COMMAND command
store received value as string of length length_param
store received value as string of length nbytes
invoke as a LAMMPS command
---------------------------------------------------------------------- */
void MDIEngine2::single_command()
{
char *cmd = new char[length_param+1];
int ierr = MDI_Recv(cmd,length_param+1,MDI_CHAR,mdicomm);
if (nbytes < 0) error->all(FLERR,"MDI: COMMAND nbytes has not been set");
char *cmd = new char[nbytes+1];
int ierr = MDI_Recv(cmd,nbytes+1,MDI_CHAR,mdicomm);
if (ierr) error->all(FLERR,"MDI: COMMAND data");
MPI_Bcast(cmd,length_param+1,MPI_CHAR,0,world);
cmd[length_param+1] = '\0';
MPI_Bcast(cmd,nbytes+1,MPI_CHAR,0,world);
cmd[nbytes+1] = '\0';
lammps_command(lmp,cmd);
@ -1244,17 +1271,19 @@ void MDIEngine2::single_command()
/* ----------------------------------------------------------------------
COMMANDS command
store received value as multi-line string of length length_param
store received value as multi-line string of length nbytes
invoke as multiple LAMMPS commands
---------------------------------------------------------------------- */
void MDIEngine2::many_commands()
{
char *cmds = new char[length_param+1];
int ierr = MDI_Recv(cmds, length_param+1, MDI_CHAR, mdicomm);
if (nbytes < 0) error->all(FLERR,"MDI: COMMANDS nbytes has not been set");
char *cmds = new char[nbytes+1];
int ierr = MDI_Recv(cmds, nbytes+1, MDI_CHAR, mdicomm);
if (ierr) error->all(FLERR,"MDI: COMMANDS data");
MPI_Bcast(cmds,length_param+1,MPI_CHAR,0,world);
cmds[length_param+1] = '\0';
MPI_Bcast(cmds,nbytes+1,MPI_CHAR,0,world);
cmds[nbytes+1] = '\0';
lammps_commands_string(lmp,cmds);
@ -1269,11 +1298,13 @@ void MDIEngine2::many_commands()
void MDIEngine2::infile()
{
char *infile = new char[length_param+1];
int ierr = MDI_Recv(infile,length_param+1,MDI_CHAR,mdicomm);
if (nbytes < 0) error->all(FLERR,"MDI: INFILE nbytes has not been set");
char *infile = new char[nbytes+1];
int ierr = MDI_Recv(infile,nbytes+1,MDI_CHAR,mdicomm);
if (ierr) error->all(FLERR,"MDI: INFILE data");
MPI_Bcast(infile,length_param+1,MPI_CHAR,0,world);
infile[length_param+1] = '\0';
MPI_Bcast(infile,nbytes+1,MPI_CHAR,0,world);
infile[nbytes+1] = '\0';
lammps_file(lmp,infile);
@ -1316,26 +1347,24 @@ void MDIEngine2::evaluate()
/* ----------------------------------------------------------------------
RESET_BOX command
9 values = boxlo, boxhi, xy, yz, xz
wrapper on library reset_box() method
requires no atoms exist
allows caller to define a new simulation box
NOTE: this will not work in plugin mode, b/c of 3 MDI_Recv() calls
how to effectively do this?
---------------------------------------------------------------------- */
void MDIEngine2::reset_box()
{
int ierr;
double boxlo[3],boxhi[3],tilts[3];
ierr = MDI_Recv(boxlo, 3, MDI_DOUBLE, mdicomm);
ierr = MDI_Recv(boxhi, 3, MDI_DOUBLE, mdicomm);
ierr = MDI_Recv(tilts, 3, MDI_DOUBLE, mdicomm);
// ierr check?
MPI_Bcast(boxlo, 3, MPI_DOUBLE, 0, world);
MPI_Bcast(boxhi, 3, MPI_DOUBLE, 0, world);
MPI_Bcast(tilts, 3, MPI_DOUBLE, 0, world);
double values[9];
lammps_reset_box(lmp,boxlo,boxhi,tilts[0],tilts[1],tilts[2]);
if (atom->natoms > 0)
error->all(FLERR,"MDI RESET_BOX cannot be used when atoms exist");
ierr = MDI_Recv(values,9,MDI_DOUBLE,mdicomm);
MPI_Bcast(values,9,MPI_DOUBLE,0,world);
lammps_reset_box(lmp,&values[0],&values[3],values[6],values[7],values[8]);
}
/* ----------------------------------------------------------------------
@ -1344,62 +1373,105 @@ void MDIEngine2::reset_box()
requires simulation box be defined
allows caller to define a new set of atoms
with their IDs, types, coords, velocities, image flags
NOTE: this will not work in plugin mode, b/c of multiple MDI_Recv() calls
how to effectively do this?
NOTE: also the memory here is not yet allocated correctly
called in stages via flag
since MDI plugin mode only allows 1 MDI Send/Recv per MDI command
assumes current atom->natoms set by >NATOMS command is correct
---------------------------------------------------------------------- */
void MDIEngine2::create_atoms()
void MDIEngine2::create_atoms(int flag)
{
int ierr;
int natoms;
ierr = MDI_Recv(&natoms, 1, MDI_INT, mdicomm);
// ierr checks everywhere?
MPI_Bcast(&natoms, 1, MPI_INT, 0, world);
tagint *id = nullptr;
int *type = nullptr;
double *x = nullptr;
double *v = nullptr;
imageint *image = nullptr;
// NOTE: error check on imageint = INT
while (1) {
char label;
ierr = MDI_Recv(&label, 1, MDI_CHAR, mdicomm);
MPI_Bcast(&label, 1, MPI_CHAR, 0, world);
if (flag == CREATE_ATOM) {
if (label == '0') break;
if (create_atoms_flag)
error->all(FLERR,"MDI CREATE_ATOM already in progress");
if (label == 'i') {
id = new tagint[natoms];
ierr = MDI_Recv(id, natoms, MDI_INT, mdicomm);
MPI_Bcast(id, natoms, MPI_INT, 0, world);
} else if (label == 't') {
type = new int[natoms];
ierr = MDI_Recv(type, natoms, MDI_INT, mdicomm);
MPI_Bcast(type, natoms, MPI_INT, 0, world);
} else if (label == 'x') {
x = new double[3*natoms];
ierr = MDI_Recv(x, 3*natoms, MDI_DOUBLE, mdicomm);
MPI_Bcast(x, 3*natoms, MPI_DOUBLE, 0, world);
} else if (label == 'v') {
v = new double[3*natoms];
ierr = MDI_Recv(v, 3*natoms, MDI_DOUBLE, mdicomm);
MPI_Bcast(v, 3*natoms, MPI_DOUBLE, 0, world);
} else if (label == 'i') {
image = new imageint[natoms];
ierr = MDI_Recv(image, natoms, MDI_INT, mdicomm);
MPI_Bcast(image, natoms, MPI_INT, 0, world);
}
create_atoms_flag = 1;
create_id = nullptr;
create_type = nullptr;
create_x = nullptr;
create_v = nullptr;
create_image = nullptr;
} else if (flag == CREATE_ID) {
if (!create_atoms_flag) error->all(FLERR,"MDI CREATE_ATOM not in progress");
if (create_id) error->all(FLERR,"MDI CREATE_ATOM already in progress");
int natoms = atom->natoms;
memory->create(create_id,natoms,"mdi:create_id");
ierr = MDI_Recv(create_id,natoms,MDI_INT,mdicomm);
MPI_Bcast(create_id,natoms,MPI_INT,0,world);
} else if (flag == CREATE_TYPE) {
if (!create_atoms_flag) error->all(FLERR,"MDI CREATE_ATOM not in progress");
if (create_type) error->all(FLERR,"MDI CREATE_ATOM already in progress");
int natoms = atom->natoms;
if (create_type) error->all(FLERR,"MDI CREATE_ATOM already in progress");
memory->create(create_type,natoms,"mdi:create_type");
ierr = MDI_Recv(create_type,natoms,MDI_INT,mdicomm);
MPI_Bcast(create_type,natoms,MPI_INT,0,world);
} else if (flag == CREATE_X) {
if (!create_atoms_flag) error->all(FLERR,"MDI CREATE_ATOM not in progress");
if (create_x) error->all(FLERR,"MDI CREATE_ATOM already in progress");
int natoms = atom->natoms;
if (create_x) error->all(FLERR,"MDI CREATE_ATOM already in progress");
memory->create(create_x,3*natoms,"mdi:create_x");
ierr = MDI_Recv(create_x,3*natoms,MDI_DOUBLE,mdicomm);
MPI_Bcast(create_x,3*natoms,MPI_DOUBLE,0,world);
} else if (flag == CREATE_V) {
if (!create_atoms_flag) error->all(FLERR,"MDI CREATE_ATOM not in progress");
if (create_v) error->all(FLERR,"MDI CREATE_ATOM already in progress");
int natoms = atom->natoms;
if (create_v) error->all(FLERR,"MDI CREATE_ATOM already in progress");
memory->create(create_v,3*natoms,"mdi:create_x");
ierr = MDI_Recv(create_v,3*natoms,MDI_DOUBLE,mdicomm);
MPI_Bcast(create_v,3*natoms,MPI_DOUBLE,0,world);
} else if (flag == CREATE_IMAGE) {
if (!create_atoms_flag) error->all(FLERR,"MDI CREATE_ATOM not in progress");
if (create_image) error->all(FLERR,"MDI CREATE_ATOM already in progress");
int natoms = atom->natoms;
if (create_image) error->all(FLERR,"MDI CREATE_ATOM already in progress");
memory->create(create_image,natoms,"mdi:create_image");
ierr = MDI_Recv(create_image,natoms,MDI_INT,mdicomm);
MPI_Bcast(create_image,natoms,MPI_INT,0,world);
} else if (flag == CREATE_GO) {
if (!create_atoms_flag) error->all(FLERR,"MDI CREATE_ATOM not in progress");
if (!create_type || !create_x)
error->all(FLERR,"MDI: CREATE_ATOM requires types and coords");
int natom = atom->natoms;
int ncreate = lammps_create_atoms(lmp,natom,create_id,create_type,
create_x,create_v,create_image,1);
if (ncreate != natom)
error->all(FLERR, "MDI: CREATE ATOM created atoms != sent atoms");
// clean up create_atoms state
create_atoms_flag = 0;
memory->destroy(create_id);
memory->destroy(create_type);
memory->destroy(create_x);
memory->destroy(create_v);
memory->destroy(create_image);
}
if (!x || !type)
error->all(FLERR,"MDI: CREATE_ATOM did not receive atom coords or types");
int ncreate = lammps_create_atoms(lmp,natoms,id,type,x,v,image,1);
if (ncreate != natoms)
error->all(FLERR, "MDI: CREATE ATOM created atoms != sent atoms");
}
/* ----------------------------------------------------------------------

View File

@ -55,7 +55,15 @@ class MDIEngine2 : public Command {
class Minimize *minimizer;
class Compute *ke,*pe,*press;
int length_param; // LENGTH command value used by other commands
int nbytes; // NBYTES command value used by other commands
// create_atoms state
int create_atoms_flag;
tagint *create_id;
int *create_type;
double *create_x,*create_v;
imageint *create_image;
// unit conversion factors
@ -98,13 +106,13 @@ class MDIEngine2 : public Command {
void send_celldispl();
void receive_celldispl();
void length_command();
void nbytes_command();
void single_command();
void many_commands();
void infile();
void evaluate();
void reset_box();
void create_atoms();
void create_atoms(int);
void send_pressure();
void send_ptensor();