diff --git a/examples/QM/LATTE/README b/examples/QM/LATTE/README index a39df8b2a4..f7ab834563 100644 --- a/examples/QM/LATTE/README +++ b/examples/QM/LATTE/README @@ -53,24 +53,23 @@ Building 3 codes needed to run these examples (3) Build LAMMPS with its MDI package also with the MOLECULE package for these example scripts -traditional make: +Build with regular make: % cd lammps/lib/mdi -% python Install.py -m mpi # creates static libmdi.a +% python Install.py -m mpi % cd lammps/src % make yes-mdi -% make mpi # build LAMMPS as exe and shared lib - # shared lib for use of LAMMPS as MDI plugin +% make mpi # creates lmp_mpi -CMake build: +Build with CMake: % cd lammps % mkdir build; cd build % cmake -D PKG_MDI=yes -D PKG_MOLECULE=yes ../cmake -% make +% make # creates lmp -(4) Copy LAMMPS and LATTE files into this dir +(4) Copy LAMMPS and LATTE executables into this dir -Copy the LAMMPS executable (e.g. lmp_mpi) into this dir. -Copy the LATTE executabe (LATTE_DOUBLE) into this dir. +Copy the LAMMPS executable into this dir as lmp_mpi. +Copy the LATTE executable LATTE_DOUBLE into this dir. The run commands below assume you have done this. ------------------ diff --git a/examples/QM/README b/examples/QM/README new file mode 100644 index 0000000000..7fa24093ab --- /dev/null +++ b/examples/QM/README @@ -0,0 +1,18 @@ +Each of the directories shows how to use LAMMPS in tandem with a +specific quantum code + +LATTE = semi-empirical tight-binding code from LANL + https://www.osti.gov/biblio/1526907-los-alamos-transferable-tight-binding-energetics-latte-version + https://github.com/lanl/LATTE + +To be added later (as of July 2022): + +DFT-FE = real-space DFT code from U Michigan + https://github.com/dftfeDevelopers/dftfe + +Quantum Espresso (QE) = DFT code for materials modeling + https://www.quantum-espresso.org/ + +NWChem = computational chemistry code from PNNL + focus here is on DFT portion of NWChem + https://www.nwchem-sw.org diff --git a/examples/mdi/README b/examples/mdi/README index d6bcc48f21..4669b2febd 100644 --- a/examples/mdi/README +++ b/examples/mdi/README @@ -27,17 +27,33 @@ Examples for all these use cases, using LAMMPS as a driver and as an engine are in this directory. The Run.sh file shows how run in all the modes. Type "sh Run.sh" to try them all out. -Examples for using LAMMPS as a driver with the tight-binding code LATTE -are in the LATTE sub-directory. See its README file for more info. +Examples for using LAMMPS as a driver with the tight-binding code +LATTE are in the examples/QM/LATTE sub-directory. See its README file +for more info. -Note that to use LAMMPS as a plugin engine for some the examples in -this dir, you must build it as a shared library. Something like this -with traditional make, which also builds the normal LAMMPS executable -lmp_mpi: +------------------------------------------------- -cd src -make yes-mdi -make mode=shlib mpi +Here is how to build LAMMPS with MDI support. Both as an executable +and a shared library. The former is needed to use LAMMPS as an MDI +driver or as an MDI engine in stand-alone mode. The latter is needed +to use LAMMPS as an MDI engine in plugin mode. + +Build via regular make: + +% cd lammps/src +% make lib-mdi args="-m mpi" # download, install MDI in lib/mdi w/ MPI support +% make yes-mdi # include MDI package in LAMMPS build +% make mode=shlib mpi # creates lmp_mpi and liblammps.so + +Build via CMake: + +cd lammps +mkdir build; cd build +cmake -D PKG_MDI=yes -D BUILD_SHARED_LIBS=yes ../cmake +make # creates lmp and liblammps.so + +Both of these build procedures build LAMMPS both as an executable +(lmp_mpi) and as a shared library (liblammps.so). ------------------------------------------------- diff --git a/lib/mdi/Install.py b/lib/mdi/Install.py index 6269126e94..5caa819982 100644 --- a/lib/mdi/Install.py +++ b/lib/mdi/Install.py @@ -27,9 +27,7 @@ specify -m and optionally -e, order does not matter Examples: -make lib-poems args="-m serial" # build POEMS lib with same settings as in the serial Makefile in src -make lib-colvars args="-m mpi" # build COLVARS lib with same settings as in the mpi Makefile in src -make lib-meam args="-m ifort" # build MEAM lib with custom Makefile.ifort (using Intel Fortran) +make lib-mdi args="-m mpi" # build MDI lib with same settings as in the mpi Makefile in src """ # settings diff --git a/src/MDI/library_mdi.cpp b/src/MDI/library_mdi.cpp index ad2e995b4c..dd062f7724 100644 --- a/src/MDI/library_mdi.cpp +++ b/src/MDI/library_mdi.cpp @@ -23,12 +23,8 @@ #define LAMMPS_LIB_MPI 1 #include "library.h" -#include "mdi_engine.h" - #include -using namespace LAMMPS_NS; - /* ---------------------------------------------------------------------- */ /** Initialize an instance of LAMMPS as an MDI plugin @@ -58,6 +54,7 @@ int MDI_Plugin_init_lammps() int mdi_argc; char **mdi_argv; + if (MDI_Plugin_get_argc(&mdi_argc)) MPI_Abort(MPI_COMM_WORLD, 1); if (MDI_Plugin_get_argv(&mdi_argv)) MPI_Abort(MPI_COMM_WORLD, 1); if (MDI_Init(&mdi_argc, &mdi_argv)) MPI_Abort(MPI_COMM_WORLD, 1); @@ -90,14 +87,24 @@ int MDI_Plugin_init_lammps() if (!found_filename) MPI_Abort(MPI_COMM_WORLD, 1); // create and run a LAMMPS instance - // lammps_open() expects a first arg (not used) which is executable name - // same as if called from main.cpp + // need to add an initial pseudo arg to mdi_argc & mdi_argv + // b/c lammps_open() expects first arg to be an executable name + // same as if it were called from main.cpp + + int mdi_argc_extra = mdi_argc + 1; + char **mdi_argv_extra = new char*[mdi_argc_extra]; + + mdi_argv_extra[0] = (char *) "MDI_plugin_engine"; + for (int i = 0; i < mdi_argc; i++) + mdi_argv_extra[i+1] = mdi_argv[i]; void *lmp = nullptr; if (lammps_config_has_mpi_support() > 0) - lmp = lammps_open(mdi_argc + 1, &mdi_argv[-1], mpi_world_comm, nullptr); + lmp = lammps_open(mdi_argc_extra, mdi_argv_extra, mpi_world_comm, nullptr); else - lmp = lammps_open_no_mpi(mdi_argc + 1, &mdi_argv[-1], nullptr); + lmp = lammps_open_no_mpi(mdi_argc_extra, mdi_argv_extra, nullptr); + + delete [] mdi_argv_extra; // process the specified input script // must contain "mdi engine" command @@ -110,25 +117,3 @@ int MDI_Plugin_init_lammps() return 0; } - -/* ---------------------------------------------------------------------- */ - -/** Execute an MDI command - * -\verbatim embed:rst - -This function is called by the MolSSI Driver Interface Library (MDI) -when LAMMPS is run as a plugin, and should not otherwise be used. -The function executes a single command from an external MDI driver. - -\endverbatim - * \param command string buffer corresponding to the command to be executed - * \param comm MDI communicator that can be used to communicated with the driver. - * \param class_obj pointer to an instance of an mdi/engine fix cast to ``void *``. - * \return 0 on no error, 1 on error. */ - -int lammps_execute_mdi_command(const char *command, MDI_Comm comm, void *class_obj) -{ - auto mdi_engine = (MDIEngine *) class_obj; - return mdi_engine->execute_command(command, comm); -} diff --git a/src/MDI/library_mdi.h b/src/MDI/library_mdi.h index 1928244dd8..afc522ed68 100644 --- a/src/MDI/library_mdi.h +++ b/src/MDI/library_mdi.h @@ -14,13 +14,12 @@ #ifndef LAMMPS_LIBRARY_MDI_H #define LAMMPS_LIBRARY_MDI_H -/* C style library calls to LAMMPS when a LAMMPS shared library is - * used as a plugin through MolSSI Driver Interface (MDI). */ +/* C style library call to LAMMPS when a LAMMPS shared library is + * used as a plugin through MolSSI Driver Interface (MDI) */ #include extern "C" { int MDI_Plugin_init_lammps(); -int lammps_execute_mdi_command(const char *, MDI_Comm, void *); } #endif diff --git a/src/MDI/mdi_engine.cpp b/src/MDI/mdi_engine.cpp index aeb18e856c..e9f8b0651d 100644 --- a/src/MDI/mdi_engine.cpp +++ b/src/MDI/mdi_engine.cpp @@ -184,10 +184,10 @@ MDIEngine::MDIEngine(LAMMPS *_lmp, int narg, char ** arg) : Pointers(_lmp) mdi_commands(); - // register the execute_command function with MDI - // only used when engine runs in plugin mode + // register a callback function with MDI used when engine runs in plugin mode + // execute_command_plugin_wrapper() must be a static method - MDI_Set_execute_command_func(lammps_execute_mdi_command, this); + MDI_Set_execute_command_func(execute_command_plugin_wrapper, this); // one-time operation to establish a connection with the driver @@ -291,11 +291,23 @@ void MDIEngine::engine_node(const char *node) node_match = true; } +/* ---------------------------------------------------------------------- + wrapper function on execute_command() + invoked as callback by MDI when engine operates in plugin mode + this is a static method in mdi_engine.h +---------------------------------------------------------------------- */ + +int MDIEngine::execute_command_plugin_wrapper(const char *command, + MDI_Comm comm, void *class_obj) +{ + auto mdi_engine = (MDIEngine *) class_obj; + return mdi_engine->execute_command(command, comm); +} + /* ---------------------------------------------------------------------- process a single driver command - called by engine_node() in loop - also called by MDI itself via lib::lammps_execute_mdi_command() - when LAMMPS is running as a plugin + called by engine_node() in loop when engine runs as stand-alone code + called by execute_command_plugin_wrapper() when engine runs as plugin lib ---------------------------------------------------------------------- */ int MDIEngine::execute_command(const char *command, MDI_Comm mdicomm) diff --git a/src/MDI/mdi_engine.h b/src/MDI/mdi_engine.h index 242755e3b7..56db28c73d 100644 --- a/src/MDI/mdi_engine.h +++ b/src/MDI/mdi_engine.h @@ -22,8 +22,6 @@ namespace LAMMPS_NS { class MDIEngine : protected Pointers { public: MDIEngine(class LAMMPS *, int, char **); - - int execute_command(const char *command, MDI_Comm mdicomm); void engine_node(const char *node); private: @@ -87,9 +85,13 @@ class MDIEngine : protected Pointers { class Irregular *irregular; // irregular comm if new COORDS // are highly displaced + // static method for MDI to callback to, when LAMMPS used as plugin engine + + static int execute_command_plugin_wrapper(const char *, MDI_Comm, void *); + // class methods - void mdi_engine(int, char **); + int execute_command(const char *, MDI_Comm); void mdi_commands(); void mdi_md(); diff --git a/src/MDI/mdi_plugin.cpp b/src/MDI/mdi_plugin.cpp index 4bd917b7d7..6f052173f6 100644 --- a/src/MDI/mdi_plugin.cpp +++ b/src/MDI/mdi_plugin.cpp @@ -98,16 +98,19 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp) // launch the MDI plugin library // path for lib was specified in -mdi command-line arg when LAMMPS started - // this calls back to plugin_wrapper, which must issue MDI EXIT at end + // this calls back to plugin_wrapper(), which issues MDI EXIT at end & returns + // plugin_wrapper() must be a static method - MDI_Launch_plugin(plugin_name, plugin_args, &world, plugin_wrapper, (void *) this); + MDI_Launch_plugin(plugin_name, plugin_args, &world, plugin_wrapper, + (void *) this); delete[] plugin_args; } /* ---------------------------------------------------------------------- - callback function from MDI_Launch_plugin() - this function wraps entire interaction of LAMMPS driver with the plugin + wrapper on entire interaction of LAMMPS as a driver with the plugin engine + invoked as a callback by MDI once plugin library engine is launched + this is a static method in mdi_plugin.h ---------------------------------------------------------------------- */ int MDIPlugin::plugin_wrapper(void * /*pmpicomm*/, MDI_Comm mdicomm, void *vptr) diff --git a/src/MDI/mdi_plugin.h b/src/MDI/mdi_plugin.h index d5fc81f050..c28f1997f7 100644 --- a/src/MDI/mdi_plugin.h +++ b/src/MDI/mdi_plugin.h @@ -26,6 +26,9 @@ class MDIPlugin : protected Pointers { private: char *lammps_command; + // static method for MDI to callback to + // when LAMMPS is a driver which launches a plugin engine + static int plugin_wrapper(void *, MDI_Comm, void *); };