Merge remote-tracking branch 'github/master' into collected-small-changes

# Conflicts:
#	python/lammps/__init__.py
#	python/lammps/core.py
This commit is contained in:
Axel Kohlmeyer
2021-06-04 00:28:32 -04:00
35 changed files with 560 additions and 706 deletions

View File

@ -377,14 +377,6 @@ make MPI calls directly from Python in your script, if you desire.
We have tested this with `MPI for Python <https://mpi4py.readthedocs.io/>`_ We have tested this with `MPI for Python <https://mpi4py.readthedocs.io/>`_
(aka mpi4py) and you will find installation instruction for it below. (aka mpi4py) and you will find installation instruction for it below.
.. note::
Older LAMMPS versions were also tested with `PyPar <https://github.com/daleroberts/pypar>`_
but we can no longer test it, since it does not work with the Python
(3.x) versions on our test servers. Since there have been no updates
to PyPar visible in its repository since November 2016 we have to assume
it is no longer maintained.
Installation of mpi4py (version 3.0.3 as of Sep 2020) can be done as Installation of mpi4py (version 3.0.3 as of Sep 2020) can be done as
follows: follows:

View File

@ -65,7 +65,7 @@
{% elif show_source and has_source and sourcename %} {% elif show_source and has_source and sourcename %}
<a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> {{ _('View page source') }}</a> <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> {{ _('View page source') }}</a>
{% endif %} {% endif %}
<a href="http://lammps.sandia.gov">Website</a> <a href="https://www.lammps.org">Website</a>
<a href="Commands_all.html">Commands</a> <a href="Commands_all.html">Commands</a>
{% endif %} {% endif %}
</li> </li>

View File

