Add call to MDI_Set_execute_command

This commit is contained in:
taylor-a-barnes
2021-04-27 10:19:01 -04:00
parent b95fa003f5
commit e053619eed
4 changed files with 218 additions and 187 deletions

View File

@ -25,7 +25,7 @@
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
#include "irregular.h" #include "irregular.h"
#include "mdi.h" #include "library.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
#include "update.h" #include "update.h"
@ -261,6 +261,191 @@ void FixMDIEngine::post_force(int vflag)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
int FixMDIEngine::execute_command(const char *command, MDI_Comm driver_socket)
{
/*
if (screen)
fprintf(screen,"MDI command: %s\n",command);
if (logfile)
fprintf(logfile,"MDI command: %s:\n",command);
*/
// confirm that this command is supported at this node
int command_exists = 0;
ierr = MDI_Check_Command_Exists(current_node, command, MDI_COMM_NULL, &command_exists);
if (ierr != 0)
error->all(FLERR,"Unable to check whether the current command is supported");
if ( command_exists != 1 )
error->all(FLERR,"Received a command that is not supported at the current node");
if (strcmp(command,"STATUS ") == 0 ) {
// send the calculation status to the driver
if (master) {
ierr = MDI_Send_Command("READY", driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to return status to driver");
}
}
else if (strcmp(command,">NATOMS") == 0 ) {
// receive the number of atoms from the driver
if (master) {
ierr = MDI_Recv((char*) &atom->natoms, 1, MDI_INT, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to receive number of atoms from driver");
}
MPI_Bcast(&atom->natoms,1,MPI_INT,0,world);
}
else if (strcmp(command,"<NATOMS") == 0 ) {
// send the number of atoms to the driver
if (master) {
int64_t mdi_natoms = atom->natoms;
ierr = MDI_Send((char*) &mdi_natoms, 1, MDI_INT64_T, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to send number of atoms to driver");
}
}
else if (strcmp(command,"<NTYPES") == 0 ) {
// send the number of atom types to the driver
if (master) {
ierr = MDI_Send((char*) &atom->ntypes, 1, MDI_INT, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to send number of atom types to driver");
}
}
else if (strcmp(command,"<TYPES") == 0 ) {
// send the atom types
send_types(error);
}
else if (strcmp(command,"<LABELS") == 0 ) {
// send the atom labels
send_labels(error);
}
else if (strcmp(command,"<MASSES") == 0 ) {
// send the atom types
send_masses(error);
}
else if (strcmp(command,"<CELL") == 0 ) {
// send the cell dimensions to the driver
send_cell(error);
}
else if (strcmp(command,">COORDS") == 0 ) {
// receive the coordinate information
receive_coordinates(error);
}
else if (strcmp(command,"<COORDS") == 0 ) {
// send the coordinate information
send_coordinates(error);
}
else if (strcmp(command,"<CHARGES") == 0 ) {
// send the charges
send_charges(error);
}
else if (strcmp(command,"<ENERGY") == 0 ) {
// send the total energy to the driver
send_energy(error);
}
else if (strcmp(command,"<FORCES") == 0 ) {
// send the forces to the driver
send_forces(error);
}
else if (strcmp(command,">FORCES") == 0 ) {
// receive the forces from the driver
receive_forces(error);
}
else if (strcmp(command,"+FORCES") == 0 ) {
// receive additional forces from the driver
// these are added prior to SHAKE or other post-processing
add_forces(error);
}
else if (strcmp(command,"@INIT_MD") == 0 ) {
if ( most_recent_init != 0 ) {
error->all(FLERR,"MDI is already performing a simulation");
}
// initialize a new MD simulation
most_recent_init = 1;
local_exit_flag = true;
}
else if (strcmp(command,"@INIT_OPTG") == 0 ) {
if ( most_recent_init != 0 ) {
error->all(FLERR,"MDI is already performing a simulation");
}
// initialize a new geometry optimization
most_recent_init = 2;
local_exit_flag = true;
//optg_init(error);
}
else if (strcmp(command,"@") == 0 ) {
strncpy(target_node, "\0", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"<@") == 0 ) {
if (master) {
ierr = MDI_Send(current_node, MDI_NAME_LENGTH, MDI_CHAR, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to send node to driver");
}
}
else if (strcmp(command,"<KE") == 0 ) {
// send the kinetic energy to the driver
send_ke(error);
}
else if (strcmp(command,"<PE") == 0 ) {
// send the potential energy to the driver
send_pe(error);
}
else if (strcmp(command,"@COORDS") == 0 ) {
strncpy(target_node, "@COORDS", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"@PRE-FORCES") == 0 ) {
strncpy(target_node, "@PRE-FORCES", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"@FORCES") == 0 ) {
strncpy(target_node, "@FORCES", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"EXIT_SIM") == 0 ) {
most_recent_init = 0;
local_exit_flag = true;
// are we in the middle of a geometry optimization?
if ( most_recent_init == 2 ) {
// ensure that the energy and force tolerances are met
update->etol = std::numeric_limits<double>::max();
update->ftol = std::numeric_limits<double>::max();
// set the maximum number of force evaluations to 0
update->max_eval = 0;
}
}
else if (strcmp(command,"EXIT") == 0 ) {
// exit the driver code
exit_flag = true;
// are we in the middle of a geometry optimization?
if ( most_recent_init == 2 ) {
// ensure that the energy and force tolerances are met
update->etol = std::numeric_limits<double>::max();
update->ftol = std::numeric_limits<double>::max();
// set the maximum number of force evaluations to 0
update->max_eval = 0;
}
}
else {
// the command is not supported
error->all(FLERR,"Unknown command from driver");
}
return 0;
}
/* ---------------------------------------------------------------------- */
char *FixMDIEngine::engine_mode(const char *node) char *FixMDIEngine::engine_mode(const char *node)
{ {
/* /*
@ -276,199 +461,25 @@ char *FixMDIEngine::engine_mode(const char *node)
local_exit_flag = true; local_exit_flag = true;
} }
// register the execute_command function with MDI
MDI_Set_execute_command_func(lammps_execute_mdi_command, this);
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
// Answer commands from the driver // Answer commands from the driver
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
while (not exit_flag and not local_exit_flag) { while (not exit_flag and not local_exit_flag) {
if (master) { // read the next command from the driver
// read the next command from the driver ierr = MDI_Recv_Command(command, driver_socket);
ierr = MDI_Recv_Command(command, driver_socket); if (ierr != 0)
if (ierr != 0) error->all(FLERR,"Unable to receive command from driver");
error->all(FLERR,"Unable to receive command from driver");
command[MDI_COMMAND_LENGTH]=0;
}
// broadcast the command to the other tasks // broadcast the command to the other tasks
MPI_Bcast(command,MDI_COMMAND_LENGTH,MPI_CHAR,0,world); MPI_Bcast(command,MDI_COMMAND_LENGTH,MPI_CHAR,0,world);
/* // execute the command
if (screen) this->execute_command(command, driver_socket);
fprintf(screen,"MDI command: %s\n",command);
if (logfile)
fprintf(logfile,"MDI command: %s:\n",command);
*/
// confirm that this command is supported at this node
int command_exists = 0;
ierr = MDI_Check_Command_Exists(current_node, command, MDI_COMM_NULL, &command_exists);
if (ierr != 0)
error->all(FLERR,"Unable to check whether the current command is supported");
if ( command_exists != 1 )
error->all(FLERR,"Received a command that is not supported at the current node");
if (strcmp(command,"STATUS ") == 0 ) {
// send the calculation status to the driver
if (master) {
ierr = MDI_Send_Command("READY", driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to return status to driver");
}
}
else if (strcmp(command,">NATOMS") == 0 ) {
// receive the number of atoms from the driver
if (master) {
ierr = MDI_Recv((char*) &atom->natoms, 1, MDI_INT, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to receive number of atoms from driver");
}
MPI_Bcast(&atom->natoms,1,MPI_INT,0,world);
}
else if (strcmp(command,"<NATOMS") == 0 ) {
// send the number of atoms to the driver
if (master) {
int64_t mdi_natoms = atom->natoms;
ierr = MDI_Send((char*) &mdi_natoms, 1, MDI_INT64_T, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to send number of atoms to driver");
}
}
else if (strcmp(command,"<NTYPES") == 0 ) {
// send the number of atom types to the driver
if (master) {
ierr = MDI_Send((char*) &atom->ntypes, 1, MDI_INT, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to send number of atom types to driver");
}
}
else if (strcmp(command,"<TYPES") == 0 ) {
// send the atom types
send_types(error);
}
else if (strcmp(command,"<LABELS") == 0 ) {
// send the atom labels
send_labels(error);
}
else if (strcmp(command,"<MASSES") == 0 ) {
// send the atom types
send_masses(error);
}
else if (strcmp(command,"<CELL") == 0 ) {
// send the cell dimensions to the driver
send_cell(error);
}
else if (strcmp(command,">COORDS") == 0 ) {
// receive the coordinate information
receive_coordinates(error);
}
else if (strcmp(command,"<COORDS") == 0 ) {
// send the coordinate information
send_coordinates(error);
}
else if (strcmp(command,"<CHARGES") == 0 ) {
// send the charges
send_charges(error);
}
else if (strcmp(command,"<ENERGY") == 0 ) {
// send the total energy to the driver
send_energy(error);
}
else if (strcmp(command,"<FORCES") == 0 ) {
// send the forces to the driver
send_forces(error);
}
else if (strcmp(command,">FORCES") == 0 ) {
// receive the forces from the driver
receive_forces(error);
}
else if (strcmp(command,"+FORCES") == 0 ) {
// receive additional forces from the driver
// these are added prior to SHAKE or other post-processing
add_forces(error);
}
else if (strcmp(command,"@INIT_MD") == 0 ) {
if ( most_recent_init != 0 ) {
error->all(FLERR,"MDI is already performing a simulation");
}
// initialize a new MD simulation
most_recent_init = 1;
local_exit_flag = true;
}
else if (strcmp(command,"@INIT_OPTG") == 0 ) {
if ( most_recent_init != 0 ) {
error->all(FLERR,"MDI is already performing a simulation");
}
// initialize a new geometry optimization
most_recent_init = 2;
local_exit_flag = true;
//optg_init(error);
}
else if (strcmp(command,"@") == 0 ) {
strncpy(target_node, "\0", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"<@") == 0 ) {
if (master) {
ierr = MDI_Send(current_node, MDI_NAME_LENGTH, MDI_CHAR, driver_socket);
if (ierr != 0)
error->all(FLERR,"Unable to send node to driver");
}
}
else if (strcmp(command,"<KE") == 0 ) {
// send the kinetic energy to the driver
send_ke(error);
}
else if (strcmp(command,"<PE") == 0 ) {
// send the potential energy to the driver
send_pe(error);
}
else if (strcmp(command,"@COORDS") == 0 ) {
strncpy(target_node, "@COORDS", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"@PRE-FORCES") == 0 ) {
strncpy(target_node, "@PRE-FORCES", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"@FORCES") == 0 ) {
strncpy(target_node, "@FORCES", MDI_COMMAND_LENGTH);
local_exit_flag = true;
}
else if (strcmp(command,"EXIT_SIM") == 0 ) {
most_recent_init = 0;
local_exit_flag = true;
// are we in the middle of a geometry optimization?
if ( most_recent_init == 2 ) {
// ensure that the energy and force tolerances are met
update->etol = std::numeric_limits<double>::max();
update->ftol = std::numeric_limits<double>::max();
// set the maximum number of force evaluations to 0
update->max_eval = 0;
}
}
else if (strcmp(command,"EXIT") == 0 ) {
// exit the driver code
exit_flag = true;
// are we in the middle of a geometry optimization?
if ( most_recent_init == 2 ) {
// ensure that the energy and force tolerances are met
update->etol = std::numeric_limits<double>::max();
update->ftol = std::numeric_limits<double>::max();
// set the maximum number of force evaluations to 0
update->max_eval = 0;
}
}
else {
// the command is not supported
error->all(FLERR,"Unknown command from driver");
}
// check if the target node is something other than the current node // check if the target node is something other than the current node
if ( strcmp(target_node,"\0") != 0 and strcmp(target_node, current_node) != 0 ) { if ( strcmp(target_node,"\0") != 0 and strcmp(target_node, current_node) != 0 ) {

View File

@ -22,6 +22,7 @@ FixStyle(mdi/engine,FixMDIEngine)
#define LMP_FIX_MDI_ENGINE_H #define LMP_FIX_MDI_ENGINE_H
#include "fix.h" #include "fix.h"
#include "mdi.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
@ -32,6 +33,7 @@ class FixMDIEngine : public Fix {
int setmask(); int setmask();
void init(); void init();
int execute_command(const char *command, MDI_Comm driver_socket);
char *engine_mode(const char *node); char *engine_mode(const char *node);
// receive and update forces // receive and update forces

View File

@ -27,11 +27,13 @@
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
#include "fix_external.h" #include "fix_external.h"
#if defined(LMP_USER_MDI)
#include "fix_mdi_engine.h"
#endif
#include "force.h" #include "force.h"
#include "group.h" #include "group.h"
#include "info.h" #include "info.h"
#include "input.h" #include "input.h"
#include "mdi_interface.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
#include "molecule.h" #include "molecule.h"
@ -4979,7 +4981,8 @@ int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// MDI functions // MDI functions
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
int MDI_Plugin_init_lammps() { int MDI_Plugin_init_lammps()
{
// initialize MDI // initialize MDI
int mdi_argc; int mdi_argc;
char** mdi_argv; char** mdi_argv;
@ -5026,6 +5029,18 @@ int MDI_Plugin_init_lammps() {
return 0; return 0;
} }
int lammps_execute_mdi_command(const char* command, MDI_Comm comm, void* class_obj)
{
#if defined(LMP_USER_MDI)
FixMDIEngine *mdi_fix = (FixMDIEngine*) class_obj;
mdi_fix->execute_command(command, comm);
return 0;
#else
return 1;
#endif
}
// Local Variables: // Local Variables:
// fill-column: 72 // fill-column: 72
// End: // End:

View File

@ -40,6 +40,8 @@
#include <inttypes.h> /* for int64_t */ #include <inttypes.h> /* for int64_t */
#endif #endif
#include "mdi_interface.h"
/** Data type constants for extracting data from atoms, computes and fixes /** Data type constants for extracting data from atoms, computes and fixes
* *
* Must be kept in sync with the equivalent constants in lammps/constants.py */ * Must be kept in sync with the equivalent constants in lammps/constants.py */
@ -247,6 +249,7 @@ int lammps_get_last_error_message(void *handle, char *buffer, int buf_size);
* MDI functions * MDI functions
* ---------------------------------------------------------------------- */ * ---------------------------------------------------------------------- */
int MDI_Plugin_init_lammps(); int MDI_Plugin_init_lammps();
int lammps_execute_mdi_command(const char* command, MDI_Comm comm, void* class_obj);
#ifdef __cplusplus #ifdef __cplusplus