git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@8636 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
@ -34,5 +34,7 @@ library collection of useful inter-code communication routines
|
|||||||
simple simple example of driver code calling LAMMPS as library
|
simple simple example of driver code calling LAMMPS as library
|
||||||
fortran a wrapper on the LAMMPS library API that
|
fortran a wrapper on the LAMMPS library API that
|
||||||
can be called from Fortran
|
can be called from Fortran
|
||||||
|
fortran2 a more sophisticated wrapper on the LAMMPS library API that
|
||||||
|
can be called from Fortran
|
||||||
|
|
||||||
Each sub-directory has its own README.
|
Each sub-directory has its own README.
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
libfwrapper.c is a C file that wraps the LAMMPS library API
|
libfwrapper.c is a C file that wraps the LAMMPS library API
|
||||||
in src/library.h so that it can be called from Fortran.
|
in src/library.h so that it can be called from Fortran.
|
||||||
|
|
||||||
See the couple/simple/simple.f90 program for an example
|
See the couple/simple/simple.f90 program for an example of a Fortran
|
||||||
of a Fortran code that does this.
|
code that does this.
|
||||||
|
|
||||||
See the README file in that dir for instructions
|
See the README file in that dir for instructions on how to build a
|
||||||
on how to build a Fortran code that uses this
|
Fortran code that uses this wrapper and links to the LAMMPS library.
|
||||||
wrapper and links to the LAMMPS library.
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
#include "library.h" /* this is a LAMMPS include file */
|
#include "library.h" /* this is a LAMMPS include file */
|
||||||
|
|
||||||
/* wrapper for creating a lammps instance from fortran.
|
/* wrapper for creating a lammps instance from fortran.
|
||||||
since fortran has no simple way to emit a c-compatible
|
since fortran has no simple way to emit a C-compatible
|
||||||
argument array, we don't support it. for simplicity,
|
argument array, we don't support it. for simplicity,
|
||||||
the address of the pointer to the lammps object is
|
the address of the pointer to the lammps object is
|
||||||
stored in a 64-bit integer on all platforms. */
|
stored in a 64-bit integer on all platforms. */
|
||||||
@ -109,6 +109,8 @@ void lammps_get_natoms_(int64_t *ptr, MPI_Fint *natoms)
|
|||||||
|
|
||||||
/* wrapper to copy coordinates from lammps to fortran */
|
/* wrapper to copy coordinates from lammps to fortran */
|
||||||
|
|
||||||
|
/* NOTE: this is now out-of-date, needs to be updated to lammps_gather_atoms()
|
||||||
|
|
||||||
void lammps_get_coords_(int64_t *ptr, double *coords)
|
void lammps_get_coords_(int64_t *ptr, double *coords)
|
||||||
{
|
{
|
||||||
void *obj;
|
void *obj;
|
||||||
@ -117,8 +119,12 @@ void lammps_get_coords_(int64_t *ptr, double *coords)
|
|||||||
lammps_get_coords(obj,coords);
|
lammps_get_coords(obj,coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* wrapper to copy coordinates from fortran to lammps */
|
/* wrapper to copy coordinates from fortran to lammps */
|
||||||
|
|
||||||
|
/* NOTE: this is now out-of-date, needs to be updated to lammps_scatter_atoms()
|
||||||
|
|
||||||
void lammps_put_coords_(int64_t *ptr, double *coords)
|
void lammps_put_coords_(int64_t *ptr, double *coords)
|
||||||
{
|
{
|
||||||
void *obj;
|
void *obj;
|
||||||
@ -127,3 +133,4 @@ void lammps_put_coords_(int64_t *ptr, double *coords)
|
|||||||
lammps_put_coords(obj,coords);
|
lammps_put_coords(obj,coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|||||||
235
examples/COUPLE/fortran2/LAMMPS-wrapper.cpp
Normal file
235
examples/COUPLE/fortran2/LAMMPS-wrapper.cpp
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------
|
||||||
|
Contributing author: Karl D. Hammond <karlh@ugcs.caltech.edu>
|
||||||
|
University of Tennessee, Knoxville (USA), 2012
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself
|
||||||
|
provides a (I hope) robust Fortran interface to library.cpp and
|
||||||
|
library.h. All functions herein COULD be added to library.cpp instead of
|
||||||
|
including this as a separate file. See the README for instructions. */
|
||||||
|
|
||||||
|
#include <mpi.h>
|
||||||
|
#include "LAMMPS-wrapper.h"
|
||||||
|
#include <library.h>
|
||||||
|
#include <lammps.h>
|
||||||
|
#include <atom.h>
|
||||||
|
#include <fix.h>
|
||||||
|
#include <compute.h>
|
||||||
|
#include <modify.h>
|
||||||
|
#include <error.h>
|
||||||
|
|
||||||
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
void lammps_open_fortran_wrapper (int argc, char **argv,
|
||||||
|
MPI_Fint communicator, void **ptr)
|
||||||
|
{
|
||||||
|
MPI_Comm C_communicator = MPI_Comm_f2c (communicator);
|
||||||
|
lammps_open (argc, argv, C_communicator, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lammps_get_ntypes (void *ptr)
|
||||||
|
{
|
||||||
|
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||||
|
int ntypes = lmp->atom->ntypes;
|
||||||
|
return ntypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lammps_error_all (void *ptr, const char *file, int line, const char *str)
|
||||||
|
{
|
||||||
|
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||||
|
lmp->error->all (file, line, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lammps_extract_compute_vectorsize (void *ptr, char *id, int style)
|
||||||
|
{
|
||||||
|
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||||
|
int icompute = lmp->modify->find_compute(id);
|
||||||
|
if ( icompute < 0 ) return 0;
|
||||||
|
class Compute *compute = lmp->modify->compute[icompute];
|
||||||
|
|
||||||
|
if ( style == 0 )
|
||||||
|
{
|
||||||
|
if ( !compute->vector_flag )
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return compute->size_vector;
|
||||||
|
}
|
||||||
|
else if ( style == 1 )
|
||||||
|
{
|
||||||
|
return lammps_get_natoms (ptr);
|
||||||
|
}
|
||||||
|
else if ( style == 2 )
|
||||||
|
{
|
||||||
|
if ( !compute->local_flag )
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return compute->size_local_rows;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lammps_extract_compute_arraysize (void *ptr, char *id, int style,
|
||||||
|
int *nrows, int *ncols)
|
||||||
|
{
|
||||||
|
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||||
|
int icompute = lmp->modify->find_compute(id);
|
||||||
|
if ( icompute < 0 )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
class Compute *compute = lmp->modify->compute[icompute];
|
||||||
|
|
||||||
|
if ( style == 0 )
|
||||||
|
{
|
||||||
|
if ( !compute->array_flag )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = compute->size_array_rows;
|
||||||
|
*ncols = compute->size_array_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( style == 1 )
|
||||||
|
{
|
||||||
|
if ( !compute->peratom_flag )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = lammps_get_natoms (ptr);
|
||||||
|
*ncols = compute->size_peratom_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( style == 2 )
|
||||||
|
{
|
||||||
|
if ( !compute->local_flag )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = compute->size_local_rows;
|
||||||
|
*ncols = compute->size_local_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lammps_extract_fix_vectorsize (void *ptr, char *id, int style)
|
||||||
|
{
|
||||||
|
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||||
|
int ifix = lmp->modify->find_fix(id);
|
||||||
|
if ( ifix < 0 ) return 0;
|
||||||
|
class Fix *fix = lmp->modify->fix[ifix];
|
||||||
|
|
||||||
|
if ( style == 0 )
|
||||||
|
{
|
||||||
|
if ( !fix->vector_flag )
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return fix->size_vector;
|
||||||
|
}
|
||||||
|
else if ( style == 1 )
|
||||||
|
{
|
||||||
|
return lammps_get_natoms (ptr);
|
||||||
|
}
|
||||||
|
else if ( style == 2 )
|
||||||
|
{
|
||||||
|
if ( !fix->local_flag )
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return fix->size_local_rows;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lammps_extract_fix_arraysize (void *ptr, char *id, int style,
|
||||||
|
int *nrows, int *ncols)
|
||||||
|
{
|
||||||
|
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||||
|
int ifix = lmp->modify->find_fix(id);
|
||||||
|
if ( ifix < 0 )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
class Fix *fix = lmp->modify->fix[ifix];
|
||||||
|
|
||||||
|
if ( style == 0 )
|
||||||
|
{
|
||||||
|
if ( !fix->array_flag )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = fix->size_array_rows;
|
||||||
|
*ncols = fix->size_array_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( style == 1 )
|
||||||
|
{
|
||||||
|
if ( !fix->peratom_flag )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = lammps_get_natoms (ptr);
|
||||||
|
*ncols = fix->size_peratom_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( style == 2 )
|
||||||
|
{
|
||||||
|
if ( !fix->local_flag )
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = fix->size_local_rows;
|
||||||
|
*ncols = fix->size_local_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*nrows = 0;
|
||||||
|
*ncols = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ts=3 sts=3 expandtab: */
|
||||||
47
examples/COUPLE/fortran2/LAMMPS-wrapper.h
Normal file
47
examples/COUPLE/fortran2/LAMMPS-wrapper.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
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.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------
|
||||||
|
Contributing author: Karl D. Hammond <karlh@ugcs.caltech.edu>
|
||||||
|
University of Tennessee, Knoxville (USA), 2012
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself
|
||||||
|
provides a (I hope) robust Fortran interface to library.cpp and
|
||||||
|
library.h. All prototypes herein COULD be added to library.h instead of
|
||||||
|
including this as a separate file. See the README for instructions. */
|
||||||
|
|
||||||
|
/* These prototypes probably belong in mpi.h in the src/STUBS directory. */
|
||||||
|
#ifndef OPEN_MPI
|
||||||
|
#define MPI_Comm_f2c(a) a
|
||||||
|
#define MPI_Fint int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Prototypes for auxiliary functions */
|
||||||
|
void lammps_open_fortran_wrapper (int, char**, MPI_Fint, void**);
|
||||||
|
int lammps_get_ntypes (void*);
|
||||||
|
int lammps_extract_compute_vectorsize (void*, char*, int);
|
||||||
|
void lammps_extract_compute_arraysize (void*, char*, int, int*, int*);
|
||||||
|
int lammps_extract_fix_vectorsize (void*, char*, int);
|
||||||
|
void lammps_extract_fix_arraysize (void*, char*, int, int*, int*);
|
||||||
|
void lammps_error_all (void *ptr, const char*, int, const char*);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* vim: set ts=3 sts=3 expandtab: */
|
||||||
1094
examples/COUPLE/fortran2/LAMMPS.F90
Normal file
1094
examples/COUPLE/fortran2/LAMMPS.F90
Normal file
File diff suppressed because it is too large
Load Diff
213
examples/COUPLE/fortran2/README
Normal file
213
examples/COUPLE/fortran2/README
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
LAMMPS.F90 defines a Fortran 2003 module, LAMMPS, which wraps all functions in
|
||||||
|
src/library.h so they can be used directly from Fortran-encoded programs.
|
||||||
|
|
||||||
|
All functions in src/library.h that use and/or return C-style pointers have
|
||||||
|
Fortran wrapper functions that use Fortran-style arrays, pointers, and
|
||||||
|
strings; all C-style memory management is handled internally with no user
|
||||||
|
intervention.
|
||||||
|
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
--COMPILATION--
|
||||||
|
|
||||||
|
First, be advised that mixed-language programming is not trivial. It requires
|
||||||
|
you to link in the required libraries of all languages you use (in this case,
|
||||||
|
those for Fortran, C, and C++), as well as any other libraries required.
|
||||||
|
You are also advised to read the --USE-- section below before trying to
|
||||||
|
compile.
|
||||||
|
|
||||||
|
The following steps will work to compile this module (replace ${LAMMPS_SRC}
|
||||||
|
with the path to your LAMMPS source directory):
|
||||||
|
(1) Compile LAMMPS as a static library. Call the resulting file ${LAMMPS_LIB},
|
||||||
|
which will have an actual name lake liblmp_openmpi.a. If compiling
|
||||||
|
using the MPI stubs in ${LAMMPS_SRC}/STUBS, you will need to know where
|
||||||
|
libmpi.a is as well (I'll call it ${MPI_STUBS} hereafter)
|
||||||
|
(2) Copy said library to your Fortran program's source directory or include
|
||||||
|
its location in a -L${LAMMPS_SRC} flag to your compiler.
|
||||||
|
(3) Compile (but don't link!) LAMMPS.F90. Example:
|
||||||
|
mpif90 -c LAMMPS.f90
|
||||||
|
OR
|
||||||
|
gfortran -c LAMMPS.F90
|
||||||
|
Copy the LAMMPS.o and lammps.mod (or whatever your compiler calls module
|
||||||
|
files) to your Fortran program's source directory.
|
||||||
|
NOTE: you may get a warning such as,
|
||||||
|
subroutine lammps_open_wrapper (argc, argv, communicator, ptr) &
|
||||||
|
Variable 'communicator' at (1) is a parameter to the BIND(C)
|
||||||
|
procedure 'lammps_open_wrapper' but may not be C interoperable
|
||||||
|
This is normal (see --IMPLEMENTATION NOTES--).
|
||||||
|
(4) Compile (but don't link) LAMMPS-wrapper.cpp. You will need its header
|
||||||
|
file as well. You will have to provide the locations of LAMMPS's
|
||||||
|
header files. For example,
|
||||||
|
mpicxx -c -I${LAMMPS_SRC} LAMMPS-wrapper.cpp
|
||||||
|
OR
|
||||||
|
g++ -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp
|
||||||
|
OR
|
||||||
|
icpc -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp
|
||||||
|
Copy the resulting object file LAMMPS-wrapper.o to your Fortran program's
|
||||||
|
source directory.
|
||||||
|
(4b) OPTIONAL: Make a library so you can carry around two files instead of
|
||||||
|
three. Example:
|
||||||
|
ar rs liblammps_fortran.a LAMMPS.o LAMMPS-wrapper.o
|
||||||
|
This will create the file liblammps_fortran.a that you can use in place
|
||||||
|
of "LAMMPS.o LAMMPS-wrapper.o" in part (6). Note that you will still
|
||||||
|
need to have the .mod file from part (3).
|
||||||
|
|
||||||
|
It is also possible to add LAMMPS.o and LAMMPS-wrapper.o into the
|
||||||
|
LAMMPS library (e.g., liblmp_openmpi.a) instead of creating a separate
|
||||||
|
library, like so:
|
||||||
|
ar rs ${LAMMPS_LIB} LAMMPS.o LAMMPS-wrapper.o
|
||||||
|
In this case, you can now use the Fortran wrapper functions as if they
|
||||||
|
were part of the usual LAMMPS library interface (if you have the module
|
||||||
|
file visible to the compiler, that is).
|
||||||
|
(5) Compile your Fortran program. Example:
|
||||||
|
mpif90 -c myfreeformatfile.f90
|
||||||
|
mpif90 -c myfixedformatfile.f
|
||||||
|
OR
|
||||||
|
gfortran -c myfreeformatfile.f90
|
||||||
|
gfortran -c myfixedformatfile.f
|
||||||
|
The object files generated by these steps are collectively referred to
|
||||||
|
as ${my_object_files} in the next step(s).
|
||||||
|
|
||||||
|
IMPORTANT: If the Fortran module from part (3) is not in the current
|
||||||
|
directory or in one searched by the compiler for module files, you will
|
||||||
|
need to include that location via the -I flag to the compiler.
|
||||||
|
(6) Link everything together, including any libraries needed by LAMMPS (such
|
||||||
|
as the C++ standard library, the C math library, the JPEG library, fftw,
|
||||||
|
etc.) For example,
|
||||||
|
mpif90 LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
|
||||||
|
${LAMMPS_LIB} -lstdc++ -lm
|
||||||
|
OR
|
||||||
|
gfortran LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
|
||||||
|
${LAMMPS_LIB} ${MPI_STUBS} -lstdc++ -lm
|
||||||
|
OR
|
||||||
|
ifort LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
|
||||||
|
${LAMMPS_LIB} ${MPI_STUBS} -cxxlib -limf -lm
|
||||||
|
Any other required libraries (e.g. -ljpeg, -lfftw) should be added to
|
||||||
|
the end of this line.
|
||||||
|
|
||||||
|
You should now have a working executable.
|
||||||
|
|
||||||
|
Steps 3 and 4 above are accomplished, possibly after some modifications to
|
||||||
|
the makefile, by make using the attached makefile.
|
||||||
|
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
--USAGE--
|
||||||
|
|
||||||
|
To use this API, your program unit (PROGRAM/SUBROUTINE/FUNCTION/MODULE/etc.)
|
||||||
|
should look something like this:
|
||||||
|
program call_lammps
|
||||||
|
use LAMMPS
|
||||||
|
! Other modules, etc.
|
||||||
|
implicit none
|
||||||
|
type (lammps_instance) :: lmp ! This is a pointer to your LAMMPS instance
|
||||||
|
double precision :: fix
|
||||||
|
double precision, dimension(:), allocatable :: fix2
|
||||||
|
! Rest of declarations
|
||||||
|
call lammps_open_no_mpi ('lmp -in /dev/null -screen out.lammps',lmp)
|
||||||
|
! Set up rest of program here
|
||||||
|
call lammps_file (lmp, 'in.example')
|
||||||
|
call lammps_extract_fix (fix, lmp, '2', 0, 1, 1, 1)
|
||||||
|
call lammps_extract_fix (fix2, lmp, '4', 0, 2, 1, 1)
|
||||||
|
call lammps_close (lmp)
|
||||||
|
end program call_lammps
|
||||||
|
|
||||||
|
Important notes:
|
||||||
|
* All arguments which are char* variables in library.cpp are character (len=*)
|
||||||
|
variables here. For example,
|
||||||
|
call lammps_command (lmp, 'units metal')
|
||||||
|
will work as expected.
|
||||||
|
* The public functions (the only ones you can use) have interfaces as
|
||||||
|
described in the comments at the top of LAMMPS.F90. They are not always
|
||||||
|
the same as those in library.h, since C strings are replaced by Fortran
|
||||||
|
strings and the like.
|
||||||
|
* The module attempts to check whether you have done something stupid (such
|
||||||
|
as assign a 2D array to a scalar), but it's not perfect. For example, the
|
||||||
|
command
|
||||||
|
call lammps_extract_global (nlocal, ptr, 'nlocal')
|
||||||
|
will give nlocal correctly if nlocal is of type INTEGER, but it will give
|
||||||
|
the wrong answer if nlocal is of type REAL or DOUBLE PRECISION. This is a
|
||||||
|
feature of the (void*) type cast in library.cpp. There is no way I can
|
||||||
|
check this for you!
|
||||||
|
* You are allowed to use REAL or DOUBLE PRECISION floating-point numbers.
|
||||||
|
All LAMMPS data (which are of type REAL(C_double)) are rounded off if
|
||||||
|
placed in single precision variables. It is tacitly assumed that NO C++
|
||||||
|
variables are of type float; everything is int or double (since this is
|
||||||
|
all library.cpp currently handles).
|
||||||
|
* An example of a complete program is offered at the end of this file.
|
||||||
|
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
--TROUBLESHOOTING--
|
||||||
|
|
||||||
|
Compile-time errors probably indicate that your compiler is not new enough to
|
||||||
|
support Fortran 2003 features. For example, GCC 4.1.2 will not compile this
|
||||||
|
module, but GCC 4.4.0 will.
|
||||||
|
|
||||||
|
If your compiler balks at 'use, intrinsic :: ISO_C_binding,' try removing the
|
||||||
|
intrinsic part so it looks like an ordinary module. However, it is likely
|
||||||
|
that such a compiler will also have problems with everything else in the
|
||||||
|
file as well.
|
||||||
|
|
||||||
|
If you get a segfault as soon as the lammps_open call is made, check that you
|
||||||
|
compiled your program AND LAMMPS-header.cpp using the same MPI headers. Using
|
||||||
|
the stubs for one and the actual MPI library for the other will cause major
|
||||||
|
problems.
|
||||||
|
|
||||||
|
If you find run-time errors, please pass them along via the LAMMPS Users
|
||||||
|
mailing list. Please provide a minimal working example along with the names
|
||||||
|
and versions of the compilers you are using. Please make sure the error is
|
||||||
|
repeatable and is in MY code, not yours (generating a minimal working example
|
||||||
|
will usually ensure this anyway).
|
||||||
|
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
--IMPLEMENTATION NOTES--
|
||||||
|
|
||||||
|
The Fortran procedures have the same names as the C procedures, and
|
||||||
|
their purpose is the same, but they may take different arguments. Here are
|
||||||
|
some of the important differences:
|
||||||
|
* lammps_open and lammps_open_no_mpi take a string instead of argc and
|
||||||
|
argv. This is necessary because C and C++ have a very different way
|
||||||
|
of treating strings than Fortran.
|
||||||
|
* All C++ functions that accept char* pointers now accept Fortran-style
|
||||||
|
strings within this interface instead.
|
||||||
|
* All of the lammps_extract_[something] functions, which return void*
|
||||||
|
C-style pointers, have been replaced by generic subroutines that return
|
||||||
|
Fortran variables (which may be arrays). The first argument houses the
|
||||||
|
variable to be returned; all other arguments are identical except as
|
||||||
|
stipulated above. Note that it is not possible to declare generic
|
||||||
|
functions that are selected based solely on the type/kind/rank (TKR)
|
||||||
|
signature of the return value, only based on the TKR of the arguments.
|
||||||
|
* The SHAPE of the first argument to lammps_extract_[something] is checked
|
||||||
|
against the "shape" of the C array (e.g., double vs. double* vs. double**).
|
||||||
|
Calling a subroutine with arguments of inappropriate rank will result in an
|
||||||
|
error at run time.
|
||||||
|
* All arrays passed to subroutines must be ALLOCATABLE and are REALLOCATED
|
||||||
|
to fit the shape of the array LAMMPS will be returning.
|
||||||
|
* The indices i and j in lammps_extract_fix are used the same way they
|
||||||
|
are in f_ID[i][j] references in LAMMPS (i.e., starting from 1). This is
|
||||||
|
different than the way library.cpp uses these numbers, but is more
|
||||||
|
consistent with the way arrays are accessed in LAMMPS and in Fortran.
|
||||||
|
* The char* pointer normally returned by lammps_command is thrown away
|
||||||
|
in this version; note also that lammps_command is now a subroutine
|
||||||
|
instead of a function.
|
||||||
|
* The pointer to LAMMPS itself is of type(lammps_instance), which is itself
|
||||||
|
a synonym for type(C_ptr), part of ISO_C_BINDING. Type (C_ptr) is
|
||||||
|
C's void* data type. This should be the only C data type that needs to
|
||||||
|
be used by the end user.
|
||||||
|
* This module will almost certainly generate a compile-time warning,
|
||||||
|
such as,
|
||||||
|
subroutine lammps_open_wrapper (argc, argv, communicator, ptr) &
|
||||||
|
Variable 'communicator' at (1) is a parameter to the BIND(C)
|
||||||
|
procedure 'lammps_open_wrapper' but may not be C interoperable
|
||||||
|
This happens because lammps_open_wrapper actually takes a Fortran
|
||||||
|
INTEGER argument, whose type is defined by the MPI library itself. The
|
||||||
|
Fortran integer is converted to a C integer by the MPI library (if such
|
||||||
|
conversion is actually necessary).
|
||||||
|
* Unlike library.cpp, this module returns COPIES of the data LAMMPS actually
|
||||||
|
uses. This is done for safety reasons, as you should, in general, not be
|
||||||
|
overwriting LAMMPS data directly from Fortran. If you require this
|
||||||
|
functionality, it is possible to write another function that, for example,
|
||||||
|
returns a Fortran pointer that resolves to the C/C++ data instead of
|
||||||
|
copying the contents of that pointer to the original array as is done now.
|
||||||
15
examples/COUPLE/fortran2/in.simple
Normal file
15
examples/COUPLE/fortran2/in.simple
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
units metal
|
||||||
|
lattice bcc 3.1656
|
||||||
|
region simbox block 0 10 0 10 0 10
|
||||||
|
create_box 2 simbox
|
||||||
|
create_atoms 1 region simbox
|
||||||
|
pair_style eam/fs
|
||||||
|
pair_coeff * * path/to/my_potential.eam.fs A1 A2
|
||||||
|
mass 1 58.2 # These are made-up numbers
|
||||||
|
mass 2 28.3
|
||||||
|
velocity all create 1200.0 7474848 dist gaussian
|
||||||
|
fix 1 all nve
|
||||||
|
fix 2 all dt/reset 1 1E-5 1E-3 0.01 units box
|
||||||
|
fix 4 all ave/histo 10 5 100 0.5 1.5 50 f_2 file temp.histo ave running
|
||||||
|
thermo_style custom step dt temp press etotal f_4[1][1]
|
||||||
|
thermo 100
|
||||||
33
examples/COUPLE/fortran2/makefile
Normal file
33
examples/COUPLE/fortran2/makefile
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
# Path to LAMMPS extraction directory
|
||||||
|
LAMMPS_ROOT = ../svn-dist
|
||||||
|
LAMMPS_SRC = $(LAMMPS_ROOT)/src
|
||||||
|
|
||||||
|
# Remove the line below if using mpicxx/mpic++ as your C++ compiler
|
||||||
|
MPI_STUBS = $(LAMMPS_SRC)/STUBS
|
||||||
|
|
||||||
|
FC = gfortran # replace with your Fortran compiler
|
||||||
|
CXX = g++ # replace with your C++ compiler
|
||||||
|
|
||||||
|
# Flags for Fortran compiler, C++ compiler, and C preprocessor, respectively
|
||||||
|
FFLAGS = -O2
|
||||||
|
CXXFLAGS = -O2
|
||||||
|
CPPFLAGS =
|
||||||
|
|
||||||
|
all : liblammps_fortran.a
|
||||||
|
|
||||||
|
liblammps_fortran.a : LAMMPS.o LAMMPS-wrapper.o
|
||||||
|
$(AR) rs $@ $^
|
||||||
|
|
||||||
|
LAMMPS.o lammps.mod : LAMMPS.F90
|
||||||
|
$(FC) $(CPPFLAGS) $(FFLAGS) -c $<
|
||||||
|
|
||||||
|
LAMMPS-wrapper.o : LAMMPS-wrapper.cpp LAMMPS-wrapper.h
|
||||||
|
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -I$(LAMMPS_SRC) -I$(MPI_STUBS)
|
||||||
|
|
||||||
|
clean :
|
||||||
|
$(RM) *.o *.mod liblammps_fortran.a
|
||||||
|
|
||||||
|
dist :
|
||||||
|
tar -czf Fortran-interface.tar.gz LAMMPS-wrapper.h LAMMPS-wrapper.cpp LAMMPS.F90 makefile README
|
||||||
44
examples/COUPLE/fortran2/simple.f90
Normal file
44
examples/COUPLE/fortran2/simple.f90
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
program simple
|
||||||
|
|
||||||
|
use LAMMPS
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
type (lammps_instance) :: lmp
|
||||||
|
double precision :: compute, fix, fix2
|
||||||
|
double precision, dimension(:), allocatable :: compute_v, mass, r
|
||||||
|
double precision, dimension(:,:), allocatable :: x
|
||||||
|
real, dimension(:,:), allocatable :: x_r
|
||||||
|
|
||||||
|
call lammps_open_no_mpi ('',lmp)
|
||||||
|
call lammps_file (lmp, 'in.simple')
|
||||||
|
call lammps_command (lmp, 'run 500')
|
||||||
|
|
||||||
|
call lammps_extract_fix (fix, lmp, '2', 0, 1, 1, 1)
|
||||||
|
print *, 'Fix is ', fix
|
||||||
|
|
||||||
|
call lammps_extract_fix (fix2, lmp, '4', 0, 2, 1, 1)
|
||||||
|
print *, 'Fix 2 is ', fix2
|
||||||
|
|
||||||
|
call lammps_extract_compute (compute, lmp, 'thermo_temp', 0, 0)
|
||||||
|
print *, 'Compute is ', compute
|
||||||
|
|
||||||
|
call lammps_extract_compute (compute_v, lmp, 'thermo_temp', 0, 1)
|
||||||
|
print *, 'Vector is ', compute_v
|
||||||
|
|
||||||
|
call lammps_extract_atom (mass, lmp, 'mass')
|
||||||
|
print *, 'Mass is ', mass
|
||||||
|
|
||||||
|
call lammps_extract_atom (x, lmp, 'x')
|
||||||
|
if ( .not. allocated (x) ) print *, 'x is not allocated'
|
||||||
|
print *, 'x is ', x(1,:)
|
||||||
|
|
||||||
|
call lammps_extract_atom (x_r, lmp, 'x')
|
||||||
|
if ( .not. allocated (x_r) ) print *, 'x is not allocated'
|
||||||
|
print *, 'x_r is ', x_r(1,:)
|
||||||
|
|
||||||
|
call lammps_get_coords (lmp, r)
|
||||||
|
print *, 'r is ', r(1:3)
|
||||||
|
|
||||||
|
call lammps_close (lmp)
|
||||||
|
|
||||||
|
end program simple
|
||||||
@ -35,7 +35,8 @@ gcc -L/home/sjplimp/lammps/src simple.o \
|
|||||||
-llmp_g++ -lfftw -lmpich -lmpl -lpthread -lstdc++ -o simpleC
|
-llmp_g++ -lfftw -lmpich -lmpl -lpthread -lstdc++ -o simpleC
|
||||||
|
|
||||||
This builds the Fortran wrapper and driver with the LAMMPS library
|
This builds the Fortran wrapper and driver with the LAMMPS library
|
||||||
using a Fortran and C compiler:
|
using a Fortran and C compiler, using the wrapper in the fortran
|
||||||
|
directory:
|
||||||
|
|
||||||
cp ../fortran/libfwrapper.c .
|
cp ../fortran/libfwrapper.c .
|
||||||
gcc -I/home/sjplimp/lammps/src -c libfwrapper.c
|
gcc -I/home/sjplimp/lammps/src -c libfwrapper.c
|
||||||
|
|||||||
Reference in New Issue
Block a user