@ -38,10 +38,11 @@
{% if favicon %} {% if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/> <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{% endif %} {% endif %}
{# CANONICAL URL #}
{% if theme_canonical_url %} {#- CANONICAL URL #}
<link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html"/> {%- if pageurl %}
{% endif %} <link rel="canonical" href="{{ pageurl|e }}" />
{%- endif -%}
{# JAVASCRIPTS #} {# JAVASCRIPTS #}
{%- block scripts %} {%- block scripts %}

View File

@ -4,7 +4,6 @@ stylesheet = css/theme.css
pygments_style = default pygments_style = default
[options] [options]
canonical_url =
analytics_id = analytics_id =
collapse_navigation = False collapse_navigation = False
sticky_navigation = False sticky_navigation = False

View File

@ -15,6 +15,7 @@
import sys import sys
import os import os
from datetime import date
has_enchant = False has_enchant = False
try: try:
@ -76,7 +77,7 @@ master_doc = 'Manual'
# General information about the project. # General information about the project.
project = 'LAMMPS' project = 'LAMMPS'
copyright = '2003-2020 Sandia Corporation' copyright = '2003-{} Sandia Corporation'.format(date.today().year)
def get_lammps_version(): def get_lammps_version():
import os import os
@ -255,6 +256,8 @@ htmlhelp_basename = 'LAMMPSdoc'
html_permalinks = True html_permalinks = True
html_baseurl = os.environ.get('LAMMPS_WEBSITE_BASEURL', '')
if 'epub' in sys.argv: if 'epub' in sys.argv:
html_math_renderer = 'imgmath' html_math_renderer = 'imgmath'
else: else:

View File

@ -2631,7 +2631,6 @@ PyLammps
pymbar pymbar
pymodule pymodule
pymol pymol
pypar
pythonic pythonic
pytorch pytorch
pyy pyy

View File

@ -8,6 +8,7 @@
# The units of Cij are whatever was used in log.lammps (usually GPa) # The units of Cij are whatever was used in log.lammps (usually GPa)
# The units of Sij are the inverse of that (usually 1/GPa) # The units of Sij are the inverse of that (usually 1/GPa)
from __future__ import print_function
from numpy import zeros from numpy import zeros
from numpy.linalg import inv from numpy.linalg import inv
@ -44,8 +45,7 @@ cindices[20] = (4,5)
# open logfile # open logfile
logfile = open("log.lammps",'r') with open("log.lammps",'r') as logfile:
txt = logfile.read() txt = logfile.read()
# search for 21 elastic constants # search for 21 elastic constants
@ -56,7 +56,7 @@ s2 = 0
for ival in range(nvals): for ival in range(nvals):
s1 = txt.find(valstr,s2) s1 = txt.find(valstr,s2)
if (s1 == -1): if (s1 == -1):
print "Failed to find elastic constants in log file" print("Failed to find elastic constants in log file")
exit(1) exit(1)
s1 += 1 s1 += 1
s2 = txt.find("\n",s1) s2 = txt.find("\n",s1)
@ -67,11 +67,11 @@ for ival in range(nvals):
c[i1,i2] = float(words[valpos]) c[i1,i2] = float(words[valpos])
c[i2,i1] = c[i1,i2] c[i2,i1] = c[i1,i2]
print "C tensor [GPa]" print("C tensor [GPa]")
for i in range(6): for i in range(6):
for j in range(6): for j in range(6):
print "%10.8g " % c[i][j], print("%10.8g " % c[i][j], end="")
print print()
# apply factor of 2 to columns of off-diagonal elements # apply factor of 2 to columns of off-diagonal elements
@ -87,9 +87,8 @@ for i in range(6):
for j in range(3,6): for j in range(3,6):
s[i][j] *= 0.5 s[i][j] *= 0.5
print "S tensor [1/GPa]" print("S tensor [1/GPa]")
for i in range(6): for i in range(6):
for j in range(6): for j in range(6):
print "%10.8g " % s[i][j], print("%10.8g " % s[i][j], end="")
print print()

1
python/.gitignore vendored
View File

@ -1 +1,2 @@
/build /build
/*.egg-info

View File

@ -44,6 +44,7 @@ split.py parallel example
mc.py Monte Carlo energy relaxation wrapper on LAMMPS mc.py Monte Carlo energy relaxation wrapper on LAMMPS
gui.py GUI go/stop/temperature-slider to control LAMMPS gui.py GUI go/stop/temperature-slider to control LAMMPS
plot.py real-time temperature plot with GnuPlot via Pizza.py 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 viz_tool.py real-time viz via some viz package
vizplotgui_tool.py combination of viz.py and plot.py and gui.py vizplotgui_tool.py combination of viz.py and plot.py and gui.py
@ -100,24 +101,24 @@ split.py in.simple # can run in parallel (see below)
gui.py in.gui 100 gui.py in.gui 100
plot.py in.plot 10 1000 thermo_temp plot.py in.plot 10 1000 thermo_temp
matplotlib_plot.py in.plot 10 1000 thermo_temp
viz_tool.py in.viz 100 5000 viz_tool.py in.viz 100 5000
vizplotgui_tool.py in.viz 100 thermo_temp vizplotgui_tool.py in.viz 100 thermo_temp
To run LAMMPS in parallel from Python, so something like this: To run LAMMPS in parallel from Python, so something like this:
% mpirun -np 4 simple.py in.simple % mpirun -np P simple.py in.simple
% mpirun -np 4 python split.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 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 one-processor run, where both Python and LAMMPS will run on single
processors. Each running job will read the same input file, and write processors. Each running job will read the same input file, and write
to same log.lammps file, which isn't too useful. to same log.lammps file, which isn't too useful.
However, if you have either the Pypar or mpi4py packages installed in However, if you have the mpi4py Python package installed and uncomment mpi4py
your Python, and uncomment the Pypar or mpi4py code in simple.py, then code in simple.py, then the above commands will invoke 1 instance of a
the above commands will invoke 1 instance of a P-processor run. Both P-processor run. Both Python and LAMMPS will run on P processors. The job will
Python and LAMMPS will run on P processors. The job will read the read the input file and write a single log.lammps file.
input file and write a single log.lammps file.
The split.py script can also be run in parallel. It uses mpi4py 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 version 2.0.0 (or later), which makes it possible to pass a

1
python/examples/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/tmp*

View File

@ -7,8 +7,7 @@
# in.lammps = LAMMPS input script # in.lammps = LAMMPS input script
# Nfreq = query GUI every this many steps # Nfreq = query GUI every this many steps
# IMPORTANT: this script cannot yet be run in parallel via Pypar, # IMPORTANT: this script cannot yet be run in parallel
# because I can't seem to do a MPI-style broadcast in Pypar
from __future__ import print_function from __future__ import print_function
import sys,time import sys,time
@ -39,10 +38,6 @@ infile = sys.argv[1]
nfreq = int(sys.argv[2]) nfreq = int(sys.argv[2])
me = 0 me = 0
# uncomment if running in parallel via Pypar
#import pypar
#me = pypar.rank()
#nprocs = pypar.size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -110,7 +105,3 @@ while 1:
if runflag: running = 1 if runflag: running = 1
else: running = 0 else: running = 0
time.sleep(0.01) time.sleep(0.01)
# uncomment if running in parallel via Pypar
#print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()

View File

@ -12,9 +12,6 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
sys.path.append("./pizza")
import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
# parse command line # parse command line
@ -30,10 +27,10 @@ nsteps = int(sys.argv[3])
compute = sys.argv[4] compute = sys.argv[4]
me = 0 me = 0
# uncomment if running in parallel via Pypar # uncomment this if running in parallel via mpi4py
#import pypar #from mpi4py import MPI
#me = pypar.rank() #me = MPI.COMM_WORLD.Get_rank()
#nprocs = pypar.size() #nprocs = MPI.COMM_WORLD.Get_size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -79,14 +76,15 @@ while ntimestep < nsteps:
ax = plt.gca() ax = plt.gca()
ax.relim() ax.relim()
ax.autoscale_view(True, True, True) ax.autoscale_view(True, True, True)
fig.canvas.draw() plt.pause(0.001)
lmp.command("run 0 pre no post yes") 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) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()
if me == 0:
if sys.version_info[0] == 3: if sys.version_info[0] == 3:
input("Press Enter to exit...") input("Press Enter to exit...")
else: else:

View File

@ -275,7 +275,7 @@ class dump:
print("no column assignments made") print("no column assignments made")
elif len(self.names): elif len(self.names):
print("assigned columns:",self.names2str()) print("assigned columns:",self.names2str())
elif self.snaps[0].atoms == None: elif self.snaps[0].atoms is None:
print("no column assignments made") print("no column assignments made")
elif len(self.snaps[0].atoms[0]) == 5: elif len(self.snaps[0].atoms[0]) == 5:
self.map(1,"id",2,"type",3,"x",4,"y",5,"z") self.map(1,"id",2,"type",3,"x",4,"y",5,"z")
@ -969,12 +969,12 @@ class dump:
xhi = yhi = zhi = None xhi = yhi = zhi = None
for snap in self.snaps: for snap in self.snaps:
if not snap.tselect: continue if not snap.tselect: continue
if xlo == None or snap.xlo < xlo: xlo = snap.xlo if xlo is None or snap.xlo < xlo: xlo = snap.xlo
if xhi == None or snap.xhi > xhi: xhi = snap.xhi if xhi is None or snap.xhi > xhi: xhi = snap.xhi
if ylo == None or snap.ylo < ylo: ylo = snap.ylo if ylo is None or snap.ylo < ylo: ylo = snap.ylo
if yhi == None or snap.yhi > yhi: yhi = snap.yhi if yhi is None or snap.yhi > yhi: yhi = snap.yhi
if zlo == None or snap.zlo < zlo: zlo = snap.zlo if zlo is None or snap.zlo < zlo: zlo = snap.zlo
if zhi == None or snap.zhi > zhi: zhi = snap.zhi if zhi is None or snap.zhi > zhi: zhi = snap.zhi
return [xlo,ylo,zlo,xhi,yhi,zhi] return [xlo,ylo,zlo,xhi,yhi,zhi]
# -------------------------------------------------------------------- # --------------------------------------------------------------------

View File

@ -851,7 +851,7 @@ class gl:
ncolor = self.vizinfo.ntcolor ncolor = self.vizinfo.ntcolor
for tri in self.tridraw: for tri in self.tridraw:
itype = int(tri[1]) 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] red,green,blue = self.vizinfo.tcolor[itype]
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,[red,green,blue,1.0]); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,[red,green,blue,1.0]);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,self.shiny); 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: ymin >= ylo and ymax <= yhi and zmin >= zlo and zmax <= zhi:
if bond[10] > bound: continue if bond[10] > bound: continue
itype = int(bond[1]) 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] red,green,blue = self.vizinfo.bcolor[itype]
rad = self.vizinfo.brad[itype] rad = self.vizinfo.brad[itype]
glPushMatrix() glPushMatrix()
@ -941,7 +941,7 @@ class gl:
ymin >= ylo and ymax <= yhi and \ ymin >= ylo and ymax <= yhi and \
zmin >= zlo and zmax <= zhi: zmin >= zlo and zmax <= zhi:
itype = int(tri[1]) 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] red,green,blue = self.vizinfo.tcolor[itype]
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION, glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,
[red,green,blue,1.0]); [red,green,blue,1.0]);

View File

@ -87,12 +87,13 @@ g.curve(N,'r') set color of curve N
# Imports and external programs # Imports and external programs
import types, os import os
import sys
try: from DEFAULTS import PIZZA_GNUPLOT try: from DEFAULTS import PIZZA_GNUPLOT
except: PIZZA_GNUPLOT = "gnuplot -p" except ImportError: PIZZA_GNUPLOT = "gnuplot -p"
try: from DEFAULTS import PIZZA_GNUTERM try: from DEFAULTS import PIZZA_GNUTERM
except: PIZZA_GNUTERM = "x11" except ImportError: PIZZA_GNUTERM = "x11"
# Class definition # Class definition
@ -122,6 +123,9 @@ class gnu:
def enter(self): def enter(self):
while 1: while 1:
if sys.version_info[0] == 3:
command = input("gnuplot> ")
else:
command = raw_input("gnuplot> ") command = raw_input("gnuplot> ")
if command == "quit" or command == "exit": return if command == "quit" or command == "exit": return
self.__call__(command) self.__call__(command)
@ -136,7 +140,7 @@ class gnu:
self.export(file,linear,vectors[0]) self.export(file,linear,vectors[0])
self.figures[self.current-1].ncurves = 1 self.figures[self.current-1].ncurves = 1
else: 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): for i in range(0,len(vectors),2):
file = self.file + ".%d.%d" % (self.current,i/2+1) file = self.file + ".%d.%d" % (self.current,i/2+1)
self.export(file,vectors[i],vectors[i+1]) self.export(file,vectors[i],vectors[i+1])
@ -170,7 +174,7 @@ class gnu:
def export(self,filename,*vectors): def export(self,filename,*vectors):
n = len(vectors[0]) n = len(vectors[0])
for vector in vectors: 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') f = open(filename,'w')
nvec = len(vectors) nvec = len(vectors)
for i in range(n): for i in range(n):

View File

@ -68,7 +68,7 @@ index,time,flag = p.iterator(1)
# Imports and external programs # Imports and external programs
import sys, types, glob, urllib import sys, glob, urllib
PY3 = sys.version_info[0] == 3 PY3 = sys.version_info[0] == 3
if PY3: if PY3:
@ -93,7 +93,7 @@ class pdbfile:
elif len(args) == 2: elif len(args) == 2:
filestr = args[0] filestr = args[0]
self.data = args[1] 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 # flist = full list of all PDB input file names
# append .pdb if needed # append .pdb if needed
@ -104,17 +104,17 @@ class pdbfile:
for file in list: for file in list:
if '*' in file: flist += glob.glob(file) if '*' in file: flist += glob.glob(file)
else: flist.append(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 flist[i][-4:] != ".pdb": flist[i] += ".pdb"
if len(flist) == 0: if len(flist) == 0:
raise StandardError("no PDB file specified") raise Exception("no PDB file specified")
self.files = flist self.files = flist
else: self.files = [] else: self.files = []
if len(self.files) > 1 and self.data: 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: 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 # grab PDB file from http://rcsb.org if not a local file

View File

@ -79,7 +79,7 @@ class vizinfo:
# if list of types has a 0, increment each type value # if list of types has a 0, increment each type value
if 0 in ids: 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 storage list if necessary
# extend other arrays for same "which" so that gl::make_atom_calllist # extend other arrays for same "which" so that gl::make_atom_calllist
@ -109,7 +109,7 @@ class vizinfo:
ntypes = len(ids) ntypes = len(ids)
nrgbs = len(rgbs) nrgbs = len(rgbs)
for i in xrange(ntypes): for i in range(ntypes):
id = ids[i] id = ids[i]
if rgbs[0] == "loop": if rgbs[0] == "loop":
@ -157,7 +157,7 @@ class vizinfo:
# if list of types has a 0, increment each type value # if list of types has a 0, increment each type value
if 0 in ids: 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 storage list if necessary
# extend other arrays for same "which" so that gl::make_atom_calllist # 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 list of types has a 0, increment each type value
if 0 in ids: 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 storage list if necessary
# extend other arrays for same "which" so that gl::make_atom_calllist # 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 list lengths match, set directly, else set types to 1st fill value
if len(fills) == len(ids): 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: else:
for id in ids: self.tfill[id] = int(fills[0]) for id in ids: self.tfill[id] = int(fills[0])

View File

@ -45,17 +45,16 @@ v.debug([True|False]) display generated VMD script commands?
# Imports and external programs # Imports and external programs
import types, os import os
import numpy
try: from DEFAULTS import PIZZA_VMDNAME try: from DEFAULTS import PIZZA_VMDNAME
except: PIZZA_VMDNAME = "vmd" except ImportError: PIZZA_VMDNAME = "vmd"
try: from DEFAULTS import PIZZA_VMDDIR 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 try: from DEFAULTS import PIZZA_VMDDEV
except: PIZZA_VMDDEV = "win" except ImportError: PIZZA_VMDDEV = "win"
try: from DEFAULTS import PIZZA_VMDARCH try: from DEFAULTS import PIZZA_VMDARCH
except: PIZZA_VMDARCH = "LINUXAMD64" except ImportError: PIZZA_VMDARCH = "LINUXAMD64"
# try these settings for a Mac # try these settings for a Mac
#PIZZA_VMDNAME = "vmd" #PIZZA_VMDNAME = "vmd"
@ -64,7 +63,7 @@ except: PIZZA_VMDARCH = "LINUXAMD64"
#PIZZA_VMDARCH = "MACOSXX86" #PIZZA_VMDARCH = "MACOSXX86"
try: import pexpect try: import pexpect
except: except ImportError:
print("pexpect from http://pypi.python.org/pypi/pexpect", \ print("pexpect from http://pypi.python.org/pypi/pexpect", \
"is required for vmd tool") "is required for vmd tool")
raise raise

View File

@ -28,10 +28,10 @@ nsteps = int(sys.argv[3])
compute = sys.argv[4] compute = sys.argv[4]
me = 0 me = 0
# uncomment if running in parallel via Pypar # uncomment this if running in parallel via mpi4py
#import pypar #from mpi4py import MPI
#me = pypar.rank() #me = MPI.COMM_WORLD.Get_rank()
#nprocs = pypar.size() #nprocs = MPI.COMM_WORLD.Get_size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -57,7 +57,7 @@ if me == 0:
gn = gnu() gn = gnu()
gn.plot(xaxis,yaxis) gn.plot(xaxis,yaxis)
gn.xrange(0,nsteps) 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 # 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") 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) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()

View File

@ -9,7 +9,7 @@
# Parallel syntax: mpirun -np 4 simple.py in.lammps # Parallel syntax: mpirun -np 4 simple.py in.lammps
# in.lammps = LAMMPS input script # 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 from __future__ import print_function
import sys import sys
@ -27,11 +27,6 @@ infile = sys.argv[1]
me = 0 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 # uncomment this if running in parallel via mpi4py
#from mpi4py import MPI #from mpi4py import MPI
#me = MPI.COMM_WORLD.Get_rank() #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() 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) 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 # uncomment if running in parallel via mpi4py
#print("Proc %d out of %d procs has" % (me,nprocs), lmp) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)

View File

@ -28,10 +28,10 @@ nfreq = int(sys.argv[2])
nsteps = int(sys.argv[3]) nsteps = int(sys.argv[3])
me = 0 me = 0
# uncomment if running in parallel via Pypar # uncomment this if running in parallel via mpi4py
#import pypar #from mpi4py import MPI
#me = pypar.rank() #me = MPI.COMM_WORLD.Get_rank()
#nprocs = pypar.size() #nprocs = MPI.COMM_WORLD.Get_size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -68,6 +68,5 @@ while ntimestep < nsteps:
lmp.command("run 0 pre no post yes") 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) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()

View File

@ -24,10 +24,10 @@ nfreq = int(sys.argv[2])
nsteps = int(sys.argv[3]) nsteps = int(sys.argv[3])
me = 0 me = 0
# uncomment if running in parallel via Pypar # uncomment this if running in parallel via mpi4py
#import pypar #from mpi4py import MPI
#me = pypar.rank() #me = MPI.COMM_WORLD.Get_rank()
#nprocs = pypar.size() #nprocs = MPI.COMM_WORLD.Get_size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -83,6 +83,5 @@ while ntimestep < nsteps:
lmp.command("run 0 pre no post yes") 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) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()

View File

@ -24,10 +24,10 @@ nfreq = int(sys.argv[2])
nsteps = int(sys.argv[3]) nsteps = int(sys.argv[3])
me = 0 me = 0
# uncomment if running in parallel via Pypar # uncomment this if running in parallel via mpi4py
#import pypar #from mpi4py import MPI
#me = pypar.rank() #me = MPI.COMM_WORLD.Get_rank()
#nprocs = pypar.size() #nprocs = MPI.COMM_WORLD.Get_size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -78,6 +78,5 @@ while ntimestep < nsteps:
lmp.command("run 0 pre no post yes") 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) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()

View File

@ -24,10 +24,10 @@ nfreq = int(sys.argv[2])
nsteps = int(sys.argv[3]) nsteps = int(sys.argv[3])
me = 0 me = 0
# uncomment if running in parallel via Pypar # uncomment this if running in parallel via mpi4py
#import pypar #from mpi4py import MPI
#me = pypar.rank() #me = MPI.COMM_WORLD.Get_rank()
#nprocs = pypar.size() #nprocs = MPI.COMM_WORLD.Get_size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -87,6 +87,5 @@ if me == 0:
#v.enter() #v.enter()
#v.stop() #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) #print("Proc %d out of %d procs has" % (me,nprocs), lmp)
#pypar.finalize()

View File

@ -9,9 +9,6 @@
# compute-ID = ID of compute that calculates temperature # compute-ID = ID of compute that calculates temperature
# (or any other scalar quantity) # (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 from __future__ import print_function
import sys,os,time import sys,os,time
sys.path.append("./pizza") sys.path.append("./pizza")
@ -59,10 +56,6 @@ nfreq = int(sys.argv[2])
compute = sys.argv[3] compute = sys.argv[3]
me = 0 me = 0
# uncomment if running in parallel via Pypar
#import pypar
#me = pypar.rank()
#nprocs = pypar.size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -163,7 +156,3 @@ while 1:
time.sleep(0.01) time.sleep(0.01)
lmp.command("run 0 pre no post yes") 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()

View File

@ -9,9 +9,6 @@
# compute-ID = ID of compute that calculates temperature # compute-ID = ID of compute that calculates temperature
# (or any other scalar quantity) # (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 from __future__ import print_function
import sys,time import sys,time
sys.path.append("./pizza") sys.path.append("./pizza")
@ -55,10 +52,6 @@ nfreq = int(sys.argv[2])
compute = sys.argv[3] compute = sys.argv[3]
me = 0 me = 0
# uncomment if running in parallel via Pypar
#import pypar
#me = pypar.rank()
#nprocs = pypar.size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -176,7 +169,3 @@ while 1:
time.sleep(0.01) time.sleep(0.01)
lmp.command("run 0 pre no post yes") 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()

View File

@ -9,9 +9,6 @@
# compute-ID = ID of compute that calculates temperature # compute-ID = ID of compute that calculates temperature
# (or any other scalar quantity) # (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 from __future__ import print_function
import sys,time import sys,time
sys.path.append("./pizza") sys.path.append("./pizza")
@ -57,10 +54,6 @@ nfreq = int(sys.argv[2])
compute = sys.argv[3] compute = sys.argv[3]
me = 0 me = 0
# uncomment if running in parallel via Pypar
#import pypar
#me = pypar.rank()
#nprocs = pypar.size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -172,7 +165,3 @@ while 1:
time.sleep(0.01) time.sleep(0.01)
lmp.command("run 0 pre no post yes") 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()

View File

@ -9,9 +9,6 @@
# compute-ID = ID of compute that calculates temperature # compute-ID = ID of compute that calculates temperature
# (or any other scalar quantity) # (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 from __future__ import print_function
import sys,time import sys,time
sys.path.append("./pizza") sys.path.append("./pizza")
@ -56,10 +53,6 @@ nfreq = int(sys.argv[2])
compute = sys.argv[3] compute = sys.argv[3]
me = 0 me = 0
# uncomment if running in parallel via Pypar
#import pypar
#me = pypar.rank()
#nprocs = pypar.size()
from lammps import lammps from lammps import lammps
lmp = lammps() lmp = lammps()
@ -171,7 +164,3 @@ while 1:
time.sleep(0.01) time.sleep(0.01)
lmp.command("run 0 pre no post yes") 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()

View File

@ -25,18 +25,18 @@ def get_version_number():
vstring = None vstring = None
if version_info.major == 3 and version_info.minor >= 8: if version_info.major == 3 and version_info.minor >= 8:
from importlib.metadata import version from importlib.metadata import version, PackageNotFoundError
try: try:
vstring = version('lammps') vstring = version('lammps')
except: # lgtm [py/catch-base-exception] except PackageNotFoundError:
# nothing to do, ignore # nothing to do, ignore
pass pass
else: else:
from pkg_resources import get_distribution from pkg_resources import get_distribution, DistributionNotFound
try: try:
vstring = get_distribution('lammps').version vstring = get_distribution('lammps').version
except: # lgtm [py/catch-base-exception] except DistributionNotFound:
# nothing to do, ignore # nothing to do, ignore
pass pass

View File

@ -11,8 +11,6 @@
# See the README file in the top-level LAMMPS directory. # 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 # various symbolic constants to be used
# in certain calls to select data formats # in certain calls to select data formats
LAMMPS_AUTODETECT = None LAMMPS_AUTODETECT = None
@ -42,6 +40,7 @@ LMP_VAR_ATOM = 1
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
def get_ctypes_int(size): def get_ctypes_int(size):
from ctypes import c_int, c_int32, c_int64
if size == 4: if size == 4:
return c_int32 return c_int32
elif size == 8: elif size == 8:

View File

@ -100,7 +100,7 @@ class lammps(object):
try: try:
if ptr: self.lib = CDLL("",RTLD_GLOBAL) if ptr: self.lib = CDLL("",RTLD_GLOBAL)
except: # lgtm [py/catch-base-exception] except OSError:
self.lib = None self.lib = None
# load liblammps.so unless name is given # load liblammps.so unless name is given
@ -307,13 +307,12 @@ class lammps(object):
from mpi4py import __version__ as mpi4py_version from mpi4py import __version__ as mpi4py_version
# tested to work with mpi4py versions 2 and 3 # tested to work with mpi4py versions 2 and 3
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3'] self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3']
except: # lgtm [py/catch-base-exception] except ImportError:
# ignore failing import # ignore failing import
pass pass
# if no ptr provided, create an instance of LAMMPS # if no ptr provided, create an instance of LAMMPS
# don't know how to pass an MPI communicator from PyPar # we can pass an MPI communicator from mpi4py v2.0.0 and later
# but we can pass an MPI communicator from mpi4py v2.0.0 and later
# no_mpi call lets LAMMPS use MPI_COMM_WORLD # no_mpi call lets LAMMPS use MPI_COMM_WORLD
# cargs = array of C strings from args # cargs = array of C strings from args
# if ptr, then are embedding Python in LAMMPS input script # if ptr, then are embedding Python in LAMMPS input script
@ -1134,10 +1133,10 @@ class lammps(object):
with ExceptionCheck(self): with ExceptionCheck(self):
if dtype == 0: if dtype == 0:
data = ((count*natoms)*c_int)() data = ((count*natoms)*c_int)()
self.lib.lammps_gather_atoms(self.lmp,name,type,count,data) self.lib.lammps_gather_atoms(self.lmp,name,dtype,count,data)
elif dtype == 1: elif dtype == 1:
data = ((count*natoms)*c_double)() 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: else:
return None return None
return data return data
@ -1150,10 +1149,10 @@ class lammps(object):
with ExceptionCheck(self): with ExceptionCheck(self):
if dtype == 0: if dtype == 0:
data = ((count*natoms)*c_int)() data = ((count*natoms)*c_int)()
self.lib.lammps_gather_atoms_concat(self.lmp,name,type,count,data) self.lib.lammps_gather_atoms_concat(self.lmp,name,dtype,count,data)
elif dtype == 1: elif dtype == 1:
data = ((count*natoms)*c_double)() 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: else:
return None return None
return data return data

View File

@ -8,8 +8,14 @@ LAMMPS_PYTHON_DIR = os.path.dirname(os.path.realpath(__file__))
LAMMPS_DIR = os.path.dirname(LAMMPS_PYTHON_DIR) LAMMPS_DIR = os.path.dirname(LAMMPS_PYTHON_DIR)
LAMMPS_SOURCE_DIR = os.path.join(LAMMPS_DIR, 'src') 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(): 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() line = f.readline()
start_pos = line.find('"')+1 start_pos = line.find('"')+1
end_pos = line.find('"', start_pos) end_pos = line.find('"', start_pos)

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,9 @@
# 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. # the GNU General Public License.
# for python3 compatibility
from __future__ import print_function
# gnu tool # gnu tool
oneline = "Create plots via GnuPlot plotting program" oneline = "Create plots via GnuPlot plotting program"
@ -84,12 +87,13 @@ g.curve(N,'r') set color of curve N
# Imports and external programs # Imports and external programs
import types, os import os
import sys
try: from DEFAULTS import PIZZA_GNUPLOT try: from DEFAULTS import PIZZA_GNUPLOT
except: PIZZA_GNUPLOT = "gnuplot" except ImportError: PIZZA_GNUPLOT = "gnuplot -p"
try: from DEFAULTS import PIZZA_GNUTERM try: from DEFAULTS import PIZZA_GNUTERM
except: PIZZA_GNUTERM = "x11" except ImportError: PIZZA_GNUTERM = "x11"
# Class definition # Class definition
@ -119,6 +123,9 @@ class gnu:
def enter(self): def enter(self):
while 1: while 1:
if sys.version_info[0] == 3:
command = input("gnuplot> ")
else:
command = raw_input("gnuplot> ") command = raw_input("gnuplot> ")
if command == "quit" or command == "exit": return if command == "quit" or command == "exit": return
self.__call__(command) self.__call__(command)
@ -133,7 +140,7 @@ class gnu:
self.export(file,linear,vectors[0]) self.export(file,linear,vectors[0])
self.figures[self.current-1].ncurves = 1 self.figures[self.current-1].ncurves = 1
else: 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): for i in range(0,len(vectors),2):
file = self.file + ".%d.%d" % (self.current,i/2+1) file = self.file + ".%d.%d" % (self.current,i/2+1)
self.export(file,vectors[i],vectors[i+1]) self.export(file,vectors[i],vectors[i+1])
@ -167,13 +174,13 @@ class gnu:
def export(self,filename,*vectors): def export(self,filename,*vectors):
n = len(vectors[0]) n = len(vectors[0])
for vector in vectors: 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') f = open(filename,'w')
nvec = len(vectors) nvec = len(vectors)
for i in xrange(n): for i in range(n):
for j in xrange(nvec): for j in range(nvec):
print >>f,vectors[j][i], print(str(vectors[j][i])+" ",file=f,end='')
print >>f print ("",file=f)
f.close() f.close()
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -350,7 +357,7 @@ class gnu:
self.__call__("set key off") self.__call__("set key off")
cmd = 'plot ' cmd = 'plot '
for i in range(fig.ncurves): for i in range(int(fig.ncurves)):
file = self.file + ".%d.%d" % (self.current,i+1) file = self.file + ".%d.%d" % (self.current,i+1)
if len(fig.colors) > i and fig.colors[i]: if len(fig.colors) > i and fig.colors[i]:
cmd += "'" + file + "' using 1:2 with line %d, " % fig.colors[i] cmd += "'" + file + "' using 1:2 with line %d, " % fig.colors[i]

View File

@ -6,6 +6,9 @@
# 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. # the GNU General Public License.
# for python3 compatibility
from __future__ import print_function
# pdb tool # pdb tool
oneline = "Read, write PDB files in combo with LAMMPS snapshots" oneline = "Read, write PDB files in combo with LAMMPS snapshots"
@ -51,6 +54,7 @@ index,time,flag = p.iterator(1)
# History # History
# 8/05, Steve Plimpton (SNL): original version # 8/05, Steve Plimpton (SNL): original version
# 3/17, Richard Berger (Temple U): improve Python 3 compatibility
# ToDo list # ToDo list
# for generic PDB file (no template) from a LJ unit system, # for generic PDB file (no template) from a LJ unit system,
@ -64,7 +68,13 @@ index,time,flag = p.iterator(1)
# Imports and external programs # Imports and external programs
import sys, types, glob, urllib import sys, glob, urllib
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str,
else:
string_types = basestring
# Class definition # Class definition
@ -74,7 +84,7 @@ class pdbfile:
def __init__(self,*args): def __init__(self,*args):
if len(args) == 1: if len(args) == 1:
if type(args[0]) is types.StringType: if type(args[0]) is string_types:
filestr = args[0] filestr = args[0]
self.data = None self.data = None
else: else:
@ -83,7 +93,7 @@ class pdbfile:
elif len(args) == 2: elif len(args) == 2:
filestr = args[0] filestr = args[0]
self.data = args[1] 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 # flist = full list of all PDB input file names
# append .pdb if needed # append .pdb if needed
@ -94,17 +104,17 @@ class pdbfile:
for file in list: for file in list:
if '*' in file: flist += glob.glob(file) if '*' in file: flist += glob.glob(file)
else: flist.append(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 flist[i][-4:] != ".pdb": flist[i] += ".pdb"
if len(flist) == 0: if len(flist) == 0:
raise StandardError,"no PDB file specified" raise Exception("no PDB file specified")
self.files = flist self.files = flist
else: self.files = [] else: self.files = []
if len(self.files) > 1 and self.data: 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: 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 # grab PDB file from http://rcsb.org if not a local file
@ -112,7 +122,7 @@ class pdbfile:
try: try:
open(self.files[0],'r').close() open(self.files[0],'r').close()
except: except:
print "downloading %s from http://rcsb.org" % self.files[0] print("downloading %s from http://rcsb.org" % self.files[0])
fetchstr = "http://www.rcsb.org/pdb/cgi/export.cgi/%s?format=PDB&pdbId=2cpk&compression=None" % self.files[0] fetchstr = "http://www.rcsb.org/pdb/cgi/export.cgi/%s?format=PDB&pdbId=2cpk&compression=None" % self.files[0]
urllib.urlretrieve(fetchstr,self.files[0]) urllib.urlretrieve(fetchstr,self.files[0])
@ -142,20 +152,20 @@ class pdbfile:
which,time,flag = self.data.iterator(flag) which,time,flag = self.data.iterator(flag)
if flag == -1: break if flag == -1: break
self.convert(f,which) self.convert(f,which)
print >>f,"END" print("END",file=f)
print time, print(time,end='')
sys.stdout.flush() sys.stdout.flush()
n += 1 n += 1
else: else:
for file in self.files: for file in self.files:
f.write(open(file,'r').read()) f.write(open(file,'r').read())
print >>f,"END" print("END",file=f)
print file, print(file,end='')
sys.stdout.flush() sys.stdout.flush()
f.close() f.close()
print "\nwrote %d datasets to %s in PDB format" % (n,file) print("\nwrote %d datasets to %s in PDB format" % (n,file))
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# write series of numbered PDB files # write series of numbered PDB files
@ -190,7 +200,7 @@ class pdbfile:
self.convert(f,which) self.convert(f,which)
f.close() f.close()
print time, print(time,end='')
sys.stdout.flush() sys.stdout.flush()
n += 1 n += 1
@ -210,12 +220,12 @@ class pdbfile:
f = open(file,'w') f = open(file,'w')
f.write(open(infile,'r').read()) f.write(open(infile,'r').read())
f.close() f.close()
print file, print(file,end='')
sys.stdout.flush() sys.stdout.flush()
n += 1 n += 1
print "\nwrote %d datasets to %s*.pdb in PDB format" % (n,root) print("\nwrote %d datasets to %s*.pdb in PDB format" % (n,root))
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# write a single PDB file # write a single PDB file
@ -280,10 +290,10 @@ class pdbfile:
if self.atomlines.has_key(id): if self.atomlines.has_key(id):
(begin,end) = self.atomlines[id] (begin,end) = self.atomlines[id]
line = "%s%8.3f%8.3f%8.3f%s" % (begin,atom[2],atom[3],atom[4],end) line = "%s%8.3f%8.3f%8.3f%s" % (begin,atom[2],atom[3],atom[4],end)
print >>f,line, print(line,file=f,end='')
else: else:
for atom in atoms: for atom in atoms:
begin = "ATOM %6d %2d R00 1 " % (atom[0],atom[1]) begin = "ATOM %6d %2d R00 1 " % (atom[0],atom[1])
middle = "%8.3f%8.3f%8.3f" % (atom[2],atom[3],atom[4]) middle = "%8.3f%8.3f%8.3f" % (atom[2],atom[3],atom[4])
end = " 1.00 0.00 NONE" end = " 1.00 0.00 NONE"
print >>f,begin+middle+end print(begin+middle+end,file=f)