From e053619eed2b308be689261d9568e25d7d707691 Mon Sep 17 00:00:00 2001 From: taylor-a-barnes Date: Tue, 27 Apr 2021 10:19:01 -0400 Subject: [PATCH] Add call to MDI_Set_execute_command --- src/USER-MDI/fix_mdi_engine.cpp | 381 ++++++++++++++++---------------- src/USER-MDI/fix_mdi_engine.h | 2 + src/library.cpp | 19 +- src/library.h | 3 + 4 files changed, 218 insertions(+), 187 deletions(-) diff --git a/src/USER-MDI/fix_mdi_engine.cpp b/src/USER-MDI/fix_mdi_engine.cpp index a31b1bc194..bec2272cd9 100644 --- a/src/USER-MDI/fix_mdi_engine.cpp +++ b/src/USER-MDI/fix_mdi_engine.cpp @@ -25,7 +25,7 @@ #include "error.h" #include "force.h" #include "irregular.h" -#include "mdi.h" +#include "library.h" #include "memory.h" #include "modify.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; + 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, 1, MDI_INT, driver_socket); + if (ierr != 0) + error->all(FLERR,"Unable to send number of atom types to driver"); + } + } + else if (strcmp(command,"COORDS") == 0 ) { + // receive the coordinate information + receive_coordinates(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,"etol = std::numeric_limits::max(); + update->ftol = std::numeric_limits::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::max(); + update->ftol = std::numeric_limits::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) { /* @@ -276,199 +461,25 @@ char *FixMDIEngine::engine_mode(const char *node) 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 /* ----------------------------------------------------------------- */ while (not exit_flag and not local_exit_flag) { - if (master) { - // read the next command from the driver - ierr = MDI_Recv_Command(command, driver_socket); - if (ierr != 0) - error->all(FLERR,"Unable to receive command from driver"); - command[MDI_COMMAND_LENGTH]=0; - } + // read the next command from the driver + ierr = MDI_Recv_Command(command, driver_socket); + if (ierr != 0) + error->all(FLERR,"Unable to receive command from driver"); + // broadcast the command to the other tasks MPI_Bcast(command,MDI_COMMAND_LENGTH,MPI_CHAR,0,world); - /* - 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; - 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, 1, MDI_INT, driver_socket); - if (ierr != 0) - error->all(FLERR,"Unable to send number of atom types to driver"); - } - } - else if (strcmp(command,"COORDS") == 0 ) { - // receive the coordinate information - receive_coordinates(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,"etol = std::numeric_limits::max(); - update->ftol = std::numeric_limits::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::max(); - update->ftol = std::numeric_limits::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"); - } + // execute the command + this->execute_command(command, driver_socket); // 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 ) { diff --git a/src/USER-MDI/fix_mdi_engine.h b/src/USER-MDI/fix_mdi_engine.h index fcb8f6c62a..d6509cf29d 100644 --- a/src/USER-MDI/fix_mdi_engine.h +++ b/src/USER-MDI/fix_mdi_engine.h @@ -22,6 +22,7 @@ FixStyle(mdi/engine,FixMDIEngine) #define LMP_FIX_MDI_ENGINE_H #include "fix.h" +#include "mdi.h" namespace LAMMPS_NS { @@ -32,6 +33,7 @@ class FixMDIEngine : public Fix { int setmask(); void init(); + int execute_command(const char *command, MDI_Comm driver_socket); char *engine_mode(const char *node); // receive and update forces diff --git a/src/library.cpp b/src/library.cpp index dfcea8d543..ed14506b31 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -27,11 +27,13 @@ #include "error.h" #include "fix.h" #include "fix_external.h" +#if defined(LMP_USER_MDI) +#include "fix_mdi_engine.h" +#endif #include "force.h" #include "group.h" #include "info.h" #include "input.h" -#include "mdi_interface.h" #include "memory.h" #include "modify.h" #include "molecule.h" @@ -4979,7 +4981,8 @@ int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) { // ---------------------------------------------------------------------- // MDI functions // ---------------------------------------------------------------------- -int MDI_Plugin_init_lammps() { +int MDI_Plugin_init_lammps() +{ // initialize MDI int mdi_argc; char** mdi_argv; @@ -5026,6 +5029,18 @@ int MDI_Plugin_init_lammps() { 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: // fill-column: 72 // End: diff --git a/src/library.h b/src/library.h index c3dcf330dd..cdd1f86d98 100644 --- a/src/library.h +++ b/src/library.h @@ -40,6 +40,8 @@ #include /* for int64_t */ #endif +#include "mdi_interface.h" + /** Data type constants for extracting data from atoms, computes and fixes * * 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 * ---------------------------------------------------------------------- */ int MDI_Plugin_init_lammps(); +int lammps_execute_mdi_command(const char* command, MDI_Comm comm, void* class_obj); #ifdef __cplusplus