Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F65764339
lammps.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Jun 6, 01:51
Size
8 KB
Mime Type
text/x-python
Expires
Sat, Jun 8, 01:51 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
18074628
Attached To
rLAMMPS lammps
lammps.py
View Options
# ----------------------------------------------------------------------
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
# http://lammps.sandia.gov, 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.
# -------------------------------------------------------------------------
# Python wrapper on LAMMPS library via ctypes
import
sys
,
traceback
,
types
from
ctypes
import
*
from
os.path
import
dirname
,
abspath
,
join
from
inspect
import
getsourcefile
class
lammps
:
# detect if Python is using version of mpi4py that can pass a communicator
has_mpi4py_v2
=
False
try
:
from
mpi4py
import
MPI
from
mpi4py
import
__version__
as
mpi4py_version
if
mpi4py_version
.
split
(
'.'
)[
0
]
==
'2'
:
has_mpi4py_v2
=
True
except
:
pass
# create instance of LAMMPS
def
__init__
(
self
,
name
=
""
,
cmdargs
=
None
,
ptr
=
None
,
comm
=
None
):
# determine module location
modpath
=
dirname
(
abspath
(
getsourcefile
(
lambda
:
0
)))
# load liblammps.so unless name is given.
# e.g. if name = "g++", load liblammps_g++.so
# try loading the LAMMPS shared object from the location
# of lammps.py with an absolute path (so that LD_LIBRARY_PATH
# does not need to be set for regular installations.
# fall back to loading with a relative path, which typically
# requires LD_LIBRARY_PATH to be set appropriately.
try
:
if
not
name
:
self
.
lib
=
CDLL
(
join
(
modpath
,
"liblammps.so"
),
RTLD_GLOBAL
)
else
:
self
.
lib
=
CDLL
(
join
(
modpath
,
"liblammps_
%s
.so"
%
name
),
RTLD_GLOBAL
)
except
:
if
not
name
:
self
.
lib
=
CDLL
(
"liblammps.so"
,
RTLD_GLOBAL
)
else
:
self
.
lib
=
CDLL
(
"liblammps_
%s
.so"
%
name
,
RTLD_GLOBAL
)
# if no ptr provided, create an instance of LAMMPS
# don't know how to pass an MPI communicator from PyPar
# but we can pass an MPI communicator from mpi4py v2.0.0 and later
# no_mpi call lets LAMMPS use MPI_COMM_WORLD
# cargs = array of C strings from args
# if ptr, then are embedding Python in LAMMPS input script
# ptr is the desired instance of LAMMPS
# just convert it to ctypes ptr and store in self.lmp
if
not
ptr
:
# with mpi4py v2, can pass MPI communicator to LAMMPS
# need to adjust for type of MPI communicator object
# allow for int (like MPICH) or void* (like OpenMPI)
if
lammps
.
has_mpi4py_v2
and
comm
!=
None
:
if
lammps
.
MPI
.
_sizeof
(
lammps
.
MPI
.
Comm
)
==
sizeof
(
c_int
):
MPI_Comm
=
c_int
else
:
MPI_Comm
=
c_void_p
narg
=
0
cargs
=
0
if
cmdargs
:
cmdargs
.
insert
(
0
,
"lammps.py"
)
narg
=
len
(
cmdargs
)
cargs
=
(
c_char_p
*
narg
)(
*
cmdargs
)
self
.
lib
.
lammps_open
.
argtypes
=
[
c_int
,
c_char_p
*
narg
,
\
MPI_Comm
,
c_void_p
()]
else
:
self
.
lib
.
lammps_open
.
argtypes
=
[
c_int
,
c_int
,
\
MPI_Comm
,
c_void_p
()]
self
.
lib
.
lammps_open
.
restype
=
None
self
.
opened
=
1
self
.
lmp
=
c_void_p
()
comm_ptr
=
lammps
.
MPI
.
_addressof
(
comm
)
comm_val
=
MPI_Comm
.
from_address
(
comm_ptr
)
self
.
lib
.
lammps_open
(
narg
,
cargs
,
comm_val
,
byref
(
self
.
lmp
))
else
:
self
.
opened
=
1
if
cmdargs
:
cmdargs
.
insert
(
0
,
"lammps.py"
)
narg
=
len
(
cmdargs
)
cargs
=
(
c_char_p
*
narg
)(
*
cmdargs
)
self
.
lmp
=
c_void_p
()
self
.
lib
.
lammps_open_no_mpi
(
narg
,
cargs
,
byref
(
self
.
lmp
))
else
:
self
.
lmp
=
c_void_p
()
self
.
lib
.
lammps_open_no_mpi
(
0
,
None
,
byref
(
self
.
lmp
))
# could use just this if LAMMPS lib interface supported it
# self.lmp = self.lib.lammps_open_no_mpi(0,None)
else
:
self
.
opened
=
0
# magic to convert ptr to ctypes ptr
pythonapi
.
PyCObject_AsVoidPtr
.
restype
=
c_void_p
pythonapi
.
PyCObject_AsVoidPtr
.
argtypes
=
[
py_object
]
self
.
lmp
=
c_void_p
(
pythonapi
.
PyCObject_AsVoidPtr
(
ptr
))
def
__del__
(
self
):
if
self
.
lmp
and
self
.
opened
:
self
.
lib
.
lammps_close
(
self
.
lmp
)
def
close
(
self
):
if
self
.
opened
:
self
.
lib
.
lammps_close
(
self
.
lmp
)
self
.
lmp
=
None
def
version
(
self
):
return
self
.
lib
.
lammps_version
(
self
.
lmp
)
def
file
(
self
,
file
):
file
=
file
.
encode
()
self
.
lib
.
lammps_file
(
self
.
lmp
,
file
)
def
command
(
self
,
cmd
):
cmd
=
cmd
.
encode
()
self
.
lib
.
lammps_command
(
self
.
lmp
,
cmd
)
def
extract_global
(
self
,
name
,
type
):
name
=
name
.
encode
()
if
type
==
0
:
self
.
lib
.
lammps_extract_global
.
restype
=
POINTER
(
c_int
)
elif
type
==
1
:
self
.
lib
.
lammps_extract_global
.
restype
=
POINTER
(
c_double
)
else
:
return
None
ptr
=
self
.
lib
.
lammps_extract_global
(
self
.
lmp
,
name
)
return
ptr
[
0
]
def
extract_atom
(
self
,
name
,
type
):
name
=
name
.
encode
()
if
type
==
0
:
self
.
lib
.
lammps_extract_atom
.
restype
=
POINTER
(
c_int
)
elif
type
==
1
:
self
.
lib
.
lammps_extract_atom
.
restype
=
POINTER
(
POINTER
(
c_int
))
elif
type
==
2
:
self
.
lib
.
lammps_extract_atom
.
restype
=
POINTER
(
c_double
)
elif
type
==
3
:
self
.
lib
.
lammps_extract_atom
.
restype
=
POINTER
(
POINTER
(
c_double
))
else
:
return
None
ptr
=
self
.
lib
.
lammps_extract_atom
(
self
.
lmp
,
name
)
return
ptr
def
extract_compute
(
self
,
id
,
style
,
type
):
id
=
id
.
encode
()
if
type
==
0
:
if
style
>
0
:
return
None
self
.
lib
.
lammps_extract_compute
.
restype
=
POINTER
(
c_double
)
ptr
=
self
.
lib
.
lammps_extract_compute
(
self
.
lmp
,
id
,
style
,
type
)
return
ptr
[
0
]
if
type
==
1
:
self
.
lib
.
lammps_extract_compute
.
restype
=
POINTER
(
c_double
)
ptr
=
self
.
lib
.
lammps_extract_compute
(
self
.
lmp
,
id
,
style
,
type
)
return
ptr
if
type
==
2
:
self
.
lib
.
lammps_extract_compute
.
restype
=
POINTER
(
POINTER
(
c_double
))
ptr
=
self
.
lib
.
lammps_extract_compute
(
self
.
lmp
,
id
,
style
,
type
)
return
ptr
return
None
# in case of global datum, free memory for 1 double via lammps_free()
# double was allocated by library interface function
def
extract_fix
(
self
,
id
,
style
,
type
,
i
=
0
,
j
=
0
):
id
=
ide
.
encode
()
if
style
==
0
:
self
.
lib
.
lammps_extract_fix
.
restype
=
POINTER
(
c_double
)
ptr
=
self
.
lib
.
lammps_extract_fix
(
self
.
lmp
,
id
,
style
,
type
,
i
,
j
)
result
=
ptr
[
0
]
self
.
lib
.
lammps_free
(
ptr
)
return
result
elif
(
style
==
1
)
or
(
style
==
2
):
if
type
==
1
:
self
.
lib
.
lammps_extract_fix
.
restype
=
POINTER
(
c_double
)
elif
type
==
2
:
self
.
lib
.
lammps_extract_fix
.
restype
=
POINTER
(
POINTER
(
c_double
))
else
:
return
None
ptr
=
self
.
lib
.
lammps_extract_fix
(
self
.
lmp
,
id
,
style
,
type
,
i
,
j
)
return
ptr
else
:
return
None
# free memory for 1 double or 1 vector of doubles via lammps_free()
# for vector, must copy nlocal returned values to local c_double vector
# memory was allocated by library interface function
def
extract_variable
(
self
,
name
,
group
,
type
):
name
=
name
.
encode
()
group
=
group
.
encode
()
if
type
==
0
:
self
.
lib
.
lammps_extract_variable
.
restype
=
POINTER
(
c_double
)
ptr
=
self
.
lib
.
lammps_extract_variable
(
self
.
lmp
,
name
,
group
)
result
=
ptr
[
0
]
self
.
lib
.
lammps_free
(
ptr
)
return
result
if
type
==
1
:
self
.
lib
.
lammps_extract_global
.
restype
=
POINTER
(
c_int
)
nlocalptr
=
self
.
lib
.
lammps_extract_global
(
self
.
lmp
,
"nlocal"
)
nlocal
=
nlocalptr
[
0
]
result
=
(
c_double
*
nlocal
)()
self
.
lib
.
lammps_extract_variable
.
restype
=
POINTER
(
c_double
)
ptr
=
self
.
lib
.
lammps_extract_variable
(
self
.
lmp
,
name
,
group
)
for
i
in
xrange
(
nlocal
):
result
[
i
]
=
ptr
[
i
]
self
.
lib
.
lammps_free
(
ptr
)
return
result
return
None
# set variable value
# value is converted to string
# returns 0 for success, -1 if failed
def
set_variable
(
self
,
name
,
value
):
name
=
name
.
encode
()
value
=
str
(
value
)
.
encode
()
return
self
.
lib
.
lammps_set_variable
(
self
.
lmp
,
name
,
str
(
value
))
# return total number of atoms in system
def
get_natoms
(
self
):
return
self
.
lib
.
lammps_get_natoms
(
self
.
lmp
)
# return vector of atom properties gathered across procs, ordered by atom ID
def
gather_atoms
(
self
,
name
,
type
,
count
):
name
=
name
.
encode
()
natoms
=
self
.
lib
.
lammps_get_natoms
(
self
.
lmp
)
if
type
==
0
:
data
=
((
count
*
natoms
)
*
c_int
)()
self
.
lib
.
lammps_gather_atoms
(
self
.
lmp
,
name
,
type
,
count
,
data
)
elif
type
==
1
:
data
=
((
count
*
natoms
)
*
c_double
)()
self
.
lib
.
lammps_gather_atoms
(
self
.
lmp
,
name
,
type
,
count
,
data
)
else
:
return
None
return
data
# scatter vector of atom properties across procs, ordered by atom ID
# assume vector is of correct type and length, as created by gather_atoms()
def
scatter_atoms
(
self
,
name
,
type
,
count
,
data
):
name
=
name
.
encode
()
self
.
lib
.
lammps_scatter_atoms
(
self
.
lmp
,
name
,
type
,
count
,
data
)
Event Timeline
Log In to Comment