Merge branch 'lammps:master' into master
This commit is contained in:
1
python/.gitignore
vendored
1
python/.gitignore
vendored
@ -1 +1,2 @@
|
||||
/build
|
||||
/*.egg-info
|
||||
|
||||
@ -38,13 +38,14 @@ Once you have successfully wrapped LAMMPS, you can run the Python
|
||||
scripts in the examples sub-directory:
|
||||
|
||||
trivial.py read/run a LAMMPS input script thru Python
|
||||
demo.py invoke various LAMMPS library interface routines
|
||||
simple.py parallel example, mimicing examples/COUPLE/simple/simple.cpp
|
||||
demo.py invoke various LAMMPS library interface routines
|
||||
simple.py parallel example, mimicing examples/COUPLE/simple/simple.cpp
|
||||
split.py parallel example
|
||||
mc.py Monte Carlo energy relaxation wrapper on LAMMPS
|
||||
gui.py GUI go/stop/temperature-slider to control LAMMPS
|
||||
plot.py real-time temperature plot with GnuPlot via Pizza.py
|
||||
viz_tool.py real-time viz via some viz package
|
||||
gui.py GUI go/stop/temperature-slider to control LAMMPS
|
||||
plot.py real-time temperature plot with GnuPlot via Pizza.py
|
||||
matplotlib_plot.py real-time temperature plot with Matplotlib via Pizza.py
|
||||
viz_tool.py real-time viz via some viz package
|
||||
vizplotgui_tool.py combination of viz.py and plot.py and gui.py
|
||||
|
||||
For the viz_tool.py and vizplotgui_tool.py commands, replace "tool"
|
||||
@ -100,24 +101,24 @@ split.py in.simple # can run in parallel (see below)
|
||||
|
||||
gui.py in.gui 100
|
||||
plot.py in.plot 10 1000 thermo_temp
|
||||
matplotlib_plot.py in.plot 10 1000 thermo_temp
|
||||
viz_tool.py in.viz 100 5000
|
||||
vizplotgui_tool.py in.viz 100 thermo_temp
|
||||
|
||||
To run LAMMPS in parallel from Python, so something like this:
|
||||
|
||||
% mpirun -np 4 simple.py in.simple
|
||||
% mpirun -np 4 python split.py in.simple
|
||||
% mpirun -np P simple.py in.simple
|
||||
% mpirun -np P python split.py in.simple
|
||||
|
||||
If you run simple.py as-is, this will invoke P instances of a
|
||||
one-processor run, where both Python and LAMMPS will run on single
|
||||
processors. Each running job will read the same input file, and write
|
||||
to same log.lammps file, which isn't too useful.
|
||||
|
||||
However, if you have either the Pypar or mpi4py packages installed in
|
||||
your Python, and uncomment the Pypar or mpi4py code in simple.py, then
|
||||
the above commands will invoke 1 instance of a P-processor run. Both
|
||||
Python and LAMMPS will run on P processors. The job will read the
|
||||
input file and write a single log.lammps file.
|
||||
However, if you have the mpi4py Python package installed and uncomment mpi4py
|
||||
code in simple.py, then the above commands will invoke 1 instance of a
|
||||
P-processor run. Both Python and LAMMPS will run on P processors. The job will
|
||||
read the input file and write a single log.lammps file.
|
||||
|
||||
The split.py script can also be run in parallel. It uses mpi4py
|
||||
version 2.0.0 (or later), which makes it possible to pass a
|
||||
|
||||
1
python/examples/.gitignore
vendored
Normal file
1
python/examples/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/tmp*
|
||||
@ -7,8 +7,7 @@
|
||||
# in.lammps = LAMMPS input script
|
||||
# Nfreq = query GUI every this many steps
|
||||
|
||||
# IMPORTANT: this script cannot yet be run in parallel via Pypar,
|
||||
# because I can't seem to do a MPI-style broadcast in Pypar
|
||||
# IMPORTANT: this script cannot yet be run in parallel
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,time
|
||||
@ -39,10 +38,6 @@ infile = sys.argv[1]
|
||||
nfreq = int(sys.argv[2])
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -110,7 +105,3 @@ while 1:
|
||||
if runflag: running = 1
|
||||
else: running = 0
|
||||
time.sleep(0.01)
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -12,9 +12,6 @@
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
sys.path.append("./pizza")
|
||||
import matplotlib
|
||||
matplotlib.use('tkagg')
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# parse command line
|
||||
@ -30,10 +27,10 @@ nsteps = int(sys.argv[3])
|
||||
compute = sys.argv[4]
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
#nprocs = MPI.COMM_WORLD.Get_size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -79,15 +76,16 @@ while ntimestep < nsteps:
|
||||
ax = plt.gca()
|
||||
ax.relim()
|
||||
ax.autoscale_view(True, True, True)
|
||||
fig.canvas.draw()
|
||||
plt.pause(0.001)
|
||||
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
input("Press Enter to exit...")
|
||||
else:
|
||||
raw_input("Press Enter to exit...")
|
||||
if me == 0:
|
||||
if sys.version_info[0] == 3:
|
||||
input("Press Enter to exit...")
|
||||
else:
|
||||
raw_input("Press Enter to exit...")
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#
|
||||
# Copyright (2005) 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
|
||||
# certain rights in this software. This software is distributed under
|
||||
# the GNU General Public License.
|
||||
|
||||
# for python3 compatibility
|
||||
@ -35,7 +35,7 @@ time = d.next() read next snapshot from dump files
|
||||
d.map(1,"id",3,"x") assign names to atom columns (1-N)
|
||||
|
||||
not needed if dump file is self-describing
|
||||
|
||||
|
||||
d.tselect.all() select all timesteps
|
||||
d.tselect.one(N) select only timestep N
|
||||
d.tselect.none() deselect all timesteps
|
||||
@ -227,7 +227,7 @@ class dump:
|
||||
for word in words: self.flist += glob.glob(word)
|
||||
if len(self.flist) == 0 and len(list) == 1:
|
||||
raise Exception("no dump file specified")
|
||||
|
||||
|
||||
if len(list) == 1:
|
||||
self.increment = 0
|
||||
self.read_all()
|
||||
@ -270,12 +270,12 @@ class dump:
|
||||
self.tselect.all()
|
||||
|
||||
# set default names for atom columns if file wasn't self-describing
|
||||
|
||||
|
||||
if len(self.snaps) == 0:
|
||||
print("no column assignments made")
|
||||
elif len(self.names):
|
||||
print("assigned columns:",self.names2str())
|
||||
elif self.snaps[0].atoms == None:
|
||||
elif self.snaps[0].atoms is None:
|
||||
print("no column assignments made")
|
||||
elif len(self.snaps[0].atoms[0]) == 5:
|
||||
self.map(1,"id",2,"type",3,"x",4,"y",5,"z")
|
||||
@ -341,7 +341,7 @@ class dump:
|
||||
# return snapshot or 0 if failed
|
||||
# assign column names if not already done and file is self-describing
|
||||
# convert xs,xu to x
|
||||
|
||||
|
||||
def read_snapshot(self,f):
|
||||
try:
|
||||
snap = Snap()
|
||||
@ -414,7 +414,7 @@ class dump:
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# map atom column names
|
||||
|
||||
|
||||
def map(self,*pairs):
|
||||
if len(pairs) % 2 != 0:
|
||||
raise Exception("dump map() requires pairs of mappings")
|
||||
@ -492,7 +492,7 @@ class dump:
|
||||
atoms[:,x] = snap.xlo + atoms[:,x]*xprd
|
||||
atoms[:,y] = snap.ylo + atoms[:,y]*yprd
|
||||
atoms[:,z] = snap.zlo + atoms[:,z]*zprd
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# wrap coords from outside box to inside
|
||||
|
||||
@ -505,7 +505,7 @@ class dump:
|
||||
ix = self.names["ix"]
|
||||
iy = self.names["iy"]
|
||||
iz = self.names["iz"]
|
||||
|
||||
|
||||
for snap in self.snaps:
|
||||
xprd = snap.xhi - snap.xlo
|
||||
yprd = snap.yhi - snap.ylo
|
||||
@ -527,7 +527,7 @@ class dump:
|
||||
ix = self.names["ix"]
|
||||
iy = self.names["iy"]
|
||||
iz = self.names["iz"]
|
||||
|
||||
|
||||
for snap in self.snaps:
|
||||
xprd = snap.xhi - snap.xlo
|
||||
yprd = snap.yhi - snap.ylo
|
||||
@ -542,7 +542,7 @@ class dump:
|
||||
|
||||
def owrap(self,other):
|
||||
print("Wrapping to other ...")
|
||||
|
||||
|
||||
id = self.names["id"]
|
||||
x = self.names["x"]
|
||||
y = self.names["y"]
|
||||
@ -551,7 +551,7 @@ class dump:
|
||||
iy = self.names["iy"]
|
||||
iz = self.names["iz"]
|
||||
iother = self.names[other]
|
||||
|
||||
|
||||
for snap in self.snaps:
|
||||
xprd = snap.xhi - snap.xlo
|
||||
yprd = snap.yhi - snap.ylo
|
||||
@ -568,7 +568,7 @@ class dump:
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# convert column names assignment to a string, in column order
|
||||
|
||||
|
||||
def names2str(self):
|
||||
ncol = len(self.snaps[0].atoms[0])
|
||||
pairs = self.names.items()
|
||||
@ -631,7 +631,7 @@ class dump:
|
||||
print(snap.ylo,snap.yhi,file=f)
|
||||
print(snap.zlo,snap.zhi,file=f)
|
||||
print("ITEM: ATOMS",namestr,file=f)
|
||||
|
||||
|
||||
atoms = snap.atoms
|
||||
nvalues = len(atoms[0])
|
||||
for i in range(snap.natoms):
|
||||
@ -655,7 +655,7 @@ class dump:
|
||||
if not snap.tselect: continue
|
||||
print(snap.time,end='')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
file = root + "." + str(snap.time)
|
||||
f = open(file,"w")
|
||||
print("ITEM: TIMESTEP",file=f)
|
||||
@ -667,7 +667,7 @@ class dump:
|
||||
print(snap.ylo,snap.yhi,file=f)
|
||||
print(snap.zlo,snap.zhi,file=f)
|
||||
print("ITEM: ATOMS",namestr,file=f)
|
||||
|
||||
|
||||
atoms = snap.atoms
|
||||
nvalues = len(atoms[0])
|
||||
for i in range(snap.natoms):
|
||||
@ -709,7 +709,7 @@ class dump:
|
||||
lhs = list[0][1:]
|
||||
if not self.names.has_key(lhs):
|
||||
self.newcolumn(lhs)
|
||||
|
||||
|
||||
for item in list:
|
||||
name = item[1:]
|
||||
column = self.names[name]
|
||||
@ -721,7 +721,7 @@ class dump:
|
||||
if not snap.tselect: continue
|
||||
for i in range(snap.natoms):
|
||||
if snap.aselect[i]: exec(ceq)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# set a column value via an input vec for all selected snapshots/atoms
|
||||
|
||||
@ -741,7 +741,7 @@ class dump:
|
||||
if snap.aselect[i]:
|
||||
atoms[i][icol] = vec[m]
|
||||
m += 1
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# clone value in col across selected timesteps for atoms with same ID
|
||||
|
||||
@ -807,7 +807,7 @@ class dump:
|
||||
columns.append(self.names[name])
|
||||
values.append(self.nselect * [0])
|
||||
ncol = len(columns)
|
||||
|
||||
|
||||
id = self.names["id"]
|
||||
m = 0
|
||||
for snap in self.snaps:
|
||||
@ -823,13 +823,13 @@ class dump:
|
||||
|
||||
if len(list) == 1: return values[0]
|
||||
else: return values
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# extract vector(s) of values for selected atoms at chosen timestep
|
||||
|
||||
def vecs(self,n,*list):
|
||||
snap = self.snaps[self.findtime(n)]
|
||||
|
||||
|
||||
if len(list) == 0:
|
||||
raise Exception("no columns specified")
|
||||
columns = []
|
||||
@ -884,7 +884,7 @@ class dump:
|
||||
del self.snaps[i]
|
||||
else:
|
||||
i += 1
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# iterate over selected snapshots
|
||||
|
||||
@ -896,11 +896,11 @@ class dump:
|
||||
self.iterate = i
|
||||
return i,self.snaps[i].time,1
|
||||
return 0,0,-1
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# return list of atoms to viz for snapshot isnap
|
||||
# augment with bonds, tris, lines if extra() was invoked
|
||||
|
||||
|
||||
def viz(self,isnap):
|
||||
snap = self.snaps[isnap]
|
||||
|
||||
@ -914,7 +914,7 @@ class dump:
|
||||
|
||||
# create atom list needed by viz from id,type,x,y,z
|
||||
# need Numeric/Numpy mode here
|
||||
|
||||
|
||||
atoms = []
|
||||
for i in range(snap.natoms):
|
||||
if not snap.aselect[i]: continue
|
||||
@ -948,12 +948,12 @@ class dump:
|
||||
elif self.triflag == 2:
|
||||
timetmp,boxtmp,atomstmp,bondstmp, \
|
||||
tris,linestmp = self.triobj.viz(time,1)
|
||||
|
||||
|
||||
lines = []
|
||||
if self.lineflag: lines = self.linelist
|
||||
|
||||
return time,box,atoms,bonds,tris,lines
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def findtime(self,n):
|
||||
@ -969,12 +969,12 @@ class dump:
|
||||
xhi = yhi = zhi = None
|
||||
for snap in self.snaps:
|
||||
if not snap.tselect: continue
|
||||
if xlo == None or snap.xlo < xlo: xlo = snap.xlo
|
||||
if xhi == None or snap.xhi > xhi: xhi = snap.xhi
|
||||
if ylo == None or snap.ylo < ylo: ylo = snap.ylo
|
||||
if yhi == None or snap.yhi > yhi: yhi = snap.yhi
|
||||
if zlo == None or snap.zlo < zlo: zlo = snap.zlo
|
||||
if zhi == None or snap.zhi > zhi: zhi = snap.zhi
|
||||
if xlo is None or snap.xlo < xlo: xlo = snap.xlo
|
||||
if xhi is None or snap.xhi > xhi: xhi = snap.xhi
|
||||
if ylo is None or snap.ylo < ylo: ylo = snap.ylo
|
||||
if yhi is None or snap.yhi > yhi: yhi = snap.yhi
|
||||
if zlo is None or snap.zlo < zlo: zlo = snap.zlo
|
||||
if zhi is None or snap.zhi > zhi: zhi = snap.zhi
|
||||
return [xlo,ylo,zlo,xhi,yhi,zhi]
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
@ -997,7 +997,7 @@ class dump:
|
||||
def extra(self,arg):
|
||||
|
||||
# read bonds from bond dump file
|
||||
|
||||
|
||||
if type(arg) is types.StringType:
|
||||
try:
|
||||
f = open(arg,'r')
|
||||
@ -1017,7 +1017,7 @@ class dump:
|
||||
f.close()
|
||||
|
||||
# convert values to int and absolute value since can be negative types
|
||||
|
||||
|
||||
if oldnumeric: bondlist = np.zeros((nbonds,4),np.Int)
|
||||
else: bondlist = np.zeros((nbonds,4),np.int)
|
||||
ints = [abs(int(value)) for value in words]
|
||||
@ -1032,9 +1032,9 @@ class dump:
|
||||
self.bondlist = bondlist
|
||||
except:
|
||||
raise Exception("could not read from bond dump file")
|
||||
|
||||
|
||||
# request bonds from data object
|
||||
|
||||
|
||||
elif type(arg) is types.InstanceType and ".data" in str(arg.__class__):
|
||||
try:
|
||||
bondlist = []
|
||||
@ -1050,7 +1050,7 @@ class dump:
|
||||
raise Exception("could not extract bonds from data object")
|
||||
|
||||
# request tris/lines from cdata object
|
||||
|
||||
|
||||
elif type(arg) is types.InstanceType and ".cdata" in str(arg.__class__):
|
||||
try:
|
||||
tmp,tmp,tmp,tmp,tris,lines = arg.viz(0)
|
||||
@ -1064,7 +1064,7 @@ class dump:
|
||||
raise Exception("could not extract tris/lines from cdata object")
|
||||
|
||||
# request tris from mdump object
|
||||
|
||||
|
||||
elif type(arg) is types.InstanceType and ".mdump" in str(arg.__class__):
|
||||
try:
|
||||
self.triflag = 2
|
||||
@ -1074,7 +1074,7 @@ class dump:
|
||||
|
||||
else:
|
||||
raise Exception("unrecognized argument to dump.extra()")
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def compare_atom(self,a,b):
|
||||
@ -1083,7 +1083,7 @@ class dump:
|
||||
elif a[0] > b[0]:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return 0
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# one snapshot
|
||||
@ -1098,7 +1098,7 @@ class tselect:
|
||||
|
||||
def __init__(self,data):
|
||||
self.data = data
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def all(self):
|
||||
@ -1145,7 +1145,7 @@ class tselect:
|
||||
data.nselect -= 1
|
||||
data.aselect.all()
|
||||
print("%d snapshots selected out of %d" % (data.nselect,data.nsnaps))
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test(self,teststr):
|
||||
@ -1191,7 +1191,7 @@ class aselect:
|
||||
data = self.data
|
||||
|
||||
# replace all $var with snap.atoms references and compile test string
|
||||
|
||||
|
||||
pattern = "\$\w*"
|
||||
list = re.findall(pattern,teststr)
|
||||
for item in list:
|
||||
|
||||
@ -851,7 +851,7 @@ class gl:
|
||||
ncolor = self.vizinfo.ntcolor
|
||||
for tri in self.tridraw:
|
||||
itype = int(tri[1])
|
||||
if itype > ncolor: raise StandardError("tri type too big")
|
||||
if itype > ncolor: raise Exception("tri type too big")
|
||||
red,green,blue = self.vizinfo.tcolor[itype]
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,[red,green,blue,1.0]);
|
||||
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,self.shiny);
|
||||
@ -909,7 +909,7 @@ class gl:
|
||||
ymin >= ylo and ymax <= yhi and zmin >= zlo and zmax <= zhi:
|
||||
if bond[10] > bound: continue
|
||||
itype = int(bond[1])
|
||||
if itype > ncolor: raise StandardError("bond type too big")
|
||||
if itype > ncolor: raise Exception("bond type too big")
|
||||
red,green,blue = self.vizinfo.bcolor[itype]
|
||||
rad = self.vizinfo.brad[itype]
|
||||
glPushMatrix()
|
||||
@ -941,7 +941,7 @@ class gl:
|
||||
ymin >= ylo and ymax <= yhi and \
|
||||
zmin >= zlo and zmax <= zhi:
|
||||
itype = int(tri[1])
|
||||
if itype > ncolor: raise StandardError("tri type too big")
|
||||
if itype > ncolor: raise Exception("tri type too big")
|
||||
red,green,blue = self.vizinfo.tcolor[itype]
|
||||
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,
|
||||
[red,green,blue,1.0]);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#
|
||||
# Copyright (2005) 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
|
||||
# certain rights in this software. This software is distributed under
|
||||
# the GNU General Public License.
|
||||
|
||||
# for python3 compatibility
|
||||
@ -16,7 +16,7 @@ oneline = "Create plots via GnuPlot plotting program"
|
||||
docstr = """
|
||||
g = gnu() start up GnuPlot
|
||||
g.stop() shut down GnuPlot process
|
||||
|
||||
|
||||
g.plot(a) plot vector A against linear index
|
||||
g.plot(a,b) plot B against A
|
||||
g.plot(a,b,c,d,...) plot B against A, D against C, etc
|
||||
@ -35,14 +35,14 @@ g("plot 'file.dat' using 2:3 with lines") execute string in GnuPlot
|
||||
g.enter() enter GnuPlot shell
|
||||
gnuplot> plot sin(x) with lines type commands directly to GnuPlot
|
||||
gnuplot> exit, quit exit GnuPlot shell
|
||||
|
||||
|
||||
g.export("data",range(100),a,...) create file with columns of numbers
|
||||
|
||||
all vectors must be of equal length
|
||||
could plot from file with GnuPlot command: plot 'data' using 1:2 with lines
|
||||
|
||||
g.select(N) figure N becomes the current plot
|
||||
|
||||
|
||||
subsequent commands apply to this plot
|
||||
|
||||
g.hide(N) delete window for figure N
|
||||
@ -87,17 +87,18 @@ g.curve(N,'r') set color of curve N
|
||||
|
||||
# Imports and external programs
|
||||
|
||||
import types, os
|
||||
import os
|
||||
import sys
|
||||
|
||||
try: from DEFAULTS import PIZZA_GNUPLOT
|
||||
except: PIZZA_GNUPLOT = "gnuplot -p"
|
||||
except ImportError: PIZZA_GNUPLOT = "gnuplot -p"
|
||||
try: from DEFAULTS import PIZZA_GNUTERM
|
||||
except: PIZZA_GNUTERM = "x11"
|
||||
except ImportError: PIZZA_GNUTERM = "x11"
|
||||
|
||||
# Class definition
|
||||
|
||||
class gnu:
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def __init__(self):
|
||||
@ -105,7 +106,7 @@ class gnu:
|
||||
self.file = "tmp.gnu"
|
||||
self.figures = []
|
||||
self.select(1)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def stop(self):
|
||||
@ -117,12 +118,15 @@ class gnu:
|
||||
def __call__(self,command):
|
||||
self.GNUPLOT.write(command + '\n')
|
||||
self.GNUPLOT.flush()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def enter(self):
|
||||
while 1:
|
||||
command = raw_input("gnuplot> ")
|
||||
if sys.version_info[0] == 3:
|
||||
command = input("gnuplot> ")
|
||||
else:
|
||||
command = raw_input("gnuplot> ")
|
||||
if command == "quit" or command == "exit": return
|
||||
self.__call__(command)
|
||||
|
||||
@ -136,7 +140,7 @@ class gnu:
|
||||
self.export(file,linear,vectors[0])
|
||||
self.figures[self.current-1].ncurves = 1
|
||||
else:
|
||||
if len(vectors) % 2: raise StandardError("vectors must come in pairs")
|
||||
if len(vectors) % 2: raise Exception("vectors must come in pairs")
|
||||
for i in range(0,len(vectors),2):
|
||||
file = self.file + ".%d.%d" % (self.current,i/2+1)
|
||||
self.export(file,vectors[i],vectors[i+1])
|
||||
@ -155,7 +159,7 @@ class gnu:
|
||||
if i: partial_vecs.append(vec[:i])
|
||||
else: partial_vecs.append([0])
|
||||
self.plot(*partial_vecs)
|
||||
|
||||
|
||||
if n < 10: newfile = file + "000" + str(n)
|
||||
elif n < 100: newfile = file + "00" + str(n)
|
||||
elif n < 1000: newfile = file + "0" + str(n)
|
||||
@ -163,14 +167,14 @@ class gnu:
|
||||
|
||||
self.save(newfile)
|
||||
n += 1
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# write list of equal-length vectors to filename
|
||||
|
||||
def export(self,filename,*vectors):
|
||||
n = len(vectors[0])
|
||||
for vector in vectors:
|
||||
if len(vector) != n: raise StandardError("vectors must be same length")
|
||||
if len(vector) != n: raise Exception("vectors must be same length")
|
||||
f = open(filename,'w')
|
||||
nvec = len(vectors)
|
||||
for i in range(n):
|
||||
@ -204,7 +208,7 @@ class gnu:
|
||||
# do not continue until plot file is written out
|
||||
# else script could go forward and change data file
|
||||
# use tmp.done as semaphore to indicate plot is finished
|
||||
|
||||
|
||||
def save(self,file):
|
||||
self.__call__("set terminal postscript enhanced solid lw 2 color portrait")
|
||||
cmd = "set output '%s.eps'" % file
|
||||
@ -215,7 +219,7 @@ class gnu:
|
||||
while not os.path.exists("tmp.done"): continue
|
||||
self.__call__("set output")
|
||||
self.select(self.current)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# restore default attributes by creating a new fig object
|
||||
|
||||
@ -224,7 +228,7 @@ class gnu:
|
||||
fig.ncurves = self.figures[self.current-1].ncurves
|
||||
self.figures[self.current-1] = fig
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def aspect(self,value):
|
||||
@ -248,12 +252,12 @@ class gnu:
|
||||
else:
|
||||
self.figures[self.current-1].ylimit = (values[0],values[1])
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def label(self,x,y,text):
|
||||
self.figures[self.current-1].labels.append((x,y,text))
|
||||
self.figures[self.current-1].nlabels += 1
|
||||
self.figures[self.current-1].nlabels += 1
|
||||
self.draw()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
@ -262,7 +266,7 @@ class gnu:
|
||||
self.figures[self.current-1].nlabel = 0
|
||||
self.figures[self.current-1].labels = []
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def title(self,*strings):
|
||||
@ -279,13 +283,13 @@ class gnu:
|
||||
def xtitle(self,label):
|
||||
self.figures[self.current-1].xtitle = label
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def ytitle(self,label):
|
||||
self.figures[self.current-1].ytitle = label
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def xlog(self):
|
||||
@ -294,7 +298,7 @@ class gnu:
|
||||
else:
|
||||
self.figures[self.current-1].xlog = 1
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def ylog(self):
|
||||
@ -303,7 +307,7 @@ class gnu:
|
||||
else:
|
||||
self.figures[self.current-1].ylog = 1
|
||||
self.draw()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def curve(self,num,color):
|
||||
@ -319,10 +323,10 @@ class gnu:
|
||||
def draw(self):
|
||||
fig = self.figures[self.current-1]
|
||||
if not fig.ncurves: return
|
||||
|
||||
|
||||
cmd = 'set size ratio ' + str(1.0/float(fig.aspect))
|
||||
self.__call__(cmd)
|
||||
|
||||
|
||||
cmd = 'set title ' + '"' + fig.title + '"'
|
||||
self.__call__(cmd)
|
||||
cmd = 'set xlabel ' + '"' + fig.xtitle + '"'
|
||||
@ -334,11 +338,11 @@ class gnu:
|
||||
else: self.__call__("unset logscale x")
|
||||
if fig.ylog: self.__call__("set logscale y")
|
||||
else: self.__call__("unset logscale y")
|
||||
if fig.xlimit:
|
||||
if fig.xlimit:
|
||||
cmd = 'set xr [' + str(fig.xlimit[0]) + ':' + str(fig.xlimit[1]) + ']'
|
||||
self.__call__(cmd)
|
||||
else: self.__call__("set xr [*:*]")
|
||||
if fig.ylimit:
|
||||
if fig.ylimit:
|
||||
cmd = 'set yr [' + str(fig.ylimit[0]) + ':' + str(fig.ylimit[1]) + ']'
|
||||
self.__call__(cmd)
|
||||
else: self.__call__("set yr [*:*]")
|
||||
@ -368,7 +372,7 @@ class figure:
|
||||
|
||||
def __init__(self):
|
||||
self.ncurves = 0
|
||||
self.colors = []
|
||||
self.colors = []
|
||||
self.title = ""
|
||||
self.xtitle = ""
|
||||
self.ytitle = ""
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#
|
||||
# Copyright (2005) 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
|
||||
# certain rights in this software. This software is distributed under
|
||||
# the GNU General Public License.
|
||||
|
||||
# for python3 compatibility
|
||||
@ -25,7 +25,7 @@ p = pdbfile("3CRO",d) read in single PDB file with snapshot data
|
||||
if only one 4-char file specified and it is not found,
|
||||
it will be downloaded from http://www.rcsb.org as 3CRO.pdb
|
||||
d arg is object with atom coordinates (dump, data)
|
||||
|
||||
|
||||
p.one() write all output as one big PDB file to tmp.pdb
|
||||
p.one("mine") write to mine.pdb
|
||||
p.many() write one PDB file per snapshot: tmp0000.pdb, ...
|
||||
@ -39,7 +39,7 @@ p.single(N,"new") write as new.pdb
|
||||
if one file in str arg and d: one new PDB file per snapshot
|
||||
using input PDB file as template
|
||||
multiple input PDB files with a d is not allowed
|
||||
|
||||
|
||||
index,time,flag = p.iterator(0)
|
||||
index,time,flag = p.iterator(1)
|
||||
|
||||
@ -68,7 +68,7 @@ index,time,flag = p.iterator(1)
|
||||
|
||||
# Imports and external programs
|
||||
|
||||
import sys, types, glob, urllib
|
||||
import sys, glob, urllib
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
if PY3:
|
||||
@ -93,31 +93,31 @@ class pdbfile:
|
||||
elif len(args) == 2:
|
||||
filestr = args[0]
|
||||
self.data = args[1]
|
||||
else: raise StandardError("invalid args for pdb()")
|
||||
else: raise Exception("invalid args for pdb()")
|
||||
|
||||
# flist = full list of all PDB input file names
|
||||
# append .pdb if needed
|
||||
|
||||
|
||||
if filestr:
|
||||
list = filestr.split()
|
||||
flist = []
|
||||
for file in list:
|
||||
if '*' in file: flist += glob.glob(file)
|
||||
else: flist.append(file)
|
||||
for i in xrange(len(flist)):
|
||||
for i in range(len(flist)):
|
||||
if flist[i][-4:] != ".pdb": flist[i] += ".pdb"
|
||||
if len(flist) == 0:
|
||||
raise StandardError("no PDB file specified")
|
||||
raise Exception("no PDB file specified")
|
||||
self.files = flist
|
||||
else: self.files = []
|
||||
|
||||
if len(self.files) > 1 and self.data:
|
||||
raise StandardError("cannot use multiple PDB files with data object")
|
||||
raise Exception("cannot use multiple PDB files with data object")
|
||||
if len(self.files) == 0 and not self.data:
|
||||
raise StandardError("no input PDB file(s)")
|
||||
raise Exception("no input PDB file(s)")
|
||||
|
||||
# grab PDB file from http://rcsb.org if not a local file
|
||||
|
||||
|
||||
if len(self.files) == 1 and len(self.files[0]) == 8:
|
||||
try:
|
||||
open(self.files[0],'r').close()
|
||||
@ -127,7 +127,7 @@ class pdbfile:
|
||||
urllib.urlretrieve(fetchstr,self.files[0])
|
||||
|
||||
if self.data and len(self.files): self.read_template(self.files[0])
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# write a single large PDB file for concatenating all input data or files
|
||||
# if data exists:
|
||||
@ -145,7 +145,7 @@ class pdbfile:
|
||||
f = open(file,'w')
|
||||
|
||||
# use template PDB file with each snapshot
|
||||
|
||||
|
||||
if self.data:
|
||||
n = flag = 0
|
||||
while 1:
|
||||
@ -163,7 +163,7 @@ class pdbfile:
|
||||
print("END",file=f)
|
||||
print(file,end='')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
f.close()
|
||||
print("\nwrote %d datasets to %s in PDB format" % (n,file))
|
||||
|
||||
@ -199,7 +199,7 @@ class pdbfile:
|
||||
f = open(file,'w')
|
||||
self.convert(f,which)
|
||||
f.close()
|
||||
|
||||
|
||||
print(time,end='')
|
||||
sys.stdout.flush()
|
||||
n += 1
|
||||
@ -216,13 +216,13 @@ class pdbfile:
|
||||
else:
|
||||
file = root + str(n)
|
||||
file += ".pdb"
|
||||
|
||||
|
||||
f = open(file,'w')
|
||||
f.write(open(infile,'r').read())
|
||||
f.close()
|
||||
print(file,end='')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
n += 1
|
||||
|
||||
print("\nwrote %d datasets to %s*.pdb in PDB format" % (n,root))
|
||||
@ -249,7 +249,7 @@ class pdbfile:
|
||||
self.convert(f,which)
|
||||
else:
|
||||
f.write(open(self.files[time],'r').read())
|
||||
|
||||
|
||||
f.close()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
@ -268,8 +268,8 @@ class pdbfile:
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# read a PDB file and store ATOM lines
|
||||
|
||||
def read_template(self,file):
|
||||
|
||||
def read_template(self,file):
|
||||
lines = open(file,'r').readlines()
|
||||
self.atomlines = {}
|
||||
for line in lines:
|
||||
|
||||
@ -79,7 +79,7 @@ class vizinfo:
|
||||
# if list of types has a 0, increment each type value
|
||||
|
||||
if 0 in ids:
|
||||
for i in xrange(len(ids)): ids[i] += 1
|
||||
for i in range(len(ids)): ids[i] += 1
|
||||
|
||||
# extend storage list if necessary
|
||||
# extend other arrays for same "which" so that gl::make_atom_calllist
|
||||
@ -109,7 +109,7 @@ class vizinfo:
|
||||
ntypes = len(ids)
|
||||
nrgbs = len(rgbs)
|
||||
|
||||
for i in xrange(ntypes):
|
||||
for i in range(ntypes):
|
||||
id = ids[i]
|
||||
|
||||
if rgbs[0] == "loop":
|
||||
@ -157,7 +157,7 @@ class vizinfo:
|
||||
# if list of types has a 0, increment each type value
|
||||
|
||||
if 0 in ids:
|
||||
for i in xrange(len(ids)): ids[i] += 1
|
||||
for i in range(len(ids)): ids[i] += 1
|
||||
|
||||
# extend storage list if necessary
|
||||
# extend other arrays for same "which" so that gl::make_atom_calllist
|
||||
@ -220,7 +220,7 @@ class vizinfo:
|
||||
# if list of types has a 0, increment each type value
|
||||
|
||||
if 0 in ids:
|
||||
for i in xrange(len(ids)): ids[i] += 1
|
||||
for i in range(len(ids)): ids[i] += 1
|
||||
|
||||
# extend storage list if necessary
|
||||
# extend other arrays for same "which" so that gl::make_atom_calllist
|
||||
@ -234,7 +234,7 @@ class vizinfo:
|
||||
# if list lengths match, set directly, else set types to 1st fill value
|
||||
|
||||
if len(fills) == len(ids):
|
||||
for i in xrange(len(ids)): self.tfill[ids[i]] = int(fills[i])
|
||||
for i in range(len(ids)): self.tfill[ids[i]] = int(fills[i])
|
||||
else:
|
||||
for id in ids: self.tfill[id] = int(fills[0])
|
||||
|
||||
|
||||
@ -45,17 +45,16 @@ v.debug([True|False]) display generated VMD script commands?
|
||||
|
||||
# Imports and external programs
|
||||
|
||||
import types, os
|
||||
import numpy
|
||||
import os
|
||||
|
||||
try: from DEFAULTS import PIZZA_VMDNAME
|
||||
except: PIZZA_VMDNAME = "vmd"
|
||||
except ImportError: PIZZA_VMDNAME = "vmd"
|
||||
try: from DEFAULTS import PIZZA_VMDDIR
|
||||
except: PIZZA_VMDDIR = "/usr/local/lib/vmd"
|
||||
except ImportError: PIZZA_VMDDIR = "/usr/local/lib/vmd"
|
||||
try: from DEFAULTS import PIZZA_VMDDEV
|
||||
except: PIZZA_VMDDEV = "win"
|
||||
except ImportError: PIZZA_VMDDEV = "win"
|
||||
try: from DEFAULTS import PIZZA_VMDARCH
|
||||
except: PIZZA_VMDARCH = "LINUXAMD64"
|
||||
except ImportError: PIZZA_VMDARCH = "LINUXAMD64"
|
||||
|
||||
# try these settings for a Mac
|
||||
#PIZZA_VMDNAME = "vmd"
|
||||
@ -64,7 +63,7 @@ except: PIZZA_VMDARCH = "LINUXAMD64"
|
||||
#PIZZA_VMDARCH = "MACOSXX86"
|
||||
|
||||
try: import pexpect
|
||||
except:
|
||||
except ImportError:
|
||||
print("pexpect from http://pypi.python.org/pypi/pexpect", \
|
||||
"is required for vmd tool")
|
||||
raise
|
||||
|
||||
@ -28,10 +28,10 @@ nsteps = int(sys.argv[3])
|
||||
compute = sys.argv[4]
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
#nprocs = MPI.COMM_WORLD.Get_size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -57,7 +57,7 @@ if me == 0:
|
||||
gn = gnu()
|
||||
gn.plot(xaxis,yaxis)
|
||||
gn.xrange(0,nsteps)
|
||||
gn.title(compute,"Timestep","Temperature")
|
||||
gn.title(compute.replace('_', ' '),"Timestep","Temperature")
|
||||
|
||||
# run nfreq steps at a time w/out pre/post, query compute, refresh plot
|
||||
|
||||
@ -71,6 +71,5 @@ while ntimestep < nsteps:
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -4,7 +4,7 @@ This folder contains examples showcasing the usage of the PyLammps Python
|
||||
interface and Jupyter notebooks. To use this you will need LAMMPS compiled as
|
||||
a shared library and the LAMMPS Python package installed.
|
||||
|
||||
An extensive guide on how to achieve this is documented in the [LAMMPS manual](https://lammps.sandia.gov/doc/Python_install.html). There is also a [PyLammps tutorial](https://lammps.sandia.gov/doc/Howto_pylammps.html).
|
||||
An extensive guide on how to achieve this is documented in the [LAMMPS manual](https://docs.lammps.org/Python_install.html). There is also a [PyLammps tutorial](https://docs.lammps.org/Howto_pylammps.html).
|
||||
|
||||
The following will show one way of creating a Python virtual environment
|
||||
which has both LAMMPS and its Python package installed:
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
"source": [
|
||||
"## Prerequisites\n",
|
||||
"\n",
|
||||
"Before running this example, make sure your Python environment can find the LAMMPS shared library (`liblammps.so`) and the LAMMPS Python package is installed. If you followed the [README](README.md) in this folder, this should already be the case. You can also find more information about how to compile LAMMPS and install the LAMMPS Python package in the [LAMMPS manual](https://lammps.sandia.gov/doc/Python_install.html). There is also a dedicated [PyLammps HowTo](https://lammps.sandia.gov/doc/Howto_pylammps.html)."
|
||||
"Before running this example, make sure your Python environment can find the LAMMPS shared library (`liblammps.so`) and the LAMMPS Python package is installed. If you followed the [README](README.md) in this folder, this should already be the case. You can also find more information about how to compile LAMMPS and install the LAMMPS Python package in the [LAMMPS manual](https://docs.lammps.org/Python_install.html). There is also a dedicated [PyLammps HowTo](https://docs.lammps.org/Howto_pylammps.html)."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
"source": [
|
||||
"## Prerequisites\n",
|
||||
"\n",
|
||||
"Before running this example, make sure your Python environment can find the LAMMPS shared library (`liblammps.so`) and the LAMMPS Python package is installed. If you followed the [README](README.md) in this folder, this should already be the case. You can also find more information about how to compile LAMMPS and install the LAMMPS Python package in the [LAMMPS manual](https://lammps.sandia.gov/doc/Python_install.html). There is also a dedicated [PyLammps HowTo](https://lammps.sandia.gov/doc/Howto_pylammps.html)."
|
||||
"Before running this example, make sure your Python environment can find the LAMMPS shared library (`liblammps.so`) and the LAMMPS Python package is installed. If you followed the [README](README.md) in this folder, this should already be the case. You can also find more information about how to compile LAMMPS and install the LAMMPS Python package in the [LAMMPS manual](https://docs.lammps.org/Python_install.html). There is also a dedicated [PyLammps HowTo](https://docs.lammps.org/Howto_pylammps.html)."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
"source": [
|
||||
"## Prerequisites\n",
|
||||
"\n",
|
||||
"Before Running this example, make sure your Python environment can find the LAMMPS shared library (`liblammps.so`) and the LAMMPS Python package is installed. If you followed the [README](README.md) in this folder, this should already be the case. You can also find more information about how to compile LAMMPS and install the LAMMPS Python package in the [LAMMPS manual](https://lammps.sandia.gov/doc/Python_install.html). There is also a dedicated [PyLammps HowTo](https://lammps.sandia.gov/doc/Howto_pylammps.html)."
|
||||
"Before Running this example, make sure your Python environment can find the LAMMPS shared library (`liblammps.so`) and the LAMMPS Python package is installed. If you followed the [README](README.md) in this folder, this should already be the case. You can also find more information about how to compile LAMMPS and install the LAMMPS Python package in the [LAMMPS manual](https://docs.lammps.org/Python_install.html). There is also a dedicated [PyLammps HowTo](https://docs.lammps.org/Howto_pylammps.html)."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -111,7 +111,7 @@
|
||||
"source": [
|
||||
"## Visualizing the initial state\n",
|
||||
"\n",
|
||||
"`IPyLammps` allows you to visualize the current simulation state with the [image](https://lammps.sandia.gov/doc/Python_module.html#lammps.IPyLammps.image) command. Here we use it to create an image of the initial state of the system."
|
||||
"`IPyLammps` allows you to visualize the current simulation state with the [image](https://docs.lammps.org/Python_module.html#lammps.IPyLammps.image) command. Here we use it to create an image of the initial state of the system."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
# Parallel syntax: mpirun -np 4 simple.py in.lammps
|
||||
# in.lammps = LAMMPS input script
|
||||
# also need to uncomment either Pypar or mpi4py sections below
|
||||
# also need to uncomment mpi4py sections below
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
@ -27,11 +27,6 @@ infile = sys.argv[1]
|
||||
|
||||
me = 0
|
||||
|
||||
# uncomment this if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
@ -133,8 +128,5 @@ lmp.reset_box([0,0,0],[10,10,8],0,0,0)
|
||||
boxlo,boxhi,xy,yz,xz,periodicity,box_change = lmp.extract_box()
|
||||
if me == 0: print("Box info",boxlo,boxhi,xy,yz,xz,periodicity,box_change)
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
|
||||
@ -28,10 +28,10 @@ nfreq = int(sys.argv[2])
|
||||
nsteps = int(sys.argv[3])
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
#nprocs = MPI.COMM_WORLD.Get_size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -68,6 +68,5 @@ while ntimestep < nsteps:
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -24,10 +24,10 @@ nfreq = int(sys.argv[2])
|
||||
nsteps = int(sys.argv[3])
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
#nprocs = MPI.COMM_WORLD.Get_size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -83,6 +83,5 @@ while ntimestep < nsteps:
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -24,10 +24,10 @@ nfreq = int(sys.argv[2])
|
||||
nsteps = int(sys.argv[3])
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
#nprocs = MPI.COMM_WORLD.Get_size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -78,6 +78,5 @@ while ntimestep < nsteps:
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -24,10 +24,10 @@ nfreq = int(sys.argv[2])
|
||||
nsteps = int(sys.argv[3])
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
# uncomment this if running in parallel via mpi4py
|
||||
#from mpi4py import MPI
|
||||
#me = MPI.COMM_WORLD.Get_rank()
|
||||
#nprocs = MPI.COMM_WORLD.Get_size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -87,6 +87,5 @@ if me == 0:
|
||||
#v.enter()
|
||||
#v.stop()
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
# uncomment if running in parallel via mpi4py
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -9,9 +9,6 @@
|
||||
# compute-ID = ID of compute that calculates temperature
|
||||
# (or any other scalar quantity)
|
||||
|
||||
# IMPORTANT: this script cannot yet be run in parallel via Pypar,
|
||||
# because I can't seem to do a MPI-style broadcast in Pypar
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,os,time
|
||||
sys.path.append("./pizza")
|
||||
@ -59,10 +56,6 @@ nfreq = int(sys.argv[2])
|
||||
compute = sys.argv[3]
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -163,7 +156,3 @@ while 1:
|
||||
time.sleep(0.01)
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -9,9 +9,6 @@
|
||||
# compute-ID = ID of compute that calculates temperature
|
||||
# (or any other scalar quantity)
|
||||
|
||||
# IMPORTANT: this script cannot yet be run in parallel via Pypar,
|
||||
# because I can't seem to do a MPI-style broadcast in Pypar
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,time
|
||||
sys.path.append("./pizza")
|
||||
@ -55,10 +52,6 @@ nfreq = int(sys.argv[2])
|
||||
compute = sys.argv[3]
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -176,7 +169,3 @@ while 1:
|
||||
time.sleep(0.01)
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -9,9 +9,6 @@
|
||||
# compute-ID = ID of compute that calculates temperature
|
||||
# (or any other scalar quantity)
|
||||
|
||||
# IMPORTANT: this script cannot yet be run in parallel via Pypar,
|
||||
# because I can't seem to do a MPI-style broadcast in Pypar
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,time
|
||||
sys.path.append("./pizza")
|
||||
@ -57,10 +54,6 @@ nfreq = int(sys.argv[2])
|
||||
compute = sys.argv[3]
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -172,7 +165,3 @@ while 1:
|
||||
time.sleep(0.01)
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -9,9 +9,6 @@
|
||||
# compute-ID = ID of compute that calculates temperature
|
||||
# (or any other scalar quantity)
|
||||
|
||||
# IMPORTANT: this script cannot yet be run in parallel via Pypar,
|
||||
# because I can't seem to do a MPI-style broadcast in Pypar
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,time
|
||||
sys.path.append("./pizza")
|
||||
@ -56,10 +53,6 @@ nfreq = int(sys.argv[2])
|
||||
compute = sys.argv[3]
|
||||
|
||||
me = 0
|
||||
# uncomment if running in parallel via Pypar
|
||||
#import pypar
|
||||
#me = pypar.rank()
|
||||
#nprocs = pypar.size()
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps()
|
||||
@ -171,7 +164,3 @@ while 1:
|
||||
time.sleep(0.01)
|
||||
|
||||
lmp.command("run 0 pre no post yes")
|
||||
|
||||
# uncomment if running in parallel via Pypar
|
||||
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
|
||||
#pypar.finalize()
|
||||
|
||||
@ -10,7 +10,7 @@ build target in the conventional and CMake based build systems
|
||||
# copy LAMMPS shared library and lammps package to system dirs
|
||||
|
||||
from __future__ import print_function
|
||||
import sys,os,shutil
|
||||
import sys,os,shutil,time
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(prog='install.py',
|
||||
@ -80,13 +80,15 @@ if args.dir:
|
||||
|
||||
sys.exit()
|
||||
|
||||
# extract version string from header
|
||||
# extract LAMMPS version string from header
|
||||
# and convert to python packaging compatible version
|
||||
def get_lammps_version(header):
|
||||
with open(header, 'r') as f:
|
||||
line = f.readline()
|
||||
start_pos = line.find('"')+1
|
||||
end_pos = line.find('"', start_pos)
|
||||
return "".join(line[start_pos:end_pos].split())
|
||||
t = time.strptime("".join(line[start_pos:end_pos].split()), "%d%b%Y")
|
||||
return "{}.{}.{}".format(t.tm_year,t.tm_mon,t.tm_mday)
|
||||
|
||||
verstr = get_lammps_version(args.version)
|
||||
|
||||
@ -110,7 +112,7 @@ setup_kwargs= dict(name="lammps",
|
||||
version=verstr,
|
||||
author="Steve Plimpton",
|
||||
author_email="sjplimp@sandia.gov",
|
||||
url="https://lammps.sandia.gov",
|
||||
url="https://www.lammps.org",
|
||||
description="LAMMPS Molecular Dynamics Python package",
|
||||
license="GPL",
|
||||
packages=pkgs,
|
||||
@ -121,7 +123,7 @@ try:
|
||||
sys.argv = ["setup.py","install"] # as if had run "python setup.py install"
|
||||
setup_kwargs['data_files']=[(os.path.join(get_python_lib(), 'lammps'), [args.lib])]
|
||||
setup(**setup_kwargs)
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
tryuser=True
|
||||
print ("Installation into global site-packages folder failed.\nTrying user folder %s now." % site.USER_SITE)
|
||||
|
||||
@ -130,5 +132,5 @@ if tryuser:
|
||||
sys.argv = ["setup.py","install","--user"] # as if had run "python setup.py install --user"
|
||||
setup_kwargs['data_files']=[(os.path.join(site.USER_SITE, 'lammps'), [args.lib])]
|
||||
setup(**setup_kwargs)
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
print("Installation into user site package folder failed.")
|
||||
|
||||
@ -8,31 +8,42 @@ LAMMPS module global members:
|
||||
result of :py:func:`lammps.version`.
|
||||
"""
|
||||
|
||||
from .constants import *
|
||||
from .core import *
|
||||
from .data import *
|
||||
from .pylammps import *
|
||||
from .constants import * # lgtm [py/polluting-import]
|
||||
from .core import * # lgtm [py/polluting-import]
|
||||
from .data import * # lgtm [py/polluting-import]
|
||||
from .pylammps import * # lgtm [py/polluting-import]
|
||||
|
||||
# convert module string version to numeric version
|
||||
# convert installed module string version to numeric version
|
||||
def get_version_number():
|
||||
from datetime import datetime
|
||||
import time
|
||||
from os.path import join
|
||||
from sys import version_info
|
||||
|
||||
# must report 0 when inside LAMMPS source tree
|
||||
if __file__.find(join('python', 'lammps', '__init__.py')) > 0:
|
||||
return 0
|
||||
|
||||
vstring = None
|
||||
if version_info.major == 3 and version_info.minor >= 8:
|
||||
from importlib.metadata import version
|
||||
from importlib.metadata import version, PackageNotFoundError
|
||||
try:
|
||||
vstring = version('lammps')
|
||||
except: pass
|
||||
except PackageNotFoundError:
|
||||
# nothing to do, ignore
|
||||
pass
|
||||
|
||||
else:
|
||||
from pkg_resources import get_distribution
|
||||
from pkg_resources import get_distribution, DistributionNotFound
|
||||
try:
|
||||
vstring = get_distribution('lammps').version
|
||||
except: pass
|
||||
except DistributionNotFound:
|
||||
# nothing to do, ignore
|
||||
pass
|
||||
|
||||
if not vstring:
|
||||
return 0
|
||||
|
||||
d = datetime.strptime(vstring, "%d%b%Y")
|
||||
return d.year*10000 + d.month*100 + d.day
|
||||
t = time.strptime(vstring, "%Y.%m.%d")
|
||||
return t.tm_year*10000 + t.tm_mon*100 + t.tm_mday
|
||||
|
||||
__version__ = get_version_number()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
@ -11,8 +11,6 @@
|
||||
# See the README file in the top-level LAMMPS directory.
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
from ctypes import c_int, c_int32, c_int64
|
||||
|
||||
# various symbolic constants to be used
|
||||
# in certain calls to select data formats
|
||||
LAMMPS_AUTODETECT = None
|
||||
@ -42,6 +40,7 @@ LMP_VAR_ATOM = 1
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def get_ctypes_int(size):
|
||||
from ctypes import c_int, c_int32, c_int64
|
||||
if size == 4:
|
||||
return c_int32
|
||||
elif size == 8:
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
@ -18,15 +18,12 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import types
|
||||
import warnings
|
||||
from ctypes import *
|
||||
from ctypes import * # lgtm [py/polluting-import]
|
||||
from os.path import dirname,abspath,join
|
||||
from inspect import getsourcefile
|
||||
|
||||
from .constants import *
|
||||
from .data import *
|
||||
from .constants import * # lgtm [py/polluting-import]
|
||||
from .data import * # lgtm [py/polluting-import]
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -47,7 +44,7 @@ class ExceptionCheck:
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
if self.lmp.has_exceptions and self.lmp.lib.lammps_has_error(self.lmp.lmp):
|
||||
raise self.lmp._lammps_exception
|
||||
|
||||
@ -103,7 +100,7 @@ class lammps(object):
|
||||
|
||||
try:
|
||||
if ptr: self.lib = CDLL("",RTLD_GLOBAL)
|
||||
except:
|
||||
except OSError:
|
||||
self.lib = None
|
||||
|
||||
# load liblammps.so unless name is given
|
||||
@ -281,9 +278,13 @@ class lammps(object):
|
||||
|
||||
self.lib.lammps_id_name.argtypes = [c_void_p, c_char_p, c_int, c_char_p, c_int]
|
||||
|
||||
self.lib.lammps_plugin_count.argtypes = [ ]
|
||||
self.lib.lammps_plugin_name.argtypes = [c_int, c_char_p, c_char_p, c_int]
|
||||
|
||||
self.lib.lammps_version.argtypes = [c_void_p]
|
||||
|
||||
self.lib.lammps_get_os_info.argtypes = [c_char_p, c_int]
|
||||
self.lib.lammps_get_gpu_device_info.argtypes = [c_char_p, c_int]
|
||||
|
||||
self.lib.lammps_get_mpi_comm.argtypes = [c_void_p]
|
||||
|
||||
@ -309,12 +310,12 @@ class lammps(object):
|
||||
from mpi4py import __version__ as mpi4py_version
|
||||
# tested to work with mpi4py versions 2 and 3
|
||||
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3']
|
||||
except:
|
||||
except ImportError:
|
||||
# ignore failing import
|
||||
pass
|
||||
|
||||
# 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
|
||||
# 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
|
||||
@ -418,9 +419,16 @@ class lammps(object):
|
||||
# shut-down LAMMPS instance
|
||||
|
||||
def __del__(self):
|
||||
if self.lmp and self.opened:
|
||||
self.lib.lammps_close(self.lmp)
|
||||
self.opened = 0
|
||||
self.close()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# context manager implementation
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, ex_type, ex_value, ex_traceback):
|
||||
self.close()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -447,7 +455,8 @@ class lammps(object):
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_close` function of the C-library interface.
|
||||
"""
|
||||
if self.opened: self.lib.lammps_close(self.lmp)
|
||||
if self.lmp and self.opened:
|
||||
self.lib.lammps_close(self.lmp)
|
||||
self.lmp = None
|
||||
self.opened = 0
|
||||
|
||||
@ -456,9 +465,7 @@ class lammps(object):
|
||||
def finalize(self):
|
||||
"""Shut down the MPI communication through the library interface by calling :cpp:func:`lammps_finalize`.
|
||||
"""
|
||||
if self.opened: self.lib.lammps_close(self.lmp)
|
||||
self.lmp = None
|
||||
self.opened = 0
|
||||
self.close()
|
||||
self.lib.lammps_finalize()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -486,7 +493,7 @@ class lammps(object):
|
||||
|
||||
sb = create_string_buffer(512)
|
||||
self.lib.lammps_get_os_info(sb,512)
|
||||
return sb
|
||||
return sb.value.decode()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -732,12 +739,11 @@ class lammps(object):
|
||||
def extract_global(self, name, dtype=LAMMPS_AUTODETECT):
|
||||
"""Query LAMMPS about global settings of different types.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_global`
|
||||
function of the C-library interface. Unlike the C function
|
||||
this method returns the value and not a pointer and thus can
|
||||
only return the first value for keywords representing a list
|
||||
of values. The :cpp:func:`lammps_extract_global` documentation
|
||||
includes a list of the supported keywords and their data types.
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_global` function
|
||||
of the C-library interface. Since there are no pointers in Python, this
|
||||
method will - unlike the C function - return the value or a list of
|
||||
values. The :cpp:func:`lammps_extract_global` documentation includes a
|
||||
list of the supported keywords and their data types.
|
||||
Since Python needs to know the data type to be able to interpret
|
||||
the result, by default, this function will try to auto-detect the data type
|
||||
by asking the library. You can also force a specific data type. For that
|
||||
@ -749,12 +755,23 @@ class lammps(object):
|
||||
:type name: string
|
||||
:param dtype: data type of the returned data (see :ref:`py_datatype_constants`)
|
||||
:type dtype: int, optional
|
||||
:return: value of the property or None
|
||||
:rtype: int, float, or NoneType
|
||||
:return: value of the property or list of values or None
|
||||
:rtype: int, float, list, or NoneType
|
||||
"""
|
||||
|
||||
if dtype == LAMMPS_AUTODETECT:
|
||||
dtype = self.extract_global_datatype(name)
|
||||
|
||||
# set length of vector for items that are not a scalar
|
||||
vec_dict = { 'boxlo':3, 'boxhi':3, 'sublo':3, 'subhi':3,
|
||||
'sublo_lambda':3, 'subhi_lambda':3, 'periodicity':3 }
|
||||
if name in vec_dict:
|
||||
veclen = vec_dict[name]
|
||||
elif name == 'respa_dt':
|
||||
veclen = self.extract_global('respa_levels',LAMMPS_INT)
|
||||
else:
|
||||
veclen = 1
|
||||
|
||||
if name: name = name.encode()
|
||||
else: return None
|
||||
|
||||
@ -769,14 +786,22 @@ class lammps(object):
|
||||
target_type = float
|
||||
elif dtype == LAMMPS_STRING:
|
||||
self.lib.lammps_extract_global.restype = c_char_p
|
||||
target_type = lambda x: str(x, 'ascii')
|
||||
target_type = str
|
||||
else:
|
||||
target_type = None
|
||||
|
||||
ptr = self.lib.lammps_extract_global(self.lmp, name)
|
||||
if ptr:
|
||||
return target_type(ptr[0])
|
||||
if dtype == LAMMPS_STRING:
|
||||
return ptr.decode('utf-8')
|
||||
if veclen > 1:
|
||||
result = []
|
||||
for i in range(0,veclen):
|
||||
result.append(target_type(ptr[i]))
|
||||
return result
|
||||
else: return target_type(ptr[0])
|
||||
return None
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract per-atom info datatype
|
||||
|
||||
@ -863,71 +888,71 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_compute(self,id,style,type):
|
||||
def extract_compute(self,cid,cstyle,ctype):
|
||||
"""Retrieve data from a LAMMPS compute
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_compute`
|
||||
function of the C-library interface.
|
||||
This function returns ``None`` if either the compute id is not
|
||||
recognized, or an invalid combination of :ref:`style <py_style_constants>`
|
||||
and :ref:`type <py_type_constants>` constants is used. The
|
||||
recognized, or an invalid combination of :ref:`cstyle <py_style_constants>`
|
||||
and :ref:`ctype <py_type_constants>` constants is used. The
|
||||
names and functionality of the constants are the same as for
|
||||
the corresponding C-library function. For requests to return
|
||||
a scalar or a size, the value is returned, otherwise a pointer.
|
||||
|
||||
:param id: compute ID
|
||||
:type id: string
|
||||
:param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type style: int
|
||||
:param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type type: int
|
||||
:param cid: compute ID
|
||||
:type cid: string
|
||||
:param cstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type cstyle: int
|
||||
:param ctype: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type ctype: int
|
||||
:return: requested data as scalar, pointer to 1d or 2d double array, or None
|
||||
:rtype: c_double, ctypes.POINTER(c_double), ctypes.POINTER(ctypes.POINTER(c_double)), or NoneType
|
||||
"""
|
||||
if id: id = id.encode()
|
||||
if cid: cid = cid.encode()
|
||||
else: return None
|
||||
|
||||
if type == LMP_TYPE_SCALAR:
|
||||
if style == LMP_STYLE_GLOBAL:
|
||||
if ctype == LMP_TYPE_SCALAR:
|
||||
if cstyle == LMP_STYLE_GLOBAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
elif style == LMP_STYLE_ATOM:
|
||||
elif cstyle == LMP_STYLE_ATOM:
|
||||
return None
|
||||
elif style == LMP_STYLE_LOCAL:
|
||||
elif cstyle == LMP_STYLE_LOCAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
|
||||
elif type == LMP_TYPE_VECTOR:
|
||||
elif ctype == LMP_TYPE_VECTOR:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
return ptr
|
||||
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
elif ctype == LMP_TYPE_ARRAY:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(POINTER(c_double))
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
return ptr
|
||||
|
||||
elif type == LMP_SIZE_COLS:
|
||||
if style == LMP_STYLE_GLOBAL \
|
||||
or style == LMP_STYLE_ATOM \
|
||||
or style == LMP_STYLE_LOCAL:
|
||||
elif ctype == LMP_SIZE_COLS:
|
||||
if cstyle == LMP_STYLE_GLOBAL \
|
||||
or cstyle == LMP_STYLE_ATOM \
|
||||
or cstyle == LMP_STYLE_LOCAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
|
||||
elif type == LMP_SIZE_VECTOR or type == LMP_SIZE_ROWS:
|
||||
if style == LMP_STYLE_GLOBAL \
|
||||
or style == LMP_STYLE_LOCAL:
|
||||
elif ctype == LMP_SIZE_VECTOR or ctype == LMP_SIZE_ROWS:
|
||||
if cstyle == LMP_STYLE_GLOBAL \
|
||||
or cstyle == LMP_STYLE_LOCAL:
|
||||
self.lib.lammps_extract_compute.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
|
||||
ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype)
|
||||
return ptr[0]
|
||||
|
||||
return None
|
||||
@ -937,25 +962,25 @@ class lammps(object):
|
||||
# in case of global data, free memory for 1 double via lammps_free()
|
||||
# double was allocated by library interface function
|
||||
|
||||
def extract_fix(self,id,style,type,nrow=0,ncol=0):
|
||||
def extract_fix(self,fid,fstyle,ftype,nrow=0,ncol=0):
|
||||
"""Retrieve data from a LAMMPS fix
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_fix`
|
||||
function of the C-library interface.
|
||||
This function returns ``None`` if either the fix id is not
|
||||
recognized, or an invalid combination of :ref:`style <py_style_constants>`
|
||||
and :ref:`type <py_type_constants>` constants is used. The
|
||||
recognized, or an invalid combination of :ref:`fstyle <py_style_constants>`
|
||||
and :ref:`ftype <py_type_constants>` constants is used. The
|
||||
names and functionality of the constants are the same as for
|
||||
the corresponding C-library function. For requests to return
|
||||
a scalar or a size, the value is returned, also when accessing
|
||||
global vectors or arrays, otherwise a pointer.
|
||||
|
||||
:param id: fix ID
|
||||
:type id: string
|
||||
:param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type style: int
|
||||
:param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type type: int
|
||||
:param fid: fix ID
|
||||
:type fid: string
|
||||
:param fstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type fstyle: int
|
||||
:param ftype: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type ftype: int
|
||||
:param nrow: index of global vector element or row index of global array element
|
||||
:type nrow: int
|
||||
:param ncol: column index of global array element
|
||||
@ -964,53 +989,53 @@ class lammps(object):
|
||||
:rtype: c_double, ctypes.POINTER(c_double), ctypes.POINTER(ctypes.POINTER(c_double)), or NoneType
|
||||
|
||||
"""
|
||||
if id: id = id.encode()
|
||||
if fid: fid = fid.encode()
|
||||
else: return None
|
||||
|
||||
if style == LMP_STYLE_GLOBAL:
|
||||
if type in (LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY):
|
||||
if fstyle == LMP_STYLE_GLOBAL:
|
||||
if ftype in (LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY):
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_double)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol)
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
result = ptr[0]
|
||||
self.lib.lammps_free(ptr)
|
||||
return result
|
||||
elif type in (LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS):
|
||||
elif ftype in (LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS):
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_int)
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol)
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
return ptr[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
elif style == LMP_STYLE_ATOM:
|
||||
if type == LMP_TYPE_VECTOR:
|
||||
elif fstyle == LMP_STYLE_ATOM:
|
||||
if ftype == LMP_TYPE_VECTOR:
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_double)
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
elif ftype == LMP_TYPE_ARRAY:
|
||||
self.lib.lammps_extract_fix.restype = POINTER(POINTER(c_double))
|
||||
elif type == LMP_SIZE_COLS:
|
||||
elif ftype == LMP_SIZE_COLS:
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_int)
|
||||
else:
|
||||
return None
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol)
|
||||
if type == LMP_SIZE_COLS:
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
if ftype == LMP_SIZE_COLS:
|
||||
return ptr[0]
|
||||
else:
|
||||
return ptr
|
||||
|
||||
elif style == LMP_STYLE_LOCAL:
|
||||
if type == LMP_TYPE_VECTOR:
|
||||
elif fstyle == LMP_STYLE_LOCAL:
|
||||
if ftype == LMP_TYPE_VECTOR:
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_double)
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
elif ftype == LMP_TYPE_ARRAY:
|
||||
self.lib.lammps_extract_fix.restype = POINTER(POINTER(c_double))
|
||||
elif type in (LMP_TYPE_SCALAR, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS):
|
||||
elif ftype in (LMP_TYPE_SCALAR, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS):
|
||||
self.lib.lammps_extract_fix.restype = POINTER(c_int)
|
||||
else:
|
||||
return None
|
||||
with ExceptionCheck(self):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol)
|
||||
if type in (LMP_TYPE_VECTOR, LMP_TYPE_ARRAY):
|
||||
ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol)
|
||||
if ftype in (LMP_TYPE_VECTOR, LMP_TYPE_ARRAY):
|
||||
return ptr
|
||||
else:
|
||||
return ptr[0]
|
||||
@ -1099,51 +1124,51 @@ class lammps(object):
|
||||
# return vector of atom properties gathered across procs
|
||||
# 3 variants to match src/library.cpp
|
||||
# name = atom property recognized by LAMMPS in atom->extract()
|
||||
# type = 0 for integer values, 1 for double values
|
||||
# dtype = 0 for integer values, 1 for double values
|
||||
# count = number of per-atom valus, 1 for type or charge, 3 for x or f
|
||||
# returned data is a 1d vector - doc how it is ordered?
|
||||
# NOTE: need to insure are converting to/from correct Python type
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
|
||||
def gather_atoms(self,name,type,count):
|
||||
def gather_atoms(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if type == 0:
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,type,count,data)
|
||||
elif type == 1:
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,type,count,data)
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def gather_atoms_concat(self,name,type,count):
|
||||
def gather_atoms_concat(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if type == 0:
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,name,type,count,data)
|
||||
elif type == 1:
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,name,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,name,type,count,data)
|
||||
self.lib.lammps_gather_atoms_concat(self.lmp,name,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
def gather_atoms_subset(self,name,type,count,ndata,ids):
|
||||
def gather_atoms_subset(self,name,dtype,count,ndata,ids):
|
||||
if name: name = name.encode()
|
||||
with ExceptionCheck(self):
|
||||
if type == 0:
|
||||
if dtype == 0:
|
||||
data = ((count*ndata)*c_int)()
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,name,type,count,ndata,ids,data)
|
||||
elif type == 1:
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*ndata)*c_double)()
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,name,type,count,ndata,ids,data)
|
||||
self.lib.lammps_gather_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
@ -1159,17 +1184,17 @@ class lammps(object):
|
||||
# NOTE: need to insure are converting to/from correct Python type
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
|
||||
def scatter_atoms(self,name,type,count,data):
|
||||
def scatter_atoms(self,name,dtype,count,data):
|
||||
if name: name = name.encode()
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter_atoms(self.lmp,name,type,count,data)
|
||||
self.lib.lammps_scatter_atoms(self.lmp,name,dtype,count,data)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def scatter_atoms_subset(self,name,type,count,ndata,ids,data):
|
||||
def scatter_atoms_subset(self,name,dtype,count,ndata,ids,data):
|
||||
if name: name = name.encode()
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter_atoms_subset(self.lmp,name,type,count,ndata,ids,data)
|
||||
self.lib.lammps_scatter_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
|
||||
# return vector of atom/compute/fix properties gathered across procs
|
||||
# 3 variants to match src/library.cpp
|
||||
@ -1179,43 +1204,43 @@ class lammps(object):
|
||||
# returned data is a 1d vector - doc how it is ordered?
|
||||
# NOTE: need to insure are converting to/from correct Python type
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
def gather(self,name,type,count):
|
||||
def gather(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if type == 0:
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather(self.lmp,name,type,count,data)
|
||||
elif type == 1:
|
||||
self.lib.lammps_gather(self.lmp,name,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather(self.lmp,name,type,count,data)
|
||||
self.lib.lammps_gather(self.lmp,name,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
def gather_concat(self,name,type,count):
|
||||
def gather_concat(self,name,dtype,count):
|
||||
if name: name = name.encode()
|
||||
natoms = self.get_natoms()
|
||||
with ExceptionCheck(self):
|
||||
if type == 0:
|
||||
if dtype == 0:
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_concat(self.lmp,name,type,count,data)
|
||||
elif type == 1:
|
||||
self.lib.lammps_gather_concat(self.lmp,name,dtype,count,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
self.lib.lammps_gather_concat(self.lmp,name,type,count,data)
|
||||
self.lib.lammps_gather_concat(self.lmp,name,dtype,count,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
|
||||
def gather_subset(self,name,type,count,ndata,ids):
|
||||
def gather_subset(self,name,dtype,count,ndata,ids):
|
||||
if name: name = name.encode()
|
||||
with ExceptionCheck(self):
|
||||
if type == 0:
|
||||
if dtype == 0:
|
||||
data = ((count*ndata)*c_int)()
|
||||
self.lib.lammps_gather_subset(self.lmp,name,type,count,ndata,ids,data)
|
||||
elif type == 1:
|
||||
self.lib.lammps_gather_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
elif dtype == 1:
|
||||
data = ((count*ndata)*c_double)()
|
||||
self.lib.lammps_gather_subset(self.lmp,name,type,count,ndata,ids,data)
|
||||
self.lib.lammps_gather_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
else:
|
||||
return None
|
||||
return data
|
||||
@ -1229,15 +1254,15 @@ class lammps(object):
|
||||
# NOTE: need to insure are converting to/from correct Python type
|
||||
# e.g. for Python list or NumPy or ctypes
|
||||
|
||||
def scatter(self,name,type,count,data):
|
||||
def scatter(self,name,dtype,count,data):
|
||||
if name: name = name.encode()
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter(self.lmp,name,type,count,data)
|
||||
self.lib.lammps_scatter(self.lmp,name,dtype,count,data)
|
||||
|
||||
def scatter_subset(self,name,type,count,ndata,ids,data):
|
||||
def scatter_subset(self,name,dtype,count,ndata,ids,data):
|
||||
if name: name = name.encode()
|
||||
with ExceptionCheck(self):
|
||||
self.lib.lammps_scatter_subset(self.lmp,name,type,count,ndata,ids,data)
|
||||
self.lib.lammps_scatter_subset(self.lmp,name,dtype,count,ndata,ids,data)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@ -1329,7 +1354,7 @@ class lammps(object):
|
||||
id_lmp = (self.c_tagint*n)()
|
||||
try:
|
||||
id_lmp[:] = id[0:n]
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
return 0
|
||||
else:
|
||||
id_lmp = None
|
||||
@ -1337,21 +1362,21 @@ class lammps(object):
|
||||
type_lmp = (c_int*n)()
|
||||
try:
|
||||
type_lmp[:] = type[0:n]
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
return 0
|
||||
|
||||
three_n = 3*n
|
||||
x_lmp = (c_double*three_n)()
|
||||
try:
|
||||
x_lmp[:] = x[0:three_n]
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
return 0
|
||||
|
||||
if v:
|
||||
v_lmp = (c_double*(three_n))()
|
||||
try:
|
||||
v_lmp[:] = v[0:three_n]
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
return 0
|
||||
else:
|
||||
v_lmp = None
|
||||
@ -1360,7 +1385,7 @@ class lammps(object):
|
||||
img_lmp = (self.c_imageint*n)()
|
||||
try:
|
||||
img_lmp[:] = image[0:n]
|
||||
except:
|
||||
except: # lgtm [py/catch-base-exception]
|
||||
return 0
|
||||
else:
|
||||
img_lmp = None
|
||||
@ -1530,6 +1555,37 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def has_gpu_device(self):
|
||||
""" Availability of GPU package compatible device
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_has_gpu_device`
|
||||
function of the C library interface.
|
||||
|
||||
:return: True if a GPU package compatible device is present, otherwise False
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.lib.lammps_has_gpu_device() != 0
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def get_gpu_device_info(self):
|
||||
"""Return a string with detailed information about any devices that are
|
||||
usable by the GPU package.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_get_gpu_device_info`
|
||||
function of the C-library interface.
|
||||
|
||||
:return: GPU device info string
|
||||
:rtype: string
|
||||
"""
|
||||
|
||||
sb = create_string_buffer(8192)
|
||||
self.lib.lammps_get_gpu_device_info(sb,8192)
|
||||
return sb.value.decode()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@property
|
||||
def installed_packages(self):
|
||||
""" List of the names of enabled packages in the LAMMPS shared library
|
||||
@ -1643,6 +1699,29 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def available_plugins(self, category):
|
||||
"""Returns a list of plugins available for a given category
|
||||
|
||||
This is a wrapper around the functions :cpp:func:`lammps_plugin_count()`
|
||||
and :cpp:func:`lammps_plugin_name()` of the library interface.
|
||||
|
||||
.. versionadded:: 10Mar2021
|
||||
|
||||
:return: list of style/name pairs of loaded plugins
|
||||
:rtype: list
|
||||
"""
|
||||
|
||||
available_plugins = []
|
||||
num = self.lib.lammps_plugin_count(self.lmp)
|
||||
sty = create_string_buffer(100)
|
||||
nam = create_string_buffer(100)
|
||||
for idx in range(num):
|
||||
self.lib.lammps_plugin_name(idx, sty, nam, 100)
|
||||
available_plugins.append([sty.value.decode(), nam.value.decode()])
|
||||
return available_plugins
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def set_fix_external_callback(self, fix_name, callback, caller=None):
|
||||
import numpy as np
|
||||
|
||||
@ -1709,17 +1788,23 @@ class lammps(object):
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def find_pair_neighlist(self, style, exact=True, nsub=0, request=0):
|
||||
def find_pair_neighlist(self, style, exact=True, nsub=0, reqid=0):
|
||||
"""Find neighbor list index of pair style neighbor list
|
||||
|
||||
Try finding pair instance that matches style. If exact is set, the pair must
|
||||
match style exactly. If exact is 0, style must only be contained. If pair is
|
||||
of style pair/hybrid, style is instead matched the nsub-th hybrid sub-style.
|
||||
Search for a neighbor list requested by a pair style instance that
|
||||
matches "style". If exact is True, the pair style name must match
|
||||
exactly. If exact is False, the pair style name is matched against
|
||||
"style" as regular expression or sub-string. If the pair style is a
|
||||
hybrid pair style, the style is instead matched against the hybrid
|
||||
sub-styles. If the same pair style is used as sub-style multiple
|
||||
types, you must set nsub to a value n > 0 which indicates the nth
|
||||
instance of that sub-style to be used (same as for the pair_coeff
|
||||
command). The default value of 0 will fail to match in that case.
|
||||
|
||||
Once the pair instance has been identified, multiple neighbor list requests
|
||||
may be found. Every neighbor list is uniquely identified by its request
|
||||
index. Thus, providing this request index ensures that the correct neighbor
|
||||
list index is returned.
|
||||
Once the pair style instance has been identified, it may have
|
||||
requested multiple neighbor lists. Those are uniquely identified by
|
||||
a request ID > 0 as set by the pair style. Otherwise the request
|
||||
ID is 0.
|
||||
|
||||
:param style: name of pair style that should be searched for
|
||||
:type style: string
|
||||
@ -1727,44 +1812,58 @@ class lammps(object):
|
||||
:type exact: bool, optional
|
||||
:param nsub: match nsub-th hybrid sub-style, defaults to 0
|
||||
:type nsub: int, optional
|
||||
:param request: index of neighbor list request, in case there are more than one, defaults to 0
|
||||
:type request: int, optional
|
||||
:param reqid: list request id, > 0 in case there are more than one, defaults to 0
|
||||
:type reqid: int, optional
|
||||
:return: neighbor list index if found, otherwise -1
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
"""
|
||||
style = style.encode()
|
||||
exact = int(exact)
|
||||
idx = self.lib.lammps_find_pair_neighlist(self.lmp, style, exact, nsub, request)
|
||||
idx = self.lib.lammps_find_pair_neighlist(self.lmp, style, exact, nsub, reqid)
|
||||
return idx
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def find_fix_neighlist(self, fixid, request=0):
|
||||
def find_fix_neighlist(self, fixid, reqid=0):
|
||||
"""Find neighbor list index of fix neighbor list
|
||||
|
||||
The fix instance requesting the neighbor list is uniquely identified
|
||||
by the fix ID. In case the fix has requested multiple neighbor
|
||||
lists, those are uniquely identified by a request ID > 0 as set by
|
||||
the fix. Otherwise the request ID is 0 (the default).
|
||||
|
||||
:param fixid: name of fix
|
||||
:type fixid: string
|
||||
:param request: index of neighbor list request, in case there are more than one, defaults to 0
|
||||
:type request: int, optional
|
||||
:param reqid: id of neighbor list request, in case there are more than one request, defaults to 0
|
||||
:type reqid: int, optional
|
||||
:return: neighbor list index if found, otherwise -1
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
"""
|
||||
fixid = fixid.encode()
|
||||
idx = self.lib.lammps_find_fix_neighlist(self.lmp, fixid, request)
|
||||
idx = self.lib.lammps_find_fix_neighlist(self.lmp, fixid, reqid)
|
||||
return idx
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def find_compute_neighlist(self, computeid, request=0):
|
||||
def find_compute_neighlist(self, computeid, reqid=0):
|
||||
"""Find neighbor list index of compute neighbor list
|
||||
|
||||
The compute instance requesting the neighbor list is uniquely
|
||||
identified by the compute ID. In case the compute has requested
|
||||
multiple neighbor lists, those are uniquely identified by a request
|
||||
ID > 0 as set by the compute. Otherwise the request ID is 0 (the
|
||||
default).
|
||||
|
||||
:param computeid: name of compute
|
||||
:type computeid: string
|
||||
:param request: index of neighbor list request, in case there are more than one, defaults to 0
|
||||
:type request: int, optional
|
||||
:param reqid: index of neighbor list request, in case there are more than one request, defaults to 0
|
||||
:type reqid: int, optional
|
||||
:return: neighbor list index if found, otherwise -1
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
"""
|
||||
computeid = computeid.encode()
|
||||
idx = self.lib.lammps_find_compute_neighlist(self.lmp, computeid, request)
|
||||
idx = self.lib.lammps_find_compute_neighlist(self.lmp, computeid, reqid)
|
||||
return idx
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
@ -16,7 +16,7 @@
|
||||
# Written by Richard Berger <richard.berger@temple.edu>
|
||||
################################################################################
|
||||
|
||||
class NeighList:
|
||||
class NeighList(object):
|
||||
"""This is a wrapper class that exposes the contents of a neighbor list.
|
||||
|
||||
It can be used like a regular Python list. Each element is a tuple of:
|
||||
@ -52,7 +52,9 @@ class NeighList:
|
||||
|
||||
def get(self, element):
|
||||
"""
|
||||
:return: tuple with atom local index, numpy array of neighbor local atom indices
|
||||
Access a specific neighbor list entry. "element" must be a number from 0 to the size-1 of the list
|
||||
|
||||
:return: tuple with atom local index, number of neighbors and ctypes pointer to neighbor's local atom indices
|
||||
:rtype: (int, int, ctypes.POINTER(c_int))
|
||||
"""
|
||||
iatom, numneigh, neighbors = self.lmp.get_neighlist_element_neighbors(self.idx, element)
|
||||
@ -71,3 +73,20 @@ class NeighList:
|
||||
|
||||
for ii in range(inum):
|
||||
yield self.get(ii)
|
||||
|
||||
def find(self, iatom):
|
||||
"""
|
||||
Find the neighbor list for a specific (local) atom iatom.
|
||||
If there is no list for iatom, (-1, None) is returned.
|
||||
|
||||
:return: tuple with number of neighbors and ctypes pointer to neighbor's local atom indices
|
||||
:rtype: (int, ctypes.POINTER(c_int))
|
||||
"""
|
||||
|
||||
inum = self.size
|
||||
for ii in range(inum):
|
||||
idx, numneigh, neighbors = self.get(ii)
|
||||
if idx == iatom:
|
||||
return numneigh, neighbors
|
||||
|
||||
return -1, None
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
@ -176,7 +176,7 @@ class AvgChunkFile:
|
||||
current[data_column] = [value]
|
||||
|
||||
chunks_read += 1
|
||||
assert (chunk == chunks_read)
|
||||
assert chunk == chunks_read
|
||||
else:
|
||||
# do not support changing number of chunks
|
||||
if not (num_chunks == int(parts[1])):
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
@ -20,7 +20,7 @@ import warnings
|
||||
from ctypes import POINTER, c_double, c_int, c_int32, c_int64, cast
|
||||
|
||||
|
||||
from .constants import *
|
||||
from .constants import * # lgtm [py/polluting-import]
|
||||
from .data import NeighList
|
||||
|
||||
|
||||
@ -142,7 +142,7 @@ class numpy_wrapper:
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_compute(self, cid, style, type):
|
||||
def extract_compute(self, cid, cstyle, ctype):
|
||||
"""Retrieve data from a LAMMPS compute
|
||||
|
||||
This is a wrapper around the
|
||||
@ -150,50 +150,50 @@ class numpy_wrapper:
|
||||
It behaves the same as the original method, but returns NumPy arrays
|
||||
instead of ``ctypes`` pointers.
|
||||
|
||||
:param id: compute ID
|
||||
:type id: string
|
||||
:param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type style: int
|
||||
:param type: type of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type type: int
|
||||
:param cid: compute ID
|
||||
:type cid: string
|
||||
:param cstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type cstyle: int
|
||||
:param ctype: type of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type ctype: int
|
||||
:return: requested data either as float, as NumPy array with direct access to C data, or None
|
||||
:rtype: float, numpy.array, or NoneType
|
||||
"""
|
||||
value = self.lmp.extract_compute(cid, style, type)
|
||||
value = self.lmp.extract_compute(cid, cstyle, ctype)
|
||||
|
||||
if style in (LMP_STYLE_GLOBAL, LMP_STYLE_LOCAL):
|
||||
if type == LMP_TYPE_VECTOR:
|
||||
nrows = self.lmp.extract_compute(cid, style, LMP_SIZE_VECTOR)
|
||||
if cstyle in (LMP_STYLE_GLOBAL, LMP_STYLE_LOCAL):
|
||||
if ctype == LMP_TYPE_VECTOR:
|
||||
nrows = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_VECTOR)
|
||||
return self.darray(value, nrows)
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
nrows = self.lmp.extract_compute(cid, style, LMP_SIZE_ROWS)
|
||||
ncols = self.lmp.extract_compute(cid, style, LMP_SIZE_COLS)
|
||||
elif ctype == LMP_TYPE_ARRAY:
|
||||
nrows = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_ROWS)
|
||||
ncols = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_COLS)
|
||||
return self.darray(value, nrows, ncols)
|
||||
elif style == LMP_STYLE_ATOM:
|
||||
if type == LMP_TYPE_VECTOR:
|
||||
elif cstyle == LMP_STYLE_ATOM:
|
||||
if ctype == LMP_TYPE_VECTOR:
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
return self.darray(value, nlocal)
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
elif ctype == LMP_TYPE_ARRAY:
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
ncols = self.lmp.extract_compute(cid, style, LMP_SIZE_COLS)
|
||||
ncols = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_COLS)
|
||||
return self.darray(value, nlocal, ncols)
|
||||
return value
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def extract_fix(self, fid, style, type, nrow=0, ncol=0):
|
||||
def extract_fix(self, fid, fstyle, ftype, nrow=0, ncol=0):
|
||||
"""Retrieve data from a LAMMPS fix
|
||||
|
||||
This is a wrapper around the :py:meth:`lammps.extract_fix() <lammps.lammps.extract_fix()>` method.
|
||||
It behaves the same as the original method, but returns NumPy arrays
|
||||
instead of ``ctypes`` pointers.
|
||||
|
||||
:param id: fix ID
|
||||
:type id: string
|
||||
:param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type style: int
|
||||
:param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type type: int
|
||||
:param fid: fix ID
|
||||
:type fid: string
|
||||
:param fstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants`
|
||||
:type fstyle: int
|
||||
:param ftype: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants`
|
||||
:type ftype: int
|
||||
:param nrow: index of global vector element or row index of global array element
|
||||
:type nrow: int
|
||||
:param ncol: column index of global array element
|
||||
@ -202,22 +202,22 @@ class numpy_wrapper:
|
||||
:rtype: integer or double value, pointer to 1d or 2d double array or None
|
||||
|
||||
"""
|
||||
value = self.lmp.extract_fix(fid, style, type, nrow, ncol)
|
||||
if style == LMP_STYLE_ATOM:
|
||||
if type == LMP_TYPE_VECTOR:
|
||||
value = self.lmp.extract_fix(fid, fstyle, ftype, nrow, ncol)
|
||||
if fstyle == LMP_STYLE_ATOM:
|
||||
if ftype == LMP_TYPE_VECTOR:
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
return self.darray(value, nlocal)
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
elif ftype == LMP_TYPE_ARRAY:
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
ncols = self.lmp.extract_fix(fid, style, LMP_SIZE_COLS, 0, 0)
|
||||
ncols = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_COLS, 0, 0)
|
||||
return self.darray(value, nlocal, ncols)
|
||||
elif style == LMP_STYLE_LOCAL:
|
||||
if type == LMP_TYPE_VECTOR:
|
||||
nrows = self.lmp.extract_fix(fid, style, LMP_SIZE_ROWS, 0, 0)
|
||||
elif fstyle == LMP_STYLE_LOCAL:
|
||||
if ftype == LMP_TYPE_VECTOR:
|
||||
nrows = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_ROWS, 0, 0)
|
||||
return self.darray(value, nrows)
|
||||
elif type == LMP_TYPE_ARRAY:
|
||||
nrows = self.lmp.extract_fix(fid, style, LMP_SIZE_ROWS, 0, 0)
|
||||
ncols = self.lmp.extract_fix(fid, style, LMP_SIZE_COLS, 0, 0)
|
||||
elif ftype == LMP_TYPE_ARRAY:
|
||||
nrows = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_ROWS, 0, 0)
|
||||
ncols = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_COLS, 0, 0)
|
||||
return self.darray(value, nrows, ncols)
|
||||
return value
|
||||
|
||||
@ -293,7 +293,11 @@ class numpy_wrapper:
|
||||
ptr = cast(raw_ptr[0], POINTER(c_int_type * nelem * dim))
|
||||
|
||||
a = np.frombuffer(ptr.contents, dtype=np_int_type)
|
||||
a.shape = (nelem, dim)
|
||||
|
||||
if dim > 1:
|
||||
a.shape = (nelem, dim)
|
||||
else:
|
||||
a.shape = (nelem)
|
||||
return a
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -306,7 +310,11 @@ class numpy_wrapper:
|
||||
ptr = cast(raw_ptr[0], POINTER(c_double * nelem * dim))
|
||||
|
||||
a = np.frombuffer(ptr.contents)
|
||||
a.shape = (nelem, dim)
|
||||
|
||||
if dim > 1:
|
||||
a.shape = (nelem, dim)
|
||||
else:
|
||||
a.shape = (nelem)
|
||||
return a
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -331,8 +339,25 @@ class NumPyNeighList(NeighList):
|
||||
|
||||
def get(self, element):
|
||||
"""
|
||||
Access a specific neighbor list entry. "element" must be a number from 0 to the size-1 of the list
|
||||
|
||||
:return: tuple with atom local index, numpy array of neighbor local atom indices
|
||||
:rtype: (int, numpy.array)
|
||||
"""
|
||||
iatom, neighbors = self.lmp.numpy.get_neighlist_element_neighbors(self.idx, element)
|
||||
return iatom, neighbors
|
||||
|
||||
def find(self, iatom):
|
||||
"""
|
||||
Find the neighbor list for a specific (local) atom iatom.
|
||||
If there is no list for iatom, None is returned.
|
||||
|
||||
:return: numpy array of neighbor local atom indices
|
||||
:rtype: numpy.array or None
|
||||
"""
|
||||
inum = self.size
|
||||
for ii in range(inum):
|
||||
idx, neighbors = self.get(ii)
|
||||
if idx == iatom:
|
||||
return neighbors
|
||||
return None
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
# http://lammps.sandia.gov, Sandia National Laboratories
|
||||
# https://www.lammps.org/ Sandia National Laboratories
|
||||
# Steve Plimpton, sjplimp@sandia.gov
|
||||
#
|
||||
# Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
@ -23,7 +23,6 @@ from __future__ import print_function
|
||||
import os
|
||||
import re
|
||||
import select
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
|
||||
from .core import lammps
|
||||
@ -41,7 +40,7 @@ class OutputCapture(object):
|
||||
os.dup2(self.stdout_pipe_write, self.stdout_fd)
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, tracebac):
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
os.dup2(self.stdout, self.stdout_fd)
|
||||
os.close(self.stdout)
|
||||
os.close(self.stdout_pipe_read)
|
||||
@ -351,6 +350,7 @@ def get_thermo_data(output):
|
||||
for i, col in enumerate(columns):
|
||||
current_run[col].append(values[i])
|
||||
except ValueError:
|
||||
# cannot convert. must be a non-thermo output. ignore.
|
||||
pass
|
||||
|
||||
return runs
|
||||
@ -409,6 +409,12 @@ class PyLammps(object):
|
||||
self._enable_cmd_history = False
|
||||
self.runs = []
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, ex_type, ex_value, ex_traceback):
|
||||
self.close()
|
||||
|
||||
def __del__(self):
|
||||
if self.lmp: self.lmp.close()
|
||||
self.lmp = None
|
||||
|
||||
@ -1,26 +1,39 @@
|
||||
# this only installs the LAMMPS python package
|
||||
# it assumes the LAMMPS shared library is already installed
|
||||
from distutils.core import setup
|
||||
import os
|
||||
from sys import version_info
|
||||
import os,time
|
||||
|
||||
LAMMPS_PYTHON_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
LAMMPS_DIR = os.path.dirname(LAMMPS_PYTHON_DIR)
|
||||
LAMMPS_SOURCE_DIR = os.path.join(LAMMPS_DIR, 'src')
|
||||
|
||||
if not os.path.exists(LAMMPS_SOURCE_DIR):
|
||||
# allows installing and building wheel from current directory
|
||||
LAMMPS_DIR = os.path.realpath(os.path.join(os.environ['PWD'], '..'))
|
||||
LAMMPS_SOURCE_DIR = os.path.join(LAMMPS_DIR, 'src')
|
||||
|
||||
def get_lammps_version():
|
||||
with open(os.path.join(LAMMPS_SOURCE_DIR, 'version.h'), 'r') as f:
|
||||
version_h_file = os.path.join(LAMMPS_SOURCE_DIR, 'version.h')
|
||||
with open(version_h_file, 'r') as f:
|
||||
line = f.readline()
|
||||
start_pos = line.find('"')+1
|
||||
end_pos = line.find('"', start_pos)
|
||||
return "".join(line[start_pos:end_pos].split())
|
||||
t = time.strptime("".join(line[start_pos:end_pos].split()), "%d%b%Y")
|
||||
return "{}.{}.{}".format(t.tm_year,t.tm_mon,t.tm_mday)
|
||||
|
||||
if version_info.major >= 3:
|
||||
pkgs = ['lammps', 'lammps.mliap']
|
||||
else:
|
||||
pkgs = ['lammps']
|
||||
|
||||
setup(
|
||||
name = "lammps",
|
||||
version = get_lammps_version(),
|
||||
author = "Steve Plimpton",
|
||||
author_email = "sjplimp@sandia.gov",
|
||||
url = "https://lammps.sandia.gov",
|
||||
url = "https://www.lammps.org",
|
||||
description = "LAMMPS Molecular Dynamics Python package",
|
||||
license = "GPL",
|
||||
packages=["lammps","lammps.mliap"],
|
||||
packages=pkgs,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user