Files
lammps/src/MDI/mdi_plugin.cpp
2022-09-09 00:03:39 -04:00

131 lines
4.4 KiB
C++

/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/ Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Taylor Barnes (MolSSI)
MolSSI Driver Interface (MDI) support for LAMMPS
------------------------------------------------------------------------- */
#include "mdi_plugin.h"
#include "error.h"
#include "input.h"
#include "modify.h"
#include <cstring>
#include <mdi.h>
using namespace LAMMPS_NS;
/* ----------------------------------------------------------------------
trigger LAMMPS to load an MDI plugin engine
after loading the plugin library, it executes a LAMMPS command such as "run"
the command will use other LAMMPS commands, such as fix mdi/aimd
which act as an MDI driver, issuing MDI commands to the engine
when MDI_Launch_plugin() exits, the engine is shut down and
this class is destroyed
---------------------------------------------------------------------- */
MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp)
{
if (narg < 1) error->all(FLERR, "Illegal mdi plugin command");
char *plugin_name = arg[0];
char *mdi_arg = nullptr;
char *infile_arg = nullptr;
char *extra_arg = nullptr;
lammps_command = nullptr;
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg], "mdi") == 0) {
if (iarg + 2 > narg) error->all(FLERR, "Illegal mdi plugin command");
mdi_arg = arg[iarg + 1];
iarg += 2;
} else if (strcmp(arg[iarg], "infile") == 0) {
if (iarg + 2 > narg) error->all(FLERR, "Illegal mdi plugin command");
infile_arg = arg[iarg + 1];
iarg += 2;
} else if (strcmp(arg[iarg], "extra") == 0) {
if (iarg + 2 > narg) error->all(FLERR, "Illegal mdi plugin command");
extra_arg = arg[iarg + 1];
iarg += 2;
} else if (strcmp(arg[iarg], "command") == 0) {
if (iarg + 2 > narg) error->all(FLERR, "Illegal mdi plugin command");
lammps_command = utils::strdup(arg[iarg + 1]);
iarg += 2;
} else
error->all(FLERR, "Illegal mdi plugin command");
}
// error checks
if (!mdi_arg || !lammps_command)
error->all(FLERR, "MDI plugin must specify mdi and command keywords");
// build full plugin_args string for args to plugin library
int n = strlen(mdi_arg) + 16;
if (infile_arg) n += strlen(infile_arg);
if (extra_arg) n += strlen(extra_arg);
auto plugin_args = new char[n];
plugin_args[0] = 0;
strcat(plugin_args, "-mdi \"");
strcat(plugin_args, mdi_arg);
strcat(plugin_args, "\"");
if (infile_arg) {
strcat(plugin_args, " -in ");
strcat(plugin_args, infile_arg);
}
if (extra_arg) {
strcat(plugin_args, " ");
strcat(plugin_args, extra_arg);
}
// 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 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);
delete[] plugin_args;
}
/* ----------------------------------------------------------------------
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)
{
auto ptr = (MDIPlugin *) vptr;
LAMMPS *lammps = ptr->lmp;
char *lammps_command = ptr->lammps_command;
// invoke the specified LAMMPS command
// that operation will issue MDI commands to the plugin engine
lammps->input->one(lammps_command);
delete[] lammps_command;
// send MDI exit to plugin, which unloads the plugin
MDI_Send_command("EXIT", mdicomm);
return 0;
}