added support for LAMMPS as MDI AIMD driver

This commit is contained in:
Steve Plimpton
2021-09-02 17:52:10 -06:00
parent 55f20288b1
commit 75cb6fc51b
9 changed files with 1936 additions and 3 deletions

143
src/MDI/fix_mdi_aimd.cpp Normal file
View File

@ -0,0 +1,143 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
#include "error.h"
#include "fix_mdi_aimd.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR, "Illegal fix mdi/aimd command");
scalar_flag = 1;
global_freq = 1;
extscalar = 1;
energy_global_flag = 1;
virial_global_flag = 1;
thermo_energy = thermo_virial = 1;
// connect to MDI engine
MDI_Accept_communicator(&engine);
}
/* ---------------------------------------------------------------------- */
FixMDIAimd::~FixMDIAimd()
{
// send exit command to engine
MDI_Send_command("EXIT",engine);
}
/* ---------------------------------------------------------------------- */
int FixMDIAimd::setmask()
{
int mask = 0;
mask |= PRE_REVERSE;
mask |= POST_FORCE;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixMDIAimd::setup(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixMDIAimd::setup_pre_reverse(int eflag, int vflag)
{
pre_reverse(eflag,vflag);
}
/* ----------------------------------------------------------------------
store eflag, so can use it in post_force to request energy
------------------------------------------------------------------------- */
void FixMDIAimd::pre_reverse(int eflag, int /*vflag*/)
{
eflag_caller = eflag;
}
/* ---------------------------------------------------------------------- */
void FixMDIAimd::post_force(int vflag)
{
int eflag = eflag_caller;
ev_init(eflag,vflag);
// send current coords to MDI engine
// NOTE: need to gather them to proc 0
MDI_Send_command(">COORDS",engine);
MDI_Send(&atom->x[0][0],3*atom->nlocal,MDI_DOUBLE,engine);
// trigger engine to evaluate forces,energy,pressure for current system
MDI_Send_command("EVAL",engine);
// request energy from MDI engine
if (eflag_global) {
MDI_Send_command("<PE",engine);
MDI_Recv(&engine_energy,1,MDI_DOUBLE,engine);
}
// request pressure tensor from MDI engine, convert to virial
if (vflag_global) {
double ptensor[6];
MDI_Send_command("<PTENSOR",engine);
MDI_Recv(ptensor,6,MDI_DOUBLE,engine);
double volume = domain->xprd * domain->yprd * domain->zprd;
for (int i = 0; i < 6; i++)
virial[i] = ptensor[i] * volume / force->nktv2p;
}
// request forces from MDI engine
// NOTE: need to scatter to procs, then add to my local forces
MDI_Send_command("<FORCES",engine);
MDI_Recv(&atom->f[0][0],3*atom->nlocal,MDI_DOUBLE,engine);
}
/* ---------------------------------------------------------------------- */
void FixMDIAimd::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
energy from MDI engine
------------------------------------------------------------------------- */
double FixMDIAimd::compute_scalar()
{
return engine_energy;
}

55
src/MDI/fix_mdi_aimd.h Normal file
View File

@ -0,0 +1,55 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(mdi/aimd,FixMDIAimd);
// clang-format on
#else
#ifndef LMP_FIX_MDI_AIMD_H
#define LMP_FIX_MDI_AIMD_H
#include "fix.h"
#include <mdi.h>
namespace LAMMPS_NS {
class FixMDIAimd : public Fix {
public:
FixMDIAimd(class LAMMPS *, int, char **);
~FixMDIAimd();
int setmask();
void setup(int);
void setup_pre_reverse(int, int);
void pre_reverse(int, int);
void post_force(int);
void min_post_force(int);
double compute_scalar();
private:
int eflag_caller;
double engine_energy;
MDI_Comm engine;
};
}
#endif
#endif
/* ERROR/WARNING messages:
*/

View File

@ -378,6 +378,9 @@ char *FixMDIEngine::engine_mode(const char *node)
fprintf(logfile,"MDI ENGINE MODE: %i\n",node);
*/
printf("ENG NODE ENTRY eng/driver %s %s %d %d\n",
node,target_node,strlen(node),strlen(target_node));
// do not process commands if engine and driver are not at same node
// target_node = node that driver has set via a @ command
// current_node = node that engine (LAMMPS) has set
@ -402,10 +405,14 @@ char *FixMDIEngine::engine_mode(const char *node)
// execute the command
printf("RECV CMD %s\n",command);
this->execute_command(command, driver_socket);
// check if the target node is something other than the current node
printf("ENG NODES eng/driver %s %s %d %d\n",
node,target_node,strlen(node),strlen(target_node));
if (strcmp(target_node, "\0") != 0 && strcmp(target_node, current_node) != 0)
local_exit_flag = true;
}

View File

@ -0,0 +1,79 @@
/* ----------------------------------------------------------------------
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 "error.h"
#include "fix_mdi_engine2.h"
#include "mdi_engine2.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixMDIEngine2::FixMDIEngine2(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR, "Illegal fix mdi/engine command");
}
/* ---------------------------------------------------------------------- */
int FixMDIEngine2::setmask()
{
int mask = 0;
mask |= POST_INTEGRATE;
mask |= POST_FORCE;
mask |= MIN_PRE_FORCE;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixMDIEngine2::min_setup(int vflag)
{
mdi_engine->engine_node("@FORCES");
}
/* ---------------------------------------------------------------------- */
void FixMDIEngine2::post_integrate()
{
mdi_engine->engine_node("@COORDS");
}
/* ---------------------------------------------------------------------- */
void FixMDIEngine2::min_pre_force(int vflag)
{
mdi_engine->engine_node("@COORDS");
}
/* ---------------------------------------------------------------------- */
void FixMDIEngine2::min_post_force(int vflag)
{
mdi_engine->engine_node("@FORCES");
}
/* ---------------------------------------------------------------------- */
void FixMDIEngine2::post_force(int vflag)
{
mdi_engine->engine_node("@FORCES");
}

81
src/MDI/fix_mdi_engine2.h Normal file
View File

@ -0,0 +1,81 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
// clang-format off
FixStyle(mdi/engine2, FixMDIEngine2);
// clang-format on
#else
#ifndef LMP_FIX_MDI_ENGINE2_H
#define LMP_FIX_MDI_ENGINE2_H
#include "fix.h"
namespace LAMMPS_NS {
class FixMDIEngine2 : public Fix {
public:
class MDIEngine2 *mdi_engine;
FixMDIEngine2(class LAMMPS *, int, char **);
~FixMDIEngine2() {}
int setmask();
void init() {}
void min_setup(int);
void post_integrate();
void post_force(int);
void min_pre_force(int);
void min_post_force(int);
};
} // namespace LAMMPS_NS
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory.
E: Potential energy ID for fix mdi does not exist
Self-explanatory.
E: Cannot use MDI command without atom IDs
Self-explanatory.
E: MDI command requires consecutive atom IDs
Self-explanatory.
E: Unable to connect to driver
Self-explanatory.
E: Unable to ... driver
Self-explanatory.
E: Unknown command from driver
The driver sent a command that is not supported by the LAMMPS
interface. In some cases this might be because a nonsensical
command was sent (i.e. "SCF"). In other cases, the LAMMPS
interface might benefit from being expanded.
*/

View File

@ -13,11 +13,13 @@
// ----------------------------------------------------------------------
// MolSSI Driver Interface functions
// these are added to LAMMPS library interface when MDI package is included
// ----------------------------------------------------------------------
#include "library_mdi.h"
// needed to enable MPI support
#define LAMMPS_LIB_MPI 1
#include "library.h"
@ -27,6 +29,8 @@
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
/** Initialize an instance of LAMMPS as an MDI plugin
*
\verbatim embed:rst
@ -51,6 +55,7 @@ command-line argument, which must be provided by the MDI driver.
int MDI_Plugin_init_lammps()
{
// initialize MDI
int mdi_argc;
char **mdi_argv;
if (MDI_Plugin_get_argc(&mdi_argc)) MPI_Abort(MPI_COMM_WORLD, 1);
@ -58,30 +63,36 @@ int MDI_Plugin_init_lammps()
if (MDI_Init(&mdi_argc, &mdi_argv)) MPI_Abort(MPI_COMM_WORLD, 1);
// get the MPI intra-communicator for this code
MPI_Comm mpi_world_comm = MPI_COMM_WORLD;
if (MDI_MPI_get_world_comm(&mpi_world_comm)) MPI_Abort(MPI_COMM_WORLD, 1);
// find the -in argument
int iarg = 0;
char *filename;
bool found_filename = false;
while (iarg < mdi_argc && !found_filename) {
if ((strcmp(mdi_argv[iarg], "-in") == 0) || (strcmp(mdi_argv[iarg], "-i") == 0)) {
if ((strcmp(mdi_argv[iarg], "-in") == 0) ||
(strcmp(mdi_argv[iarg], "-i") == 0)) {
if (iarg + 2 > mdi_argc) MPI_Abort(MPI_COMM_WORLD, 1);
filename = mdi_argv[iarg + 1];
found_filename = true;
// remove -in argument from the command list
mdi_argc -= 2;
for (int jarg = iarg; jarg < mdi_argc; jarg++) mdi_argv[jarg] = mdi_argv[jarg + 2];
for (int jarg = iarg; jarg < mdi_argc; jarg++)
mdi_argv[jarg] = mdi_argv[jarg + 2];
}
iarg++;
}
if (!found_filename) MPI_Abort(MPI_COMM_WORLD, 1);
// create and run a LAMMPS instance
void *lmp = nullptr;
if (lammps_config_has_mpi_support() > 0)
lmp = lammps_open(mdi_argc, mdi_argv, mpi_world_comm, nullptr);
@ -93,6 +104,8 @@ int MDI_Plugin_init_lammps()
return 0;
}
/* ---------------------------------------------------------------------- */
/** Execute an MDI command
*
\verbatim embed:rst

1426
src/MDI/mdi_engine2.cpp Normal file

File diff suppressed because it is too large Load Diff

128
src/MDI/mdi_engine2.h Normal file
View File

@ -0,0 +1,128 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef COMMAND_CLASS
// clang-format off
CommandStyle(mdi,MDIEngine2);
// clang-format on
#else
#ifndef LMP_MDI_ENGINE2_H
#define LMP_MDI_ENGINE2_H
#include "command.h"
#include "mdi.h"
namespace LAMMPS_NS {
class MDIEngine2 : public Command {
public:
MDIEngine2(LAMMPS *lmp) : Command(lmp) {}
virtual ~MDIEngine2() {}
void command(int, char **);
int execute_command(const char *command, MDI_Comm mdicomm);
void engine_node(const char *node);
private:
int lmpunits; // REAL or METAL or NATIVE
int root; // 1 for proc 0, otherwise 0
// state of MDI engine
int mode; // which mode engine is in (DEFAULT,MD,OPTG,etc)
char *mdicmd; // current MDI command being processed
char *node_engine; // which node engine is at
char *node_driver; // which node driver has requested
bool node_match; // true if driver and engine node currently match
bool exit_command; // true if EXIT command received from driver
MDI_Comm mdicomm;
class FixMDIEngine2 *mdi_fix;
char *id_ke,*id_pe,*id_press;
class Irregular *irregular;
class Minimize *minimizer;
class Compute *ke,*pe,*press;
int length_param; // LENGTH command value used by other commands
// unit conversion factors;
double lmp2mdi_length,mdi2lmp_length;
double lmp2mdi_energy,mdi2lmp_energy;
double lmp2mdi_velocity,mdi2lmp_velocity;
double lmp2mdi_force,mdi2lmp_force;
double lmp2mdi_pressure,mdi2lmp_pressure;
double lmp2mdi_virial,mdi2lmp_virial;
// buffers for MDI comm
int maxbuf;
double *buf1,*buf1all;
double *buf3,*buf3all;
int *ibuf1,*ibuf1all;
// class methods
void mdi_engine(int, char **);
void mdi_commands();
void mdi_md();
void mdi_optg();
void receive_double1(int);
void receive_int1(int);
void receive_double3(int, int);
void send_double1(int);
void send_int1(int);
void send_double3(int);
void send_labels();
void send_energy();
void send_pe();
void send_ke();
void send_cell();
void receive_cell();
void send_celldispl();
void receive_celldispl();
void length_command();
void single_command();
void many_commands();
void infile();
void evaluate();
void reset_box();
void create_atoms();
void send_pressure();
void send_ptensor();
void unit_conversions();
void reallocate();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
*/

View File

@ -739,7 +739,8 @@ double Comm::get_comm_cutoff()
error->warning(FLERR,"Communication cutoff adjusted to {}",maxcommcutoff);
}
// Check maximum interval size for neighbor multi
// check maximum interval size for neighbor multi
if (neighbor->interval_collection_flag) {
for (int i = 0; i < neighbor->ncollections; i++){
maxcommcutoff = MAX(maxcommcutoff, neighbor->collection2cut[i]);