git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9003 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2012-10-25 15:42:25 +00:00
parent 6dcb5fb23d
commit ccbe10ff39
4 changed files with 1292 additions and 1408 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,221 +1,265 @@
LAMMPS.F90 defines a Fortran 2003 module, LAMMPS, which wraps all functions in 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. 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 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 Fortran wrapper functions that use Fortran-style arrays, pointers, and
strings; all C-style memory management is handled internally with no user strings; all C-style memory management is handled internally with no user
intervention. intervention. See --USE-- for notes on how this interface differs from the
C interface (and the Python interface).
This interface was created by Karl Hammond who you can contact with
questions: This interface was created by Karl Hammond who you can contact with
questions:
Karl D. Hammond
University of Tennessee, Knoxville Karl D. Hammond
karlh at ugcs.caltech.edu University of Tennessee, Knoxville
karlh at utk.edu karlh at ugcs.caltech.edu
karlh at utk.edu
-------------------------------------
-------------------------------------
--COMPILATION--
--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, First, be advised that mixed-language programming is not trivial. It requires
those for Fortran, C, and C++), as well as any other libraries required. you to link in the required libraries of all languages you use (in this case,
You are also advised to read the --USE-- section below before trying to those for Fortran, C, and C++), as well as any other libraries required.
compile. 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): The following steps will work to compile this module (replace ${LAMMPS_SRC}
(1) Compile LAMMPS as a static library. Call the resulting file ${LAMMPS_LIB}, with the path to your LAMMPS source directory).
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 Steps 3-5 are accomplished, possibly after some modifications to
libmpi.a is as well (I'll call it ${MPI_STUBS} hereafter) the makefile, by make using the attached makefile. Said makefile also builds
(2) Copy said library to your Fortran program's source directory or include the dynamically-linkable library (liblammps_fortran.so).
its location in a -L${LAMMPS_SRC} flag to your compiler.
(3) Compile (but don't link!) LAMMPS.F90. Example: ** STATIC LIBRARY INSTRUCTIONS **
mpif90 -c LAMMPS.f90 (1) Compile LAMMPS as a static library.
OR Call the resulting file ${LAMMPS_LIB}, which will have an actual name
gfortran -c LAMMPS.F90 like liblmp_openmpi.a. If compiling using the MPI stubs in
Copy the LAMMPS.o and lammps.mod (or whatever your compiler calls module ${LAMMPS_SRC}/STUBS, you will need to know where libmpi_stubs.a
files) to your Fortran program's source directory. is as well (I'll call it ${MPI_STUBS} hereafter)
NOTE: you may get a warning such as, (2) Copy said library to your Fortran program's source directory or replace
subroutine lammps_open_wrapper (argc, argv, communicator, ptr) & ${LAMMPS_LIB} with its full path in the instructions below.
Variable 'communicator' at (1) is a parameter to the BIND(C) (3) Compile (but don't link!) LAMMPS.F90. Example:
procedure 'lammps_open_wrapper' but may not be C interoperable mpif90 -c LAMMPS.f90
This is normal (see --IMPLEMENTATION NOTES--). OR
(4) Compile (but don't link) LAMMPS-wrapper.cpp. You will need its header gfortran -c LAMMPS.F90
file as well. You will have to provide the locations of LAMMPS's NOTE: you may get a warning such as,
header files. For example, subroutine lammps_open_wrapper (argc, argv, communicator, ptr) &
mpicxx -c -I${LAMMPS_SRC} LAMMPS-wrapper.cpp Variable 'communicator' at (1) is a parameter to the BIND(C)
OR procedure 'lammps_open_wrapper' but may not be C interoperable
g++ -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp This is normal (see --IMPLEMENTATION NOTES--).
OR
icpc -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp (4) Compile (but don't link) LAMMPS-wrapper.cpp. You will need its header
Copy the resulting object file LAMMPS-wrapper.o to your Fortran program's file as well. You will have to provide the locations of LAMMPS's
source directory. header files. For example,
(4b) OPTIONAL: Make a library so you can carry around two files instead of mpicxx -c -I${LAMMPS_SRC} LAMMPS-wrapper.cpp
three. Example: OR
ar rs liblammps_fortran.a LAMMPS.o LAMMPS-wrapper.o g++ -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp
This will create the file liblammps_fortran.a that you can use in place OR
of "LAMMPS.o LAMMPS-wrapper.o" in part (6). Note that you will still icpc -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp
need to have the .mod file from part (3). (5) OPTIONAL: Make a library from the object files so you can carry around
two files instead of three. Example:
It is also possible to add LAMMPS.o and LAMMPS-wrapper.o into the ar rs liblammps_fortran.a LAMMPS.o LAMMPS-wrapper.o
LAMMPS library (e.g., liblmp_openmpi.a) instead of creating a separate This will create the file liblammps_fortran.a that you can use in place
library, like so: of "LAMMPS.o LAMMPS-wrapper.o" later. Note that you will still
ar rs ${LAMMPS_LIB} LAMMPS.o LAMMPS-wrapper.o need to have the .mod file from part (3).
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 It is also possible to add LAMMPS.o and LAMMPS-wrapper.o into the
file visible to the compiler, that is). LAMMPS library (e.g., liblmp_openmpi.a) instead of creating a separate
(5) Compile your Fortran program. Example: library, like so:
mpif90 -c myfreeformatfile.f90 ar rs ${LAMMPS_LIB} LAMMPS.o LAMMPS-wrapper.o
mpif90 -c myfixedformatfile.f In this case, you can now use the Fortran wrapper functions as if they
OR were part of the usual LAMMPS library interface (if you have the module
gfortran -c myfreeformatfile.f90 file visible to the compiler, that is).
gfortran -c myfixedformatfile.f (6) Compile (but don't link) your Fortran program. Example:
The object files generated by these steps are collectively referred to mpif90 -c myfreeformatfile.f90
as ${my_object_files} in the next step(s). mpif90 -c myfixedformatfile.f
OR
IMPORTANT: If the Fortran module from part (3) is not in the current gfortran -c myfreeformatfile.f90
directory or in one searched by the compiler for module files, you will gfortran -c myfixedformatfile.f
need to include that location via the -I flag to the compiler. The object files generated by these steps are collectively referred to
(6) Link everything together, including any libraries needed by LAMMPS (such as ${my_object_files} in the next step(s).
as the C++ standard library, the C math library, the JPEG library, fftw,
etc.) For example, IMPORTANT: If the Fortran module from part (3) is not in the current
mpif90 LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \ directory or in one searched by the compiler for module files, you will
${LAMMPS_LIB} -lstdc++ -lm need to include that location via the -I flag to the compiler, like so:
OR mpif90 -I${LAMMPS_SRC}/examples/COUPLE/fortran2 -c myfreeformatfile.f90
gfortran LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
${LAMMPS_LIB} ${MPI_STUBS} -lstdc++ -lm (7) Link everything together, including any libraries needed by LAMMPS (such
OR as the C++ standard library, the C math library, the JPEG library, fftw,
ifort LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \ etc.) For example,
${LAMMPS_LIB} ${MPI_STUBS} -cxxlib -limf -lm mpif90 LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
Any other required libraries (e.g. -ljpeg, -lfftw) should be added to ${LAMMPS_LIB} -lmpi_cxx -lstdc++ -lm
the end of this line. OR
gfortran LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
You should now have a working executable. ${LAMMPS_LIB} ${MPI_STUBS} -lstdc++ -lm
OR
Steps 3 and 4 above are accomplished, possibly after some modifications to ifort LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \
the makefile, by make using the attached makefile. ${LAMMPS_LIB} ${MPI_STUBS} -cxxlib -lm
Any other required libraries (e.g. -ljpeg, -lfftw) should be added to
------------------------------------- the end of this line.
--USAGE-- You should now have a working executable.
To use this API, your program unit (PROGRAM/SUBROUTINE/FUNCTION/MODULE/etc.) ** DYNAMIC LIBRARY INSTRUCTIONS **
should look something like this: (1) Compile LAMMPS as a dynamic library
program call_lammps (make makeshlib && make -f Makefile.shlib [targetname]).
use LAMMPS (2) Compile, but don't link, LAMMPS.F90 using the -fPIC flag, such as
! Other modules, etc. mpif90 -fPIC -c LAMMPS.f90
implicit none (3) Compile, but don't link, LAMMPS-wrapper.cpp in the same manner, e.g.
type (lammps_instance) :: lmp ! This is a pointer to your LAMMPS instance mpicxx -fPIC -c LAMMPS-wrapper.cpp
double precision :: fix (4) Make the dynamic library, like so:
double precision, dimension(:), allocatable :: fix2 mpif90 -fPIC -shared -o liblammps_fortran.so LAMMPS.o LAMMPS-wrapper.o
! Rest of declarations (5) Compile your program, such as,
call lammps_open_no_mpi ('lmp -in /dev/null -screen out.lammps',lmp) mpif90 -I${LAMMPS_SRC}/examples/COUPLE/fortran2 -c myfreeformatfile.f90
! Set up rest of program here where ${LAMMPS_SRC}/examples/COUPLE/fortran2 contains the .mod file from
call lammps_file (lmp, 'in.example') step (3)
call lammps_extract_fix (fix, lmp, '2', 0, 1, 1, 1) (6) Link everything together, such as
call lammps_extract_fix (fix2, lmp, '4', 0, 2, 1, 1) mpif90 ${my_object_files} -L${LAMMPS_SRC} \
call lammps_close (lmp) -L${LAMMPS_SRC}/examples/COUPLE/fortran2 -llammps_fortran \
end program call_lammps -llammps_openmpi -lmpi_cxx -lstdc++ -lm
Important notes: If you wish to avoid the -L flags, add the directories containing your
* All arguments which are char* variables in library.cpp are character (len=*) shared libraries to the LIBRARY_PATH environment variable. At run time, you
variables here. For example, will have to add these directories to LD_LIBRARY_PATH as well; otherwise,
call lammps_command (lmp, 'units metal') your executable will not find the libraries it needs.
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 --USAGE--
strings and the like.
* The module attempts to check whether you have done something stupid (such To use this API, your program unit (PROGRAM/SUBROUTINE/FUNCTION/MODULE/etc.)
as assign a 2D array to a scalar), but it's not perfect. For example, the should look something like this:
command program call_lammps
call lammps_extract_global (nlocal, ptr, 'nlocal') use LAMMPS
will give nlocal correctly if nlocal is of type INTEGER, but it will give ! Other modules, etc.
the wrong answer if nlocal is of type REAL or DOUBLE PRECISION. This is a implicit none
feature of the (void*) type cast in library.cpp. There is no way I can type (lammps_instance) :: lmp ! This is a pointer to your LAMMPS instance
check this for you! real (C_double) :: fix
* You are allowed to use REAL or DOUBLE PRECISION floating-point numbers. real (C_double), dimension(:), pointer :: fix2
All LAMMPS data (which are of type REAL(C_double)) are rounded off if ! Rest of declarations
placed in single precision variables. It is tacitly assumed that NO C++ call lammps_open_no_mpi ('lmp -in /dev/null -screen out.lammps',lmp)
variables are of type float; everything is int or double (since this is ! Set up rest of program here
all library.cpp currently handles). call lammps_file (lmp, 'in.example')
* An example of a complete program is offered at the end of this file. 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
--TROUBLESHOOTING--
Important notes:
Compile-time errors probably indicate that your compiler is not new enough to * Though I dislike the use of pointers, they are necessary when communicating
support Fortran 2003 features. For example, GCC 4.1.2 will not compile this with C and C++, which do not support Fortran's ALLOCATABLE attribute.
module, but GCC 4.4.0 will. * There is no need to deallocate C-allocated memory; this is done for you in
the cases when it is done (which are all cases when pointers are not
If your compiler balks at 'use, intrinsic :: ISO_C_binding,' try removing the accepted, such as global fix data)
intrinsic part so it looks like an ordinary module. However, it is likely * All arguments which are char* variables in library.cpp are character (len=*)
that such a compiler will also have problems with everything else in the variables here. For example,
file as well. call lammps_command (lmp, 'units metal')
will work as expected.
If you get a segfault as soon as the lammps_open call is made, check that you * The public functions (the only ones you can use) have interfaces as
compiled your program AND LAMMPS-header.cpp using the same MPI headers. Using described in the comments at the top of LAMMPS.F90. They are not always
the stubs for one and the actual MPI library for the other will cause major the same as those in library.h, since C strings are replaced by Fortran
problems. strings and the like.
* The module attempts to check whether you have done something stupid (such
If you find run-time errors, please pass them along via the LAMMPS Users as assign a 2D array to a scalar), but it's not perfect. For example, the
mailing list. Please provide a minimal working example along with the names command
and versions of the compilers you are using. Please make sure the error is call lammps_extract_global (nlocal, ptr, 'nlocal')
repeatable and is in MY code, not yours (generating a minimal working example will give nlocal correctly if nlocal is a pointer to type INTEGER, but it
will usually ensure this anyway). will give the wrong answer if nlocal is a pointer to type REAL. This is a
feature of the (void*) type cast in library.cpp. There is no way I can
------------------------------------- check this for you! It WILL catch you if you pass it an allocatable or
fixed-size array when it expects a pointer.
--IMPLEMENTATION NOTES-- * Arrays constructed from temporary data from LAMMPS are ALLOCATABLE, and
represent COPIES of data, not the originals. Functions like
The Fortran procedures have the same names as the C procedures, and lammps_extract_atom, which return actual LAMMPS data, are pointers.
their purpose is the same, but they may take different arguments. Here are * IMPORTANT: Due to the differences between C and Fortran arrays (C uses
some of the important differences: row-major vectors, Fortran uses column-major vectors), all arrays returned
* lammps_open and lammps_open_no_mpi take a string instead of argc and from LAMMPS have their indices swapped.
argv. This is necessary because C and C++ have a very different way * An example of a complete program, simple.f90, is included with this
of treating strings than Fortran. package.
* 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 --TROUBLESHOOTING--
Fortran variables (which may be arrays). The first argument houses the
variable to be returned; all other arguments are identical except as Compile-time errors (when compiling LAMMPS.F90, that is) probably indicate
stipulated above. Note that it is not possible to declare generic that your compiler is not new enough to support Fortran 2003 features. For
functions that are selected based solely on the type/kind/rank (TKR) example, GCC 4.1.2 will not compile this module, but GCC 4.4.0 will.
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 If your compiler balks at 'use, intrinsic :: ISO_C_binding,' try removing the
against the "shape" of the C array (e.g., double vs. double* vs. double**). intrinsic part so it looks like an ordinary module. However, it is likely
Calling a subroutine with arguments of inappropriate rank will result in an that such a compiler will also have problems with everything else in the
error at run time. file as well.
* All arrays passed to subroutines must be ALLOCATABLE and are REALLOCATED
to fit the shape of the array LAMMPS will be returning. If you get a segfault as soon as the lammps_open call is made, check that you
* The indices i and j in lammps_extract_fix are used the same way they compiled your program AND LAMMPS-wrapper.cpp using the same MPI headers. Using
are in f_ID[i][j] references in LAMMPS (i.e., starting from 1). This is the stubs for one and the actual MPI library for the other will cause Bad
different than the way library.cpp uses these numbers, but is more Things to happen.
consistent with the way arrays are accessed in LAMMPS and in Fortran.
* The char* pointer normally returned by lammps_command is thrown away If you find run-time errors, please pass them along via the LAMMPS Users
in this version; note also that lammps_command is now a subroutine mailing list (please CC me as well; address above). Please provide a minimal
instead of a function. working example along with the names and versions of the compilers you are
* The pointer to LAMMPS itself is of type(lammps_instance), which is itself using. Please make sure the error is repeatable and is in MY code, not yours
a synonym for type(C_ptr), part of ISO_C_BINDING. Type (C_ptr) is (generating a minimal working example will usually ensure this anyway).
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, --IMPLEMENTATION NOTES--
subroutine lammps_open_wrapper (argc, argv, communicator, ptr) &
Variable 'communicator' at (1) is a parameter to the BIND(C) The Fortran procedures have the same names as the C procedures, and
procedure 'lammps_open_wrapper' but may not be C interoperable their purpose is the same, but they may take different arguments. Here are
This happens because lammps_open_wrapper actually takes a Fortran some of the important differences:
INTEGER argument, whose type is defined by the MPI library itself. The * lammps_open and lammps_open_no_mpi take a string instead of argc and
Fortran integer is converted to a C integer by the MPI library (if such argv. This is necessary because C and C++ have a very different way
conversion is actually necessary). of treating strings than Fortran. If you want the command line to be
* Unlike library.cpp, this module returns COPIES of the data LAMMPS actually passed to lammps_open (as it often would be from C/C++), use the
uses. This is done for safety reasons, as you should, in general, not be GET_COMMAND intrinsic to obtain it.
overwriting LAMMPS data directly from Fortran. If you require this * All C++ functions that accept char* pointers now accept Fortran-style
functionality, it is possible to write another function that, for example, strings within this interface instead.
returns a Fortran pointer that resolves to the C/C++ data instead of * All of the lammps_extract_[something] functions, which return void*
copying the contents of that pointer to the original array as is done now. C-style pointers, have been replaced by generic subroutines that return
Fortran variables (which may be arrays). The first argument houses the
variable/pointer to be returned (pretend it's on the left-hand side); 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.
* 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 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).
* lammps_extract_global returns COPIES of the (scalar) data, as does the
C version.
* lammps_extract_atom, lammps_extract_compute, and lammps_extract_fix
have a first argument that will be associated with ACTUAL LAMMPS DATA.
This means the first argument must be:
* The right rank (via the DIMENSION modifier)
* A C-interoperable POINTER type (i.e., INTEGER (C_int) or
REAL (C_double)).
* lammps_extract_variable returns COPIES of the data, as the C library
interface does. There is no need to deallocate using lammps_free.
* The 'data' argument to lammps_gather_atoms and lammps_scatter atoms must
be ALLOCATABLE. It should be of type INTEGER or DOUBLE PRECISION. It
does NOT need to be C inter-operable (and indeed should not be).
* The 'count' argument of lammps_scatter_atoms is unnecessary; the shape of
the array determines the number of elements LAMMPS will read.

View File

@ -1,10 +1,11 @@
units metal units lj
lattice bcc 3.1656 atom_modify map array
lattice bcc 1.0
region simbox block 0 10 0 10 0 10 region simbox block 0 10 0 10 0 10
create_box 2 simbox create_box 2 simbox
create_atoms 1 region simbox create_atoms 1 region simbox
pair_style eam/fs pair_style lj/cut 2.5
pair_coeff * * path/to/my_potential.eam.fs A1 A2 pair_coeff * * 1.0 1.0
mass 1 58.2 # These are made-up numbers mass 1 58.2 # These are made-up numbers
mass 2 28.3 mass 2 28.3
velocity all create 1200.0 7474848 dist gaussian velocity all create 1200.0 7474848 dist gaussian

View File

@ -1,44 +1,111 @@
program simple program simple
use MPI
use LAMMPS use LAMMPS
! The following line is unnecessary, as I have included these three entities
! with the LAMMPS module, but I leave them in anyway to remind people where
! they came from
use, intrinsic :: ISO_C_binding, only : C_double, C_ptr, C_int
implicit none implicit none
type (lammps_instance) :: lmp ! Notes:
double precision :: compute, fix, fix2 ! * If LAMMPS returns a scalar that is allocated by the library interface
double precision, dimension(:), allocatable :: compute_v, mass, r ! (see library.cpp), then that memory is deallocated automatically and
double precision, dimension(:,:), allocatable :: x ! the argument to lammps_extract_fix must be a SCALAR.
real, dimension(:,:), allocatable :: x_r ! * If LAMMPS returns a pointer to an array, consisting of internal LAMMPS
! data, then the argument must be an interoperable Fortran pointer.
! Interoperable means it is of type INTEGER (C_INT) or of type
! REAL (C_DOUBLE) in this context.
! * Pointers should NEVER be deallocated, as that would deallocate internal
! LAMMPS data!
! * Note that just because you can read the values of, say, a compute at
! any time does not mean those values represent the "correct" values.
! LAMMPS will abort you if you try to grab a pointer to a non-current
! entity, but once it's bound, it's your responsibility to check that
! it's current before evaluating.
! * IMPORTANT: Two-dimensional arrays (such as 'x' from extract_atom)
! will be transposed from what they might look like in C++. This is
! because of different bookkeeping conventions between Fortran and C
! that date back to about 1970 or so (when C was written).
! * Arrays start from 1, EXCEPT for mass from extract_atom, which
! starts from 0. This is because the C array actually has a blank
! first element (and thus mass[1] corresponds to the mass of type 1)
type (C_ptr) :: lmp
real (C_double), pointer :: compute => NULL()
real (C_double) :: fix, fix2
real (C_double), dimension(:), pointer :: compute_v => NULL()
real (C_double), dimension(:,:), pointer :: x => NULL()
real (C_double), dimension(:), pointer :: mass => NULL()
integer, dimension(:), allocatable :: types
double precision, dimension(:), allocatable :: r
integer :: error, narg, me, nprocs
character (len=1024) :: command_line
call MPI_Init (error)
call MPI_Comm_rank (MPI_COMM_WORLD, me, error)
call MPI_Comm_size (MPI_COMM_WORLD, nprocs, error)
! You are free to pass any string you like to lammps_open or
! lammps_open_no_mpi; here is how you pass it the command line
!call get_command (command_line)
!call lammps_open (command_line, MPI_COMM_WORLD, lmp)
! And here's how to to it with a string constant of your choice
call lammps_open_no_mpi ('lmp -log log.simple', lmp)
call lammps_open_no_mpi ('',lmp)
call lammps_file (lmp, 'in.simple') call lammps_file (lmp, 'in.simple')
call lammps_command (lmp, 'run 500') call lammps_command (lmp, 'run 500')
! This extracts f_2 as a scalar (the last two arguments can be arbitrary)
call lammps_extract_fix (fix, lmp, '2', 0, 1, 1, 1) call lammps_extract_fix (fix, lmp, '2', 0, 1, 1, 1)
print *, 'Fix is ', fix print *, 'Fix is ', fix
! This extracts f_4[1][1] as a scalar
call lammps_extract_fix (fix2, lmp, '4', 0, 2, 1, 1) call lammps_extract_fix (fix2, lmp, '4', 0, 2, 1, 1)
print *, 'Fix 2 is ', fix2 print *, 'Fix 2 is ', fix2
! This extracts the scalar compute of compute thermo_temp
call lammps_extract_compute (compute, lmp, 'thermo_temp', 0, 0) call lammps_extract_compute (compute, lmp, 'thermo_temp', 0, 0)
print *, 'Compute is ', compute print *, 'Compute is ', compute
! This extracts the vector compute of compute thermo_temp
call lammps_extract_compute (compute_v, lmp, 'thermo_temp', 0, 1) call lammps_extract_compute (compute_v, lmp, 'thermo_temp', 0, 1)
print *, 'Vector is ', compute_v print *, 'Vector is ', compute_v
! This extracts the masses
call lammps_extract_atom (mass, lmp, 'mass') call lammps_extract_atom (mass, lmp, 'mass')
print *, 'Mass is ', mass print *, 'Mass is ', mass(1:)
! Extracts a pointer to the arrays of positions for all atoms
call lammps_extract_atom (x, lmp, 'x') call lammps_extract_atom (x, lmp, 'x')
if ( .not. allocated (x) ) print *, 'x is not allocated' if ( .not. associated (x) ) print *, 'x is not associated'
print *, 'x is ', x(1,:) print *, 'x is ', x(:,1) ! Prints x, y, z for atom 1
call lammps_extract_atom (x_r, lmp, 'x') ! Extracts pointer to atom types
if ( .not. allocated (x_r) ) print *, 'x is not allocated' call lammps_gather_atoms (lmp, 'type', 1, types)
print *, 'x_r is ', x_r(1,:) print *, 'types is ', types(1:3)
call lammps_get_coords (lmp, r) ! Allocates an array and assigns all positions to it
print *, 'r is ', r(1:3) call lammps_gather_atoms (lmp, 'x', 3, r)
print *, 'size(r) = ', size(r)
print *, 'r is ', r(1:6)
! Puts those position data back
call lammps_scatter_atoms (lmp, 'x', r)
call lammps_command (lmp, 'run 1')
print *, 'x is ', x(:,1) ! Note that the position updates!
print *, 'Compute is ', compute ! This did only because "temp" is part of
! the thermo output; the vector part did
! not, and won't until we give LAMMPS a
! thermo output or other command that
! requires its value
call lammps_close (lmp) call lammps_close (lmp)
call MPI_Finalize (error)
end program simple end program simple