149 lines
3.6 KiB
C++
149 lines
3.6 KiB
C++
// clang-format off
|
|
/* ----------------------------------------------------------------------
|
|
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 "server_mc.h"
|
|
#include "atom.h"
|
|
#include "domain.h"
|
|
#include "update.h"
|
|
#include "integrate.h"
|
|
#include "input.h"
|
|
#include "output.h"
|
|
#include "thermo.h"
|
|
#include "error.h"
|
|
|
|
// CSlib interface
|
|
|
|
#include "cslib.h"
|
|
|
|
using namespace LAMMPS_NS;
|
|
using namespace CSLIB_NS;
|
|
|
|
enum{NATOMS=1,EINIT,DISPLACE,ACCEPT,RUN};
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
ServerMC::ServerMC(LAMMPS *lmp) : Pointers(lmp) {}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
void ServerMC::loop()
|
|
{
|
|
int m;
|
|
double xold[3];
|
|
tagint atomid;
|
|
|
|
CSlib *cs = (CSlib *) lmp->cslib;
|
|
|
|
if (domain->box_exist == 0)
|
|
error->all(FLERR,"Server command before simulation box is defined");
|
|
|
|
if (atom->map_style == Atom::MAP_NONE) error->all(FLERR,"Server mc requires atom map");
|
|
if (atom->tag_enable == 0) error->all(FLERR,"Server mc requires atom IDs");
|
|
if (sizeof(tagint) != 4) error->all(FLERR,"Server mc requires 32-bit atom IDs");
|
|
|
|
// initialize LAMMPS for dynamics
|
|
|
|
input->one("run 0");
|
|
|
|
// loop on messages
|
|
// receive a message, process it, send return message if necessary
|
|
|
|
int msgID,nfield;
|
|
int *fieldID,*fieldtype,*fieldlen;
|
|
|
|
while (1) {
|
|
msgID = cs->recv(nfield,fieldID,fieldtype,fieldlen);
|
|
if (msgID < 0) break;
|
|
|
|
if (msgID == NATOMS) {
|
|
|
|
cs->send(msgID,1);
|
|
cs->pack_int(1,atom->natoms);
|
|
|
|
} else if (msgID == EINIT) {
|
|
|
|
double dval;
|
|
output->thermo->evaluate_keyword((char *) "pe",&dval);
|
|
|
|
cs->send(msgID,2);
|
|
cs->pack_double(1,dval);
|
|
double *coords = nullptr;
|
|
if (atom->nlocal) coords = &atom->x[0][0];
|
|
cs->pack_parallel(2,4,atom->nlocal,atom->tag,3,coords);
|
|
|
|
} else if (msgID == DISPLACE) {
|
|
|
|
atomid = cs->unpack_int(1);
|
|
double *xnew = (double *) cs->unpack(2);
|
|
double **x = atom->x;
|
|
|
|
m = atom->map(atomid);
|
|
if (m >= 0 && m < atom->nlocal) {
|
|
xold[0] = x[m][0];
|
|
xold[1] = x[m][1];
|
|
xold[2] = x[m][2];
|
|
x[m][0] = xnew[0];
|
|
x[m][1] = xnew[1];
|
|
x[m][2] = xnew[2];
|
|
}
|
|
|
|
input->one("run 0");
|
|
double dval;
|
|
output->thermo->evaluate_keyword((char *) "pe",&dval);
|
|
|
|
cs->send(msgID,1);
|
|
cs->pack_double(1,dval);
|
|
|
|
} else if (msgID == ACCEPT) {
|
|
|
|
int accept = cs->unpack_int(1);
|
|
double **x = atom->x;
|
|
|
|
if (!accept) {
|
|
m = atom->map(atomid);
|
|
if (m >= 0 && m < atom->nlocal) {
|
|
x[m][0] = xold[0];
|
|
x[m][1] = xold[1];
|
|
x[m][2] = xold[2];
|
|
}
|
|
}
|
|
|
|
cs->send(msgID,0);
|
|
|
|
} else if (msgID == RUN) {
|
|
|
|
int nsteps = cs->unpack_int(1);
|
|
|
|
update->nsteps = nsteps;
|
|
update->firststep = update->ntimestep;
|
|
update->laststep = update->ntimestep + nsteps;
|
|
|
|
update->integrate->setup(1);
|
|
update->integrate->run(nsteps);
|
|
|
|
cs->send(msgID,0);
|
|
|
|
} else error->all(FLERR,"Server received unrecognized message");
|
|
}
|
|
|
|
// final reply to client
|
|
|
|
cs->send(0,0);
|
|
|
|
// clean up
|
|
|
|
delete cs;
|
|
lmp->cslib = nullptr;
|
|
}
|