git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@4695 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
66
examples/COUPLE/README
Normal file
66
examples/COUPLE/README
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
This directory has a C and C++ code that shows how LAMMPS can be
|
||||||
|
linked to a driver application as a library. The purpose is to
|
||||||
|
illustrate how another code could perform computations while using
|
||||||
|
LAMMPS to perform MD, or how an umbrella code or script could call
|
||||||
|
both LAMMPS and some other code to perform a coupled calculation.
|
||||||
|
|
||||||
|
c_driver.c is the C driver
|
||||||
|
c++_driver.c is the C++ driver
|
||||||
|
|
||||||
|
The 2 codes do the same thing, so you can compare them to see how to
|
||||||
|
drive LAMMPS in this manner. The C driver is similar in spirit to
|
||||||
|
what one could use from a Fortran program or scripting language.
|
||||||
|
|
||||||
|
LAMMPS must first be built as a library. See the "Making LAMMPS"
|
||||||
|
section of Section_start.html in the documentation for info on how to
|
||||||
|
do this. Basically, you type something like
|
||||||
|
|
||||||
|
make makelib
|
||||||
|
make -f Makefile.lib g++
|
||||||
|
|
||||||
|
in the LAMMPS src directory to create liblmp_g++.a
|
||||||
|
|
||||||
|
You can then build either driver code with a compile line something
|
||||||
|
like this, which includes paths to the LAMMPS library interface, MPI,
|
||||||
|
and FFTW.
|
||||||
|
|
||||||
|
This builds the C++ driver with the LAMMPS library using a C++ compiler:
|
||||||
|
|
||||||
|
g++ -I/home/sjplimp/lammps/src -c c++_driver.cpp
|
||||||
|
g++ -L/home/sjplimp/lammps/src c++_driver.o \
|
||||||
|
-llmp_g++ -lfftw -lmpich -lpthread -o c++_driver
|
||||||
|
|
||||||
|
This builds the C driver with the LAMMPS library using a C compiler:
|
||||||
|
|
||||||
|
gcc -I/home/sjplimp/lammps/src -c c_driver.cpp
|
||||||
|
gcc -L/home/sjplimp/lammps/src c_driver.o \
|
||||||
|
-llmp_g++ -lfftw -lmpich -lpthread -lstdc++ -o c_driver
|
||||||
|
|
||||||
|
You then run c++_driver or c_driver on a parallel machine on some
|
||||||
|
number of processors Q with 2 arguments:
|
||||||
|
|
||||||
|
mpirun -np Q c_driver P in.lj
|
||||||
|
|
||||||
|
P is the number of procs you want LAMMPS to run on (must be <= Q).
|
||||||
|
In.lj is a LAMMPS input script.
|
||||||
|
|
||||||
|
The driver will launch LAMMPS on P procs, read the input script a line
|
||||||
|
at a time, and pass each command line to LAMMPS. The final line of
|
||||||
|
the script is a "run" command, so LAMMPS will run the problem.
|
||||||
|
|
||||||
|
The driver then requests all the atom coordinates from LAMMPS, moves
|
||||||
|
one of the atoms a small amount "epsilon", passes the coordinates back
|
||||||
|
to LAMMPS, and runs LAMMPS again. If you look at the output, you
|
||||||
|
should see a small energy change between runs, due to the moved atom.
|
||||||
|
|
||||||
|
The C driver is calling C-style routines in the src/library.cpp file
|
||||||
|
of LAMMPS. You could add any functions you wish to this file to
|
||||||
|
manipulate LAMMPS data however you wish.
|
||||||
|
|
||||||
|
The C++ driver does the same thing, except that it instantiates LAMMPS
|
||||||
|
as an object first. Some of the functions in src/library.cpp can be
|
||||||
|
invoked directly as methods within appropriate LAMMPS classes, which
|
||||||
|
is what the driver does. Any public LAMMPS class method could be
|
||||||
|
called from the driver this way. However the get/put functions are
|
||||||
|
only implemented in src/library.cpp, so the C++ driver calls them as
|
||||||
|
C-style functions.
|
||||||
121
examples/COUPLE/c++_driver.cpp
Normal file
121
examples/COUPLE/c++_driver.cpp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||||
|
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||||
|
|
||||||
|
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.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// c++_driver = simple example of how an umbrella program
|
||||||
|
// can invoke LAMMPS as a library on some subset of procs
|
||||||
|
// Syntax: c++_driver P in.lammps
|
||||||
|
// P = # of procs to run LAMMPS on
|
||||||
|
// must be <= # of procs the driver code itself runs on
|
||||||
|
// in.lammps = LAMMPS input script
|
||||||
|
// See README for compilation instructions
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "mpi.h"
|
||||||
|
#include "lammps.h" // these are LAMMPS include files
|
||||||
|
#include "input.h"
|
||||||
|
#include "atom.h"
|
||||||
|
#include "library.h"
|
||||||
|
|
||||||
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
int main(int narg, char **arg)
|
||||||
|
{
|
||||||
|
// setup MPI and various communicators
|
||||||
|
// driver runs on all procs in MPI_COMM_WORLD
|
||||||
|
// comm_lammps only has 1st P procs (could be all or any subset)
|
||||||
|
|
||||||
|
MPI_Init(&narg,&arg);
|
||||||
|
|
||||||
|
if (narg != 3) {
|
||||||
|
printf("Syntax: c++_driver P in.lammps\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int me,nprocs;
|
||||||
|
MPI_Comm_rank(MPI_COMM_WORLD,&me);
|
||||||
|
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
|
||||||
|
|
||||||
|
int nprocs_lammps = atoi(arg[1]);
|
||||||
|
if (nprocs_lammps > nprocs) {
|
||||||
|
if (me == 0)
|
||||||
|
printf("ERROR: LAMMPS cannot use more procs than available\n");
|
||||||
|
MPI_Abort(MPI_COMM_WORLD,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lammps;
|
||||||
|
if (me < nprocs_lammps) lammps = 1;
|
||||||
|
else lammps = MPI_UNDEFINED;
|
||||||
|
MPI_Comm comm_lammps;
|
||||||
|
MPI_Comm_split(MPI_COMM_WORLD,lammps,0,&comm_lammps);
|
||||||
|
|
||||||
|
// open LAMMPS input script
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
if (me == 0) {
|
||||||
|
fp = fopen(arg[2],"r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("ERROR: Could not open LAMMPS input script\n");
|
||||||
|
MPI_Abort(MPI_COMM_WORLD,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// run the input script thru LAMMPS one line at a time until end-of-file
|
||||||
|
// driver proc 0 reads a line, Bcasts it to all procs
|
||||||
|
// (could just send it to proc 0 of comm_lammps and let it Bcast)
|
||||||
|
// all LAMMPS procs call input->one() on the line
|
||||||
|
|
||||||
|
LAMMPS *lmp;
|
||||||
|
if (lammps == 1) lmp = new LAMMPS(0,NULL,comm_lammps);
|
||||||
|
|
||||||
|
int n;
|
||||||
|
char line[1024];
|
||||||
|
while (1) {
|
||||||
|
if (me == 0) {
|
||||||
|
if (fgets(line,1024,fp) == NULL) n = 0;
|
||||||
|
else n = strlen(line) + 1;
|
||||||
|
if (n == 0) fclose(fp);
|
||||||
|
}
|
||||||
|
MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
|
||||||
|
if (n == 0) break;
|
||||||
|
MPI_Bcast(line,n,MPI_CHAR,0,MPI_COMM_WORLD);
|
||||||
|
if (lammps == 1) lmp->input->one(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// run 10 more steps
|
||||||
|
// get coords from LAMMPS
|
||||||
|
// change coords of 1st atom
|
||||||
|
// put coords back into LAMMPS
|
||||||
|
// run a single step with changed coords
|
||||||
|
|
||||||
|
if (lammps == 1) {
|
||||||
|
lmp->input->one("run 10");
|
||||||
|
|
||||||
|
int natoms = static_cast<int> (lmp->atom->natoms);
|
||||||
|
double *x = new double[3*natoms];
|
||||||
|
lammps_get_coords(lmp,x); // no LAMMPS class function for this
|
||||||
|
double epsilon = 0.1;
|
||||||
|
x[0] += epsilon;
|
||||||
|
lammps_put_coords(lmp,x); // no LAMMPS class function for this
|
||||||
|
delete [] x;
|
||||||
|
|
||||||
|
lmp->input->one("run 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lammps == 1) delete lmp;
|
||||||
|
|
||||||
|
// close down MPI
|
||||||
|
|
||||||
|
MPI_Finalize();
|
||||||
|
}
|
||||||
116
examples/COUPLE/c_driver.c
Normal file
116
examples/COUPLE/c_driver.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||||
|
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||||
|
|
||||||
|
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.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* c_driver = simple example of how an umbrella program
|
||||||
|
can invoke LAMMPS as a library on some subset of procs
|
||||||
|
Syntax: c_driver P in.lammps
|
||||||
|
P = # of procs to run LAMMPS on
|
||||||
|
must be <= # of procs the driver code itself runs on
|
||||||
|
in.lammps = LAMMPS input script
|
||||||
|
See README for compilation instructions */
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "mpi.h"
|
||||||
|
#include "library.h" /* this is a LAMMPS include file */
|
||||||
|
|
||||||
|
int main(int narg, char **arg)
|
||||||
|
{
|
||||||
|
/* setup MPI and various communicators
|
||||||
|
driver runs on all procs in MPI_COMM_WORLD
|
||||||
|
comm_lammps only has 1st P procs (could be all or any subset) */
|
||||||
|
|
||||||
|
MPI_Init(&narg,&arg);
|
||||||
|
|
||||||
|
if (narg != 3) {
|
||||||
|
printf("Syntax: c_driver P in.lammps\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int me,nprocs;
|
||||||
|
MPI_Comm_rank(MPI_COMM_WORLD,&me);
|
||||||
|
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
|
||||||
|
|
||||||
|
int nprocs_lammps = atoi(arg[1]);
|
||||||
|
if (nprocs_lammps > nprocs) {
|
||||||
|
if (me == 0)
|
||||||
|
printf("ERROR: LAMMPS cannot use more procs than available\n");
|
||||||
|
MPI_Abort(MPI_COMM_WORLD,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lammps;
|
||||||
|
if (me < nprocs_lammps) lammps = 1;
|
||||||
|
else lammps = MPI_UNDEFINED;
|
||||||
|
MPI_Comm comm_lammps;
|
||||||
|
MPI_Comm_split(MPI_COMM_WORLD,lammps,0,&comm_lammps);
|
||||||
|
|
||||||
|
/* open LAMMPS input script */
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
if (me == 0) {
|
||||||
|
fp = fopen(arg[2],"r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("ERROR: Could not open LAMMPS input script\n");
|
||||||
|
MPI_Abort(MPI_COMM_WORLD,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* run the input script thru LAMMPS one line at a time until end-of-file
|
||||||
|
driver proc 0 reads a line, Bcasts it to all procs
|
||||||
|
(could just send it to proc 0 of comm_lammps and let it Bcast)
|
||||||
|
all LAMMPS procs call lammps_command() on the line */
|
||||||
|
|
||||||
|
void *ptr;
|
||||||
|
if (lammps == 1) lammps_open(0,NULL,comm_lammps,&ptr);
|
||||||
|
|
||||||
|
int n;
|
||||||
|
char line[1024];
|
||||||
|
while (1) {
|
||||||
|
if (me == 0) {
|
||||||
|
if (fgets(line,1024,fp) == NULL) n = 0;
|
||||||
|
else n = strlen(line) + 1;
|
||||||
|
if (n == 0) fclose(fp);
|
||||||
|
}
|
||||||
|
MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
|
||||||
|
if (n == 0) break;
|
||||||
|
MPI_Bcast(line,n,MPI_CHAR,0,MPI_COMM_WORLD);
|
||||||
|
if (lammps == 1) lammps_command(ptr,line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* run 10 more steps
|
||||||
|
get coords from LAMMPS
|
||||||
|
change coords of 1st atom
|
||||||
|
put coords back into LAMMPS
|
||||||
|
run a single step with changed coords */
|
||||||
|
|
||||||
|
if (lammps == 1) {
|
||||||
|
lammps_command(ptr,"run 10");
|
||||||
|
|
||||||
|
int natoms = lammps_get_natoms(ptr);
|
||||||
|
double *x = (double *) malloc(3*natoms*sizeof(double));
|
||||||
|
lammps_get_coords(ptr,x);
|
||||||
|
double epsilon = 0.1;
|
||||||
|
x[0] += epsilon;
|
||||||
|
lammps_put_coords(ptr,x);
|
||||||
|
free(x);
|
||||||
|
|
||||||
|
lammps_command(ptr,"run 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lammps == 1) lammps_close(ptr);
|
||||||
|
|
||||||
|
/* close down MPI */
|
||||||
|
|
||||||
|
MPI_Finalize();
|
||||||
|
}
|
||||||
24
examples/COUPLE/in.lj
Normal file
24
examples/COUPLE/in.lj
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# 3d Lennard-Jones melt
|
||||||
|
|
||||||
|
units lj
|
||||||
|
atom_style atomic
|
||||||
|
atom_modify map array
|
||||||
|
|
||||||
|
lattice fcc 0.8442
|
||||||
|
region box block 0 4 0 4 0 4
|
||||||
|
create_box 1 box
|
||||||
|
create_atoms 1 box
|
||||||
|
mass 1 1.0
|
||||||
|
|
||||||
|
velocity all create 1.44 87287 loop geom
|
||||||
|
|
||||||
|
pair_style lj/cut 2.5
|
||||||
|
pair_coeff 1 1 1.0 1.0 2.5
|
||||||
|
|
||||||
|
neighbor 0.3 bin
|
||||||
|
neigh_modify delay 0 every 20 check no
|
||||||
|
|
||||||
|
fix 1 all nve
|
||||||
|
|
||||||
|
run 10
|
||||||
|
|
||||||
Reference in New Issue
Block a user