Merge remote-tracking branch 'lammps-ro/master' into lammps-icms
Resolved Conflicts: doc/Manual.html doc/Manual.txt
This commit is contained in:
@ -82,7 +82,7 @@ also leave off the "-fft fftw3" switch if you do not have the FFTW
|
||||
library will be used.
|
||||
|
||||
cd src
|
||||
Make.py -j 16 -p none molecule manybody kspace granular orig \
|
||||
Make.py -j 16 -p none molecule manybody kspace granular rigid orig \
|
||||
-cc mpi wrap=icc -fft fftw3 -a file mpi
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
@ -8,7 +8,7 @@ units lj
|
||||
atom_style sphere
|
||||
boundary p p fs
|
||||
newton off
|
||||
communicate single vel yes
|
||||
comm_modify vel yes
|
||||
|
||||
read_data data.chute
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>LAMMPS-ICMS Users Manual</TITLE>
|
||||
<META NAME="docnumber" CONTENT="12 Mar 2015 version">
|
||||
<META NAME="docnumber" CONTENT="14 Mar 2015 version">
|
||||
<META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
|
||||
<META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
|
||||
</HEAD>
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
<CENTER><H3>LAMMPS-ICMS Documentation
|
||||
</H3></CENTER>
|
||||
<CENTER><H4>12 Mar 2015 version
|
||||
<CENTER><H4>14 Mar 2015 version
|
||||
</H4></CENTER>
|
||||
<H4>Version info:
|
||||
</H4>
|
||||
@ -260,17 +260,21 @@ it gives quick access to documentation for all LAMMPS commands.
|
||||
<BR></UL>
|
||||
<LI><A HREF = "Section_python.html">Python interface</A>
|
||||
|
||||
<UL> 11.1 <A HREF = "Section_python.html#py_1">Building LAMMPS as a shared library</A>
|
||||
<UL> 11.1 <A HREF = "Section_python.html#py_1">Overview of running LAMMPS from Python</A>
|
||||
<BR>
|
||||
11.2 <A HREF = "Section_python.html#py_2">Installing the Python wrapper into Python</A>
|
||||
11.2 <A HREF = "Section_python.html#py_2">Overview of using Python from a LAMMPS script</A>
|
||||
<BR>
|
||||
11.3 <A HREF = "Section_python.html#py_3">Extending Python with MPI to run in parallel</A>
|
||||
11.3 <A HREF = "Section_python.html#py_3">Building LAMMPS as a shared library</A>
|
||||
<BR>
|
||||
11.4 <A HREF = "Section_python.html#py_4">Testing the Python-LAMMPS interface</A>
|
||||
11.4 <A HREF = "Section_python.html#py_4">Installing the Python wrapper into Python</A>
|
||||
<BR>
|
||||
11.5 <A HREF = "Section_python.html#py_5">Using LAMMPS from Python</A>
|
||||
11.5 <A HREF = "Section_python.html#py_5">Extending Python with MPI to run in parallel</A>
|
||||
<BR>
|
||||
11.6 <A HREF = "Section_python.html#py_6">Example Python scripts that use LAMMPS</A>
|
||||
11.6 <A HREF = "Section_python.html#py_6">Testing the Python-LAMMPS interface</A>
|
||||
<BR>
|
||||
11.7 <A HREF = "py_7">Using LAMMPS from Python</A>
|
||||
<BR>
|
||||
11.8 <A HREF = "py_8">Example Python scripts that use LAMMPS</A>
|
||||
<BR></UL>
|
||||
<LI><A HREF = "Section_errors.html">Errors</A>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<HEAD>
|
||||
<TITLE>LAMMPS-ICMS Users Manual</TITLE>
|
||||
<TITLE>LAMMPS Users Manual</TITLE>
|
||||
<META NAME="docnumber" CONTENT="12 Mar 2015 version">
|
||||
<META NAME="docnumber" CONTENT="14 Mar 2015 version">
|
||||
<META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
|
||||
<META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
|
||||
</HEAD>
|
||||
@ -19,7 +19,7 @@
|
||||
<H1></H1>
|
||||
|
||||
LAMMPS-ICMS Documentation :c,h3
|
||||
12 Mar 2015 version :c,h4
|
||||
14 Mar 2015 version :c,h4
|
||||
|
||||
Version info: :h4
|
||||
|
||||
@ -175,12 +175,14 @@ it gives quick access to documentation for all LAMMPS commands.
|
||||
10.14 "Variable options"_mod_14 :b
|
||||
10.15 "Submitting new features for inclusion in LAMMPS"_mod_15 :ule,b
|
||||
"Python interface"_Section_python.html :l
|
||||
11.1 "Building LAMMPS as a shared library"_py_1 :ulb,b
|
||||
11.2 "Installing the Python wrapper into Python"_py_2 :b
|
||||
11.3 "Extending Python with MPI to run in parallel"_py_3 :b
|
||||
11.4 "Testing the Python-LAMMPS interface"_py_4 :b
|
||||
11.5 "Using LAMMPS from Python"_py_5 :b
|
||||
11.6 "Example Python scripts that use LAMMPS"_py_6 :ule,b
|
||||
11.1 "Overview of running LAMMPS from Python"_py_1 :ulb,b
|
||||
11.2 "Overview of using Python from a LAMMPS script"_py_2 :b
|
||||
11.3 "Building LAMMPS as a shared library"_py_3 :b
|
||||
11.4 "Installing the Python wrapper into Python"_py_4 :b
|
||||
11.5 "Extending Python with MPI to run in parallel"_py_5 :b
|
||||
11.6 "Testing the Python-LAMMPS interface"_py_6 :b
|
||||
11.7 "Using LAMMPS from Python"_py_7 :b
|
||||
11.8 "Example Python scripts that use LAMMPS"_py_8 :ule,b
|
||||
"Errors"_Section_errors.html :l
|
||||
12.1 "Common problems"_err_1 :ulb,b
|
||||
12.2 "Reporting bugs"_err_2 :b
|
||||
|
||||
@ -86,11 +86,12 @@ file names or user-chosen ID strings.
|
||||
</P>
|
||||
<P>Here is how each line in the input script is parsed by LAMMPS:
|
||||
</P>
|
||||
<P>(1) If the last printable character on the line is a "&" character
|
||||
(with no surrounding quotes), the command is assumed to continue on
|
||||
the next line. The next line is concatenated to the previous line by
|
||||
removing the "&" character and newline. This allows long commands to
|
||||
be continued across two or more lines.
|
||||
<P>(1) If the last printable character on the line is a "&" character,
|
||||
the command is assumed to continue on the next line. The next line is
|
||||
concatenated to the previous line by removing the "&" character and
|
||||
line break. This allows long commands to be continued across two or
|
||||
more lines. See the discussion of triple quotes in (6) for how to
|
||||
continue a command across multiple line without using "&" characters.
|
||||
</P>
|
||||
<P>(2) All characters from the first "#" character onward are treated as
|
||||
comment and discarded. See an exception in (6). Note that a
|
||||
@ -138,7 +139,7 @@ Thus you cannot do this:
|
||||
</P>
|
||||
<PRE>variable a equal 2
|
||||
variable b2 equal 4
|
||||
region 1 block ${b$a} 2 INF INF EDGE EDGE
|
||||
print "B2 = ${b$a}"
|
||||
</PRE>
|
||||
<P>Nor can you specify this $($x-1.0) for an immediate variable, but
|
||||
you could use $(v_x-1.0), since the latter is valid syntax for an
|
||||
@ -156,27 +157,38 @@ underscores, or punctuation characters.
|
||||
line are arguments.
|
||||
</P>
|
||||
<P>(6) If you want text with spaces to be treated as a single argument,
|
||||
it can be enclosed in either double or single quotes. A long single
|
||||
argument enclosed in quotes can even span multiple lines if the "&"
|
||||
character is used, as described above. E.g.
|
||||
it can be enclosed in either single or double or triple quotes. A
|
||||
long single argument enclosed in single or double quotes can span
|
||||
multiple lines if the "&" character is used, as described above. When
|
||||
the lines are concatenated together (and the "&" characters and line
|
||||
breaks removed), the text will become a single line. If you want
|
||||
multiple lines of an argument to retain their line breaks, the text
|
||||
can be enclosed in triple quotes, in which case "&" characters are not
|
||||
needed. For example:
|
||||
</P>
|
||||
<PRE>print "Volume = $v"
|
||||
print 'Volume = $v'
|
||||
if "$<I>steps</I> > 1000" then quit
|
||||
variable a string "red green blue &
|
||||
purple orange cyan"
|
||||
if "$<I>steps</I> > 1000" then quit
|
||||
print """
|
||||
System volume = $v
|
||||
System temperature = $t
|
||||
"""
|
||||
</PRE>
|
||||
<P>The quotes are removed when the single argument is stored internally.
|
||||
<P>In each case, the single, double, or triple quotes are removed when
|
||||
the single argument they enclose is stored internally.
|
||||
</P>
|
||||
<P>See the <A HREF = "dump_modify.html">dump modify format</A> or <A HREF = "print.html">print</A> or
|
||||
<A HREF = "if.html">if</A> commands for examples. A "#" or "$" character that is
|
||||
between quotes will not be treated as a comment indicator in (2) or
|
||||
substituted for as a variable in (3).
|
||||
<P>See the <A HREF = "dump_modify.html">dump modify format</A>, <A HREF = "print.html">print</A>,
|
||||
<A HREF = "if.html">if</A>, and <A HREF = "python.html">python</A> commands for examples.
|
||||
</P>
|
||||
<P>A "#" or "$" character that is between quotes will not be treated as a
|
||||
comment indicator in (2) or substituted for as a variable in (3).
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: If the argument is itself a command that requires a
|
||||
quoted argument (e.g. using a <A HREF = "print.html">print</A> command as part of an
|
||||
<A HREF = "if.html">if</A> or <A HREF = "run.html">run every</A> command), then the double and
|
||||
single quotes can be nested in the usual manner. See the doc pages
|
||||
<A HREF = "if.html">if</A> or <A HREF = "run.html">run every</A> command), then single, double, or
|
||||
triple quotes can be nested in the usual manner. See the doc pages
|
||||
for those commands for examples. Only one of level of nesting is
|
||||
allowed, but that should be sufficient for most use cases.
|
||||
</P>
|
||||
@ -407,12 +419,12 @@ g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT.
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_nh.html">npt (co)</A></TD><TD ><A HREF = "fix_npt_asphere.html">npt/asphere (o)</A></TD><TD ><A HREF = "fix_npt_sphere.html">npt/sphere (o)</A></TD><TD ><A HREF = "fix_nve.html">nve (cko)</A></TD><TD ><A HREF = "fix_nve_asphere.html">nve/asphere</A></TD><TD ><A HREF = "fix_nve_asphere_noforce.html">nve/asphere/noforce</A></TD><TD ><A HREF = "fix_nve_body.html">nve/body</A></TD><TD ><A HREF = "fix_nve_limit.html">nve/limit</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_nve_line.html">nve/line</A></TD><TD ><A HREF = "fix_nve_noforce.html">nve/noforce</A></TD><TD ><A HREF = "fix_nve_sphere.html">nve/sphere (o)</A></TD><TD ><A HREF = "fix_nve_tri.html">nve/tri</A></TD><TD ><A HREF = "fix_nh.html">nvt (co)</A></TD><TD ><A HREF = "fix_nvt_asphere.html">nvt/asphere (o)</A></TD><TD ><A HREF = "fix_nvt_sllod.html">nvt/sllod (o)</A></TD><TD ><A HREF = "fix_nvt_sphere.html">nvt/sphere (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_oneway.html">oneway</A></TD><TD ><A HREF = "fix_orient_fcc.html">orient/fcc</A></TD><TD ><A HREF = "fix_planeforce.html">planeforce</A></TD><TD ><A HREF = "fix_poems.html">poems</A></TD><TD ><A HREF = "fix_pour.html">pour</A></TD><TD ><A HREF = "fix_press_berendsen.html">press/berendsen</A></TD><TD ><A HREF = "fix_print.html">print</A></TD><TD ><A HREF = "fix_property_atom.html">property/atom</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_qeq_comb.html">qeq/comb (o)</A></TD><TD ><A HREF = "fix_qeq.html">qeq/dynamic</A></TD><TD ><A HREF = "fix_qeq.html">qeq/point</A></TD><TD ><A HREF = "fix_qeq.html">qeq/shielded</A></TD><TD ><A HREF = "fix_qeq.html">qeq/slater</A></TD><TD ><A HREF = "fix_shake.html">rattle</A></TD><TD ><A HREF = "fix_reax_bonds.html">reax/bonds</A></TD><TD ><A HREF = "fix_recenter.html">recenter</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_restrain.html">restrain</A></TD><TD ><A HREF = "fix_rigid.html">rigid (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nph (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/npt (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nve (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nvt (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small/nph</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid/small/npt</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small/nve</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small/nvt</A></TD><TD ><A HREF = "fix_setforce.html">setforce (c)</A></TD><TD ><A HREF = "fix_shake.html">shake (c)</A></TD><TD ><A HREF = "fix_spring.html">spring</A></TD><TD ><A HREF = "fix_spring_rg.html">spring/rg</A></TD><TD ><A HREF = "fix_spring_self.html">spring/self</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_srd.html">srd</A></TD><TD ><A HREF = "fix_store_force.html">store/force</A></TD><TD ><A HREF = "fix_store_state.html">store/state</A></TD><TD ><A HREF = "fix_temp_berendsen.html">temp/berendsen (c)</A></TD><TD ><A HREF = "fix_temp_csvr.html">temp/csvr</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale (c)</A></TD><TD ><A HREF = "fix_tfmc.html">tfmc</A></TD><TD ><A HREF = "fix_thermal_conductivity.html">thermal/conductivity</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_tmd.html">tmd</A></TD><TD ><A HREF = "fix_ttm.html">ttm</A></TD><TD ><A HREF = "fix_tune_kspace.html">tune/kspace</A></TD><TD ><A HREF = "fix_vector.html">vector</A></TD><TD ><A HREF = "fix_viscosity.html">viscosity</A></TD><TD ><A HREF = "fix_viscous.html">viscous (c)</A></TD><TD ><A HREF = "fix_wall.html">wall/colloid</A></TD><TD ><A HREF = "fix_wall_gran.html">wall/gran</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_wall.html">wall/harmonic</A></TD><TD ><A HREF = "fix_wall.html">wall/lj1043</A></TD><TD ><A HREF = "fix_wall.html">wall/lj126</A></TD><TD ><A HREF = "fix_wall.html">wall/lj93</A></TD><TD ><A HREF = "fix_wall_piston.html">wall/piston</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD><TD ><A HREF = "fix_wall_srd.html">wall/srd</A>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_qeq_comb.html">qeq/comb (o)</A></TD><TD ><A HREF = "fix_qeq.html">qeq/dynamic</A></TD><TD ><A HREF = "fix_qeq.html">qeq/point</A></TD><TD ><A HREF = "fix_qeq.html">qeq/shielded</A></TD><TD ><A HREF = "fix_qeq.html">qeq/slater</A></TD><TD ><A HREF = "fix_reax_bonds.html">reax/bonds</A></TD><TD ><A HREF = "fix_recenter.html">recenter</A></TD><TD ><A HREF = "fix_restrain.html">restrain</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nph (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/npt (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nve (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nvt (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small (o)</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small/nph</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small/npt</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid/small/nve</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small/nvt</A></TD><TD ><A HREF = "fix_setforce.html">setforce (c)</A></TD><TD ><A HREF = "fix_shake.html">shake (c)</A></TD><TD ><A HREF = "fix_spring.html">spring</A></TD><TD ><A HREF = "fix_spring_rg.html">spring/rg</A></TD><TD ><A HREF = "fix_spring_self.html">spring/self</A></TD><TD ><A HREF = "fix_srd.html">srd</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_store_force.html">store/force</A></TD><TD ><A HREF = "fix_store_state.html">store/state</A></TD><TD ><A HREF = "fix_temp_berendsen.html">temp/berendsen (c)</A></TD><TD ><A HREF = "fix_temp_csvr.html">temp/csvr</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale (c)</A></TD><TD ><A HREF = "fix_tfmc.html">tfmc</A></TD><TD ><A HREF = "fix_thermal_conductivity.html">thermal/conductivity</A></TD><TD ><A HREF = "fix_tmd.html">tmd</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_ttm.html">ttm</A></TD><TD ><A HREF = "fix_tune_kspace.html">tune/kspace</A></TD><TD ><A HREF = "fix_vector.html">vector</A></TD><TD ><A HREF = "fix_viscosity.html">viscosity</A></TD><TD ><A HREF = "fix_viscous.html">viscous (c)</A></TD><TD ><A HREF = "fix_wall.html">wall/colloid</A></TD><TD ><A HREF = "fix_wall_gran.html">wall/gran</A></TD><TD ><A HREF = "fix_wall.html">wall/harmonic</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "fix_wall.html">wall/lj1043</A></TD><TD ><A HREF = "fix_wall.html">wall/lj126</A></TD><TD ><A HREF = "fix_wall.html">wall/lj93</A></TD><TD ><A HREF = "fix_wall_piston.html">wall/piston</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD><TD ><A HREF = "fix_wall_srd.html">wall/srd</A>
|
||||
</TD></TR></TABLE></DIV>
|
||||
|
||||
<P>These are additional fix styles in USER packages, which can be used if
|
||||
@ -449,9 +461,9 @@ KOKKOS, o = USER-OMP, t = OPT.
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_msd_chunk.html">msd/chunk</A></TD><TD ><A HREF = "compute_msd_nongauss.html">msd/nongauss</A></TD><TD ><A HREF = "compute_pair.html">pair</A></TD><TD ><A HREF = "compute_pair_local.html">pair/local</A></TD><TD ><A HREF = "compute_pe.html">pe (c)</A></TD><TD ><A HREF = "compute_pe_atom.html">pe/atom</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_plasticity_atom.html">plasticity/atom</A></TD><TD ><A HREF = "compute_pressure.html">pressure (c)</A></TD><TD ><A HREF = "compute_property_atom.html">property/atom</A></TD><TD ><A HREF = "compute_property_local.html">property/local</A></TD><TD ><A HREF = "compute_property_chunk.html">property/chunk</A></TD><TD ><A HREF = "compute_rdf.html">rdf</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_reduce.html">reduce</A></TD><TD ><A HREF = "compute_reduce.html">reduce/region</A></TD><TD ><A HREF = "compute_slice.html">slice</A></TD><TD ><A HREF = "compute_sna.html">sna/atom</A></TD><TD ><A HREF = "compute_sna.html">snad/atom</A></TD><TD ><A HREF = "compute_sna.html">snav/atom</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_stress_atom.html">stress/atom</A></TD><TD ><A HREF = "compute_temp.html">temp (c)</A></TD><TD ><A HREF = "compute_temp_asphere.html">temp/asphere</A></TD><TD ><A HREF = "compute_temp_com.html">temp/com</A></TD><TD ><A HREF = "compute_temp_chunk.html">temp/chunk</A></TD><TD ><A HREF = "compute_temp_cs.html">temp/cs</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_temp_deform.html">temp/deform</A></TD><TD ><A HREF = "compute_temp_partial.html">temp/partial (c)</A></TD><TD ><A HREF = "compute_temp_profile.html">temp/profile</A></TD><TD ><A HREF = "compute_temp_ramp.html">temp/ramp</A></TD><TD ><A HREF = "compute_temp_region.html">temp/region</A></TD><TD ><A HREF = "compute_temp_sphere.html">temp/sphere</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_ti.html">ti</A></TD><TD ><A HREF = "compute_torque_chunk.html">torque/chunk</A></TD><TD ><A HREF = "compute_vacf.html">vacf</A></TD><TD ><A HREF = "compute_vcm_chunk.html">vcm/chunk</A></TD><TD ><A HREF = "compute_voronoi_atom.html">voronoi/atom</A>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_stress_atom.html">stress/atom</A></TD><TD ><A HREF = "compute_temp.html">temp (c)</A></TD><TD ><A HREF = "compute_temp_asphere.html">temp/asphere</A></TD><TD ><A HREF = "compute_temp_com.html">temp/com</A></TD><TD ><A HREF = "compute_temp_chunk.html">temp/chunk</A></TD><TD ><A HREF = "compute_temp_deform.html">temp/deform</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_temp_partial.html">temp/partial (c)</A></TD><TD ><A HREF = "compute_temp_profile.html">temp/profile</A></TD><TD ><A HREF = "compute_temp_ramp.html">temp/ramp</A></TD><TD ><A HREF = "compute_temp_region.html">temp/region</A></TD><TD ><A HREF = "compute_temp_sphere.html">temp/sphere</A></TD><TD ><A HREF = "compute_ti.html">ti</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "compute_torque_chunk.html">torque/chunk</A></TD><TD ><A HREF = "compute_vacf.html">vacf</A></TD><TD ><A HREF = "compute_vcm_chunk.html">vcm/chunk</A></TD><TD ><A HREF = "compute_voronoi_atom.html">voronoi/atom</A>
|
||||
</TD></TR></TABLE></DIV>
|
||||
|
||||
<P>These are additional compute styles in USER packages, which can be
|
||||
@ -478,31 +490,30 @@ KOKKOS, o = USER-OMP, t = OPT.
|
||||
<DIV ALIGN=center><TABLE BORDER=1 >
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_none.html">none</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid/overlay</A></TD><TD ><A HREF = "pair_adp.html">adp (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">airebo (o)</A></TD><TD ><A HREF = "pair_beck.html">beck (go)</A></TD><TD ><A HREF = "pair_body.html">body</A></TD><TD ><A HREF = "pair_bop.html">bop</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born (go)</A></TD><TD ><A HREF = "pair_born.html">born/coul/long (cgo)</A></TD><TD ><A HREF = "pair_cs.html">born/coul/long/cs</A></TD><TD ><A HREF = "pair_born.html">born/coul/msm (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born/coul/wolf (go)</A></TD><TD ><A HREF = "pair_brownian.html">brownian (o)</A></TD><TD ><A HREF = "pair_brownian.html">brownian/poly (o)</A></TD><TD ><A HREF = "pair_buck.html">buck (cgko)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/cut (cgo)</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/long (cgo)</A></TD><TD ><A HREF = "pair_cs.html">buck/coul/long/cs</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/msm (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_buck_long.html">buck/long/coul/long (o)</A></TD><TD ><A HREF = "pair_colloid.html">colloid (go)</A></TD><TD ><A HREF = "pair_comb.html">comb (o)</A></TD><TD ><A HREF = "pair_comb.html">comb3</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/cut (gko)</A></TD><TD ><A HREF = "pair_coul.html">coul/debye (go)</A></TD><TD ><A HREF = "pair_coul.html">coul/dsf (gko)</A></TD><TD ><A HREF = "pair_coul.html">coul/long (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/msm</A></TD><TD ><A HREF = "pair_coul.html">coul/streitz</A></TD><TD ><A HREF = "pair_coul.html">coul/wolf (ko)</A></TD><TD ><A HREF = "pair_dpd.html">dpd (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_dpd.html">dpd/tstat (o)</A></TD><TD ><A HREF = "pair_dsmc.html">dsmc</A></TD><TD ><A HREF = "pair_eam.html">eam (cgkot)</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy (cgot)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/fs (cgot)</A></TD><TD ><A HREF = "pair_eim.html">eim (o)</A></TD><TD ><A HREF = "pair_gauss.html">gauss (go)</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne (gio)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hertz/history (o)</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke (co)</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history (o)</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse (o)</A></TD><TD ><A HREF = "pair_kim.html">kim</A></TD><TD ><A HREF = "pair_lcbop.html">lcbop</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm (co)</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit (co)</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long (cgio)</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/msm</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2 (cgo)</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut (co)</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long (cgo)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut (cgikot)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut (cgko)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye (cgo)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/dsf (go)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long (cgikot)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/msm (go)</A></TD><TD ><A HREF = "pair_dipole.html">lj/cut/dipole/cut (go)</A></TD><TD ><A HREF = "pair_dipole.html">lj/cut/dipole/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/tip4p/cut (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/tip4p/long (ot)</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand (cgo)</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs (cgo)</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs (co)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj_long.html">lj/long/coul/long (o)</A></TD><TD ><A HREF = "pair_dipole.html">lj/long/dipole/long</A></TD><TD ><A HREF = "pair_lj_long.html">lj/long/tip4p/long</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth (co)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj_smooth_linear.html">lj/smooth/linear (o)</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut (cgo)</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate (o)</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/poly (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lubricateU.html">lubricateU</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD><TD ><A HREF = "pair_meam.html">meam (o)</A></TD><TD ><A HREF = "pair_mie.html">mie/cut (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_morse.html">morse (cgot)</A></TD><TD ><A HREF = "pair_nb3b_harmonic.html">nb3b/harmonic (o)</A></TD><TD ><A HREF = "pair_nm.html">nm/cut (o)</A></TD><TD ><A HREF = "pair_nm.html">nm/cut/coul/cut (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_nm.html">nm/cut/coul/long (o)</A></TD><TD ><A HREF = "pair_peri.html">peri/eps</A></TD><TD ><A HREF = "pair_peri.html">peri/lps (o)</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_peri.html">peri/ves</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD><TD ><A HREF = "pair_airebo.html">rebo (o)</A></TD><TD ><A HREF = "pair_resquared.html">resquared (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_snap.html">snap</A></TD><TD ><A HREF = "pair_soft.html">soft (go)</A></TD><TD ><A HREF = "pair_sw.html">sw (cgio)</A></TD><TD ><A HREF = "pair_table.html">table (gko)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_tersoff.html">tersoff (co)</A></TD><TD ><A HREF = "pair_tersoff_mod.html">tersoff/mod (o)</A></TD><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl (o)</A></TD><TD ><A HREF = "pair_coul.html">tip4p/cut (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">tip4p/long (o)</A></TD><TD ><A HREF = "pair_tri_lj.html">tri/lj (o)</A></TD><TD ><A HREF = "pair_yukawa.html">yukawa (go)</A></TD><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_zbl.html">zbl (o)</A>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born (go)</A></TD><TD ><A HREF = "pair_born.html">born/coul/long (cgo)</A></TD><TD ><A HREF = "pair_born.html">born/coul/msm (o)</A></TD><TD ><A HREF = "pair_born.html">born/coul/wolf (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_brownian.html">brownian (o)</A></TD><TD ><A HREF = "pair_brownian.html">brownian/poly (o)</A></TD><TD ><A HREF = "pair_buck.html">buck (cgko)</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut (cgo)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/long (cgo)</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/msm (o)</A></TD><TD ><A HREF = "pair_buck_long.html">buck/long/coul/long (o)</A></TD><TD ><A HREF = "pair_colloid.html">colloid (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_comb.html">comb (o)</A></TD><TD ><A HREF = "pair_comb.html">comb3</A></TD><TD ><A HREF = "pair_coul.html">coul/cut (gko)</A></TD><TD ><A HREF = "pair_coul.html">coul/debye (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/dsf (gko)</A></TD><TD ><A HREF = "pair_coul.html">coul/long (go)</A></TD><TD ><A HREF = "pair_coul.html">coul/msm</A></TD><TD ><A HREF = "pair_coul.html">coul/streitz</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/wolf (ko)</A></TD><TD ><A HREF = "pair_dpd.html">dpd (o)</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat (o)</A></TD><TD ><A HREF = "pair_dsmc.html">dsmc</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam (cgkot)</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy (cgot)</A></TD><TD ><A HREF = "pair_eam.html">eam/fs (cgot)</A></TD><TD ><A HREF = "pair_eim.html">eim (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_gauss.html">gauss (go)</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne (gio)</A></TD><TD ><A HREF = "pair_gran.html">gran/hertz/history (o)</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke (co)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hooke/history (o)</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj (o)</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse (o)</A></TD><TD ><A HREF = "pair_kim.html">kim</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lcbop.html">lcbop</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj (o)</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm (co)</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit (co)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long (cgio)</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/msm</A></TD><TD ><A HREF = "pair_class2.html">lj/class2 (cgo)</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut (co)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/coul/long (cgo)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut (cgikot)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut (cgko)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye (cgo)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/dsf (go)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long (cgikot)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/msm (go)</A></TD><TD ><A HREF = "pair_dipole.html">lj/cut/dipole/cut (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_dipole.html">lj/cut/dipole/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/tip4p/cut (o)</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/tip4p/long (ot)</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand (cgo)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs (cgo)</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs (co)</A></TD><TD ><A HREF = "pair_lj_long.html">lj/long/coul/long (o)</A></TD><TD ><A HREF = "pair_dipole.html">lj/long/dipole/long</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj_long.html">lj/long/tip4p/long</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth (co)</A></TD><TD ><A HREF = "pair_lj_smooth_linear.html">lj/smooth/linear (o)</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut (cgo)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lubricate.html">lubricate (o)</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/poly (o)</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_meam.html">meam (o)</A></TD><TD ><A HREF = "pair_mie.html">mie/cut (o)</A></TD><TD ><A HREF = "pair_morse.html">morse (cgot)</A></TD><TD ><A HREF = "pair_nb3b_harmonic.html">nb3b/harmonic (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_nm.html">nm/cut (o)</A></TD><TD ><A HREF = "pair_nm.html">nm/cut/coul/cut (o)</A></TD><TD ><A HREF = "pair_nm.html">nm/cut/coul/long (o)</A></TD><TD ><A HREF = "pair_peri.html">peri/eps</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_peri.html">peri/lps (o)</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb (o)</A></TD><TD ><A HREF = "pair_peri.html">peri/ves</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">rebo (o)</A></TD><TD ><A HREF = "pair_resquared.html">resquared (go)</A></TD><TD ><A HREF = "pair_snap.html">snap</A></TD><TD ><A HREF = "pair_soft.html">soft (go)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_sw.html">sw (cgo)</A></TD><TD ><A HREF = "pair_table.html">table (gko)</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff (co)</A></TD><TD ><A HREF = "pair_tersoff_mod.html">tersoff/mod (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl (o)</A></TD><TD ><A HREF = "pair_coul.html">tip4p/cut (o)</A></TD><TD ><A HREF = "pair_coul.html">tip4p/long (o)</A></TD><TD ><A HREF = "pair_tri_lj.html">tri/lj (o)</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_yukawa.html">yukawa (go)</A></TD><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid (go)</A></TD><TD ><A HREF = "pair_zbl.html">zbl (o)</A>
|
||||
</TD></TR></TABLE></DIV>
|
||||
|
||||
<P>These are additional pair styles in USER packages, which can be used
|
||||
|
||||
@ -82,11 +82,12 @@ file names or user-chosen ID strings.
|
||||
|
||||
Here is how each line in the input script is parsed by LAMMPS:
|
||||
|
||||
(1) If the last printable character on the line is a "&" character
|
||||
(with no surrounding quotes), the command is assumed to continue on
|
||||
the next line. The next line is concatenated to the previous line by
|
||||
removing the "&" character and newline. This allows long commands to
|
||||
be continued across two or more lines.
|
||||
(1) If the last printable character on the line is a "&" character,
|
||||
the command is assumed to continue on the next line. The next line is
|
||||
concatenated to the previous line by removing the "&" character and
|
||||
line break. This allows long commands to be continued across two or
|
||||
more lines. See the discussion of triple quotes in (6) for how to
|
||||
continue a command across multiple line without using "&" characters.
|
||||
|
||||
(2) All characters from the first "#" character onward are treated as
|
||||
comment and discarded. See an exception in (6). Note that a
|
||||
@ -134,7 +135,7 @@ Thus you cannot do this:
|
||||
|
||||
variable a equal 2
|
||||
variable b2 equal 4
|
||||
region 1 block $\{b$a\} 2 INF INF EDGE EDGE :pre
|
||||
print "B2 = $\{b$a\}" :pre
|
||||
|
||||
Nor can you specify this $($x-1.0) for an immediate variable, but
|
||||
you could use $(v_x-1.0), since the latter is valid syntax for an
|
||||
@ -152,27 +153,38 @@ underscores, or punctuation characters.
|
||||
line are arguments.
|
||||
|
||||
(6) If you want text with spaces to be treated as a single argument,
|
||||
it can be enclosed in either double or single quotes. A long single
|
||||
argument enclosed in quotes can even span multiple lines if the "&"
|
||||
character is used, as described above. E.g.
|
||||
it can be enclosed in either single or double or triple quotes. A
|
||||
long single argument enclosed in single or double quotes can span
|
||||
multiple lines if the "&" character is used, as described above. When
|
||||
the lines are concatenated together (and the "&" characters and line
|
||||
breaks removed), the text will become a single line. If you want
|
||||
multiple lines of an argument to retain their line breaks, the text
|
||||
can be enclosed in triple quotes, in which case "&" characters are not
|
||||
needed. For example:
|
||||
|
||||
print "Volume = $v"
|
||||
print 'Volume = $v'
|
||||
if "${steps} > 1000" then quit
|
||||
variable a string "red green blue &
|
||||
purple orange cyan"
|
||||
if "${steps} > 1000" then quit :pre
|
||||
print """
|
||||
System volume = $v
|
||||
System temperature = $t
|
||||
""" :pre
|
||||
|
||||
The quotes are removed when the single argument is stored internally.
|
||||
In each case, the single, double, or triple quotes are removed when
|
||||
the single argument they enclose is stored internally.
|
||||
|
||||
See the "dump modify format"_dump_modify.html or "print"_print.html or
|
||||
"if"_if.html commands for examples. A "#" or "$" character that is
|
||||
between quotes will not be treated as a comment indicator in (2) or
|
||||
substituted for as a variable in (3).
|
||||
See the "dump modify format"_dump_modify.html, "print"_print.html,
|
||||
"if"_if.html, and "python"_python.html commands for examples.
|
||||
|
||||
A "#" or "$" character that is between quotes will not be treated as a
|
||||
comment indicator in (2) or substituted for as a variable in (3).
|
||||
|
||||
IMPORTANT NOTE: If the argument is itself a command that requires a
|
||||
quoted argument (e.g. using a "print"_print.html command as part of an
|
||||
"if"_if.html or "run every"_run.html command), then the double and
|
||||
single quotes can be nested in the usual manner. See the doc pages
|
||||
"if"_if.html or "run every"_run.html command), then single, double, or
|
||||
triple quotes can be nested in the usual manner. See the doc pages
|
||||
for those commands for examples. Only one of level of nesting is
|
||||
allowed, but that should be sufficient for most use cases.
|
||||
|
||||
@ -535,7 +547,6 @@ g = GPU, i = USER-INTEL, k = KOKKOS, o = USER-OMP, t = OPT.
|
||||
"qeq/point"_fix_qeq.html,
|
||||
"qeq/shielded"_fix_qeq.html,
|
||||
"qeq/slater"_fix_qeq.html,
|
||||
"rattle"_fix_shake.html,
|
||||
"reax/bonds"_fix_reax_bonds.html,
|
||||
"recenter"_fix_recenter.html,
|
||||
"restrain"_fix_restrain.html,
|
||||
@ -681,7 +692,6 @@ KOKKOS, o = USER-OMP, t = OPT.
|
||||
"temp/asphere"_compute_temp_asphere.html,
|
||||
"temp/com"_compute_temp_com.html,
|
||||
"temp/chunk"_compute_temp_chunk.html,
|
||||
"temp/cs"_compute_temp_cs.html,
|
||||
"temp/deform"_compute_temp_deform.html,
|
||||
"temp/partial (c)"_compute_temp_partial.html,
|
||||
"temp/profile"_compute_temp_profile.html,
|
||||
@ -733,7 +743,6 @@ KOKKOS, o = USER-OMP, t = OPT.
|
||||
"bop"_pair_bop.html,
|
||||
"born (go)"_pair_born.html,
|
||||
"born/coul/long (cgo)"_pair_born.html,
|
||||
"born/coul/long/cs"_pair_cs.html,
|
||||
"born/coul/msm (o)"_pair_born.html,
|
||||
"born/coul/wolf (go)"_pair_born.html,
|
||||
"brownian (o)"_pair_brownian.html,
|
||||
@ -741,7 +750,6 @@ KOKKOS, o = USER-OMP, t = OPT.
|
||||
"buck (cgko)"_pair_buck.html,
|
||||
"buck/coul/cut (cgo)"_pair_buck.html,
|
||||
"buck/coul/long (cgo)"_pair_buck.html,
|
||||
"buck/coul/long/cs"_pair_cs.html,
|
||||
"buck/coul/msm (o)"_pair_buck.html,
|
||||
"buck/long/coul/long (o)"_pair_buck_long.html,
|
||||
"colloid (go)"_pair_colloid.html,
|
||||
@ -817,7 +825,7 @@ KOKKOS, o = USER-OMP, t = OPT.
|
||||
"resquared (go)"_pair_resquared.html,
|
||||
"snap"_pair_snap.html,
|
||||
"soft (go)"_pair_soft.html,
|
||||
"sw (cgio)"_pair_sw.html,
|
||||
"sw (cgo)"_pair_sw.html,
|
||||
"table (gko)"_pair_table.html,
|
||||
"tersoff (co)"_pair_tersoff.html,
|
||||
"tersoff/mod (o)"_pair_tersoff_mod.html,
|
||||
|
||||
@ -63,6 +63,7 @@ packages, more details are provided.
|
||||
<TR ALIGN="center"><TD >OPT</TD><TD > optimized pair styles</TD><TD > Fischer & Richie & Natoli (2)</TD><TD > <A HREF = "accelerate_opt.html">Section accelerate</A></TD><TD > -</TD><TD > -</TD></TR>
|
||||
<TR ALIGN="center"><TD >PERI</TD><TD > Peridynamics models</TD><TD > Mike Parks (Sandia)</TD><TD > <A HREF = "pair_peri.html">pair_style peri</A></TD><TD > peri</TD><TD > -</TD></TR>
|
||||
<TR ALIGN="center"><TD >POEMS</TD><TD > coupled rigid body motion</TD><TD > Rudra Mukherjee (JPL)</TD><TD > <A HREF = "fix_poems.html">fix poems</A></TD><TD > rigid</TD><TD > lib/poems</TD></TR>
|
||||
<TR ALIGN="center"><TD >PYTHON</TD><TD > embed Python code in an input script</TD><TD > -</TD><TD > <A HREF = "python.html">python</A></TD><TD > python</TD><TD > lib/python</TD></TR>
|
||||
<TR ALIGN="center"><TD >REAX</TD><TD > ReaxFF potential</TD><TD > Aidan Thompson (Sandia)</TD><TD > <A HREF = "pair_reax.html">pair_style reax</A></TD><TD > reax</TD><TD > lib/reax</TD></TR>
|
||||
<TR ALIGN="center"><TD >REPLICA</TD><TD > multi-replica methods</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_5">Section_howto 6.5</A></TD><TD > tad</TD><TD > -</TD></TR>
|
||||
<TR ALIGN="center"><TD >RIGID</TD><TD > rigid bodies</TD><TD > -</TD><TD > <A HREF = "fix_rigid.html">fix rigid</A></TD><TD > rigid</TD><TD > -</TD></TR>
|
||||
|
||||
@ -58,6 +58,7 @@ MOLECULE, molecular system force fields, -, "Section_howto 6.3"_Section_howto.ht
|
||||
OPT, optimized pair styles, Fischer & Richie & Natoli (2), "Section accelerate"_accelerate_opt.html, -, -
|
||||
PERI, Peridynamics models, Mike Parks (Sandia), "pair_style peri"_pair_peri.html, peri, -
|
||||
POEMS, coupled rigid body motion, Rudra Mukherjee (JPL), "fix poems"_fix_poems.html, rigid, lib/poems
|
||||
PYTHON, embed Python code in an input script, -, "python"_python.html, python, lib/python
|
||||
REAX, ReaxFF potential, Aidan Thompson (Sandia), "pair_style reax"_pair_reax.html, reax, lib/reax
|
||||
REPLICA, multi-replica methods, -, "Section_howto 6.5"_Section_howto.html#howto_5, tad, -
|
||||
RIGID, rigid bodies, -, "fix rigid"_fix_rigid.html, rigid, -
|
||||
|
||||
@ -11,61 +11,98 @@
|
||||
|
||||
<H3>11. Python interface to LAMMPS
|
||||
</H3>
|
||||
<P>This section describes how to build and use LAMMPS via a Python
|
||||
interface.
|
||||
<P>LAMMPS can work together with Python in two ways. First, Python can
|
||||
wrap LAMMPS through the <A HREF = "Section_howto.html#howto_19">LAMMPS library
|
||||
interface</A>, so that a Python script can
|
||||
create one or more instances of LAMMPS and launch one or more
|
||||
simulations. In Python lingo, this is "extending" Python with LAMMPS.
|
||||
</P>
|
||||
<UL><LI>11.1 <A HREF = "#py_1">Building LAMMPS as a shared library</A>
|
||||
<LI>11.2 <A HREF = "#py_2">Installing the Python wrapper into Python</A>
|
||||
<LI>11.3 <A HREF = "#py_3">Extending Python with MPI to run in parallel</A>
|
||||
<LI>11.4 <A HREF = "#py_4">Testing the Python-LAMMPS interface</A>
|
||||
<LI>11.5 <A HREF = "#py_5">Using LAMMPS from Python</A>
|
||||
<LI>11.6 <A HREF = "#py_6">Example Python scripts that use LAMMPS</A>
|
||||
<P>Second, LAMMPS can use the Python interpreter, so that a LAMMPS input
|
||||
script can invoke Python code, and pass information back-and-forth
|
||||
between the input script and Python functions you write. The Python
|
||||
code can also callback to LAMMPS to query or change its attributes.
|
||||
In Python lingo, this is "embedding" Python in LAMMPS.
|
||||
</P>
|
||||
<P>This section describes how to do both.
|
||||
</P>
|
||||
<UL><LI>11.1 <A HREF = "#py_1">Overview of running LAMMPS from Python</A>
|
||||
<LI>11.2 <A HREF = "#py_2">Overview of using Python from a LAMMPS script</A>
|
||||
<LI>11.3 <A HREF = "#py_3">Building LAMMPS as a shared library</A>
|
||||
<LI>11.4 <A HREF = "#py_4">Installing the Python wrapper into Python</A>
|
||||
<LI>11.5 <A HREF = "#py_5">Extending Python with MPI to run in parallel</A>
|
||||
<LI>11.6 <A HREF = "#py_6">Testing the Python-LAMMPS interface</A>
|
||||
<LI>11.7 <A HREF = "#py_7">Using LAMMPS from Python</A>
|
||||
<LI>11.8 <A HREF = "#py_8">Example Python scripts that use LAMMPS</A>
|
||||
</UL>
|
||||
<P>The LAMMPS distribution includes the file python/lammps.py which wraps
|
||||
the library interface to LAMMPS. This file makes it is possible to
|
||||
run LAMMPS, invoke LAMMPS commands or give it an input script, extract
|
||||
LAMMPS results, an modify internal LAMMPS variables, either from a
|
||||
Python script or interactively from a Python prompt. You can do the
|
||||
former in serial or parallel. Running Python interactively in
|
||||
parallel does not generally work, unless you have a package installed
|
||||
that extends your Python to enable multiple instances of Python to
|
||||
read what you type.
|
||||
<P>If you are not familiar with it, <A HREF = "http://www.python.org">Python</A> is a
|
||||
powerful scripting and programming language which can essentially do
|
||||
anything that faster, lower-level languages like C or C++ can do, but
|
||||
typically with much fewer lines of code. When used in embedded mode,
|
||||
Python can perform operations that the simplistic LAMMPS input script
|
||||
syntax cannot. Python can be also be used as a "glue" language to
|
||||
drive a program through its library interface, or to hook multiple
|
||||
pieces of software together, such as a simulation package plus a
|
||||
visualization package, or to run a coupled multiscale or multiphysics
|
||||
model.
|
||||
</P>
|
||||
<P><A HREF = "http://www.python.org">Python</A> is a powerful scripting and programming
|
||||
language which can be used to wrap software like LAMMPS and other
|
||||
packages. It can be used to glue multiple pieces of software
|
||||
together, e.g. to run a coupled or multiscale model. See <A HREF = "Section_howto.html#howto_10">Section
|
||||
section</A> of the manual and the couple
|
||||
directory of the distribution for more ideas about coupling LAMMPS to
|
||||
other codes. See <A HREF = "Section_start.html#start_5">Section_start 4</A> about
|
||||
how to build LAMMPS as a library, and <A HREF = "Section_howto.html#howto_19">Section_howto
|
||||
19</A> for a description of the library
|
||||
interface provided in src/library.cpp and src/library.h and how to
|
||||
extend it for your needs. As described below, that interface is what
|
||||
is exposed to Python. It is designed to be easy to add functions to.
|
||||
This can easily extend the Python inteface as well. See details
|
||||
below.
|
||||
<P>See <A HREF = "Section_howto.html#howto_10">Section_howto 10</A> of the manual and
|
||||
the couple directory of the distribution for more ideas about coupling
|
||||
LAMMPS to other codes. See <A HREF = "Section_howto.html#howto_19">Section_howto
|
||||
19</A> for a description of the LAMMPS
|
||||
library interface provided in src/library.cpp and src/library.h, and
|
||||
how to extend it for your needs. As described below, that interface
|
||||
is what is exposed to Python either when calling LAMMPS from Python or
|
||||
when calling Python from a LAMMPS input script and then calling back
|
||||
to LAMMPS from Python code. The library interface is designed to be
|
||||
easy to add functions to. Thus the Python interface to LAMMPS is also
|
||||
easy to extend as well.
|
||||
</P>
|
||||
<P>By using the Python interface, LAMMPS can also be coupled with a GUI
|
||||
or other visualization tools that display graphs or animations in real
|
||||
time as LAMMPS runs. Examples of such scripts are inlcluded in the
|
||||
python directory.
|
||||
<P>If you create interesting Python scripts that run LAMMPS or
|
||||
interesting Python functions that can be called from a LAMMPS input
|
||||
script, that you think would be useful to other users, please <A HREF = "http://lammps.sandia.gov/authors.html">email
|
||||
them to the developers</A>. We can
|
||||
include them in the LAMMPS distribution.
|
||||
</P>
|
||||
<P>Two advantages of using Python are how concise the language is, and
|
||||
that it can be run interactively, enabling rapid development and
|
||||
debugging of programs. If you use it to mostly invoke costly
|
||||
operations within LAMMPS, such as running a simulation for a
|
||||
<HR>
|
||||
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_1"></A><H4>11.1 Overview of running LAMMPS from Python
|
||||
</H4>
|
||||
<P>The LAMMPS distribution includes a python directory with all you need
|
||||
to run LAMMPS from Python. The python/lammps.py file wraps the LAMMPS
|
||||
library interface, with one wrapper function per LAMMPS library
|
||||
function. This file makes it is possible to do the following either
|
||||
from a Python script, or interactively from a Python prompt: create
|
||||
one or more instances of LAMMPS, invoke LAMMPS commands or give it an
|
||||
input script, run LAMMPS incrementally, extract LAMMPS results, an
|
||||
modify internal LAMMPS variables. From a Python script you can do
|
||||
this in serial or parallel. Running Python interactively in parallel
|
||||
does not generally work, unless you have a version of Python that
|
||||
extends standard Python to enable multiple instances of Python to read
|
||||
what you type.
|
||||
</P>
|
||||
<P>To do all of this, you must first build LAMMPS as a shared library,
|
||||
then insure that your Python can find the python/lammps.py file and
|
||||
the shared library. These steps are explained in subsequent sections
|
||||
11.3 and 11.4. Sections 11.5 and 11.6 discuss using MPI from a
|
||||
parallel Python program and how to test that you are ready to use
|
||||
LAMMPS from Python. Section 11.7 lists all the functions in the
|
||||
current LAMMPS library interface and how to call them from Python.
|
||||
</P>
|
||||
<P>Section 11.8 gives some examples of coupling LAMMPS to other tools via
|
||||
Python. For example, LAMMPS can easily be coupled to a GUI or other
|
||||
visualization tools that display graphs or animations in real time as
|
||||
LAMMPS runs. Examples of such scripts are inlcluded in the python
|
||||
directory.
|
||||
</P>
|
||||
<P>Two advantages of using Python to run LAMMPS are how concise the
|
||||
language is, and that it can be run interactively, enabling rapid
|
||||
development and debugging of programs. If you use it to mostly invoke
|
||||
costly operations within LAMMPS, such as running a simulation for a
|
||||
reasonable number of timesteps, then the overhead cost of invoking
|
||||
LAMMPS thru Python will be negligible.
|
||||
</P>
|
||||
<P>Before using LAMMPS from a Python script, you need to do two things.
|
||||
You need to build LAMMPS as a dynamic shared library, so it can be
|
||||
loaded by Python. And you need to tell Python how to find the library
|
||||
and the Python wrapper file python/lammps.py. Both these steps are
|
||||
discussed below. If you wish to run LAMMPS in parallel from Python,
|
||||
you also need to extend your Python with MPI. This is also discussed
|
||||
below.
|
||||
</P>
|
||||
<P>The Python wrapper for LAMMPS uses the amazing and magical (to me)
|
||||
"ctypes" package in Python, which auto-generates the interface code
|
||||
needed between Python and a set of C interface routines for a library.
|
||||
@ -75,16 +112,82 @@ check which version of Python you have installed, by simply typing
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_2"></A><H4>11.2 Overview of using Python from a LAMMPS script
|
||||
</H4>
|
||||
<P>IMPORTANT NOTE: It is not currently possible to use the
|
||||
<A HREF = "python.html">python</A> command described in this section with Python 3,
|
||||
only with Python 2. The C API changed from Python 2 to 3 and the
|
||||
LAMMPS code is not compatible with both.
|
||||
</P>
|
||||
<P>LAMMPS has a <A HREF = "python.html">python</A> command which can be used in an
|
||||
input script to define and execute a Python function that you write
|
||||
the code for. The Python function can also be assigned to a LAMMPS
|
||||
python-style variable via the <A HREF = "variable.html">variable</A> command. Each
|
||||
time the variable is evaluated, either in the LAMMPS input script
|
||||
itself, or by another LAMMPS command that uses the variable, this will
|
||||
trigger the Python function to be invoked.
|
||||
</P>
|
||||
<P>The Python code for the function can be included directly in the input
|
||||
script or in an auxiliary file. The function can have arguments which
|
||||
are mapped to LAMMPS variables (also defined in the input script) and
|
||||
it can return a value to a LAMMPS variable. This is thus a mechanism
|
||||
for your input script to pass information to a piece of Python code,
|
||||
ask Python to execute the code, and return information to your input
|
||||
script.
|
||||
</P>
|
||||
<P>Note that a Python function can be arbitrarily complex. It can import
|
||||
other Python modules, instantiate Python classes, call other Python
|
||||
functions, etc. The Python code that you provide can contain more
|
||||
code than the single function. It can contain other functions or
|
||||
Python classes, as well as global variables or other mechanisms for
|
||||
storing state between calls from LAMMPS to the function.
|
||||
</P>
|
||||
<P>The Python function you provide can consist of "pure" Python code that
|
||||
only performs operations provided by standard Python. However, the
|
||||
Python function can also "call back" to LAMMPS through its
|
||||
Python-wrapped library interface, in the manner described in the
|
||||
previous section 11.1. This means it can issue LAMMPS input script
|
||||
commands or query and set internal LAMMPS state. As an example, this
|
||||
can be useful in an input script to create a more complex loop with
|
||||
branching logic, than can be created using the simple looping and
|
||||
brancing logic enabled by the <A HREF = "next_html">next</A> and <A HREF = "if.html">if</A>
|
||||
commands.
|
||||
</P>
|
||||
<P>See the <A HREF = "python.html">python</A> doc page and the <A HREF = "variable.html">variable</A>
|
||||
doc page for its python-style variables for more info, including
|
||||
examples of Python code you can write for both pure Python operations
|
||||
and callbacks to LAMMPS.
|
||||
</P>
|
||||
<P>To run pure Python code from LAMMPS, you only need to build LAMMPS
|
||||
with the PYTHON package installed:
|
||||
</P>
|
||||
<P>make yes-python
|
||||
make machine
|
||||
</P>
|
||||
<P>Note that this will link LAMMPS with the Python library on your
|
||||
system, which typically requires several auxiliary system libraries to
|
||||
also be linked. The list of these libraries and the paths to find
|
||||
them are specified in the lib/python/Makefile.lammps file. You need
|
||||
to insure that file contains the correct information for your version
|
||||
of Python and your machine to successfully build LAMMPS. See the
|
||||
lib/python/README file for more info.
|
||||
</P>
|
||||
<P>If you want to write Python code with callbacks to LAMMPS, then you
|
||||
must also follow the steps overviewed in the preceeding section (11.1)
|
||||
for running LAMMPS from Python. I.e. you must build LAMMPS as a
|
||||
shared library and insure that Python can find the python/lammps.py
|
||||
file and the shared library.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_1"></A><H4>11.1 Building LAMMPS as a shared library
|
||||
<A NAME = "py_3"></A><H4>11.3 Building LAMMPS as a shared library
|
||||
</H4>
|
||||
<P>Instructions on how to build LAMMPS as a shared library are given in
|
||||
<A HREF = "Section_start.html#start_5">Section_start 5</A>. A shared library is one
|
||||
that is dynamically loadable, which is what Python requires. On Linux
|
||||
this is a library file that ends in ".so", not ".a".
|
||||
that is dynamically loadable, which is what Python requires to wrap
|
||||
LAMMPS. On Linux this is a library file that ends in ".so", not ".a".
|
||||
</P>
|
||||
<P>From the src directory, type
|
||||
<P>>From the src directory, type
|
||||
</P>
|
||||
<PRE>make foo mode=shlib
|
||||
</PRE>
|
||||
@ -102,7 +205,7 @@ system.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_2"></A><H4>11.2 Installing the Python wrapper into Python
|
||||
<A NAME = "py_4"></A><H4>11.4 Installing the Python wrapper into Python
|
||||
</H4>
|
||||
<P>For Python to invoke LAMMPS, there are 2 files it needs to know about:
|
||||
</P>
|
||||
@ -170,7 +273,7 @@ environment variable as described above.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_3"></A><H4>11.3 Extending Python with MPI to run in parallel
|
||||
<A NAME = "py_5"></A><H4>11.5 Extending Python with MPI to run in parallel
|
||||
</H4>
|
||||
<P>If you wish to run LAMMPS in parallel from Python, you need to extend
|
||||
your Python with an interface to MPI. This also allows you to
|
||||
@ -197,11 +300,12 @@ believe) creates a new alternate executable (in place of "python"
|
||||
itself) as a result.
|
||||
</P>
|
||||
<P>In principle any of these Python/MPI packages should work to invoke
|
||||
LAMMPS in parallel and MPI calls themselves from a Python script which
|
||||
is itself running in parallel. However, when I downloaded and looked
|
||||
at a few of them, their documentation was incomplete and I had trouble
|
||||
with their installation. It's not clear if some of the packages are
|
||||
still being actively developed and supported.
|
||||
LAMMPS in parallel and to make MPI calls themselves from a Python
|
||||
script which is itself running in parallel. However, when I
|
||||
downloaded and looked at a few of them, their documentation was
|
||||
incomplete and I had trouble with their installation. It's not clear
|
||||
if some of the packages are still being actively developed and
|
||||
supported.
|
||||
</P>
|
||||
<P>The one I recommend, since I have successfully used it with LAMMPS, is
|
||||
Pypar. Pypar requires the ubiquitous <A HREF = "http://numpy.scipy.org">Numpy
|
||||
@ -261,7 +365,7 @@ the right one.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_4"></A><H4>11.4 Testing the Python-LAMMPS interface
|
||||
<A NAME = "py_6"></A><H4>11.6 Testing the Python-LAMMPS interface
|
||||
</H4>
|
||||
<P>To test if LAMMPS is callable from Python, launch Python interactively
|
||||
and type:
|
||||
@ -375,22 +479,24 @@ Python on a single processor, not in parallel.
|
||||
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_5"></A><H4>11.5 Using LAMMPS from Python
|
||||
<A NAME = "py_7"></A><H4>11.7 Using LAMMPS from Python
|
||||
</H4>
|
||||
<P>The Python interface to LAMMPS consists of a Python "lammps" module,
|
||||
the source code for which is in python/lammps.py, which creates a
|
||||
"lammps" object, with a set of methods that can be invoked on that
|
||||
object. The sample Python code below assumes you have first imported
|
||||
the "lammps" module in your Python script, as follows:
|
||||
<P>As described above, the Python interface to LAMMPS consists of a
|
||||
Python "lammps" module, the source code for which is in
|
||||
python/lammps.py, which creates a "lammps" object, with a set of
|
||||
methods that can be invoked on that object. The sample Python code
|
||||
below assumes you have first imported the "lammps" module in your
|
||||
Python script, as follows:
|
||||
</P>
|
||||
<PRE>from lammps import lammps
|
||||
</PRE>
|
||||
<P>These are the methods defined by the lammps module. If you look
|
||||
at the file src/library.cpp you will see that they correspond
|
||||
one-to-one with calls you can make to the LAMMPS library from a C++ or
|
||||
C or Fortran program.
|
||||
<P>These are the methods defined by the lammps module. If you look at
|
||||
the files src/library.cpp and src/library.h you will see that they
|
||||
correspond one-to-one with calls you can make to the LAMMPS library
|
||||
from a C++ or C or Fortran program.
|
||||
</P>
|
||||
<PRE>lmp = lammps() # create a LAMMPS object using the default liblammps.so library
|
||||
lmp = lammps(ptr=lmpptr) # ditto, but use lmpptr as previously created LAMMPS object
|
||||
lmp = lammps("g++") # create a LAMMPS object using the liblammps_g++.so library
|
||||
lmp = lammps("",list) # ditto, with command-line args, e.g. list = ["-echo","screen"]
|
||||
lmp = lammps("g++",list)
|
||||
@ -449,6 +555,33 @@ processors. If someone figures out how to do this with one or more of
|
||||
the Python wrappers for MPI, like Pypar, please let us know and we
|
||||
will amend these doc pages.
|
||||
</P>
|
||||
<P>The lines
|
||||
</P>
|
||||
<PRE>from lammps import lammps
|
||||
lmp = lammps()
|
||||
</PRE>
|
||||
<P>create an instance of LAMMPS, wrapped in a Python class by the lammps
|
||||
Python module, and return an instance of the Python class as lmp. It
|
||||
is used to make all subequent calls to the LAMMPS library.
|
||||
</P>
|
||||
<P>Additional arguments can be used to tell Python the name of the shared
|
||||
library to load or to pass arguments to the LAMMPS instance, the same
|
||||
as if LAMMPS were launched from a command-line prompt.
|
||||
</P>
|
||||
<P>If the ptr argument is set like this:
|
||||
</P>
|
||||
<PRE>lmp = lammps(ptr=lmpptr)
|
||||
</PRE>
|
||||
<P>then lmpptr must be an argument passed to Python via the LAMMPS
|
||||
<A HREF = "python.html">python</A> command, when it is used to define a Python
|
||||
function that is invoked by the LAMMPS input script. This mode of
|
||||
using Python with LAMMPS is described above in 11.2. The variable
|
||||
lmpptr refers to the instance of LAMMPS that called the embedded
|
||||
Python interpreter. Using it as an argument to lammps() allows the
|
||||
returned Python class instance "lmp" to make calls to that instance of
|
||||
LAMMPS. See the <A HREF = "python.html">python</A> command doc page for examples
|
||||
using this syntax.
|
||||
</P>
|
||||
<P>Note that you can create multiple LAMMPS objects in your Python
|
||||
script, and coordinate and run multiple simulations, e.g.
|
||||
</P>
|
||||
@ -578,7 +711,7 @@ Python script. Isn't ctypes amazing?
|
||||
|
||||
<HR>
|
||||
|
||||
<A NAME = "py_6"></A><H4>11.6 Example Python scripts that use LAMMPS
|
||||
<A NAME = "py_8"></A><H4>11.8 Example Python scripts that use LAMMPS
|
||||
</H4>
|
||||
<P>These are the Python scripts included as demos in the python/examples
|
||||
directory of the LAMMPS distribution, to illustrate the kinds of
|
||||
|
||||
@ -8,61 +8,97 @@
|
||||
|
||||
11. Python interface to LAMMPS :h3
|
||||
|
||||
This section describes how to build and use LAMMPS via a Python
|
||||
interface.
|
||||
LAMMPS can work together with Python in two ways. First, Python can
|
||||
wrap LAMMPS through the "LAMMPS library
|
||||
interface"_Section_howto.html#howto_19, so that a Python script can
|
||||
create one or more instances of LAMMPS and launch one or more
|
||||
simulations. In Python lingo, this is "extending" Python with LAMMPS.
|
||||
|
||||
11.1 "Building LAMMPS as a shared library"_#py_1
|
||||
11.2 "Installing the Python wrapper into Python"_#py_2
|
||||
11.3 "Extending Python with MPI to run in parallel"_#py_3
|
||||
11.4 "Testing the Python-LAMMPS interface"_#py_4
|
||||
11.5 "Using LAMMPS from Python"_#py_5
|
||||
11.6 "Example Python scripts that use LAMMPS"_#py_6 :ul
|
||||
Second, LAMMPS can use the Python interpreter, so that a LAMMPS input
|
||||
script can invoke Python code, and pass information back-and-forth
|
||||
between the input script and Python functions you write. The Python
|
||||
code can also callback to LAMMPS to query or change its attributes.
|
||||
In Python lingo, this is "embedding" Python in LAMMPS.
|
||||
|
||||
The LAMMPS distribution includes the file python/lammps.py which wraps
|
||||
the library interface to LAMMPS. This file makes it is possible to
|
||||
run LAMMPS, invoke LAMMPS commands or give it an input script, extract
|
||||
LAMMPS results, an modify internal LAMMPS variables, either from a
|
||||
Python script or interactively from a Python prompt. You can do the
|
||||
former in serial or parallel. Running Python interactively in
|
||||
parallel does not generally work, unless you have a package installed
|
||||
that extends your Python to enable multiple instances of Python to
|
||||
read what you type.
|
||||
This section describes how to do both.
|
||||
|
||||
"Python"_http://www.python.org is a powerful scripting and programming
|
||||
language which can be used to wrap software like LAMMPS and other
|
||||
packages. It can be used to glue multiple pieces of software
|
||||
together, e.g. to run a coupled or multiscale model. See "Section
|
||||
section"_Section_howto.html#howto_10 of the manual and the couple
|
||||
directory of the distribution for more ideas about coupling LAMMPS to
|
||||
other codes. See "Section_start 4"_Section_start.html#start_5 about
|
||||
how to build LAMMPS as a library, and "Section_howto
|
||||
19"_Section_howto.html#howto_19 for a description of the library
|
||||
interface provided in src/library.cpp and src/library.h and how to
|
||||
extend it for your needs. As described below, that interface is what
|
||||
is exposed to Python. It is designed to be easy to add functions to.
|
||||
This can easily extend the Python inteface as well. See details
|
||||
below.
|
||||
11.1 "Overview of running LAMMPS from Python"_#py_1
|
||||
11.2 "Overview of using Python from a LAMMPS script"_#py_2
|
||||
11.3 "Building LAMMPS as a shared library"_#py_3
|
||||
11.4 "Installing the Python wrapper into Python"_#py_4
|
||||
11.5 "Extending Python with MPI to run in parallel"_#py_5
|
||||
11.6 "Testing the Python-LAMMPS interface"_#py_6
|
||||
11.7 "Using LAMMPS from Python"_#py_7
|
||||
11.8 "Example Python scripts that use LAMMPS"_#py_8 :ul
|
||||
|
||||
By using the Python interface, LAMMPS can also be coupled with a GUI
|
||||
or other visualization tools that display graphs or animations in real
|
||||
time as LAMMPS runs. Examples of such scripts are inlcluded in the
|
||||
python directory.
|
||||
If you are not familiar with it, "Python"_http://www.python.org is a
|
||||
powerful scripting and programming language which can essentially do
|
||||
anything that faster, lower-level languages like C or C++ can do, but
|
||||
typically with much fewer lines of code. When used in embedded mode,
|
||||
Python can perform operations that the simplistic LAMMPS input script
|
||||
syntax cannot. Python can be also be used as a "glue" language to
|
||||
drive a program through its library interface, or to hook multiple
|
||||
pieces of software together, such as a simulation package plus a
|
||||
visualization package, or to run a coupled multiscale or multiphysics
|
||||
model.
|
||||
|
||||
Two advantages of using Python are how concise the language is, and
|
||||
that it can be run interactively, enabling rapid development and
|
||||
debugging of programs. If you use it to mostly invoke costly
|
||||
operations within LAMMPS, such as running a simulation for a
|
||||
See "Section_howto 10"_Section_howto.html#howto_10 of the manual and
|
||||
the couple directory of the distribution for more ideas about coupling
|
||||
LAMMPS to other codes. See "Section_howto
|
||||
19"_Section_howto.html#howto_19 for a description of the LAMMPS
|
||||
library interface provided in src/library.cpp and src/library.h, and
|
||||
how to extend it for your needs. As described below, that interface
|
||||
is what is exposed to Python either when calling LAMMPS from Python or
|
||||
when calling Python from a LAMMPS input script and then calling back
|
||||
to LAMMPS from Python code. The library interface is designed to be
|
||||
easy to add functions to. Thus the Python interface to LAMMPS is also
|
||||
easy to extend as well.
|
||||
|
||||
If you create interesting Python scripts that run LAMMPS or
|
||||
interesting Python functions that can be called from a LAMMPS input
|
||||
script, that you think would be useful to other users, please "email
|
||||
them to the developers"_http://lammps.sandia.gov/authors.html. We can
|
||||
include them in the LAMMPS distribution.
|
||||
|
||||
:line
|
||||
:line
|
||||
|
||||
11.1 Overview of running LAMMPS from Python :link(py_1),h4
|
||||
|
||||
The LAMMPS distribution includes a python directory with all you need
|
||||
to run LAMMPS from Python. The python/lammps.py file wraps the LAMMPS
|
||||
library interface, with one wrapper function per LAMMPS library
|
||||
function. This file makes it is possible to do the following either
|
||||
from a Python script, or interactively from a Python prompt: create
|
||||
one or more instances of LAMMPS, invoke LAMMPS commands or give it an
|
||||
input script, run LAMMPS incrementally, extract LAMMPS results, an
|
||||
modify internal LAMMPS variables. From a Python script you can do
|
||||
this in serial or parallel. Running Python interactively in parallel
|
||||
does not generally work, unless you have a version of Python that
|
||||
extends standard Python to enable multiple instances of Python to read
|
||||
what you type.
|
||||
|
||||
To do all of this, you must first build LAMMPS as a shared library,
|
||||
then insure that your Python can find the python/lammps.py file and
|
||||
the shared library. These steps are explained in subsequent sections
|
||||
11.3 and 11.4. Sections 11.5 and 11.6 discuss using MPI from a
|
||||
parallel Python program and how to test that you are ready to use
|
||||
LAMMPS from Python. Section 11.7 lists all the functions in the
|
||||
current LAMMPS library interface and how to call them from Python.
|
||||
|
||||
Section 11.8 gives some examples of coupling LAMMPS to other tools via
|
||||
Python. For example, LAMMPS can easily be coupled to a GUI or other
|
||||
visualization tools that display graphs or animations in real time as
|
||||
LAMMPS runs. Examples of such scripts are inlcluded in the python
|
||||
directory.
|
||||
|
||||
Two advantages of using Python to run LAMMPS are how concise the
|
||||
language is, and that it can be run interactively, enabling rapid
|
||||
development and debugging of programs. If you use it to mostly invoke
|
||||
costly operations within LAMMPS, such as running a simulation for a
|
||||
reasonable number of timesteps, then the overhead cost of invoking
|
||||
LAMMPS thru Python will be negligible.
|
||||
|
||||
Before using LAMMPS from a Python script, you need to do two things.
|
||||
You need to build LAMMPS as a dynamic shared library, so it can be
|
||||
loaded by Python. And you need to tell Python how to find the library
|
||||
and the Python wrapper file python/lammps.py. Both these steps are
|
||||
discussed below. If you wish to run LAMMPS in parallel from Python,
|
||||
you also need to extend your Python with MPI. This is also discussed
|
||||
below.
|
||||
|
||||
The Python wrapper for LAMMPS uses the amazing and magical (to me)
|
||||
"ctypes" package in Python, which auto-generates the interface code
|
||||
needed between Python and a set of C interface routines for a library.
|
||||
@ -71,16 +107,83 @@ check which version of Python you have installed, by simply typing
|
||||
"python" at a shell prompt.
|
||||
|
||||
:line
|
||||
|
||||
11.2 Overview of using Python from a LAMMPS script :link(py_2),h4
|
||||
|
||||
IMPORTANT NOTE: It is not currently possible to use the
|
||||
"python"_python.html command described in this section with Python 3,
|
||||
only with Python 2. The C API changed from Python 2 to 3 and the
|
||||
LAMMPS code is not compatible with both.
|
||||
|
||||
LAMMPS has a "python"_python.html command which can be used in an
|
||||
input script to define and execute a Python function that you write
|
||||
the code for. The Python function can also be assigned to a LAMMPS
|
||||
python-style variable via the "variable"_variable.html command. Each
|
||||
time the variable is evaluated, either in the LAMMPS input script
|
||||
itself, or by another LAMMPS command that uses the variable, this will
|
||||
trigger the Python function to be invoked.
|
||||
|
||||
The Python code for the function can be included directly in the input
|
||||
script or in an auxiliary file. The function can have arguments which
|
||||
are mapped to LAMMPS variables (also defined in the input script) and
|
||||
it can return a value to a LAMMPS variable. This is thus a mechanism
|
||||
for your input script to pass information to a piece of Python code,
|
||||
ask Python to execute the code, and return information to your input
|
||||
script.
|
||||
|
||||
Note that a Python function can be arbitrarily complex. It can import
|
||||
other Python modules, instantiate Python classes, call other Python
|
||||
functions, etc. The Python code that you provide can contain more
|
||||
code than the single function. It can contain other functions or
|
||||
Python classes, as well as global variables or other mechanisms for
|
||||
storing state between calls from LAMMPS to the function.
|
||||
|
||||
The Python function you provide can consist of "pure" Python code that
|
||||
only performs operations provided by standard Python. However, the
|
||||
Python function can also "call back" to LAMMPS through its
|
||||
Python-wrapped library interface, in the manner described in the
|
||||
previous section 11.1. This means it can issue LAMMPS input script
|
||||
commands or query and set internal LAMMPS state. As an example, this
|
||||
can be useful in an input script to create a more complex loop with
|
||||
branching logic, than can be created using the simple looping and
|
||||
brancing logic enabled by the "next"_next_html and "if"_if.html
|
||||
commands.
|
||||
|
||||
See the "python"_python.html doc page and the "variable"_variable.html
|
||||
doc page for its python-style variables for more info, including
|
||||
examples of Python code you can write for both pure Python operations
|
||||
and callbacks to LAMMPS.
|
||||
|
||||
To run pure Python code from LAMMPS, you only need to build LAMMPS
|
||||
with the PYTHON package installed:
|
||||
|
||||
make yes-python
|
||||
make machine
|
||||
|
||||
Note that this will link LAMMPS with the Python library on your
|
||||
system, which typically requires several auxiliary system libraries to
|
||||
also be linked. The list of these libraries and the paths to find
|
||||
them are specified in the lib/python/Makefile.lammps file. You need
|
||||
to insure that file contains the correct information for your version
|
||||
of Python and your machine to successfully build LAMMPS. See the
|
||||
lib/python/README file for more info.
|
||||
|
||||
If you want to write Python code with callbacks to LAMMPS, then you
|
||||
must also follow the steps overviewed in the preceeding section (11.1)
|
||||
for running LAMMPS from Python. I.e. you must build LAMMPS as a
|
||||
shared library and insure that Python can find the python/lammps.py
|
||||
file and the shared library.
|
||||
|
||||
:line
|
||||
|
||||
11.1 Building LAMMPS as a shared library :link(py_1),h4
|
||||
11.3 Building LAMMPS as a shared library :link(py_3),h4
|
||||
|
||||
Instructions on how to build LAMMPS as a shared library are given in
|
||||
"Section_start 5"_Section_start.html#start_5. A shared library is one
|
||||
that is dynamically loadable, which is what Python requires. On Linux
|
||||
this is a library file that ends in ".so", not ".a".
|
||||
that is dynamically loadable, which is what Python requires to wrap
|
||||
LAMMPS. On Linux this is a library file that ends in ".so", not ".a".
|
||||
|
||||
From the src directory, type
|
||||
>From the src directory, type
|
||||
|
||||
make foo mode=shlib :pre
|
||||
|
||||
@ -98,7 +201,7 @@ system.
|
||||
|
||||
:line
|
||||
|
||||
11.2 Installing the Python wrapper into Python :link(py_2),h4
|
||||
11.4 Installing the Python wrapper into Python :link(py_4),h4
|
||||
|
||||
For Python to invoke LAMMPS, there are 2 files it needs to know about:
|
||||
|
||||
@ -166,7 +269,7 @@ environment variable as described above.
|
||||
|
||||
:line
|
||||
|
||||
11.3 Extending Python with MPI to run in parallel :link(py_3),h4
|
||||
11.5 Extending Python with MPI to run in parallel :link(py_5),h4
|
||||
|
||||
If you wish to run LAMMPS in parallel from Python, you need to extend
|
||||
your Python with an interface to MPI. This also allows you to
|
||||
@ -193,11 +296,12 @@ believe) creates a new alternate executable (in place of "python"
|
||||
itself) as a result.
|
||||
|
||||
In principle any of these Python/MPI packages should work to invoke
|
||||
LAMMPS in parallel and MPI calls themselves from a Python script which
|
||||
is itself running in parallel. However, when I downloaded and looked
|
||||
at a few of them, their documentation was incomplete and I had trouble
|
||||
with their installation. It's not clear if some of the packages are
|
||||
still being actively developed and supported.
|
||||
LAMMPS in parallel and to make MPI calls themselves from a Python
|
||||
script which is itself running in parallel. However, when I
|
||||
downloaded and looked at a few of them, their documentation was
|
||||
incomplete and I had trouble with their installation. It's not clear
|
||||
if some of the packages are still being actively developed and
|
||||
supported.
|
||||
|
||||
The one I recommend, since I have successfully used it with LAMMPS, is
|
||||
Pypar. Pypar requires the ubiquitous "Numpy
|
||||
@ -257,7 +361,7 @@ the right one.
|
||||
|
||||
:line
|
||||
|
||||
11.4 Testing the Python-LAMMPS interface :link(py_4),h4
|
||||
11.6 Testing the Python-LAMMPS interface :link(py_6),h4
|
||||
|
||||
To test if LAMMPS is callable from Python, launch Python interactively
|
||||
and type:
|
||||
@ -370,22 +474,24 @@ Python on a single processor, not in parallel.
|
||||
:line
|
||||
:line
|
||||
|
||||
11.5 Using LAMMPS from Python :link(py_5),h4
|
||||
11.7 Using LAMMPS from Python :link(py_7),h4
|
||||
|
||||
The Python interface to LAMMPS consists of a Python "lammps" module,
|
||||
the source code for which is in python/lammps.py, which creates a
|
||||
"lammps" object, with a set of methods that can be invoked on that
|
||||
object. The sample Python code below assumes you have first imported
|
||||
the "lammps" module in your Python script, as follows:
|
||||
As described above, the Python interface to LAMMPS consists of a
|
||||
Python "lammps" module, the source code for which is in
|
||||
python/lammps.py, which creates a "lammps" object, with a set of
|
||||
methods that can be invoked on that object. The sample Python code
|
||||
below assumes you have first imported the "lammps" module in your
|
||||
Python script, as follows:
|
||||
|
||||
from lammps import lammps :pre
|
||||
|
||||
These are the methods defined by the lammps module. If you look
|
||||
at the file src/library.cpp you will see that they correspond
|
||||
one-to-one with calls you can make to the LAMMPS library from a C++ or
|
||||
C or Fortran program.
|
||||
These are the methods defined by the lammps module. If you look at
|
||||
the files src/library.cpp and src/library.h you will see that they
|
||||
correspond one-to-one with calls you can make to the LAMMPS library
|
||||
from a C++ or C or Fortran program.
|
||||
|
||||
lmp = lammps() # create a LAMMPS object using the default liblammps.so library
|
||||
lmp = lammps(ptr=lmpptr) # ditto, but use lmpptr as previously created LAMMPS object
|
||||
lmp = lammps("g++") # create a LAMMPS object using the liblammps_g++.so library
|
||||
lmp = lammps("",list) # ditto, with command-line args, e.g. list = \["-echo","screen"\]
|
||||
lmp = lammps("g++",list) :pre
|
||||
@ -444,6 +550,33 @@ processors. If someone figures out how to do this with one or more of
|
||||
the Python wrappers for MPI, like Pypar, please let us know and we
|
||||
will amend these doc pages.
|
||||
|
||||
The lines
|
||||
|
||||
from lammps import lammps
|
||||
lmp = lammps() :pre
|
||||
|
||||
create an instance of LAMMPS, wrapped in a Python class by the lammps
|
||||
Python module, and return an instance of the Python class as lmp. It
|
||||
is used to make all subequent calls to the LAMMPS library.
|
||||
|
||||
Additional arguments can be used to tell Python the name of the shared
|
||||
library to load or to pass arguments to the LAMMPS instance, the same
|
||||
as if LAMMPS were launched from a command-line prompt.
|
||||
|
||||
If the ptr argument is set like this:
|
||||
|
||||
lmp = lammps(ptr=lmpptr) :pre
|
||||
|
||||
then lmpptr must be an argument passed to Python via the LAMMPS
|
||||
"python"_python.html command, when it is used to define a Python
|
||||
function that is invoked by the LAMMPS input script. This mode of
|
||||
using Python with LAMMPS is described above in 11.2. The variable
|
||||
lmpptr refers to the instance of LAMMPS that called the embedded
|
||||
Python interpreter. Using it as an argument to lammps() allows the
|
||||
returned Python class instance "lmp" to make calls to that instance of
|
||||
LAMMPS. See the "python"_python.html command doc page for examples
|
||||
using this syntax.
|
||||
|
||||
Note that you can create multiple LAMMPS objects in your Python
|
||||
script, and coordinate and run multiple simulations, e.g.
|
||||
|
||||
@ -572,7 +705,7 @@ Python script. Isn't ctypes amazing? :l,ule
|
||||
:line
|
||||
:line
|
||||
|
||||
11.6 Example Python scripts that use LAMMPS :link(py_6),h4
|
||||
11.8 Example Python scripts that use LAMMPS :link(py_8),h4
|
||||
|
||||
These are the Python scripts included as demos in the python/examples
|
||||
directory of the LAMMPS distribution, to illustrate the kinds of
|
||||
|
||||
@ -171,7 +171,7 @@ all good starting points if you find you need to change them for your
|
||||
machine. Put any file you edit into the src/MAKE/MINE directory and
|
||||
it will be never be touched by any LAMMPS updates.
|
||||
</P>
|
||||
<P>From within the src directory, type "make" or "gmake". You should see
|
||||
<P>>From within the src directory, type "make" or "gmake". You should see
|
||||
a list of available choices from src/MAKE and all of its
|
||||
sub-directories. If one of those has the options you want or is the
|
||||
machine you want, you can type a command like:
|
||||
@ -772,20 +772,30 @@ options.
|
||||
<A NAME = "start_3_3"></A><B><I>Packages that require extra libraries:</I></B>
|
||||
|
||||
<P>A few of the standard and user packages require additional auxiliary
|
||||
libraries. They must be compiled first, before LAMMPS is built. If
|
||||
you get a LAMMPS build error about a missing library, this is likely
|
||||
the reason. See the <A HREF = "Section_packages.html">Section_packages</A> doc page
|
||||
for a list of packages that have auxiliary libraries.
|
||||
libraries. Most of them are provided with LAMMPS, in which case they
|
||||
must be compiled first, before LAMMPS is built if you wish to include
|
||||
that package. If you get a LAMMPS build error about a missing
|
||||
library, this is likely the reason. See the
|
||||
<A HREF = "Section_packages.html">Section_packages</A> doc page for a list of
|
||||
packages that have these kinds of auxiliary libraries.
|
||||
</P>
|
||||
<P>The lib directory in the distribution has sub-directories with package
|
||||
names that correspond to the needed auxiliary libs, e.g. lib/reax.
|
||||
Each sub-directory has a README file that gives more details. Code
|
||||
for most of the auxiliary libraries is included in that directory.
|
||||
Examples are the USER-ATC and MEAM packages. A few of the
|
||||
sub-directories do not include code, but do include instructions and
|
||||
sometimes scripts that automate the process of downloading the
|
||||
auxiliary library and installing it so LAMMPS can link to it.
|
||||
Examples are the KIM and VORONOI and USER-MOLFILE packages.
|
||||
Examples are the USER-ATC and MEAM packages.
|
||||
</P>
|
||||
<P>A few of the lib sub-directories do not include code, but do include
|
||||
instructions and sometimes scripts that automate the process of
|
||||
downloading the auxiliary library and installing it so LAMMPS can link
|
||||
to it. Examples are the KIM and VORONOI and USER-MOLFILE packages.
|
||||
</P>
|
||||
<P>The lib/python directory (for the PYTHON package) contains only a
|
||||
choice of Makefile.lammps.* files. This is because no auxiliary code
|
||||
or libraries are needed, only the Python library and other system libs
|
||||
that already available on your system. However, the Makefile.lammps
|
||||
file is needed to tell the LAMMPS build which libs to use and where to
|
||||
find them.
|
||||
</P>
|
||||
<P>For libraries with provided code, the sub-directory README file
|
||||
(e.g. lib/reax/README) has instructions on how to build that library.
|
||||
|
||||
@ -165,7 +165,7 @@ all good starting points if you find you need to change them for your
|
||||
machine. Put any file you edit into the src/MAKE/MINE directory and
|
||||
it will be never be touched by any LAMMPS updates.
|
||||
|
||||
From within the src directory, type "make" or "gmake". You should see
|
||||
>From within the src directory, type "make" or "gmake". You should see
|
||||
a list of available choices from src/MAKE and all of its
|
||||
sub-directories. If one of those has the options you want or is the
|
||||
machine you want, you can type a command like:
|
||||
@ -766,20 +766,30 @@ options.
|
||||
[{Packages that require extra libraries:}] :link(start_3_3)
|
||||
|
||||
A few of the standard and user packages require additional auxiliary
|
||||
libraries. They must be compiled first, before LAMMPS is built. If
|
||||
you get a LAMMPS build error about a missing library, this is likely
|
||||
the reason. See the "Section_packages"_Section_packages.html doc page
|
||||
for a list of packages that have auxiliary libraries.
|
||||
libraries. Most of them are provided with LAMMPS, in which case they
|
||||
must be compiled first, before LAMMPS is built if you wish to include
|
||||
that package. If you get a LAMMPS build error about a missing
|
||||
library, this is likely the reason. See the
|
||||
"Section_packages"_Section_packages.html doc page for a list of
|
||||
packages that have these kinds of auxiliary libraries.
|
||||
|
||||
The lib directory in the distribution has sub-directories with package
|
||||
names that correspond to the needed auxiliary libs, e.g. lib/reax.
|
||||
Each sub-directory has a README file that gives more details. Code
|
||||
for most of the auxiliary libraries is included in that directory.
|
||||
Examples are the USER-ATC and MEAM packages. A few of the
|
||||
sub-directories do not include code, but do include instructions and
|
||||
sometimes scripts that automate the process of downloading the
|
||||
auxiliary library and installing it so LAMMPS can link to it.
|
||||
Examples are the KIM and VORONOI and USER-MOLFILE packages.
|
||||
Examples are the USER-ATC and MEAM packages.
|
||||
|
||||
A few of the lib sub-directories do not include code, but do include
|
||||
instructions and sometimes scripts that automate the process of
|
||||
downloading the auxiliary library and installing it so LAMMPS can link
|
||||
to it. Examples are the KIM and VORONOI and USER-MOLFILE packages.
|
||||
|
||||
The lib/python directory (for the PYTHON package) contains only a
|
||||
choice of Makefile.lammps.* files. This is because no auxiliary code
|
||||
or libraries are needed, only the Python library and other system libs
|
||||
that already available on your system. However, the Makefile.lammps
|
||||
file is needed to tell the LAMMPS build which libs to use and where to
|
||||
find them.
|
||||
|
||||
For libraries with provided code, the sub-directory README file
|
||||
(e.g. lib/reax/README) has instructions on how to build that library.
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
</H3>
|
||||
<P><B>Syntax:</B>
|
||||
</P>
|
||||
<P>print string keyword value:pre
|
||||
</P>
|
||||
<PRE>print string keyword value
|
||||
</PRE>
|
||||
<UL><LI>string = text string to print, which may contain variables
|
||||
|
||||
<LI>zero or more keyword/value pairs may be appended
|
||||
@ -33,13 +33,19 @@
|
||||
print Vol=$v append info.dat screen no
|
||||
print "The system volume is now $v"
|
||||
print 'The system volume is now $v'
|
||||
print """
|
||||
System volume = $v
|
||||
System temperature = $t
|
||||
"""
|
||||
</PRE>
|
||||
<P><B>Description:</B>
|
||||
</P>
|
||||
<P>Print a text string to the screen and logfile. One line of output is
|
||||
generated. The text string must be a single argument, so it should be
|
||||
enclosed in double quotes if it is more than one word. If it contains
|
||||
variables, they will be evaluated and their current values printed.
|
||||
<P>Print a text string to the screen and logfile. The text string must
|
||||
be a single argument, so if it is one line but more than one word, it
|
||||
should be enclosed in single or double quotes. To generate multiple
|
||||
lines of output, the string can be enclosed in triple quotes, as in
|
||||
the last example above. If the text string contains variables, they
|
||||
will be evaluated and their current values printed.
|
||||
</P>
|
||||
<P>If the <I>file</I> or <I>append</I> keyword is used, a filename is specified to
|
||||
which the output will be written. If <I>file</I> is used, then the
|
||||
|
||||
@ -25,14 +25,20 @@ keyword = {file} or {append} or {screen} :l
|
||||
print "Done with equilibration" file info.dat
|
||||
print Vol=$v append info.dat screen no
|
||||
print "The system volume is now $v"
|
||||
print 'The system volume is now $v' :pre
|
||||
print 'The system volume is now $v'
|
||||
print """
|
||||
System volume = $v
|
||||
System temperature = $t
|
||||
""" :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
Print a text string to the screen and logfile. One line of output is
|
||||
generated. The text string must be a single argument, so it should be
|
||||
enclosed in double quotes if it is more than one word. If it contains
|
||||
variables, they will be evaluated and their current values printed.
|
||||
Print a text string to the screen and logfile. The text string must
|
||||
be a single argument, so if it is one line but more than one word, it
|
||||
should be enclosed in single or double quotes. To generate multiple
|
||||
lines of output, the string can be enclosed in triple quotes, as in
|
||||
the last example above. If the text string contains variables, they
|
||||
will be evaluated and their current values printed.
|
||||
|
||||
If the {file} or {append} keyword is used, a filename is specified to
|
||||
which the output will be written. If {file} is used, then the
|
||||
@ -69,4 +75,3 @@ thermodynamic properties, global values calculated by a
|
||||
[Default:]
|
||||
|
||||
The option defaults are no file output and screen = yes.
|
||||
|
||||
|
||||
490
doc/python.html
Normal file
490
doc/python.html
Normal file
@ -0,0 +1,490 @@
|
||||
<HTML>
|
||||
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
|
||||
</CENTER>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<HR>
|
||||
|
||||
<H3>python command
|
||||
</H3>
|
||||
<P><B>Syntax:</B>
|
||||
</P>
|
||||
<PRE>python func keyword args ...
|
||||
</PRE>
|
||||
<UL><LI>func = name of Python function
|
||||
|
||||
<LI>one or more keyword/args pairs must be appended
|
||||
|
||||
<PRE>keyword = <I>invoke</I> or <I>input</I> or <I>return</I> or <I>format</I> or <I>file</I> or <I>here</I> or <I>exists</I>
|
||||
<I>invoke</I> arg = none = invoke the previously defined Python function
|
||||
<I>input</I> args = N i1 i2 ... iN
|
||||
N = # of inputs to function
|
||||
i1,...,iN = value, SELF, or LAMMPS variable name
|
||||
value = integer number, floating point number, or string
|
||||
SELF = reference to LAMMPS itself which can be accessed by Python function
|
||||
variable = v_name, where name = name of LAMMPS variable, e.g. v_abc
|
||||
<I>return</I> arg = varReturn
|
||||
varReturn = v_name = LAMMPS variable name which return value of function will be assigned to
|
||||
<I>format</I> arg = fstring with M characters
|
||||
M = N if no return value, where N = # of inputs
|
||||
M = N+1 if there is a return value
|
||||
fstring = each character (i,f,s,p) corresponds in order to an input or return value
|
||||
'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF
|
||||
<I>file</I> arg = filename
|
||||
filename = file of Python code, which defines func
|
||||
<I>here</I> arg = inline
|
||||
inline = one or more lines of Python code which defines func
|
||||
must be a single argument, typically enclosed between triple quotes
|
||||
<I>exists</I> arg = none = Python code has been loaded by previous python command
|
||||
</PRE>
|
||||
|
||||
</UL>
|
||||
<P><B>Examples:</B>
|
||||
</P>
|
||||
<PRE>python pForce input 2 v_x 20.0 return v_f format fff file force.py
|
||||
python pForce invoke
|
||||
</PRE>
|
||||
<PRE>python factorial input 1 myN return v_fac format ii here """
|
||||
def factorial(n):
|
||||
if n == 1: return n
|
||||
return n * factorial(n-1)
|
||||
"""
|
||||
</PRE>
|
||||
<PRE>python loop input 1 SELF return v_value format -f here """
|
||||
def loop(lmpptr,N,cut0):
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
</PRE>
|
||||
<PRE> # loop N times, increasing cutoff each time
|
||||
</PRE>
|
||||
<PRE> for i in range(N):
|
||||
cut = cut0 + i*0.1
|
||||
lmp.set_variable("cut",cut) # set a variable in LAMMPS
|
||||
lmp.command("pair_style lj/cut $<I>cut</I>") # LAMMPS commands
|
||||
lmp.command("pair_coeff * * 1.0 1.0")
|
||||
lmp.command("run 100")
|
||||
"""
|
||||
</PRE>
|
||||
<P><B>Description:</B>
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: It is not currently possible to use the
|
||||
<A HREF = "python.html">python</A> command described in this section with Python 3,
|
||||
only with Python 2. The C API changed from Python 2 to 3 and the
|
||||
LAMMPS code is not compatible with both.
|
||||
</P>
|
||||
<P>Define a Python function or execute a previously defined function.
|
||||
Arguments, including LAMMPS variables, can be passed to the function
|
||||
from the LAMMPS input script and a value returned by the Python
|
||||
function to a LAMMPS variable. The Python code for the function can
|
||||
be included directly in the input script or in a separate Python file.
|
||||
The function can be standard Python code or it can make "callbacks" to
|
||||
LAMMPS through its library interface to query or set internal values
|
||||
within LAMMPS. This is a powerful mechanism for performing complex
|
||||
operations in a LAMMPS input script that are not possible with the
|
||||
simple input script and variable syntax which LAMMPS defines. Thus
|
||||
your input script can operate more like a true programming language.
|
||||
</P>
|
||||
<P>Use of this command requires building LAMMPS with the PYTHON package
|
||||
which links to the Python library so that the Python interpreter is
|
||||
embedded in LAMMPS. More details about this process are given below.
|
||||
</P>
|
||||
<P>There are two ways to invoke a Python function once it has been
|
||||
defined. One is using the <I>invoke</I> keyword. The other is to assign
|
||||
the function to a <A HREF = "variable.html">python-style variable</A> defined in
|
||||
your input script. Whenever the variable is evaluated, it will
|
||||
execute the Python function to assign a value to the variable. Note
|
||||
that variables can be evaluated in many different ways within LAMMPS.
|
||||
They can be substituted for directly in an input script. Or they can
|
||||
be passed to various commands as arguments, so that the variable is
|
||||
evaluated during a simulation run.
|
||||
</P>
|
||||
<P>A broader overview of how Python can be used with LAMMPS is
|
||||
given in <A HREF = "Section_python.html">Section python</A>. There is an
|
||||
examples/python directory which illustrates use of the python
|
||||
command.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>The <I>func</I> setting specifies the name of the Python function. The
|
||||
code for the function is defined using the <I>file</I> or <I>here</I> keywords
|
||||
as explained below.
|
||||
</P>
|
||||
<P>If the <I>invoke</I> keyword is used, no other keywords can be used, and a
|
||||
previous python command must have defined the Python function
|
||||
referenced by this command. This invokes the Python function with the
|
||||
previously defined arguments and return value processed as explained
|
||||
below. You can invoke the function as many times as you wish in your
|
||||
input script.
|
||||
</P>
|
||||
<P>The <I>input</I> keyword defines how many arguments <I>N</I> the Python function
|
||||
expects. If it takes no arguments, then the <I>input</I> keyword should
|
||||
not be used. Each argument can be specified directly as a value,
|
||||
e.g. 6 or 3.14159 or abc (a string of characters). The type of each
|
||||
argument is specified by the <I>format</I> keyword as explained below, so
|
||||
that Python will know how to interpret the value. If the word SELF is
|
||||
used for an argument it has a special meaning. A pointer is passed to
|
||||
the Python function which it converts into a reference to LAMMPS
|
||||
itself. This enables the function to call back to LAMMPS through its
|
||||
library interface as explained below. This allows the Python function
|
||||
to query or set values internal to LAMMPS which can affect the
|
||||
subsequent execution of the input script. A LAMMPS variable can also
|
||||
be used as an argument, specified as v_name, where "name" is the name
|
||||
of the variable. Any style of LAMMPS variable can be used, as defined
|
||||
by the <A HREF = "variable.html">variable</A> command. Each time the Python
|
||||
function is invoked, the LAMMPS variable is evaluated and its value is
|
||||
passed to the Python function.
|
||||
</P>
|
||||
<P>The <I>return</I> keyword is only needed if the Python function returns a
|
||||
value. The specified <I>varReturn</I> must be of the form v_name, where
|
||||
"name" is the name of a python-style LAMMPS variable, defined by the
|
||||
<A HREF = "variable.html">variable</A> command. The Python function can return a
|
||||
numeric or string value, as specified by the <I>format</I> keyword.
|
||||
</P>
|
||||
<P>As explained on the <A HREF = "variable.html">variable</A> doc page, the definition
|
||||
of a python-style variable associates a Python function name with the
|
||||
variable. This must match the <I>func</I> setting for this command. For
|
||||
exampe these two commands would be self-consistent:
|
||||
</P>
|
||||
<PRE>variable foo python myMultiply
|
||||
python myMultiply return v_foo format f file funcs.py
|
||||
</PRE>
|
||||
<P>The two commands can appear in either order in the input script so
|
||||
long as both are specified before the Python function is invoked for
|
||||
the first time.
|
||||
</P>
|
||||
<P>The <I>format</I> keyword must be used if the <I>input</I> or <I>return</I> keyword
|
||||
is used. It defines an <I>fstring</I> with M characters, where M = sum of
|
||||
number of inputs and outputs. The order of characters corresponds to
|
||||
the N inputs, followed by the return value (if it exists). Each
|
||||
character must be one of the following: "i" for integer, "f" for
|
||||
floating point, "s" for string, or "p" for SELF. Each character
|
||||
defines the type of the corresponding input or output value of the
|
||||
Python function and affects the type conversion that is performed
|
||||
internally as data is passed back and forth between LAMMPS and Python.
|
||||
Note that it is permissible to use a <A HREF = "variable.html">python-style
|
||||
variable</A> in a LAMMPS command that allows for an
|
||||
equal-style variable as an argument, but only if the output of the
|
||||
Python function is flagged as a numeric value ("i" or "f") via the
|
||||
<I>format</I> keyword.
|
||||
</P>
|
||||
<P>Either the <I>file</I>, <I>here</I>, or <I>exists</I> keyword must be used, but only
|
||||
one of them. These keywords specify what Python code to load into the
|
||||
Python interpreter. The <I>file</I> keyword gives the name of a file,
|
||||
which should end with a ".py" suffix, which contains Python code. The
|
||||
code will be immediately loaded into and run in the "main" module of
|
||||
the Python interpreter. Note that Python code which contains a
|
||||
function definition does not "execute" the function when it is run; it
|
||||
simply defines the function so that it can be invoked later.
|
||||
</P>
|
||||
<P>The <I>here</I> keyword does the same thing, except that the Python code
|
||||
follows as a single argument to the <I>here</I> keyword. This can be done
|
||||
using triple quotes as delimiters, as in the examples above. This
|
||||
allows Python code to be listed verbatim in your input script, with
|
||||
proper indentation, blank lines, and comments, as desired. See
|
||||
<A HREF = "Section_commands.html#cmd_2">Section 3.2</A>, for an explanation of how
|
||||
triple quotes can be used as part of input script syntax.
|
||||
</P>
|
||||
<P>The <I>exists</I> keyword takes no argument. It means that Python code
|
||||
containing the required Python function defined by the <I>func</I> setting,
|
||||
is assumed to have been previously loaded by another python command.
|
||||
</P>
|
||||
<P>Note that the Python code that is loaded and run must contain a
|
||||
function with the specified <I>func</I> name. To operate properly when
|
||||
later invoked, the the function code must match the <I>input</I> and
|
||||
<I>return</I> and <I>format</I> keywords specified by the python command.
|
||||
Otherwise Python will generate an error.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>This section describes how Python code can be written to work with
|
||||
LAMMPS.
|
||||
</P>
|
||||
<P>Whether you load Python code from a file or directly from your input
|
||||
script, via the <I>file</I> and <I>here</I> keywords, the code can be identical.
|
||||
It must be indented properly as Python requires. It can contain
|
||||
comments or blank lines. If the code is in your input script, it
|
||||
cannot however contain triple-quoted Python strings, since that will
|
||||
conflict with the triple-quote parsing that the LAMMPS input script
|
||||
performs.
|
||||
</P>
|
||||
<P>All the Python code you specify via one or more python commands is
|
||||
loaded into the Python "main" module, i.e. __main__. The code can
|
||||
define global variables or statements that are outside of function
|
||||
definitions. It can contain multiple functions, only one of which
|
||||
matches the <I>func</I> setting in the python command. This means you can
|
||||
use the <I>file</I> keyword once to load several functions, and the
|
||||
<I>exists</I> keyword thereafter in subsequent python commands to access
|
||||
the other functions previously loaded.
|
||||
</P>
|
||||
<P>A Python function you define (or more generally, the code you load)
|
||||
can import other Python modules or classes, it can make calls to other
|
||||
system functions or functions you define, and it can access or modify
|
||||
global variables (in the "main" module) which will persist between
|
||||
successive function calls. The latter can be useful, for example, to
|
||||
prevent a function from being invoke multiple times per timestep by
|
||||
different commands in a LAMMPS input script that access the returned
|
||||
python-style variable associated with the function. For example,
|
||||
consider this function loaded with two global variables defined
|
||||
outside the function:
|
||||
</P>
|
||||
<PRE>nsteplast = -1
|
||||
nvaluelast = 0
|
||||
</PRE>
|
||||
<PRE>def expensive(nstep):
|
||||
global nsteplast,nvaluelast
|
||||
if nstep == nsteplast: return nvaluelast
|
||||
nsteplast = nstep
|
||||
# perform complicated calculation
|
||||
nvalue = ...
|
||||
nvaluelast = nvalue
|
||||
return nvalue
|
||||
</PRE>
|
||||
<P>Nsteplast stores the previous timestep the function was invoked
|
||||
(passed as an argument to the function). Nvaluelast stores the return
|
||||
value computed on the last function invocation. If the function is
|
||||
invoked again on the same timestep, the previous value is simply
|
||||
returned, without re-computing it. The "global" statement inside the
|
||||
Python function allows it to overwrite the global variables.
|
||||
</P>
|
||||
<P>Note that if you load Python code multiple times (via multiple python
|
||||
commands), you can overwrite previously loaded variables and functions
|
||||
if you are not careful. E.g. if the code above were loaded twice, the
|
||||
global variables would be re-initialized, which might not be what you
|
||||
want. Likewise, if a function with the same name exists in two chunks
|
||||
of Python code you load, the function loaded second will override the
|
||||
function loaded first.
|
||||
</P>
|
||||
<P>It's important to realize that if you are running LAMMPS in parallel,
|
||||
each MPI task will load the Python interpreter and execute a local
|
||||
copy of the Python function(s) you define. There is no connection
|
||||
between the Python interpreters running on different processors.
|
||||
This implies three important things.
|
||||
</P>
|
||||
<P>First, if you put a print statement in your Python function, you will
|
||||
see P copies of the output, when running on P processors. If the
|
||||
prints occur at (nearly) the same time, the P copies of the output may
|
||||
be mixed together. Welcome to the world of parallel programming and
|
||||
debugging.
|
||||
</P>
|
||||
<P>Second, if your Python code loads modules that are not pre-loaded by
|
||||
the Python library, then it will load the module from disk. This may
|
||||
be a bottleneck if 1000s of processors try to load a module at the
|
||||
same time. On some large supercomputers, loading of modules from disk
|
||||
by Python may be disabled. In this case you would need to pre-build a
|
||||
Python library that has the required modules pre-loaded and link
|
||||
LAMMPS with that library.
|
||||
</P>
|
||||
<P>Third, if your Python code calls back to LAMMPS (discussed in the
|
||||
next section) and causes LAMMPS to perform an MPI operation requires
|
||||
global communication (e.g. via MPI_Allreduce), such as computing the
|
||||
global temperature of the system, then you must insure all your Python
|
||||
functions (running independently on different processors) call back to
|
||||
LAMMPS. Otherwise the code may hang.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>Your Python function can "call back" to LAMMPS through its
|
||||
library interface, if you use the SELF input to pass Python
|
||||
a pointer to LAMMPS. The mechanism for doing this in your
|
||||
Python function is as follows:
|
||||
</P>
|
||||
<PRE>def foo(lmpptr,...):
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
lmp.command('print "Hello from inside Python"')
|
||||
...
|
||||
</PRE>
|
||||
<P>The function definition must include a variable (lmpptr in this case)
|
||||
which corresponds to SELF in the python command. The first line of
|
||||
the function imports the Python module lammps.py in the python dir of
|
||||
the distribution. The second line creates a Python object "lmp" which
|
||||
wraps the instance of LAMMPS that called the function. The
|
||||
"ptr=lmpptr" argument is what makes that happen. The thrid line
|
||||
invokes the command() function in the LAMMPS library interface. It
|
||||
takes a single string argument which is a LAMMPS input script command
|
||||
for LAMMPS to execute, the same as if it appeared in your input
|
||||
script. In this case, LAMMPS should output
|
||||
</P>
|
||||
<PRE>Hello from inside Python
|
||||
</PRE>
|
||||
<P>to the screen and log file. Note that since the LAMMPS print command
|
||||
itself takes a string in quotes as its argument, the Python string
|
||||
must be delimited with a different style of quotes.
|
||||
</P>
|
||||
<P><A HREF = "Section_python.html#py_7">Section 11.7</A> describes the syntax for how
|
||||
Python wraps the various functions included in the LAMMPS library
|
||||
interface.
|
||||
</P>
|
||||
<P>A more interesting example is in the examples/python/in.python script
|
||||
which loads and runs the following function from examples/python/funcs.py:
|
||||
</P>
|
||||
<PRE>def loop(N,cut0,thresh,lmpptr):
|
||||
print "LOOP ARGS",N,cut0,thresh,lmpptr
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
natoms = lmp.get_natoms()
|
||||
</PRE>
|
||||
<PRE> for i in range(N):
|
||||
cut = cut0 + i*0.1
|
||||
</PRE>
|
||||
<PRE> lmp.set_variable("cut",cut) # set a variable in LAMMPS
|
||||
lmp.command("pair_style lj/cut $<I>cut</I>") # LAMMPS command
|
||||
#lmp.command("pair_style lj/cut %d" % cut) # LAMMPS command option
|
||||
</PRE>
|
||||
<PRE> lmp.command("pair_coeff * * 1.0 1.0") # ditto
|
||||
lmp.command("run 10") # ditto
|
||||
pe = lmp.extract_compute("thermo_pe",0,0) # extract total PE from LAMMPS
|
||||
print "PE",pe/natoms,thresh
|
||||
if pe/natoms < thresh: return
|
||||
</PRE>
|
||||
<P>with these input script commands:
|
||||
</P>
|
||||
<PRE>python loop input 4 10 1.0 -4.0 SELF format iffp file funcs.py
|
||||
python loop invoke
|
||||
</PRE>
|
||||
<P>This has the effect of looping over a series of 10 short runs (10
|
||||
timesteps each) where the pair style cutoff is increased from a value
|
||||
of 1.0 in distance units, in increments of 0.1. The looping stops
|
||||
when the per-atom potential energy falls below a threshhold of -4.0 in
|
||||
energy units. More generally, Python can be used to implement a loop
|
||||
with complex logic, much more so than can be created using the LAMMPS
|
||||
<A HREF = "jump.html">jump</A> and <A HREF = "if.html">if</A> commands.
|
||||
</P>
|
||||
<P>Several LAMMPS library functions are called from the loop function.
|
||||
Get_natoms() returns the number of atoms in the simulation, so that it
|
||||
can be used to normalize the potential energy that is returned by
|
||||
extract_compute() for the "thermo_pe" compute that is defined by
|
||||
default for LAMMPS thermodynamic output. Set_variable() sets the
|
||||
value of a string variable defined in LAMMPS. This library function
|
||||
is a useful way for a Python function to return multiple values to
|
||||
LAMMPS, more than the single value that can be passed back via a
|
||||
return statement. This cutoff value in the "cut" variable is then
|
||||
substituted (by LAMMPS) in the pair_style command that is executed
|
||||
next. Alternatively, the "LAMMPS command option" line could be used
|
||||
in place of the 2 preceeding lines, to have Python insert the value
|
||||
into the LAMMPS command string.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: When using the callback mechanism just described,
|
||||
recognize that there are some operations you should not attempt
|
||||
because LAMMPS cannot execute them correctly. If the Python function
|
||||
is invoked between runs in the LAMMPS input script, then it should be
|
||||
OK to invoke any LAMMPS input script command via the library interface
|
||||
command() or file() functions, so long as the command would work if it
|
||||
were executed in the LAMMPS input script directly at the same point.
|
||||
</P>
|
||||
<P>However, a Python function can also be invoked during a run, whenever
|
||||
an associated LAMMPS variable it is assigned to is evaluted. If the
|
||||
variable is an input argument to another LAMMPS command (e.g. <A HREF = "fix_setforce.html">fix
|
||||
setforce</A>), then the Python function will be invoked
|
||||
inside the class for that command, in one of its methods that is
|
||||
invoked in the middle of a timestep. You cannot execute arbitrary
|
||||
input script commands from the Python function (again, via the
|
||||
command() or file() functions) at that point in the run and expect it
|
||||
to work. Other library functions such as those that invoke computes
|
||||
or other variables may have hidden side effects as well. In these
|
||||
cases, LAMMPS has no simple way to check that something illogical is
|
||||
being attempted.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>If you run Python code directly on your workstation, either
|
||||
interactively or by using Python to launch a Python script stored in a
|
||||
file, and your code has an error, you will typically see informative
|
||||
error messages. That is not the case when you run Python code from
|
||||
LAMMPS using an embedded Python interpreter. The code will typically
|
||||
fail silently. LAMMPS will catch some errors but cannot tell you
|
||||
where in the Python code the problem occurred. For example, if the
|
||||
Python code cannot be loaded and run because it has syntax or other
|
||||
logic errors, you may get an error from Python pointing to the
|
||||
offending line, or you may get one of these generic errors from
|
||||
LAMMPS:
|
||||
</P>
|
||||
<PRE>Could not process Python file
|
||||
Could not process Python string
|
||||
</PRE>
|
||||
<P>When the Python function is invoked, if it does not return properly,
|
||||
you will typically get this generic error from LAMMPS:
|
||||
</P>
|
||||
<PRE>Python function evaluation failed
|
||||
</PRE>
|
||||
<P>Here are three suggestions for debugging your Python code while
|
||||
running it under LAMMPS.
|
||||
</P>
|
||||
<P>First, don't run it under LAMMPS, at least to start with! Debug it
|
||||
using plain Python. Load and invoke your function, pass it arguments,
|
||||
check return values, etc.
|
||||
</P>
|
||||
<P>Second, add Python print statements to the function to check how far
|
||||
it gets and intermediate values it calculates. See the discussion
|
||||
above about printing from Python when running in parallel.
|
||||
</P>
|
||||
<P>Third, use Python exception handling. For example, say this statement
|
||||
in your Python function is failing, because you have not initialized the
|
||||
variable foo:
|
||||
</P>
|
||||
<PRE>foo += 1
|
||||
</PRE>
|
||||
<P>If you put one (or more) statements inside a "try" statement,
|
||||
like this:
|
||||
</P>
|
||||
<PRE>import exceptions
|
||||
print "Inside simple function"
|
||||
try:
|
||||
foo += 1 # one or more statements here
|
||||
except Exception, e:
|
||||
print "FOO error:",e
|
||||
</PRE>
|
||||
<P>then you will get this message printed to the screen:
|
||||
</P>
|
||||
<PRE>FOO error: local variable 'foo' referenced before assignment
|
||||
</PRE>
|
||||
<P>If there is no error in the try statements, then nothing is printed.
|
||||
Either way the function continues on (unless you put a return or
|
||||
sys.exit() in the except clause).
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P><B>Restrictions:</B>
|
||||
</P>
|
||||
<P>This command is part of the PYTHON package. It is only enabled if
|
||||
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
|
||||
LAMMPS</A> section for more info.
|
||||
</P>
|
||||
<P>Building LAMMPS with the PYTHON package will link LAMMPS with the
|
||||
Python library on your system. Settings to enable this are in the
|
||||
lib/python/Makefile.lammps file. See the lib/python/README file for
|
||||
information on those settings.
|
||||
</P>
|
||||
<P>If you use Python code which calls back to LAMMPS, via the SELF input
|
||||
argument explained above, there is an extra step required when
|
||||
building LAMMPS. LAMMPS must also be built as a shared library and
|
||||
your Python function must be able to to load the Python module in
|
||||
python/lammps.py that wraps the LAMMPS library interface. These are
|
||||
the same steps required to use Python by itself to wrap LAMMPS.
|
||||
Details on these steps are explained in <A HREF = "Section.python.html">Section
|
||||
python</A>. Note that it is important that the
|
||||
stand-alone LAMMPS executable and the LAMMPS shared library be
|
||||
consistent (built from the same source code files) in order for this
|
||||
to work. If the two have been built at different times using
|
||||
different source files, problems may occur.
|
||||
</P>
|
||||
<P>As described above, you can use the python command to invoke a Python
|
||||
function which calls back to LAMMPS through its Python-wrapped library
|
||||
interface. However you cannot do the opposite. I.e. you cannot call
|
||||
LAMMPS from Python and invoke the python command to "callback" to
|
||||
Python and execute a Python function. LAMMPS will generate an error
|
||||
if you try to do that. Note that we think there actually should be a
|
||||
way to do that, but haven't yet been able to figure out how to do it
|
||||
successfully.
|
||||
</P>
|
||||
<P><B>Related commands:</B>
|
||||
</P>
|
||||
<P><A HREF = "shell.html">shell</A>, <A HREF = "variable.html">variable</A>
|
||||
</P>
|
||||
<P><B>Default:</B> none
|
||||
</P>
|
||||
</HTML>
|
||||
482
doc/python.txt
Normal file
482
doc/python.txt
Normal file
@ -0,0 +1,482 @@
|
||||
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
|
||||
|
||||
:link(lws,http://lammps.sandia.gov)
|
||||
:link(ld,Manual.html)
|
||||
:link(lc,Section_commands.html#comm)
|
||||
|
||||
:line
|
||||
|
||||
python command :h3
|
||||
|
||||
[Syntax:]
|
||||
|
||||
python func keyword args ... :pre
|
||||
|
||||
func = name of Python function :ulb,l
|
||||
one or more keyword/args pairs must be appended :l
|
||||
keyword = {invoke} or {input} or {return} or {format} or {file} or {here} or {exists}
|
||||
{invoke} arg = none = invoke the previously defined Python function
|
||||
{input} args = N i1 i2 ... iN
|
||||
N = # of inputs to function
|
||||
i1,...,iN = value, SELF, or LAMMPS variable name
|
||||
value = integer number, floating point number, or string
|
||||
SELF = reference to LAMMPS itself which can be accessed by Python function
|
||||
variable = v_name, where name = name of LAMMPS variable, e.g. v_abc
|
||||
{return} arg = varReturn
|
||||
varReturn = v_name = LAMMPS variable name which return value of function will be assigned to
|
||||
{format} arg = fstring with M characters
|
||||
M = N if no return value, where N = # of inputs
|
||||
M = N+1 if there is a return value
|
||||
fstring = each character (i,f,s,p) corresponds in order to an input or return value
|
||||
'i' = integer, 'f' = floating point, 's' = string, 'p' = SELF
|
||||
{file} arg = filename
|
||||
filename = file of Python code, which defines func
|
||||
{here} arg = inline
|
||||
inline = one or more lines of Python code which defines func
|
||||
must be a single argument, typically enclosed between triple quotes
|
||||
{exists} arg = none = Python code has been loaded by previous python command :pre
|
||||
:ule
|
||||
|
||||
[Examples:]
|
||||
|
||||
python pForce input 2 v_x 20.0 return v_f format fff file force.py
|
||||
python pForce invoke :pre
|
||||
|
||||
python factorial input 1 myN return v_fac format ii here """
|
||||
def factorial(n):
|
||||
if n == 1: return n
|
||||
return n * factorial(n-1)
|
||||
""" :pre
|
||||
|
||||
python loop input 1 SELF return v_value format -f here """
|
||||
def loop(lmpptr,N,cut0):
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr) :pre
|
||||
|
||||
# loop N times, increasing cutoff each time :pre
|
||||
|
||||
for i in range(N):
|
||||
cut = cut0 + i*0.1
|
||||
lmp.set_variable("cut",cut) # set a variable in LAMMPS
|
||||
lmp.command("pair_style lj/cut ${cut}") # LAMMPS commands
|
||||
lmp.command("pair_coeff * * 1.0 1.0")
|
||||
lmp.command("run 100")
|
||||
""" :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
IMPORTANT NOTE: It is not currently possible to use the
|
||||
"python"_python.html command described in this section with Python 3,
|
||||
only with Python 2. The C API changed from Python 2 to 3 and the
|
||||
LAMMPS code is not compatible with both.
|
||||
|
||||
Define a Python function or execute a previously defined function.
|
||||
Arguments, including LAMMPS variables, can be passed to the function
|
||||
from the LAMMPS input script and a value returned by the Python
|
||||
function to a LAMMPS variable. The Python code for the function can
|
||||
be included directly in the input script or in a separate Python file.
|
||||
The function can be standard Python code or it can make "callbacks" to
|
||||
LAMMPS through its library interface to query or set internal values
|
||||
within LAMMPS. This is a powerful mechanism for performing complex
|
||||
operations in a LAMMPS input script that are not possible with the
|
||||
simple input script and variable syntax which LAMMPS defines. Thus
|
||||
your input script can operate more like a true programming language.
|
||||
|
||||
Use of this command requires building LAMMPS with the PYTHON package
|
||||
which links to the Python library so that the Python interpreter is
|
||||
embedded in LAMMPS. More details about this process are given below.
|
||||
|
||||
There are two ways to invoke a Python function once it has been
|
||||
defined. One is using the {invoke} keyword. The other is to assign
|
||||
the function to a "python-style variable"_variable.html defined in
|
||||
your input script. Whenever the variable is evaluated, it will
|
||||
execute the Python function to assign a value to the variable. Note
|
||||
that variables can be evaluated in many different ways within LAMMPS.
|
||||
They can be substituted for directly in an input script. Or they can
|
||||
be passed to various commands as arguments, so that the variable is
|
||||
evaluated during a simulation run.
|
||||
|
||||
A broader overview of how Python can be used with LAMMPS is
|
||||
given in "Section python"_Section_python.html. There is an
|
||||
examples/python directory which illustrates use of the python
|
||||
command.
|
||||
|
||||
:line
|
||||
|
||||
The {func} setting specifies the name of the Python function. The
|
||||
code for the function is defined using the {file} or {here} keywords
|
||||
as explained below.
|
||||
|
||||
If the {invoke} keyword is used, no other keywords can be used, and a
|
||||
previous python command must have defined the Python function
|
||||
referenced by this command. This invokes the Python function with the
|
||||
previously defined arguments and return value processed as explained
|
||||
below. You can invoke the function as many times as you wish in your
|
||||
input script.
|
||||
|
||||
The {input} keyword defines how many arguments {N} the Python function
|
||||
expects. If it takes no arguments, then the {input} keyword should
|
||||
not be used. Each argument can be specified directly as a value,
|
||||
e.g. 6 or 3.14159 or abc (a string of characters). The type of each
|
||||
argument is specified by the {format} keyword as explained below, so
|
||||
that Python will know how to interpret the value. If the word SELF is
|
||||
used for an argument it has a special meaning. A pointer is passed to
|
||||
the Python function which it converts into a reference to LAMMPS
|
||||
itself. This enables the function to call back to LAMMPS through its
|
||||
library interface as explained below. This allows the Python function
|
||||
to query or set values internal to LAMMPS which can affect the
|
||||
subsequent execution of the input script. A LAMMPS variable can also
|
||||
be used as an argument, specified as v_name, where "name" is the name
|
||||
of the variable. Any style of LAMMPS variable can be used, as defined
|
||||
by the "variable"_variable.html command. Each time the Python
|
||||
function is invoked, the LAMMPS variable is evaluated and its value is
|
||||
passed to the Python function.
|
||||
|
||||
The {return} keyword is only needed if the Python function returns a
|
||||
value. The specified {varReturn} must be of the form v_name, where
|
||||
"name" is the name of a python-style LAMMPS variable, defined by the
|
||||
"variable"_variable.html command. The Python function can return a
|
||||
numeric or string value, as specified by the {format} keyword.
|
||||
|
||||
As explained on the "variable"_variable.html doc page, the definition
|
||||
of a python-style variable associates a Python function name with the
|
||||
variable. This must match the {func} setting for this command. For
|
||||
exampe these two commands would be self-consistent:
|
||||
|
||||
variable foo python myMultiply
|
||||
python myMultiply return v_foo format f file funcs.py :pre
|
||||
|
||||
The two commands can appear in either order in the input script so
|
||||
long as both are specified before the Python function is invoked for
|
||||
the first time.
|
||||
|
||||
The {format} keyword must be used if the {input} or {return} keyword
|
||||
is used. It defines an {fstring} with M characters, where M = sum of
|
||||
number of inputs and outputs. The order of characters corresponds to
|
||||
the N inputs, followed by the return value (if it exists). Each
|
||||
character must be one of the following: "i" for integer, "f" for
|
||||
floating point, "s" for string, or "p" for SELF. Each character
|
||||
defines the type of the corresponding input or output value of the
|
||||
Python function and affects the type conversion that is performed
|
||||
internally as data is passed back and forth between LAMMPS and Python.
|
||||
Note that it is permissible to use a "python-style
|
||||
variable"_variable.html in a LAMMPS command that allows for an
|
||||
equal-style variable as an argument, but only if the output of the
|
||||
Python function is flagged as a numeric value ("i" or "f") via the
|
||||
{format} keyword.
|
||||
|
||||
Either the {file}, {here}, or {exists} keyword must be used, but only
|
||||
one of them. These keywords specify what Python code to load into the
|
||||
Python interpreter. The {file} keyword gives the name of a file,
|
||||
which should end with a ".py" suffix, which contains Python code. The
|
||||
code will be immediately loaded into and run in the "main" module of
|
||||
the Python interpreter. Note that Python code which contains a
|
||||
function definition does not "execute" the function when it is run; it
|
||||
simply defines the function so that it can be invoked later.
|
||||
|
||||
The {here} keyword does the same thing, except that the Python code
|
||||
follows as a single argument to the {here} keyword. This can be done
|
||||
using triple quotes as delimiters, as in the examples above. This
|
||||
allows Python code to be listed verbatim in your input script, with
|
||||
proper indentation, blank lines, and comments, as desired. See
|
||||
"Section 3.2"_Section_commands.html#cmd_2, for an explanation of how
|
||||
triple quotes can be used as part of input script syntax.
|
||||
|
||||
The {exists} keyword takes no argument. It means that Python code
|
||||
containing the required Python function defined by the {func} setting,
|
||||
is assumed to have been previously loaded by another python command.
|
||||
|
||||
Note that the Python code that is loaded and run must contain a
|
||||
function with the specified {func} name. To operate properly when
|
||||
later invoked, the the function code must match the {input} and
|
||||
{return} and {format} keywords specified by the python command.
|
||||
Otherwise Python will generate an error.
|
||||
|
||||
:line
|
||||
|
||||
This section describes how Python code can be written to work with
|
||||
LAMMPS.
|
||||
|
||||
Whether you load Python code from a file or directly from your input
|
||||
script, via the {file} and {here} keywords, the code can be identical.
|
||||
It must be indented properly as Python requires. It can contain
|
||||
comments or blank lines. If the code is in your input script, it
|
||||
cannot however contain triple-quoted Python strings, since that will
|
||||
conflict with the triple-quote parsing that the LAMMPS input script
|
||||
performs.
|
||||
|
||||
All the Python code you specify via one or more python commands is
|
||||
loaded into the Python "main" module, i.e. __main__. The code can
|
||||
define global variables or statements that are outside of function
|
||||
definitions. It can contain multiple functions, only one of which
|
||||
matches the {func} setting in the python command. This means you can
|
||||
use the {file} keyword once to load several functions, and the
|
||||
{exists} keyword thereafter in subsequent python commands to access
|
||||
the other functions previously loaded.
|
||||
|
||||
A Python function you define (or more generally, the code you load)
|
||||
can import other Python modules or classes, it can make calls to other
|
||||
system functions or functions you define, and it can access or modify
|
||||
global variables (in the "main" module) which will persist between
|
||||
successive function calls. The latter can be useful, for example, to
|
||||
prevent a function from being invoke multiple times per timestep by
|
||||
different commands in a LAMMPS input script that access the returned
|
||||
python-style variable associated with the function. For example,
|
||||
consider this function loaded with two global variables defined
|
||||
outside the function:
|
||||
|
||||
nsteplast = -1
|
||||
nvaluelast = 0 :pre
|
||||
|
||||
def expensive(nstep):
|
||||
global nsteplast,nvaluelast
|
||||
if nstep == nsteplast: return nvaluelast
|
||||
nsteplast = nstep
|
||||
# perform complicated calculation
|
||||
nvalue = ...
|
||||
nvaluelast = nvalue
|
||||
return nvalue :pre
|
||||
|
||||
Nsteplast stores the previous timestep the function was invoked
|
||||
(passed as an argument to the function). Nvaluelast stores the return
|
||||
value computed on the last function invocation. If the function is
|
||||
invoked again on the same timestep, the previous value is simply
|
||||
returned, without re-computing it. The "global" statement inside the
|
||||
Python function allows it to overwrite the global variables.
|
||||
|
||||
Note that if you load Python code multiple times (via multiple python
|
||||
commands), you can overwrite previously loaded variables and functions
|
||||
if you are not careful. E.g. if the code above were loaded twice, the
|
||||
global variables would be re-initialized, which might not be what you
|
||||
want. Likewise, if a function with the same name exists in two chunks
|
||||
of Python code you load, the function loaded second will override the
|
||||
function loaded first.
|
||||
|
||||
It's important to realize that if you are running LAMMPS in parallel,
|
||||
each MPI task will load the Python interpreter and execute a local
|
||||
copy of the Python function(s) you define. There is no connection
|
||||
between the Python interpreters running on different processors.
|
||||
This implies three important things.
|
||||
|
||||
First, if you put a print statement in your Python function, you will
|
||||
see P copies of the output, when running on P processors. If the
|
||||
prints occur at (nearly) the same time, the P copies of the output may
|
||||
be mixed together. Welcome to the world of parallel programming and
|
||||
debugging.
|
||||
|
||||
Second, if your Python code loads modules that are not pre-loaded by
|
||||
the Python library, then it will load the module from disk. This may
|
||||
be a bottleneck if 1000s of processors try to load a module at the
|
||||
same time. On some large supercomputers, loading of modules from disk
|
||||
by Python may be disabled. In this case you would need to pre-build a
|
||||
Python library that has the required modules pre-loaded and link
|
||||
LAMMPS with that library.
|
||||
|
||||
Third, if your Python code calls back to LAMMPS (discussed in the
|
||||
next section) and causes LAMMPS to perform an MPI operation requires
|
||||
global communication (e.g. via MPI_Allreduce), such as computing the
|
||||
global temperature of the system, then you must insure all your Python
|
||||
functions (running independently on different processors) call back to
|
||||
LAMMPS. Otherwise the code may hang.
|
||||
|
||||
:line
|
||||
|
||||
Your Python function can "call back" to LAMMPS through its
|
||||
library interface, if you use the SELF input to pass Python
|
||||
a pointer to LAMMPS. The mechanism for doing this in your
|
||||
Python function is as follows:
|
||||
|
||||
def foo(lmpptr,...):
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
lmp.command('print "Hello from inside Python"')
|
||||
... :pre
|
||||
|
||||
The function definition must include a variable (lmpptr in this case)
|
||||
which corresponds to SELF in the python command. The first line of
|
||||
the function imports the Python module lammps.py in the python dir of
|
||||
the distribution. The second line creates a Python object "lmp" which
|
||||
wraps the instance of LAMMPS that called the function. The
|
||||
"ptr=lmpptr" argument is what makes that happen. The thrid line
|
||||
invokes the command() function in the LAMMPS library interface. It
|
||||
takes a single string argument which is a LAMMPS input script command
|
||||
for LAMMPS to execute, the same as if it appeared in your input
|
||||
script. In this case, LAMMPS should output
|
||||
|
||||
Hello from inside Python :pre
|
||||
|
||||
to the screen and log file. Note that since the LAMMPS print command
|
||||
itself takes a string in quotes as its argument, the Python string
|
||||
must be delimited with a different style of quotes.
|
||||
|
||||
"Section 11.7"_Section_python.html#py_7 describes the syntax for how
|
||||
Python wraps the various functions included in the LAMMPS library
|
||||
interface.
|
||||
|
||||
A more interesting example is in the examples/python/in.python script
|
||||
which loads and runs the following function from examples/python/funcs.py:
|
||||
|
||||
def loop(N,cut0,thresh,lmpptr):
|
||||
print "LOOP ARGS",N,cut0,thresh,lmpptr
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
natoms = lmp.get_natoms() :pre
|
||||
|
||||
for i in range(N):
|
||||
cut = cut0 + i*0.1 :pre
|
||||
|
||||
lmp.set_variable("cut",cut) # set a variable in LAMMPS
|
||||
lmp.command("pair_style lj/cut ${cut}") # LAMMPS command
|
||||
#lmp.command("pair_style lj/cut %d" % cut) # LAMMPS command option :pre
|
||||
|
||||
lmp.command("pair_coeff * * 1.0 1.0") # ditto
|
||||
lmp.command("run 10") # ditto
|
||||
pe = lmp.extract_compute("thermo_pe",0,0) # extract total PE from LAMMPS
|
||||
print "PE",pe/natoms,thresh
|
||||
if pe/natoms < thresh: return :pre
|
||||
|
||||
with these input script commands:
|
||||
|
||||
python loop input 4 10 1.0 -4.0 SELF format iffp file funcs.py
|
||||
python loop invoke :pre
|
||||
|
||||
This has the effect of looping over a series of 10 short runs (10
|
||||
timesteps each) where the pair style cutoff is increased from a value
|
||||
of 1.0 in distance units, in increments of 0.1. The looping stops
|
||||
when the per-atom potential energy falls below a threshhold of -4.0 in
|
||||
energy units. More generally, Python can be used to implement a loop
|
||||
with complex logic, much more so than can be created using the LAMMPS
|
||||
"jump"_jump.html and "if"_if.html commands.
|
||||
|
||||
Several LAMMPS library functions are called from the loop function.
|
||||
Get_natoms() returns the number of atoms in the simulation, so that it
|
||||
can be used to normalize the potential energy that is returned by
|
||||
extract_compute() for the "thermo_pe" compute that is defined by
|
||||
default for LAMMPS thermodynamic output. Set_variable() sets the
|
||||
value of a string variable defined in LAMMPS. This library function
|
||||
is a useful way for a Python function to return multiple values to
|
||||
LAMMPS, more than the single value that can be passed back via a
|
||||
return statement. This cutoff value in the "cut" variable is then
|
||||
substituted (by LAMMPS) in the pair_style command that is executed
|
||||
next. Alternatively, the "LAMMPS command option" line could be used
|
||||
in place of the 2 preceeding lines, to have Python insert the value
|
||||
into the LAMMPS command string.
|
||||
|
||||
IMPORTANT NOTE: When using the callback mechanism just described,
|
||||
recognize that there are some operations you should not attempt
|
||||
because LAMMPS cannot execute them correctly. If the Python function
|
||||
is invoked between runs in the LAMMPS input script, then it should be
|
||||
OK to invoke any LAMMPS input script command via the library interface
|
||||
command() or file() functions, so long as the command would work if it
|
||||
were executed in the LAMMPS input script directly at the same point.
|
||||
|
||||
However, a Python function can also be invoked during a run, whenever
|
||||
an associated LAMMPS variable it is assigned to is evaluted. If the
|
||||
variable is an input argument to another LAMMPS command (e.g. "fix
|
||||
setforce"_fix_setforce.html), then the Python function will be invoked
|
||||
inside the class for that command, in one of its methods that is
|
||||
invoked in the middle of a timestep. You cannot execute arbitrary
|
||||
input script commands from the Python function (again, via the
|
||||
command() or file() functions) at that point in the run and expect it
|
||||
to work. Other library functions such as those that invoke computes
|
||||
or other variables may have hidden side effects as well. In these
|
||||
cases, LAMMPS has no simple way to check that something illogical is
|
||||
being attempted.
|
||||
|
||||
:line
|
||||
|
||||
If you run Python code directly on your workstation, either
|
||||
interactively or by using Python to launch a Python script stored in a
|
||||
file, and your code has an error, you will typically see informative
|
||||
error messages. That is not the case when you run Python code from
|
||||
LAMMPS using an embedded Python interpreter. The code will typically
|
||||
fail silently. LAMMPS will catch some errors but cannot tell you
|
||||
where in the Python code the problem occurred. For example, if the
|
||||
Python code cannot be loaded and run because it has syntax or other
|
||||
logic errors, you may get an error from Python pointing to the
|
||||
offending line, or you may get one of these generic errors from
|
||||
LAMMPS:
|
||||
|
||||
Could not process Python file
|
||||
Could not process Python string :pre
|
||||
|
||||
When the Python function is invoked, if it does not return properly,
|
||||
you will typically get this generic error from LAMMPS:
|
||||
|
||||
Python function evaluation failed :pre
|
||||
|
||||
Here are three suggestions for debugging your Python code while
|
||||
running it under LAMMPS.
|
||||
|
||||
First, don't run it under LAMMPS, at least to start with! Debug it
|
||||
using plain Python. Load and invoke your function, pass it arguments,
|
||||
check return values, etc.
|
||||
|
||||
Second, add Python print statements to the function to check how far
|
||||
it gets and intermediate values it calculates. See the discussion
|
||||
above about printing from Python when running in parallel.
|
||||
|
||||
Third, use Python exception handling. For example, say this statement
|
||||
in your Python function is failing, because you have not initialized the
|
||||
variable foo:
|
||||
|
||||
foo += 1 :pre
|
||||
|
||||
If you put one (or more) statements inside a "try" statement,
|
||||
like this:
|
||||
|
||||
import exceptions
|
||||
print "Inside simple function"
|
||||
try:
|
||||
foo += 1 # one or more statements here
|
||||
except Exception, e:
|
||||
print "FOO error:",e :pre
|
||||
|
||||
then you will get this message printed to the screen:
|
||||
|
||||
FOO error: local variable 'foo' referenced before assignment :pre
|
||||
|
||||
If there is no error in the try statements, then nothing is printed.
|
||||
Either way the function continues on (unless you put a return or
|
||||
sys.exit() in the except clause).
|
||||
|
||||
:line
|
||||
|
||||
[Restrictions:]
|
||||
|
||||
This command is part of the PYTHON package. It is only enabled if
|
||||
LAMMPS was built with that package. See the "Making
|
||||
LAMMPS"_Section_start.html#start_3 section for more info.
|
||||
|
||||
Building LAMMPS with the PYTHON package will link LAMMPS with the
|
||||
Python library on your system. Settings to enable this are in the
|
||||
lib/python/Makefile.lammps file. See the lib/python/README file for
|
||||
information on those settings.
|
||||
|
||||
If you use Python code which calls back to LAMMPS, via the SELF input
|
||||
argument explained above, there is an extra step required when
|
||||
building LAMMPS. LAMMPS must also be built as a shared library and
|
||||
your Python function must be able to to load the Python module in
|
||||
python/lammps.py that wraps the LAMMPS library interface. These are
|
||||
the same steps required to use Python by itself to wrap LAMMPS.
|
||||
Details on these steps are explained in "Section
|
||||
python"_Section.python.html. Note that it is important that the
|
||||
stand-alone LAMMPS executable and the LAMMPS shared library be
|
||||
consistent (built from the same source code files) in order for this
|
||||
to work. If the two have been built at different times using
|
||||
different source files, problems may occur.
|
||||
|
||||
As described above, you can use the python command to invoke a Python
|
||||
function which calls back to LAMMPS through its Python-wrapped library
|
||||
interface. However you cannot do the opposite. I.e. you cannot call
|
||||
LAMMPS from Python and invoke the python command to "callback" to
|
||||
Python and execute a Python function. LAMMPS will generate an error
|
||||
if you try to do that. Note that we think there actually should be a
|
||||
way to do that, but haven't yet been able to figure out how to do it
|
||||
successfully.
|
||||
|
||||
[Related commands:]
|
||||
|
||||
"shell"_shell.html, "variable"_variable.html
|
||||
|
||||
[Default:] none
|
||||
@ -17,7 +17,8 @@
|
||||
</PRE>
|
||||
<UL><LI>name = name of variable to define
|
||||
|
||||
<LI>style = <I>delete</I> or <I>index</I> or <I>loop</I> or <I>world</I> or <I>universe</I> or <I>uloop</I> or <I>string</I> or <I>format</I> or <I>getenv</I> or <I>file</I> or <I>atomfile</I> or <I>equal</I> or <I>atom</I>
|
||||
<LI>style = <I>delete</I> or <I>index</I> or <I>loop</I> or <I>world</I> or <I>universe</I> or
|
||||
<I>uloop</I> or <I>string</I> or <I>format</I> or <I>getenv</I> or <I>file</I> or <I>atomfile</I> or <I>python</I> or <I>equal</I> or <I>atom</I>
|
||||
|
||||
<PRE> <I>delete</I> = no args
|
||||
<I>index</I> args = one or more strings
|
||||
@ -45,6 +46,7 @@
|
||||
<I>getenv</I> arg = one string
|
||||
<I>file</I> arg = filename
|
||||
<I>atomfile</I> arg = filename
|
||||
<I>python</I> arg = function
|
||||
<I>equal</I> or <I>atom</I> args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references
|
||||
numbers = 0.0, 100, -5.4, 2.8e-4, etc
|
||||
constants = PI
|
||||
@ -87,6 +89,7 @@ variable b equal xcm(mol1,x)/2.0
|
||||
variable b equal c_myTemp
|
||||
variable b atom x*y/vol
|
||||
variable foo string myfile
|
||||
variable myPy python increase
|
||||
variable f file values.txt
|
||||
variable temp world 300.0 310.0 320.0 ${Tfinal}
|
||||
variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
@ -116,7 +119,9 @@ command) or used as input to an averaging fix (see the <A HREF = "fix_ave_spatia
|
||||
ave/spatial</A> and <A HREF = "fix_ave_atom.html">fix ave/atom</A>
|
||||
commands). Variables of style <I>atomfile</I> can be used anywhere in an
|
||||
input script that atom-style variables are used; they get their
|
||||
per-atom values from a file rather than from a formula.
|
||||
per-atom values from a file rather than from a formula. Variables can
|
||||
be hooked to Python functions using code you provide, so that the
|
||||
variable gets its value from the evaluation of the Python code.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: As discussed in <A HREF = "Section_commands.html#cmd_2">Section
|
||||
3.2</A> of the manual, an input script can
|
||||
@ -138,11 +143,31 @@ different values when it is evaluated at different times during a
|
||||
simulation.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: When the input script line is encountered that defines
|
||||
a variable of style <I>equal</I> or <I>atom</I> that contains a formula, the
|
||||
formula is NOT immediately evaluated and the result stored. See the
|
||||
discussion below about "Immediate Evaluation of Variables" if you want
|
||||
to do this. This is also true of the <I>format</I> style variable
|
||||
since it evaluates another variable when it is invoked.
|
||||
a variable of style <I>equal</I> or <I>atom</I> or <I>python</I> that contains a
|
||||
formula or Python code, the formula is NOT immediately evaluated and
|
||||
the result stored. See the discussion below about "Immediate
|
||||
Evaluation of Variables" if you want to do this. This is also true of
|
||||
the <I>format</I> style variable since it evaluates another variable when
|
||||
it is invoked.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: Variables of style <I>equal</I> and <I>atom</I> can be used as
|
||||
inputs to various other LAMMPS commands which evaluate their formulas
|
||||
as needed, e.g. at different timesteps during a <A HREF = "run.html">run</A>.
|
||||
Variables of style <I>python</I> can be used in place of an equal-style
|
||||
variable so long as the associated Python function, as defined by the
|
||||
<A HREF = "python.html">python</A> command, returns a numeric value. Thus any
|
||||
command that states it can use an equal-style variable as an argument,
|
||||
can also use such a python-style variable. This means that when the
|
||||
LAMMPS command evaluates the variable, the Python function will be
|
||||
executed.
|
||||
</P>
|
||||
<P>When the input script line is encountered that defines
|
||||
a variable of style <I>equal</I> or <I>atom</I> or <I>python</I> that contains a
|
||||
formula or Python code, the formula is NOT immediately evaluated and
|
||||
the result stored. See the discussion below about "Immediate
|
||||
Evaluation of Variables" if you want to do this. This is also true of
|
||||
the <I>format</I> style variable since it evaluates another variable when
|
||||
it is invoked.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: When a variable command is encountered in the input
|
||||
script and the variable name has already been specified, the command
|
||||
@ -155,12 +180,12 @@ means that using the <A HREF = "Section_start.html#start_7">command-line switch<
|
||||
script.
|
||||
</P>
|
||||
<P>There are two exceptions to this rule. First, variables of style
|
||||
<I>string</I>, <I>getenv</I>, <I>equal</I> and <I>atom</I> ARE redefined each time the
|
||||
command is encountered. This allows these style of variables to be
|
||||
redefined multiple times in an input script. In a loop, this means
|
||||
the formula associated with an <I>equal</I> or <I>atom</I> style variable can
|
||||
change if it contains a substitution for another variable, e.g. $x or
|
||||
v_x.
|
||||
<I>string</I>, <I>getenv</I>, <I>equal</I>, <I>atom</I>, and <I>python</I> ARE redefined each
|
||||
time the command is encountered. This allows these style of variables
|
||||
to be redefined multiple times in an input script. In a loop, this
|
||||
means the formula associated with an <I>equal</I> or <I>atom</I> style variable
|
||||
can change if it contains a substitution for another variable, e.g. $x
|
||||
or v_x.
|
||||
</P>
|
||||
<P>Second, as described below, if a variable is iterated on to the end of
|
||||
its list of strings via the <A HREF = "next.html">next</A> command, it is removed
|
||||
@ -202,13 +227,15 @@ variable a delete
|
||||
</PRE>
|
||||
<HR>
|
||||
|
||||
<P>This section describes how various variable styles are defined and
|
||||
what they store. Many of the styles store one or more strings. Note
|
||||
that a single string can contain spaces (multiple words), if it is
|
||||
enclosed in quotes in the variable command. When the variable is
|
||||
substituted for in another input script command, its returned string
|
||||
will then be interpreted as multiple arguments in the expanded
|
||||
command.
|
||||
<P>This section describes how all the various variable styles are defined
|
||||
and what they store. Except for the <I>equal</I> and <I>atom</I> styles,
|
||||
which are explaine in the next section.
|
||||
</P>
|
||||
<P>Many of the styles store one or more strings. Note that a single
|
||||
string can contain spaces (multiple words), if it is enclosed in
|
||||
quotes in the variable command. When the variable is substituted for
|
||||
in another input script command, its returned string will then be
|
||||
interpreted as multiple arguments in the expanded command.
|
||||
</P>
|
||||
<P>For the <I>index</I> style, one or more strings are specified. Initially,
|
||||
the 1st string is assigned to the variable. Each time a
|
||||
@ -338,6 +365,31 @@ will be assigned to that atom. IDs can be listed in any order.
|
||||
for all atoms is first set to 0.0. Thus values for atoms whose ID
|
||||
does not appear in the set, will remain 0.0.
|
||||
</P>
|
||||
<P>For the <I>python</I> style a Python function name is provided. This needs
|
||||
to match a function name specified in a <A HREF = "python.html">python</A> command
|
||||
which returns a value to this variable as defined by its <I>return</I>
|
||||
keyword. For exampe these two commands would be self-consistent:
|
||||
</P>
|
||||
<PRE>variable foo python myMultiply
|
||||
python myMultiply return v_foo format f file funcs.py
|
||||
</PRE>
|
||||
<P>The two commands can appear in either order so long as both are
|
||||
specified before the Python function is invoked for the first time.
|
||||
</P>
|
||||
<P>Each time the variable is evaluated, the associated Python function is
|
||||
invoked, and the value it returns is also returned by the variable.
|
||||
Since the Python function can use other LAMMPS variables as input, or
|
||||
query interal LAMMPS quantities to perform its computation, this means
|
||||
the variable can return a different value each time it is evaluated.
|
||||
</P>
|
||||
<P>The type of value stored in the variable is determined by the <I>format</I>
|
||||
keyword of the <A HREF = "python.html">python</A> command. It can be an integer
|
||||
(i), floating point (f), or string (s) value. As mentioned above, if
|
||||
it is a numeric value (integer or floating point), then the
|
||||
python-style variable can be used in place of an equal-style variable
|
||||
anywhere in an input script, e.g. as an argument to another command
|
||||
that allows for equal-style variables.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>For the <I>equal</I> and <I>atom</I> styles, a single string is specified which
|
||||
|
||||
@ -13,7 +13,8 @@ variable command :h3
|
||||
variable name style args ... :pre
|
||||
|
||||
name = name of variable to define :ulb,l
|
||||
style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {string} or {format} or {getenv} or {file} or {atomfile} or {equal} or {atom} :l
|
||||
style = {delete} or {index} or {loop} or {world} or {universe} or
|
||||
{uloop} or {string} or {format} or {getenv} or {file} or {atomfile} or {python} or {equal} or {atom} :l
|
||||
{delete} = no args
|
||||
{index} args = one or more strings
|
||||
{loop} args = N
|
||||
@ -40,6 +41,7 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st
|
||||
{getenv} arg = one string
|
||||
{file} arg = filename
|
||||
{atomfile} arg = filename
|
||||
{python} arg = function
|
||||
{equal} or {atom} args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references
|
||||
numbers = 0.0, 100, -5.4, 2.8e-4, etc
|
||||
constants = PI
|
||||
@ -81,6 +83,7 @@ variable b equal xcm(mol1,x)/2.0
|
||||
variable b equal c_myTemp
|
||||
variable b atom x*y/vol
|
||||
variable foo string myfile
|
||||
variable myPy python increase
|
||||
variable f file values.txt
|
||||
variable temp world 300.0 310.0 320.0 $\{Tfinal\}
|
||||
variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
@ -110,7 +113,9 @@ command) or used as input to an averaging fix (see the "fix
|
||||
ave/spatial"_fix_ave_spatial.html and "fix ave/atom"_fix_ave_atom.html
|
||||
commands). Variables of style {atomfile} can be used anywhere in an
|
||||
input script that atom-style variables are used; they get their
|
||||
per-atom values from a file rather than from a formula.
|
||||
per-atom values from a file rather than from a formula. Variables can
|
||||
be hooked to Python functions using code you provide, so that the
|
||||
variable gets its value from the evaluation of the Python code.
|
||||
|
||||
IMPORTANT NOTE: As discussed in "Section
|
||||
3.2"_Section_commands.html#cmd_2 of the manual, an input script can
|
||||
@ -132,11 +137,31 @@ different values when it is evaluated at different times during a
|
||||
simulation.
|
||||
|
||||
IMPORTANT NOTE: When the input script line is encountered that defines
|
||||
a variable of style {equal} or {atom} that contains a formula, the
|
||||
formula is NOT immediately evaluated and the result stored. See the
|
||||
discussion below about "Immediate Evaluation of Variables" if you want
|
||||
to do this. This is also true of the {format} style variable
|
||||
since it evaluates another variable when it is invoked.
|
||||
a variable of style {equal} or {atom} or {python} that contains a
|
||||
formula or Python code, the formula is NOT immediately evaluated and
|
||||
the result stored. See the discussion below about "Immediate
|
||||
Evaluation of Variables" if you want to do this. This is also true of
|
||||
the {format} style variable since it evaluates another variable when
|
||||
it is invoked.
|
||||
|
||||
IMPORTANT NOTE: Variables of style {equal} and {atom} can be used as
|
||||
inputs to various other LAMMPS commands which evaluate their formulas
|
||||
as needed, e.g. at different timesteps during a "run"_run.html.
|
||||
Variables of style {python} can be used in place of an equal-style
|
||||
variable so long as the associated Python function, as defined by the
|
||||
"python"_python.html command, returns a numeric value. Thus any
|
||||
command that states it can use an equal-style variable as an argument,
|
||||
can also use such a python-style variable. This means that when the
|
||||
LAMMPS command evaluates the variable, the Python function will be
|
||||
executed.
|
||||
|
||||
When the input script line is encountered that defines
|
||||
a variable of style {equal} or {atom} or {python} that contains a
|
||||
formula or Python code, the formula is NOT immediately evaluated and
|
||||
the result stored. See the discussion below about "Immediate
|
||||
Evaluation of Variables" if you want to do this. This is also true of
|
||||
the {format} style variable since it evaluates another variable when
|
||||
it is invoked.
|
||||
|
||||
IMPORTANT NOTE: When a variable command is encountered in the input
|
||||
script and the variable name has already been specified, the command
|
||||
@ -149,12 +174,12 @@ means that using the "command-line switch"_Section_start.html#start_7
|
||||
script.
|
||||
|
||||
There are two exceptions to this rule. First, variables of style
|
||||
{string}, {getenv}, {equal} and {atom} ARE redefined each time the
|
||||
command is encountered. This allows these style of variables to be
|
||||
redefined multiple times in an input script. In a loop, this means
|
||||
the formula associated with an {equal} or {atom} style variable can
|
||||
change if it contains a substitution for another variable, e.g. $x or
|
||||
v_x.
|
||||
{string}, {getenv}, {equal}, {atom}, and {python} ARE redefined each
|
||||
time the command is encountered. This allows these style of variables
|
||||
to be redefined multiple times in an input script. In a loop, this
|
||||
means the formula associated with an {equal} or {atom} style variable
|
||||
can change if it contains a substitution for another variable, e.g. $x
|
||||
or v_x.
|
||||
|
||||
Second, as described below, if a variable is iterated on to the end of
|
||||
its list of strings via the "next"_next.html command, it is removed
|
||||
@ -196,13 +221,15 @@ variable a delete :pre
|
||||
|
||||
:line
|
||||
|
||||
This section describes how various variable styles are defined and
|
||||
what they store. Many of the styles store one or more strings. Note
|
||||
that a single string can contain spaces (multiple words), if it is
|
||||
enclosed in quotes in the variable command. When the variable is
|
||||
substituted for in another input script command, its returned string
|
||||
will then be interpreted as multiple arguments in the expanded
|
||||
command.
|
||||
This section describes how all the various variable styles are defined
|
||||
and what they store. Except for the {equal} and {atom} styles,
|
||||
which are explaine in the next section.
|
||||
|
||||
Many of the styles store one or more strings. Note that a single
|
||||
string can contain spaces (multiple words), if it is enclosed in
|
||||
quotes in the variable command. When the variable is substituted for
|
||||
in another input script command, its returned string will then be
|
||||
interpreted as multiple arguments in the expanded command.
|
||||
|
||||
For the {index} style, one or more strings are specified. Initially,
|
||||
the 1st string is assigned to the variable. Each time a
|
||||
@ -332,6 +359,31 @@ IMPORTANT NOTE: Every time a set of per-atom lines is read, the value
|
||||
for all atoms is first set to 0.0. Thus values for atoms whose ID
|
||||
does not appear in the set, will remain 0.0.
|
||||
|
||||
For the {python} style a Python function name is provided. This needs
|
||||
to match a function name specified in a "python"_python.html command
|
||||
which returns a value to this variable as defined by its {return}
|
||||
keyword. For exampe these two commands would be self-consistent:
|
||||
|
||||
variable foo python myMultiply
|
||||
python myMultiply return v_foo format f file funcs.py :pre
|
||||
|
||||
The two commands can appear in either order so long as both are
|
||||
specified before the Python function is invoked for the first time.
|
||||
|
||||
Each time the variable is evaluated, the associated Python function is
|
||||
invoked, and the value it returns is also returned by the variable.
|
||||
Since the Python function can use other LAMMPS variables as input, or
|
||||
query interal LAMMPS quantities to perform its computation, this means
|
||||
the variable can return a different value each time it is evaluated.
|
||||
|
||||
The type of value stored in the variable is determined by the {format}
|
||||
keyword of the "python"_python.html command. It can be an integer
|
||||
(i), floating point (f), or string (s) value. As mentioned above, if
|
||||
it is a numeric value (integer or floating point), then the
|
||||
python-style variable can be used in place of an equal-style variable
|
||||
anywhere in an input script, e.g. as an argument to another command
|
||||
that allows for equal-style variables.
|
||||
|
||||
:line
|
||||
|
||||
For the {equal} and {atom} styles, a single string is specified which
|
||||
|
||||
@ -88,7 +88,8 @@ peptide: dynamics of a small solvated peptide chain (5-mer)
|
||||
peri: Peridynamic model of cylinder impacted by indenter
|
||||
pour: pouring of granular particles into a 3d box, then chute flow
|
||||
prd: parallel replica dynamics of vacancy diffusion in bulk Si
|
||||
qeq: use of the QEQ pacakge for charge equilibration
|
||||
python: use of PYTHON package to invoke Python code from input script
|
||||
qeq: use of QEQ pacakge for charge equilibration
|
||||
reax: RDX and TATB models using the ReaxFF
|
||||
rigid: rigid bodies modeled as independent or coupled
|
||||
shear: sideways shear applied to 2d solid, with and without a void
|
||||
@ -106,8 +107,7 @@ accelerate/README for Make.py commands suitable for its example
|
||||
scripts.
|
||||
|
||||
cd src
|
||||
Make.py -j 16 -p none std no-lib no-kokkos reax meam poems reaxc orig \
|
||||
-a lib-all mpi
|
||||
Make.py -j 16 -p none std no-lib reax meam poems reaxc orig -a lib-all mpi
|
||||
|
||||
Here is how you might run and visualize one of the sample problems:
|
||||
|
||||
|
||||
22
examples/python/funcs.py
Normal file
22
examples/python/funcs.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Python function that implements a loop of short runs
|
||||
# calls back to LAMMPS via "lmp" instance
|
||||
# lammps() must be called with ptr=lmpptr for this to work
|
||||
|
||||
def loop(N,cut0,thresh,lmpptr):
|
||||
print "LOOP ARGS",N,cut0,thresh,lmpptr
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
natoms = lmp.get_natoms()
|
||||
|
||||
for i in range(N):
|
||||
cut = cut0 + i*0.1
|
||||
|
||||
lmp.set_variable("cut",cut) # set a variable in LAMMPS
|
||||
lmp.command("pair_style lj/cut ${cut}") # LAMMPS command
|
||||
#lmp.command("pair_style lj/cut %d" % cut) # LAMMPS command option
|
||||
|
||||
lmp.command("pair_coeff * * 1.0 1.0") # ditto
|
||||
lmp.command("run 10") # ditto
|
||||
pe = lmp.extract_compute("thermo_pe",0,0) # extract total PE from LAMMPS
|
||||
print "PE",pe/natoms,thresh
|
||||
if pe/natoms < thresh: return
|
||||
64
examples/python/in.python
Normal file
64
examples/python/in.python
Normal file
@ -0,0 +1,64 @@
|
||||
# 3d Lennard-Jones melt with Python functions added
|
||||
|
||||
units lj
|
||||
atom_style atomic
|
||||
|
||||
lattice fcc 0.8442
|
||||
region box block 0 10 0 10 0 10
|
||||
create_box 1 box
|
||||
create_atoms 1 box
|
||||
mass 1 1.0
|
||||
|
||||
velocity all create 1.44 87287 loop geom
|
||||
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
|
||||
fix 1 all nve
|
||||
|
||||
run 10
|
||||
|
||||
# 1st Python function
|
||||
# example of catching a syntax error
|
||||
|
||||
python simple here """
|
||||
def simple():
|
||||
import exceptions
|
||||
print "Inside simple function"
|
||||
try:
|
||||
foo += 1
|
||||
except Exception, e:
|
||||
print "FOO error:",e
|
||||
"""
|
||||
|
||||
python simple invoke
|
||||
|
||||
# 2nd Python function
|
||||
# example of returning the function value to a python-style variable
|
||||
# invoke it twice
|
||||
|
||||
variable fact python factorial
|
||||
python factorial input 1 v_n return v_fact format ii here """
|
||||
def factorial(n):
|
||||
if n == 1: return 1
|
||||
return n*factorial(n-1)
|
||||
"""
|
||||
|
||||
variable n string 10
|
||||
python factorial invoke
|
||||
print "Factorial of $n = ${fact}"
|
||||
|
||||
variable n string 20
|
||||
python factorial invoke
|
||||
print "Factorial of $n = ${fact}"
|
||||
|
||||
# 3rd Python function
|
||||
# example of calling back to LAMMPS and writing a run loop in Python
|
||||
|
||||
variable cut string 0.0
|
||||
|
||||
python loop input 4 10 1.0 -4.0 SELF format iffp file funcs.py
|
||||
python loop invoke
|
||||
315
examples/python/log.python.17Mar15.linux.1
Normal file
315
examples/python/log.python.17Mar15.linux.1
Normal file
@ -0,0 +1,315 @@
|
||||
LAMMPS (12 Mar 2015)
|
||||
# 3d Lennard-Jones melt
|
||||
|
||||
units lj
|
||||
atom_style atomic
|
||||
|
||||
lattice fcc 0.8442
|
||||
Lattice spacing in x,y,z = 1.6796 1.6796 1.6796
|
||||
region box block 0 10 0 10 0 10
|
||||
create_box 1 box
|
||||
Created orthogonal box = (0 0 0) to (16.796 16.796 16.796)
|
||||
1 by 1 by 1 MPI processor grid
|
||||
create_atoms 1 box
|
||||
Created 4000 atoms
|
||||
mass 1 1.0
|
||||
|
||||
velocity all create 1.44 87287 loop geom
|
||||
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
|
||||
fix 1 all nve
|
||||
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 2.8
|
||||
Memory usage per processor = 2.69271 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
0 1.44 -6.7733681 0 -4.6139081 -5.0199732
|
||||
10 1.1259767 -6.3010653 0 -4.6125225 -2.5704638
|
||||
Loop time of 0.03213 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.0242701 (75.5371)
|
||||
Neigh time (%) = 0.006531 (20.3268)
|
||||
Comm time (%) = 0.000502825 (1.56497)
|
||||
Outpt time (%) = 2.09808e-05 (0.0652998)
|
||||
Other time (%) = 0.00080514 (2.50588)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 5841 ave 5841 max 5841 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 155984 ave 155984 max 155984 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 155984
|
||||
Ave neighs/atom = 38.996
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
|
||||
# 1st Python function
|
||||
# example of catching a syntax error
|
||||
|
||||
python simple here """
|
||||
def simple():
|
||||
import exceptions
|
||||
print "Inside simple function"
|
||||
try:
|
||||
foo += 1
|
||||
except Exception, e:
|
||||
print "FOO error:",e
|
||||
"""
|
||||
|
||||
python simple invoke
|
||||
|
||||
# 2nd Python function
|
||||
# example of returning the function value to a python-style variable
|
||||
# invoke it twice
|
||||
|
||||
variable fact python factorial
|
||||
python factorial input 1 v_n return v_fact format ii here """
|
||||
def factorial(n):
|
||||
if n == 1: return 1
|
||||
return n*factorial(n-1)
|
||||
"""
|
||||
|
||||
variable n string 10
|
||||
python factorial invoke
|
||||
print "Factorial of $n = ${fact}"
|
||||
Factorial of 10 = 3628800
|
||||
|
||||
variable n string 20
|
||||
python factorial invoke
|
||||
print "Factorial of $n = ${fact}"
|
||||
Factorial of 20 = 2432902008176640000
|
||||
|
||||
# 3rd Python function
|
||||
# example of calling back to LAMMPS and writing a run loop in Python
|
||||
|
||||
variable cut string 0.0
|
||||
|
||||
python loop input 4 10 1.0 -4.0 SELF format iffp file funcs.py
|
||||
python loop invoke
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.0
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.3
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
10 1.1259767 0.016557378 0 1.7051002 1.2784679
|
||||
20 0.87608998 0.39300382 0 1.7068103 6.0488236
|
||||
Loop time of 0.00451207 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00158691 (35.1704)
|
||||
Neigh time (%) = 0.00194287 (43.0594)
|
||||
Comm time (%) = 0.000257015 (5.69617)
|
||||
Outpt time (%) = 2.09808e-05 (0.464993)
|
||||
Other time (%) = 0.000704288 (15.609)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 2083 ave 2083 max 2083 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 17727 ave 17727 max 17727 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 17727
|
||||
Ave neighs/atom = 4.43175
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.1
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.4
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
20 0.87608998 -0.33042884 0 0.9833776 8.5817494
|
||||
30 1.0155079 -0.83166219 0 0.69121891 7.9905553
|
||||
Loop time of 0.00607896 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00298262 (49.0646)
|
||||
Neigh time (%) = 0.00210714 (34.6629)
|
||||
Comm time (%) = 0.000262499 (4.31816)
|
||||
Outpt time (%) = 2.00272e-05 (0.329451)
|
||||
Other time (%) = 0.000706673 (11.6249)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 2087 ave 2087 max 2087 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 21036 ave 21036 max 21036 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 21036
|
||||
Ave neighs/atom = 5.259
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.2
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.5
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
30 1.0155079 -2.0616558 0 -0.53877467 7.6238572
|
||||
40 1.0490928 -2.1868324 0 -0.61358669 7.2084131
|
||||
Loop time of 0.00735807 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00416398 (56.5906)
|
||||
Neigh time (%) = 0.00219989 (29.8976)
|
||||
Comm time (%) = 0.000262022 (3.56101)
|
||||
Outpt time (%) = 1.90735e-05 (0.259218)
|
||||
Other time (%) = 0.00071311 (9.69153)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 2250 ave 2250 max 2250 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 24095 ave 24095 max 24095 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 24095
|
||||
Ave neighs/atom = 6.02375
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.3
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.6
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
40 1.0490928 -3.0667608 0 -1.493515 6.2796311
|
||||
50 1.0764484 -3.1173704 0 -1.5031014 6.0850409
|
||||
Loop time of 0.0085659 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00486517 (56.7969)
|
||||
Neigh time (%) = 0.00266886 (31.1568)
|
||||
Comm time (%) = 0.000301838 (3.52371)
|
||||
Outpt time (%) = 2.00272e-05 (0.233801)
|
||||
Other time (%) = 0.000710011 (8.2888)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 2572 ave 2572 max 2572 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 27137 ave 27137 max 27137 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 27137
|
||||
Ave neighs/atom = 6.78425
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.4
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.7
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
50 1.0764484 -3.6112241 0 -1.9969552 5.4223348
|
||||
60 1.1101013 -3.6616014 0 -1.9968657 5.2348251
|
||||
Loop time of 0.0091939 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00552583 (60.1032)
|
||||
Neigh time (%) = 0.00259781 (28.2558)
|
||||
Comm time (%) = 0.000323296 (3.51642)
|
||||
Outpt time (%) = 2.00272e-05 (0.217831)
|
||||
Other time (%) = 0.000726938 (7.90675)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 3013 ave 3013 max 3013 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 30887 ave 30887 max 30887 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 30887
|
||||
Ave neighs/atom = 7.72175
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.5
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.8
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
60 1.1101013 -3.9655053 0 -2.3007696 4.7849008
|
||||
70 1.1122144 -3.9657095 0 -2.297805 4.8014106
|
||||
Loop time of 0.0102301 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00630403 (61.6225)
|
||||
Neigh time (%) = 0.00282717 (27.6359)
|
||||
Comm time (%) = 0.000349283 (3.41428)
|
||||
Outpt time (%) = 2.00272e-05 (0.195768)
|
||||
Other time (%) = 0.000729561 (7.13154)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 3388 ave 3388 max 3388 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 35959 ave 35959 max 35959 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 35959
|
||||
Ave neighs/atom = 8.98975
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.6
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.9
|
||||
Memory usage per processor = 2.78761 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
70 1.1122144 -4.1752688 0 -2.5073643 4.4755409
|
||||
80 1.117224 -4.1831357 0 -2.5077187 4.446079
|
||||
Loop time of 0.011508 on 1 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00736189 (63.972)
|
||||
Neigh time (%) = 0.00303006 (26.3301)
|
||||
Comm time (%) = 0.000365019 (3.17187)
|
||||
Outpt time (%) = 2.00272e-05 (0.174028)
|
||||
Other time (%) = 0.000730991 (6.35203)
|
||||
|
||||
Nlocal: 4000 ave 4000 max 4000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 3612 ave 3612 max 3612 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 43239 ave 43239 max 43239 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 43239
|
||||
Ave neighs/atom = 10.8097
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
315
examples/python/log.python.17Mar15.linux.4
Normal file
315
examples/python/log.python.17Mar15.linux.4
Normal file
@ -0,0 +1,315 @@
|
||||
LAMMPS (12 Mar 2015)
|
||||
# 3d Lennard-Jones melt
|
||||
|
||||
units lj
|
||||
atom_style atomic
|
||||
|
||||
lattice fcc 0.8442
|
||||
Lattice spacing in x,y,z = 1.6796 1.6796 1.6796
|
||||
region box block 0 10 0 10 0 10
|
||||
create_box 1 box
|
||||
Created orthogonal box = (0 0 0) to (16.796 16.796 16.796)
|
||||
1 by 2 by 2 MPI processor grid
|
||||
create_atoms 1 box
|
||||
Created 4000 atoms
|
||||
mass 1 1.0
|
||||
|
||||
velocity all create 1.44 87287 loop geom
|
||||
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
|
||||
fix 1 all nve
|
||||
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 2.8
|
||||
Memory usage per processor = 2.60344 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
0 1.44 -6.7733681 0 -4.6139081 -5.0199732
|
||||
10 1.1259767 -6.3010653 0 -4.6125225 -2.5704638
|
||||
Loop time of 0.00962114 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00643039 (66.836)
|
||||
Neigh time (%) = 0.00174427 (18.1296)
|
||||
Comm time (%) = 0.00106865 (11.1073)
|
||||
Outpt time (%) = 3.48091e-05 (0.361798)
|
||||
Other time (%) = 0.000343025 (3.56532)
|
||||
|
||||
Nlocal: 1000 ave 1013 max 989 min
|
||||
Histogram: 1 0 1 0 0 1 0 0 0 1
|
||||
Nghost: 2901 ave 2912 max 2888 min
|
||||
Histogram: 1 0 0 0 1 0 0 1 0 1
|
||||
Neighs: 38996 ave 39269 max 38365 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 1 2
|
||||
|
||||
Total # of neighbors = 155984
|
||||
Ave neighs/atom = 38.996
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
|
||||
# 1st Python function
|
||||
# example of catching a syntax error
|
||||
|
||||
python simple here """
|
||||
def simple():
|
||||
import exceptions
|
||||
print "Inside simple function"
|
||||
try:
|
||||
foo += 1
|
||||
except Exception, e:
|
||||
print "FOO error:",e
|
||||
"""
|
||||
|
||||
python simple invoke
|
||||
|
||||
# 2nd Python function
|
||||
# example of returning the function value to a python-style variable
|
||||
# invoke it twice
|
||||
|
||||
variable fact python factorial
|
||||
python factorial input 1 v_n return v_fact format ii here """
|
||||
def factorial(n):
|
||||
if n == 1: return 1
|
||||
return n*factorial(n-1)
|
||||
"""
|
||||
|
||||
variable n string 10
|
||||
python factorial invoke
|
||||
print "Factorial of $n = ${fact}"
|
||||
Factorial of 10 = 3628800
|
||||
|
||||
variable n string 20
|
||||
python factorial invoke
|
||||
print "Factorial of $n = ${fact}"
|
||||
Factorial of 20 = 2432902008176640000
|
||||
|
||||
# 3rd Python function
|
||||
# example of calling back to LAMMPS and writing a run loop in Python
|
||||
|
||||
variable cut string 0.0
|
||||
|
||||
python loop input 4 10 1.0 -4.0 SELF format iffp file funcs.py
|
||||
python loop invoke
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.0
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.3
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
10 1.1259767 0.016557378 0 1.7051002 1.2784679
|
||||
20 0.87608998 0.39300382 0 1.7068103 6.0488236
|
||||
Loop time of 0.00155491 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.000403821 (25.9708)
|
||||
Neigh time (%) = 0.00049901 (32.0926)
|
||||
Comm time (%) = 0.000386357 (24.8476)
|
||||
Outpt time (%) = 2.87294e-05 (1.84766)
|
||||
Other time (%) = 0.000236988 (15.2413)
|
||||
|
||||
Nlocal: 1000 ave 1015 max 987 min
|
||||
Histogram: 1 0 0 1 0 1 0 0 0 1
|
||||
Nghost: 943 ave 956 max 928 min
|
||||
Histogram: 1 0 0 0 1 0 1 0 0 1
|
||||
Neighs: 4431.75 ave 4498 max 4325 min
|
||||
Histogram: 1 0 0 0 0 0 1 0 1 1
|
||||
|
||||
Total # of neighbors = 17727
|
||||
Ave neighs/atom = 4.43175
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.1
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.4
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
20 0.87608998 -0.33042884 0 0.9833776 8.5817494
|
||||
30 1.0155079 -0.83166219 0 0.69121891 7.9905553
|
||||
Loop time of 0.00199097 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.000789523 (39.6551)
|
||||
Neigh time (%) = 0.000541985 (27.2221)
|
||||
Comm time (%) = 0.000392973 (19.7377)
|
||||
Outpt time (%) = 2.49147e-05 (1.25138)
|
||||
Other time (%) = 0.000241578 (12.1336)
|
||||
|
||||
Nlocal: 1000 ave 1019 max 983 min
|
||||
Histogram: 1 0 1 0 0 0 1 0 0 1
|
||||
Nghost: 945.25 ave 962 max 925 min
|
||||
Histogram: 1 0 0 0 1 0 0 1 0 1
|
||||
Neighs: 5259 ave 5343 max 5125 min
|
||||
Histogram: 1 0 0 0 0 1 0 0 0 2
|
||||
|
||||
Total # of neighbors = 21036
|
||||
Ave neighs/atom = 5.259
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.2
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.5
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
30 1.0155079 -2.0616558 0 -0.53877467 7.6238572
|
||||
40 1.0490928 -2.1868324 0 -0.61358669 7.2084131
|
||||
Loop time of 0.00233454 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00106812 (45.7528)
|
||||
Neigh time (%) = 0.000583589 (24.9981)
|
||||
Comm time (%) = 0.000406563 (17.4152)
|
||||
Outpt time (%) = 2.41399e-05 (1.03403)
|
||||
Other time (%) = 0.000252128 (10.7999)
|
||||
|
||||
Nlocal: 1000 ave 1013 max 984 min
|
||||
Histogram: 1 0 0 1 0 0 0 0 1 1
|
||||
Nghost: 1023 ave 1035 max 1005 min
|
||||
Histogram: 1 0 0 0 0 1 0 0 0 2
|
||||
Neighs: 6023.75 ave 6093 max 5953 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 0 2
|
||||
|
||||
Total # of neighbors = 24095
|
||||
Ave neighs/atom = 6.02375
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.3
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.6
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
40 1.0490928 -3.0667608 0 -1.493515 6.2796311
|
||||
50 1.0764484 -3.1173704 0 -1.5031014 6.0850409
|
||||
Loop time of 0.00265193 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00123417 (46.5387)
|
||||
Neigh time (%) = 0.000687182 (25.9125)
|
||||
Comm time (%) = 0.000449538 (16.9514)
|
||||
Outpt time (%) = 2.40803e-05 (0.908028)
|
||||
Other time (%) = 0.000256956 (9.68938)
|
||||
|
||||
Nlocal: 1000 ave 1013 max 974 min
|
||||
Histogram: 1 0 0 0 0 0 0 1 0 2
|
||||
Nghost: 1184.75 ave 1200 max 1165 min
|
||||
Histogram: 1 0 0 0 1 0 0 0 1 1
|
||||
Neighs: 6784.25 ave 6922 max 6577 min
|
||||
Histogram: 1 0 0 0 0 1 0 0 1 1
|
||||
|
||||
Total # of neighbors = 27137
|
||||
Ave neighs/atom = 6.78425
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.4
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.7
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
50 1.0764484 -3.6112241 0 -1.9969552 5.4223348
|
||||
60 1.1101013 -3.6616014 0 -1.9968657 5.2348251
|
||||
Loop time of 0.00285125 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00141847 (49.7491)
|
||||
Neigh time (%) = 0.000675321 (23.6851)
|
||||
Comm time (%) = 0.000490129 (17.19)
|
||||
Outpt time (%) = 2.77162e-05 (0.972071)
|
||||
Other time (%) = 0.000239611 (8.40371)
|
||||
|
||||
Nlocal: 1000 ave 1016 max 981 min
|
||||
Histogram: 1 0 0 0 1 0 1 0 0 1
|
||||
Nghost: 1402.25 ave 1408 max 1390 min
|
||||
Histogram: 1 0 0 0 0 0 0 1 0 2
|
||||
Neighs: 7721.75 ave 7798 max 7615 min
|
||||
Histogram: 1 0 0 1 0 0 0 0 0 2
|
||||
|
||||
Total # of neighbors = 30887
|
||||
Ave neighs/atom = 7.72175
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.5
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.8
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
60 1.1101013 -3.9655053 0 -2.3007696 4.7849008
|
||||
70 1.1122144 -3.9657095 0 -2.297805 4.8014106
|
||||
Loop time of 0.00325108 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00161421 (49.6517)
|
||||
Neigh time (%) = 0.000730813 (22.4791)
|
||||
Comm time (%) = 0.000600517 (18.4713)
|
||||
Outpt time (%) = 2.87294e-05 (0.88369)
|
||||
Other time (%) = 0.000276804 (8.51423)
|
||||
|
||||
Nlocal: 1000 ave 1022 max 982 min
|
||||
Histogram: 1 0 0 1 0 1 0 0 0 1
|
||||
Nghost: 1595.75 ave 1604 max 1588 min
|
||||
Histogram: 1 0 0 1 0 0 1 0 0 1
|
||||
Neighs: 8989.75 ave 9204 max 8776 min
|
||||
Histogram: 1 0 0 0 1 1 0 0 0 1
|
||||
|
||||
Total # of neighbors = 35959
|
||||
Ave neighs/atom = 8.98975
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
pair_style lj/cut ${cut}
|
||||
pair_style lj/cut 1.6
|
||||
pair_coeff * * 1.0 1.0
|
||||
run 10
|
||||
Neighbor list info ...
|
||||
1 neighbor list requests
|
||||
update every 1 steps, delay 0 steps, check yes
|
||||
master list distance cutoff = 1.9
|
||||
Memory usage per processor = 2.63679 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
70 1.1122144 -4.1752688 0 -2.5073643 4.4755409
|
||||
80 1.117224 -4.1831357 0 -2.5077187 4.446079
|
||||
Loop time of 0.00360203 on 4 procs for 10 steps with 4000 atoms
|
||||
|
||||
Pair time (%) = 0.00191045 (53.0381)
|
||||
Neigh time (%) = 0.000787675 (21.8676)
|
||||
Comm time (%) = 0.000629485 (17.4758)
|
||||
Outpt time (%) = 2.46167e-05 (0.683413)
|
||||
Other time (%) = 0.000249803 (6.93507)
|
||||
|
||||
Nlocal: 1000 ave 1013 max 987 min
|
||||
Histogram: 1 0 1 0 0 0 0 1 0 1
|
||||
Nghost: 1706 ave 1720 max 1693 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 1 1
|
||||
Neighs: 10809.8 ave 10831 max 10761 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 1 2
|
||||
|
||||
Total # of neighbors = 43239
|
||||
Ave neighs/atom = 10.8097
|
||||
Neighbor list builds = 1
|
||||
Dangerous builds = 0
|
||||
@ -37,6 +37,8 @@ meam modified embedded atom method (MEAM) potential, MEAM package
|
||||
from Greg Wagner (Sandia)
|
||||
molfile hooks to VMD molfile plugins, used by the USER-MOLFILE package
|
||||
from Axel Kohlmeyer (Temple U) and the VMD development team
|
||||
python hooks to the system Python library, used by the PYTHON package
|
||||
from the LAMMPS development team
|
||||
qmmm quantum mechanics/molecular mechanics coupling interface
|
||||
from Axel Kohlmeyer (Temple U)
|
||||
quip interface to QUIP/libAtoms framework, USER-QUIP package
|
||||
|
||||
6
lib/python/Makefile.lammps
Normal file
6
lib/python/Makefile.lammps
Normal file
@ -0,0 +1,6 @@
|
||||
# Settings that the LAMMPS build will import when this package library is used
|
||||
# See the README file for more explanation
|
||||
|
||||
python_SYSINC = -I/usr/local/include/python2.7
|
||||
python_SYSLIB = -lpython2.7 -lnsl -ldl -lreadline -ltermcap -lpthread -lutil -lm
|
||||
python_SYSPATH =
|
||||
6
lib/python/Makefile.lammps.python2.7
Normal file
6
lib/python/Makefile.lammps.python2.7
Normal file
@ -0,0 +1,6 @@
|
||||
# Settings that the LAMMPS build will import when this package library is used
|
||||
# See the README file for more explanation
|
||||
|
||||
python_SYSINC = -I/usr/local/include/python2.7
|
||||
python_SYSLIB = -lpython2.7 -lnsl -ldl -lreadline -ltermcap -lpthread -lutil -lm
|
||||
python_SYSPATH =
|
||||
58
lib/python/README
Normal file
58
lib/python/README
Normal file
@ -0,0 +1,58 @@
|
||||
The Makefile.lammps file in this directory is used when building
|
||||
LAMMPS with its PYTHON package installed. The file has several
|
||||
settings needed to compile and link LAMMPS with the Python library.
|
||||
You should choose a Makefile.lammps.* file compatible with your system
|
||||
and your version of Python, and copy it to Makefile.lammps before
|
||||
building LAMMPS itself. You may need to edit one of the provided
|
||||
files to match your system.
|
||||
|
||||
Note that is not currently possible to use the PYTHON package with
|
||||
Python 3, only with Python 2. The C API changed from Python 2 to 3
|
||||
and the LAMMPS code is not compatible with both.
|
||||
|
||||
If you create a new Makefile.lammps file suitable for some version of
|
||||
Python on some system, that is not a match to one of the provided
|
||||
Makefile.lammps.* files, you can send it to the developers, and we can
|
||||
include it in the distribution for others to use.
|
||||
|
||||
To illustrate, these are example settings from the
|
||||
Makefile.lammps.python2.7 file:
|
||||
|
||||
python_SYSINC = -I/usr/local/include/python2.7
|
||||
python_SYSLIB = -lpython2.7 -lnsl -ldl -lreadline -ltermcap -lpthread -lutil -lm
|
||||
python_SYSPATH =
|
||||
|
||||
python_SYSINC refers to the directory where Python's Python.h file is
|
||||
found. LAMMPS includes this file.
|
||||
|
||||
python_SYSLIB refers to the libraries needed to link to from an
|
||||
application (LAMMPS in this case) to "embed" Python in the
|
||||
application. The Python library itself is listed (-lpython2.7) are
|
||||
are several system libraries needed by Python.
|
||||
|
||||
python_SYSPATH = refers to the path (e.g. -L/usr/local/lib) where the
|
||||
Python library can be found. You may not need this setting if the
|
||||
path is already included in your LD_LIBRARY_PATH environment variable.
|
||||
|
||||
-------------------------
|
||||
|
||||
Note that the trickiest issue to figure out for inclusion in
|
||||
Makefile.lammps is what system libraries are needed by your Python to
|
||||
run in embedded mode on your machine.
|
||||
|
||||
Here is what this Python doc page says about it:
|
||||
|
||||
https://docs.python.org/2/extending/embedding.html#compiling-and-linking-under-unix-like-systems
|
||||
|
||||
"It is not necessarily trivial to find the right flags to pass to your
|
||||
compiler (and linker) in order to embed the Python interpreter into
|
||||
your application, particularly because Python needs to load library
|
||||
modules implemented as C dynamic extensions (.so files) linked against
|
||||
it.
|
||||
|
||||
To find out the required compiler and linker flags, you can execute
|
||||
the pythonX.Y-config script which is generated as part of the
|
||||
installation process (a python-config script may also be available)."
|
||||
|
||||
It then gives examples of how to use the pythonX.Y-config script
|
||||
and further instructions for what to do if that doesn't work.
|
||||
@ -1,6 +1,6 @@
|
||||
This directory contains Python code which wraps LAMMPS as a library
|
||||
and allows the LAMMPS library interface to be invoked from Python,
|
||||
either from a script or interactively.
|
||||
either from a Python script or using Python interactively.
|
||||
|
||||
Details on the Python interface to LAMMPS and how to build LAMMPS as a
|
||||
shared library, for use with Python, are given in
|
||||
@ -16,16 +16,22 @@ variables in your shell script. Or you can run the python/install.py
|
||||
script directly to give you more control over where the two relevant
|
||||
files are installed. See doc/Section_python.html for details.
|
||||
|
||||
You can then launch Python and instantiate an instance of LAMMPS:
|
||||
You should then be able to launch Python and instantiate an instance
|
||||
of LAMMPS:
|
||||
|
||||
% python
|
||||
>>> from lammps import lammps
|
||||
>>> lmp = lammps()
|
||||
|
||||
If that gives no errors, you have succesfully wrapped LAMMPS with
|
||||
Python. See doc/Section_python.html#py_5 for tests you can then use
|
||||
Python. See doc/Section_python.html#py_7 for tests you can then use
|
||||
to run LAMMPS both in serial or parallel thru Python.
|
||||
|
||||
Note that you can also invoke Python code from within a LAMMPS input
|
||||
script, using the "python" command. See the doc/python.html doc page
|
||||
for details. The Python code you invoke can also call back to LAMMPS
|
||||
using the same interface described here for wrapping LAMMPS.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Once you have successfully wrapped LAMMPS, you can run the Python
|
||||
|
||||
@ -43,14 +43,14 @@ endif
|
||||
|
||||
PACKAGE = asphere body class2 colloid coreshell dipole fld gpu granular kim \
|
||||
kokkos kspace manybody mc meam misc molecule mpiio opt peri poems \
|
||||
qeq reax replica rigid shock snap srd voronoi xtc
|
||||
python qeq reax replica rigid shock snap srd voronoi xtc
|
||||
|
||||
PACKUSER = user-atc user-awpmd user-cg-cmm user-colvars \
|
||||
user-cuda user-eff user-fep user-intel user-lb user-misc \
|
||||
user-molfile user-omp user-phonon user-qmmm user-quip \
|
||||
user-reaxc user-sph
|
||||
|
||||
PACKLIB = gpu kim kokkos meam poems reax voronoi \
|
||||
PACKLIB = gpu kim kokkos meam poems python reax voronoi \
|
||||
user-atc user-awpmd user-colvars user-cuda user-molfile \
|
||||
user-qmmm user-quip
|
||||
|
||||
|
||||
69
src/PYTHON/Install.sh
Executable file
69
src/PYTHON/Install.sh
Executable file
@ -0,0 +1,69 @@
|
||||
# Install/unInstall package files in LAMMPS
|
||||
# mode = 0/1/2 for uninstall/install/update
|
||||
|
||||
mode=$1
|
||||
|
||||
# arg1 = file, arg2 = file it depends on
|
||||
|
||||
action () {
|
||||
if (test $mode = 0) then
|
||||
rm -f ../$1
|
||||
elif (! cmp -s $1 ../$1) then
|
||||
if (test -z "$2" || test -e ../$2) then
|
||||
cp $1 ..
|
||||
if (test $mode = 2) then
|
||||
echo " updating src/$1"
|
||||
fi
|
||||
fi
|
||||
elif (test -n "$2") then
|
||||
if (test ! -e ../$2) then
|
||||
rm -f ../$1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# force rebuild of files with LMP_KOKKOS switch
|
||||
# also variable so its *.d dependence on changed python_wrapper.h is rebuilt
|
||||
|
||||
touch ../python_wrapper.h
|
||||
touch ../variable.cpp
|
||||
|
||||
# all package files with no dependencies
|
||||
|
||||
for file in *.cpp *.h; do
|
||||
action $file
|
||||
done
|
||||
|
||||
# edit 2 Makefile.package files to include/exclude package info
|
||||
|
||||
if (test $1 = 1) then
|
||||
|
||||
if (test -e ../Makefile.package) then
|
||||
sed -i -e 's/[^ \t]*python[^ \t]* //' ../Makefile.package
|
||||
sed -i -e 's/[^ \t]*PYTHON[^ \t]* //g' ../Makefile.package
|
||||
sed -i -e 's|^PKG_INC =[ \t]*|&-DLMP_PYTHON |' ../Makefile.package
|
||||
sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(python_SYSINC) |' ../Makefile.package
|
||||
sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(python_SYSLIB) |' ../Makefile.package
|
||||
sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(python_SYSPATH) |' ../Makefile.package
|
||||
fi
|
||||
|
||||
if (test -e ../Makefile.package.settings) then
|
||||
sed -i -e '/^include.*python.*$/d' ../Makefile.package.settings
|
||||
# multiline form needed for BSD sed on Macs
|
||||
sed -i -e '4 i \
|
||||
include ..\/..\/lib\/python\/Makefile.lammps
|
||||
' ../Makefile.package.settings
|
||||
fi
|
||||
|
||||
elif (test $1 = 0) then
|
||||
|
||||
if (test -e ../Makefile.package) then
|
||||
sed -i -e 's/[^ \t]*python[^ \t]* //' ../Makefile.package
|
||||
sed -i -e 's/[^ \t]*PYTHON[^ \t]* //g' ../Makefile.package
|
||||
fi
|
||||
|
||||
if (test -e ../Makefile.package.settings) then
|
||||
sed -i -e '/^include.*python.*$/d' ../Makefile.package.settings
|
||||
fi
|
||||
|
||||
fi
|
||||
400
src/PYTHON/python.cpp
Normal file
400
src/PYTHON/python.cpp
Normal file
@ -0,0 +1,400 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "Python.h"
|
||||
#include "python.h"
|
||||
#include "force.h"
|
||||
#include "input.h"
|
||||
#include "variable.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
enum{NONE,INT,DOUBLE,STRING,PTR};
|
||||
|
||||
#define VALUELENGTH 64 // also in variable.cpp
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Python::Python(LAMMPS *lmp) : Pointers(lmp)
|
||||
{
|
||||
python_exists = 1;
|
||||
|
||||
pyMain = NULL;
|
||||
|
||||
// pfuncs stores interface info for each Python function
|
||||
|
||||
nfunc = 0;
|
||||
pfuncs = NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Python::~Python()
|
||||
{
|
||||
// clean up
|
||||
|
||||
for (int i = 0; i < nfunc; i++) {
|
||||
delete [] pfuncs[i].name;
|
||||
deallocate(i);
|
||||
PyObject *pFunc = (PyObject *) pfuncs[i].pFunc;
|
||||
Py_XDECREF(pFunc);
|
||||
}
|
||||
|
||||
// shutdown Python interpreter
|
||||
|
||||
if (pyMain) Py_Finalize();
|
||||
|
||||
memory->sfree(pfuncs);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void Python::command(int narg, char **arg)
|
||||
{
|
||||
if (narg < 2) error->all(FLERR,"Invalid python command");
|
||||
|
||||
// if invoke is only keyword, invoke the previously defined function
|
||||
|
||||
if (narg == 2 && strcmp(arg[1],"invoke") == 0) {
|
||||
int ifunc = find(arg[0]);
|
||||
if (ifunc < 0) error->all(FLERR,"Python invoke of undefined function");
|
||||
|
||||
char *str = NULL;
|
||||
if (noutput) {
|
||||
str = input->variable->pythonstyle(pfuncs[ifunc].ovarname,
|
||||
pfuncs[ifunc].name);
|
||||
if (!str)
|
||||
error->all(FLERR,"Python variable does not match Python function");
|
||||
}
|
||||
|
||||
invoke_function(ifunc,str);
|
||||
return;
|
||||
}
|
||||
|
||||
// parse optional args, invoke is not allowed in this mode
|
||||
|
||||
ninput = noutput = 0;
|
||||
istr = NULL;
|
||||
ostr = NULL;
|
||||
format = NULL;
|
||||
char *pyfile = NULL;
|
||||
char *herestr = NULL;
|
||||
int existflag = 0;
|
||||
|
||||
int iarg = 1;
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"input") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
ninput = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (ninput < 0) error->all(FLERR,"Invalid python command");
|
||||
iarg += 2;
|
||||
istr = new char*[ninput];
|
||||
if (iarg+ninput > narg) error->all(FLERR,"Invalid python command");
|
||||
for (int i = 0; i < ninput; i++) istr[i] = arg[iarg+i];
|
||||
iarg += ninput;
|
||||
} else if (strcmp(arg[iarg],"return") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
noutput = 1;
|
||||
ostr = arg[iarg+1];
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"format") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
int n = strlen(arg[iarg+1]) + 1;
|
||||
format = new char[n];
|
||||
strcpy(format,arg[iarg+1]);
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"file") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
int n = strlen(arg[iarg+1]) + 1;
|
||||
pyfile = new char[n];
|
||||
strcpy(pyfile,arg[iarg+1]);
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"here") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Invalid python command");
|
||||
herestr = arg[iarg+1];
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"exists") == 0) {
|
||||
existflag = 1;
|
||||
iarg++;
|
||||
} else error->all(FLERR,"Invalid python command");
|
||||
}
|
||||
|
||||
if (pyfile && herestr) error->all(FLERR,"Invalid python command");
|
||||
if (pyfile && existflag) error->all(FLERR,"Invalid python command");
|
||||
if (herestr && existflag) error->all(FLERR,"Invalid python command");
|
||||
|
||||
// create or overwrite entry in pfuncs vector with name = arg[0]
|
||||
|
||||
int ifunc = create_entry(arg[0]);
|
||||
|
||||
// one-time intitialization of Python interpreter
|
||||
// Py_SetArgv() enables finding of *.py module files in current dir
|
||||
// only needed for module load, not for direct file read into __main__
|
||||
// pymain stores pointer to main module
|
||||
|
||||
if (pyMain == NULL) {
|
||||
if (Py_IsInitialized())
|
||||
error->all(FLERR,"Cannot embed Python when also "
|
||||
"extending Python with LAMMPS");
|
||||
Py_Initialize();
|
||||
|
||||
//char *arg = (char *) "./lmp";
|
||||
//PySys_SetArgv(1,&arg);
|
||||
|
||||
//PyObject *pName = PyString_FromString("__main__");
|
||||
//if (!pName) error->all(FLERR,"Bad pName");
|
||||
//PyObject *pModule = PyImport_Import(pName);
|
||||
//Py_DECREF(pName);
|
||||
|
||||
PyObject *pModule = PyImport_AddModule("__main__");
|
||||
if (!pModule) error->all(FLERR,"Could not initialize embedded Python");
|
||||
//if (!pModule) error->one(FLERR,"Could not initialize embedded Python");
|
||||
pyMain = (void *) pModule;
|
||||
}
|
||||
|
||||
// send Python code to Python interpreter
|
||||
// file: read the file via PyRun_SimpleFile()
|
||||
// here: process the here string directly
|
||||
// exist: do nothing, assume code has already been run
|
||||
|
||||
if (pyfile) {
|
||||
FILE *fp = fopen(pyfile,"r");
|
||||
if (fp == NULL) error->all(FLERR,"Could not open Python file");
|
||||
int err = PyRun_SimpleFile(fp,pyfile);
|
||||
if (err) error->all(FLERR,"Could not process Python file");
|
||||
} else if (herestr) {
|
||||
int err = PyRun_SimpleString(herestr);
|
||||
if (err) error->all(FLERR,"Could not process Python string");
|
||||
}
|
||||
|
||||
// pFunc = function object for requested function
|
||||
|
||||
PyObject *pModule = (PyObject *) pyMain;
|
||||
PyObject *pFunc = PyObject_GetAttrString(pModule,pfuncs[ifunc].name);
|
||||
if (!pFunc) error->all(FLERR,"Could not find Python function");
|
||||
if (!PyCallable_Check(pFunc))
|
||||
error->all(FLERR,"Python function is not callable");
|
||||
pfuncs[ifunc].pFunc = (void *) pFunc;
|
||||
|
||||
// clean-up input storage
|
||||
|
||||
delete [] istr;
|
||||
delete [] format;
|
||||
delete [] pyfile;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void Python::invoke_function(int ifunc, char *result)
|
||||
{
|
||||
PyObject *pValue;
|
||||
char *str;
|
||||
|
||||
PyObject *pFunc = (PyObject *) pfuncs[ifunc].pFunc;
|
||||
|
||||
// create Python tuple of input arguments
|
||||
|
||||
int ninput = pfuncs[ifunc].ninput;
|
||||
PyObject *pArgs = PyTuple_New(ninput);
|
||||
if (!pArgs) error->all(FLERR,"Could not create Python function arguments");
|
||||
|
||||
for (int i = 0; i < ninput; i++) {
|
||||
int itype = pfuncs[ifunc].itype[i];
|
||||
if (itype == INT) {
|
||||
if (pfuncs[ifunc].ivarflag[i]) {
|
||||
str = input->variable->retrieve(pfuncs[ifunc].svalue[i]);
|
||||
if (!str)
|
||||
error->all(FLERR,"Could not evaluate Python function input variable");
|
||||
pValue = PyInt_FromLong(atoi(str));
|
||||
} else pValue = PyInt_FromLong(pfuncs[ifunc].ivalue[i]);
|
||||
} else if (itype == DOUBLE) {
|
||||
if (pfuncs[ifunc].ivarflag[i]) {
|
||||
str = input->variable->retrieve(pfuncs[ifunc].svalue[i]);
|
||||
if (!str)
|
||||
error->all(FLERR,"Could not evaluate Python function input variable");
|
||||
pValue = PyFloat_FromDouble(atof(str));
|
||||
} else pValue = PyFloat_FromDouble(pfuncs[ifunc].dvalue[i]);
|
||||
} else if (itype == STRING) {
|
||||
if (pfuncs[ifunc].ivarflag[i]) {
|
||||
str = input->variable->retrieve(pfuncs[ifunc].svalue[i]);
|
||||
if (!str)
|
||||
error->all(FLERR,"Could not evaluate Python function input variable");
|
||||
pValue = PyString_FromString(str);
|
||||
} else pValue = PyString_FromString(pfuncs[ifunc].svalue[i]);
|
||||
} else if (itype == PTR) {
|
||||
pValue = PyCObject_FromVoidPtr((void *) lmp,NULL);
|
||||
}
|
||||
PyTuple_SetItem(pArgs,i,pValue);
|
||||
}
|
||||
|
||||
// call the Python function
|
||||
// error check with one() since only some procs may fail
|
||||
|
||||
pValue = PyObject_CallObject(pFunc,pArgs);
|
||||
if (!pValue) error->one(FLERR,"Python function evaluation failed");
|
||||
Py_DECREF(pArgs);
|
||||
|
||||
// function returned a value
|
||||
// assign it to result string stored by python-style variable
|
||||
|
||||
if (pfuncs[ifunc].noutput) {
|
||||
int otype = pfuncs[ifunc].otype;
|
||||
if (otype == INT) {
|
||||
sprintf(result,"%ld",PyInt_AsLong(pValue));
|
||||
} else if (otype == DOUBLE) {
|
||||
sprintf(result,"%.15g",PyFloat_AsDouble(pValue));
|
||||
} else if (otype == STRING) {
|
||||
char *pystr = PyString_AsString(pValue);
|
||||
strncpy(result,pystr,VALUELENGTH-1);
|
||||
}
|
||||
Py_DECREF(pValue);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int Python::find(char *name)
|
||||
{
|
||||
for (int i = 0; i < nfunc; i++)
|
||||
if (strcmp(name,pfuncs[i].name) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int Python::variable_match(char *name, char *varname, int numeric)
|
||||
{
|
||||
int ifunc = find(name);
|
||||
if (ifunc < 0) return -1;
|
||||
if (pfuncs[ifunc].noutput == 0) return -1;
|
||||
if (strcmp(pfuncs[ifunc].ovarname,varname) != 0) return -1;
|
||||
if (numeric && pfuncs[ifunc].otype == STRING) return -1;
|
||||
return ifunc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int Python::create_entry(char *name)
|
||||
{
|
||||
// ifunc = index to entry by name in pfuncs vector, can be old or new
|
||||
// free old vectors if overwriting old pfunc
|
||||
|
||||
int ifunc = find(name);
|
||||
|
||||
if (ifunc < 0) {
|
||||
ifunc = nfunc;
|
||||
nfunc++;
|
||||
pfuncs = (PyFunc *)
|
||||
memory->srealloc(pfuncs,nfunc*sizeof(struct PyFunc),"python:pfuncs");
|
||||
int n = strlen(name) + 1;
|
||||
pfuncs[ifunc].name = new char[n];
|
||||
strcpy(pfuncs[ifunc].name,name);
|
||||
} else deallocate(ifunc);
|
||||
|
||||
pfuncs[ifunc].ninput = ninput;
|
||||
pfuncs[ifunc].noutput = noutput;
|
||||
|
||||
if (!format && ninput+noutput)
|
||||
error->all(FLERR,"Invalid python command");
|
||||
else if (format && strlen(format) != ninput+noutput)
|
||||
error->all(FLERR,"Invalid python command");
|
||||
|
||||
// process inputs as values or variables
|
||||
|
||||
pfuncs[ifunc].itype = new int[ninput];
|
||||
pfuncs[ifunc].ivarflag = new int[ninput];
|
||||
pfuncs[ifunc].ivalue = new int[ninput];
|
||||
pfuncs[ifunc].dvalue = new double[ninput];
|
||||
pfuncs[ifunc].svalue = new char*[ninput];
|
||||
|
||||
for (int i = 0; i < ninput; i++) {
|
||||
pfuncs[ifunc].svalue[i] = NULL;
|
||||
char type = format[i];
|
||||
if (type == 'i') {
|
||||
pfuncs[ifunc].itype[i] = INT;
|
||||
if (strstr(istr[i],"v_") == istr[i]) {
|
||||
pfuncs[ifunc].ivarflag[i] = 1;
|
||||
int n = strlen(&istr[i][2]) + 1;
|
||||
pfuncs[ifunc].svalue[i] = new char[n];
|
||||
strcpy(pfuncs[ifunc].svalue[i],&istr[i][2]);
|
||||
} else {
|
||||
pfuncs[ifunc].ivarflag[i] = 0;
|
||||
pfuncs[ifunc].ivalue[i] = force->inumeric(FLERR,istr[i]);
|
||||
}
|
||||
} else if (type == 'f') {
|
||||
pfuncs[ifunc].itype[i] = DOUBLE;
|
||||
if (strstr(istr[i],"v_") == istr[i]) {
|
||||
pfuncs[ifunc].ivarflag[i] = 1;
|
||||
int n = strlen(&istr[i][2]) + 1;
|
||||
pfuncs[ifunc].svalue[i] = new char[n];
|
||||
strcpy(pfuncs[ifunc].svalue[i],&istr[i][2]);
|
||||
} else {
|
||||
pfuncs[ifunc].ivarflag[i] = 0;
|
||||
pfuncs[ifunc].dvalue[i] = force->numeric(FLERR,istr[i]);
|
||||
}
|
||||
} else if (type == 's') {
|
||||
pfuncs[ifunc].itype[i] = STRING;
|
||||
if (strstr(istr[i],"v_") == istr[i]) {
|
||||
pfuncs[ifunc].ivarflag[i] = 1;
|
||||
int n = strlen(&istr[i][2]) + 1;
|
||||
pfuncs[ifunc].svalue[i] = new char[n];
|
||||
strcpy(pfuncs[ifunc].svalue[i],&istr[i][2]);
|
||||
} else {
|
||||
pfuncs[ifunc].ivarflag[i] = 0;
|
||||
int n = strlen(istr[i]) + 1;
|
||||
pfuncs[ifunc].svalue[i] = new char[n];
|
||||
strcpy(pfuncs[ifunc].svalue[i],istr[i]);
|
||||
}
|
||||
} else if (type == 'p') {
|
||||
pfuncs[ifunc].ivarflag[i] = 0;
|
||||
pfuncs[ifunc].itype[i] = PTR;
|
||||
if (strcmp(istr[i],"SELF") != 0)
|
||||
error->all(FLERR,"Invalid python command");
|
||||
|
||||
} else error->all(FLERR,"Invalid python command");
|
||||
}
|
||||
|
||||
// process output as value or variable
|
||||
|
||||
pfuncs[ifunc].ovarname = NULL;
|
||||
if (!noutput) return ifunc;
|
||||
|
||||
char type = format[ninput];
|
||||
if (type == 'i') pfuncs[ifunc].otype = INT;
|
||||
else if (type == 'f') pfuncs[ifunc].otype = DOUBLE;
|
||||
else if (type == 's') pfuncs[ifunc].otype = STRING;
|
||||
else error->all(FLERR,"Invalid python command");
|
||||
|
||||
if (strstr(ostr,"v_") != ostr) error->all(FLERR,"Invalid python command");
|
||||
int n = strlen(&ostr[2]) + 1;
|
||||
pfuncs[ifunc].ovarname = new char[n];
|
||||
strcpy(pfuncs[ifunc].ovarname,&ostr[2]);
|
||||
|
||||
return ifunc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void Python::deallocate(int i)
|
||||
{
|
||||
delete [] pfuncs[i].itype;
|
||||
delete [] pfuncs[i].ivarflag;
|
||||
delete [] pfuncs[i].ivalue;
|
||||
delete [] pfuncs[i].dvalue;
|
||||
for (int j = 0; j < pfuncs[i].ninput; j++)
|
||||
delete [] pfuncs[i].svalue[j];
|
||||
delete [] pfuncs[i].svalue;
|
||||
delete [] pfuncs[i].ovarname;
|
||||
}
|
||||
59
src/PYTHON/python.h
Normal file
59
src/PYTHON/python.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LMP_PYTHON_H
|
||||
#define LMP_PYTHON_H
|
||||
|
||||
#include "pointers.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class Python : protected Pointers {
|
||||
public:
|
||||
int python_exists;
|
||||
|
||||
Python(class LAMMPS *);
|
||||
~Python();
|
||||
void command(int, char **);
|
||||
void invoke_function(int, char *);
|
||||
int find(char *);
|
||||
int variable_match(char *, char *, int);
|
||||
|
||||
private:
|
||||
int ninput,noutput;
|
||||
char **istr;
|
||||
char *ostr,*format;
|
||||
void *pyMain;
|
||||
|
||||
struct PyFunc {
|
||||
char *name;
|
||||
int ninput,noutput;
|
||||
int *itype,*ivarflag;
|
||||
int *ivalue;
|
||||
double *dvalue;
|
||||
char **svalue;
|
||||
int otype;
|
||||
char *ovarname;
|
||||
void *pFunc;
|
||||
};
|
||||
|
||||
PyFunc *pfuncs;
|
||||
int nfunc;
|
||||
|
||||
int create_entry(char *);
|
||||
void deallocate(int);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
142
src/input.cpp
142
src/input.cpp
@ -161,17 +161,33 @@ void Input::file()
|
||||
m = 0;
|
||||
while (1) {
|
||||
if (maxline-m < 2) reallocate(line,maxline,0);
|
||||
|
||||
// end of file reached, so break
|
||||
// n == 0 if nothing read, else n = line with str terminator
|
||||
|
||||
if (fgets(&line[m],maxline-m,infile) == NULL) {
|
||||
if (m) n = strlen(line) + 1;
|
||||
else n = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// continue if last char read was not a newline
|
||||
// could happen if line is very long
|
||||
|
||||
m = strlen(line);
|
||||
if (line[m-1] != '\n') continue;
|
||||
|
||||
// continue reading if final printable char is & char
|
||||
// or if odd number of triple quotes
|
||||
// else break with n = line with str terminator
|
||||
|
||||
m--;
|
||||
while (m >= 0 && isspace(line[m])) m--;
|
||||
if (m < 0 || line[m] != '&') {
|
||||
if (numtriple(line) % 2) {
|
||||
m += 2;
|
||||
continue;
|
||||
}
|
||||
line[m+1] = '\0';
|
||||
n = m+2;
|
||||
break;
|
||||
@ -302,11 +318,11 @@ char *Input::one(const char *single)
|
||||
/* ----------------------------------------------------------------------
|
||||
parse copy of command line by inserting string terminators
|
||||
strip comment = all chars from # on
|
||||
replace all $ via variable substitution
|
||||
replace all $ via variable substitution except within quotes
|
||||
command = first word
|
||||
narg = # of args
|
||||
arg[] = individual args
|
||||
treat text between single/double quotes as one arg
|
||||
treat text between single/double/triple quotes as one arg via nextword()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Input::parse()
|
||||
@ -318,17 +334,32 @@ void Input::parse()
|
||||
strcpy(copy,line);
|
||||
|
||||
// strip any # comment by replacing it with 0
|
||||
// do not strip # inside single/double quotes
|
||||
// do not strip from a # inside single/double/triple quotes
|
||||
// quoteflag = 1,2,3 when encounter first single/double,triple quote
|
||||
// quoteflag = 0 when encounter matching single/double,triple quote
|
||||
|
||||
char quote = '\0';
|
||||
int quoteflag = 0;
|
||||
char *ptr = copy;
|
||||
while (*ptr) {
|
||||
if (*ptr == '#' && !quote) {
|
||||
if (*ptr == '#' && !quoteflag) {
|
||||
*ptr = '\0';
|
||||
break;
|
||||
}
|
||||
if (*ptr == quote) quote = '\0';
|
||||
else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
|
||||
if (quoteflag == 0) {
|
||||
if (strstr(ptr,"\"\"\"") == ptr) {
|
||||
quoteflag = 3;
|
||||
ptr += 2;
|
||||
}
|
||||
else if (*ptr == '"') quoteflag = 2;
|
||||
else if (*ptr == '\'') quoteflag = 1;
|
||||
} else {
|
||||
if (quoteflag == 3 && strstr(ptr,"\"\"\"") == ptr) {
|
||||
quoteflag = 0;
|
||||
ptr += 2;
|
||||
}
|
||||
else if (quoteflag == 2 && *ptr == '"') quoteflag = 0;
|
||||
else if (quoteflag == 1 && *ptr == '\'') quoteflag = 0;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
@ -345,7 +376,7 @@ void Input::parse()
|
||||
|
||||
// point arg[] at each subsequent arg in copy string
|
||||
// nextword() inserts string terminators into copy string to delimit args
|
||||
// nextword() treats text between single/double quotes as one arg
|
||||
// nextword() treats text between single/double/triple quotes as one arg
|
||||
|
||||
narg = 0;
|
||||
ptr = next;
|
||||
@ -365,31 +396,53 @@ void Input::parse()
|
||||
find next word in str
|
||||
insert 0 at end of word
|
||||
ignore leading whitespace
|
||||
treat text between single/double quotes as one arg
|
||||
treat text between single/double/triple quotes as one arg
|
||||
matching quote must be followed by whitespace char if not end of string
|
||||
strip quotes from returned word
|
||||
return ptr to start of word
|
||||
return next = ptr after word or NULL if word ended with 0
|
||||
return NULL if no word in string
|
||||
return ptr to start of word or NULL if no word in string
|
||||
also return next = ptr after word
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
char *Input::nextword(char *str, char **next)
|
||||
{
|
||||
char *start,*stop;
|
||||
|
||||
// start = first non-whitespace char
|
||||
|
||||
start = &str[strspn(str," \t\n\v\f\r")];
|
||||
if (*start == '\0') return NULL;
|
||||
|
||||
if (*start == '"' || *start == '\'') {
|
||||
// if start is single/double/triple quote:
|
||||
// start = first char beyond quote
|
||||
// stop = first char of matching quote
|
||||
// next = first char beyond matching quote
|
||||
// next must be NULL or whitespace
|
||||
// if start is not single/double/triple quote:
|
||||
// stop = first whitespace char after start
|
||||
// next = char after stop, or stop itself if stop is NULL
|
||||
|
||||
if (strstr(start,"\"\"\"") == start) {
|
||||
stop = strstr(&start[3],"\"\"\"");
|
||||
if (!stop) error->all(FLERR,"Unbalanced quotes in input line");
|
||||
start += 3;
|
||||
*next = stop+3;
|
||||
if (**next && !isspace(**next))
|
||||
error->all(FLERR,"Input line quote not followed by whitespace");
|
||||
} else if (*start == '"' || *start == '\'') {
|
||||
stop = strchr(&start[1],*start);
|
||||
if (!stop) error->all(FLERR,"Unbalanced quotes in input line");
|
||||
if (stop[1] && !isspace(stop[1]))
|
||||
error->all(FLERR,"Input line quote not followed by whitespace");
|
||||
start++;
|
||||
} else stop = &start[strcspn(start," \t\n\v\f\r")];
|
||||
|
||||
if (*stop == '\0') *next = NULL;
|
||||
*next = stop+1;
|
||||
if (**next && !isspace(**next))
|
||||
error->all(FLERR,"Input line quote not followed by whitespace");
|
||||
} else {
|
||||
stop = &start[strcspn(start," \t\n\v\f\r")];
|
||||
if (*stop == '\0') *next = stop;
|
||||
else *next = stop+1;
|
||||
}
|
||||
|
||||
// set stop to NULL to terminate word
|
||||
|
||||
*stop = '\0';
|
||||
return start;
|
||||
}
|
||||
@ -405,7 +458,7 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
{
|
||||
// use str2 as scratch space to expand str, then copy back to str
|
||||
// reallocate str and str2 as necessary
|
||||
// do not replace $ inside single/double quotes
|
||||
// do not replace $ inside single/double/triple quotes
|
||||
// var = pts at variable name, ended by NULL
|
||||
// if $ is followed by '{', trailing '}' becomes NULL
|
||||
// else $x becomes x followed by NULL
|
||||
@ -414,7 +467,7 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
int i,n,paren_count;
|
||||
char immediate[256];
|
||||
char *var,*value,*beyond;
|
||||
char quote = '\0';
|
||||
int quoteflag = 0;
|
||||
char *ptr = str;
|
||||
|
||||
n = strlen(str) + 1;
|
||||
@ -423,9 +476,10 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
char *ptr2 = str2;
|
||||
|
||||
while (*ptr) {
|
||||
|
||||
// variable substitution
|
||||
|
||||
if (*ptr == '$' && !quote) {
|
||||
if (*ptr == '$' && !quoteflag) {
|
||||
|
||||
// value = ptr to expanded variable
|
||||
// variable name between curly braces, e.g. ${a}
|
||||
@ -494,8 +548,27 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*ptr == quote) quote = '\0';
|
||||
else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
|
||||
// quoteflag = 1,2,3 when encounter first single/double,triple quote
|
||||
// quoteflag = 0 when encounter matching single/double,triple quote
|
||||
// copy 2 extra triple quote chars into str2
|
||||
|
||||
if (quoteflag == 0) {
|
||||
if (strstr(ptr,"\"\"\"") == ptr) {
|
||||
quoteflag = 3;
|
||||
*ptr2++ = *ptr++;
|
||||
*ptr2++ = *ptr++;
|
||||
}
|
||||
else if (*ptr == '"') quoteflag = 2;
|
||||
else if (*ptr == '\'') quoteflag = 1;
|
||||
} else {
|
||||
if (quoteflag == 3 && strstr(ptr,"\"\"\"") == ptr) {
|
||||
quoteflag = 0;
|
||||
*ptr2++ = *ptr++;
|
||||
*ptr2++ = *ptr++;
|
||||
}
|
||||
else if (quoteflag == 2 && *ptr == '"') quoteflag = 0;
|
||||
else if (quoteflag == 1 && *ptr == '\'') quoteflag = 0;
|
||||
}
|
||||
|
||||
// copy current character into str2
|
||||
|
||||
@ -510,6 +583,21 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
|
||||
strcpy(str,str2);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return number of triple quotes in line
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Input::numtriple(char *line)
|
||||
{
|
||||
int count = 0;
|
||||
char *ptr = line;
|
||||
while ((ptr = strstr(ptr,"\"\"\""))) {
|
||||
ptr += 3;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
rellocate a string
|
||||
if n > 0: set max >= n in increments of DELTALINE
|
||||
@ -544,6 +632,7 @@ int Input::execute_command()
|
||||
else if (!strcmp(command,"next")) next_command();
|
||||
else if (!strcmp(command,"partition")) partition();
|
||||
else if (!strcmp(command,"print")) print();
|
||||
else if (!strcmp(command,"python")) python();
|
||||
else if (!strcmp(command,"quit")) quit();
|
||||
else if (!strcmp(command,"shell")) shell();
|
||||
else if (!strcmp(command,"variable")) variable_command();
|
||||
@ -980,6 +1069,13 @@ void Input::print()
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void Input::python()
|
||||
{
|
||||
variable->python_command(narg,arg);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void Input::quit()
|
||||
{
|
||||
if (narg) error->all(FLERR,"Illegal quit command");
|
||||
|
||||
@ -58,6 +58,7 @@ class Input : protected Pointers {
|
||||
|
||||
void parse(); // parse an input text line
|
||||
char *nextword(char *, char **); // find next word in string with quotes
|
||||
int numtriple(char *); // count number of triple quotes
|
||||
void reallocate(char *&, int &, int); // reallocate a char string
|
||||
int execute_command(); // execute a single command
|
||||
|
||||
@ -71,6 +72,7 @@ class Input : protected Pointers {
|
||||
void next_command();
|
||||
void partition();
|
||||
void print();
|
||||
void python();
|
||||
void quit();
|
||||
void shell();
|
||||
void variable_command();
|
||||
|
||||
@ -357,6 +357,19 @@ void *lammps_extract_variable(void *ptr, char *name, char *group)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set the value of a STRING variable to str
|
||||
return -1 if variable doesn't exist or not a STRING variable
|
||||
return 0 for success
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int lammps_set_variable(void *ptr, char *name, char *str)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) ptr;
|
||||
int err = lmp->input->variable->set_string(name,str);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return the total number of atoms in the system
|
||||
useful before call to lammps_get_atoms() so can pre-allocate vector
|
||||
@ -365,6 +378,7 @@ void *lammps_extract_variable(void *ptr, char *name, char *group)
|
||||
int lammps_get_natoms(void *ptr)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) ptr;
|
||||
|
||||
if (lmp->atom->natoms > MAXSMALLINT) return 0;
|
||||
int natoms = static_cast<int> (lmp->atom->natoms);
|
||||
return natoms;
|
||||
|
||||
@ -37,6 +37,7 @@ void *lammps_extract_compute(void *, char *, int, int);
|
||||
void *lammps_extract_fix(void *, char *, int, int, int, int);
|
||||
void *lammps_extract_variable(void *, char *, char *);
|
||||
|
||||
int lammps_set_variable(void *, char *, char *);
|
||||
int lammps_get_natoms(void *);
|
||||
void lammps_gather_atoms(void *, char *, int, int, void *);
|
||||
void lammps_scatter_atoms(void *, char *, int, int, void *);
|
||||
|
||||
47
src/python_wrapper.h
Normal file
47
src/python_wrapper.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LMP_PYTHON_WRAPPER_H
|
||||
#define LMP_PYTHON_WRAPPER_H
|
||||
|
||||
// true interface to embedded Python
|
||||
// used when PYTHON package is installed
|
||||
|
||||
#ifdef LMP_PYTHON
|
||||
|
||||
#include "python.h"
|
||||
|
||||
#else
|
||||
|
||||
// dummy interface to PYTHON
|
||||
// needed for compiling when PYTHON is not installed
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class Python {
|
||||
public:
|
||||
int python_exists;
|
||||
|
||||
Python(class LAMMPS *) {python_exists = 0;}
|
||||
~Python() {}
|
||||
void command(int, char **) {}
|
||||
void invoke_function(int, char *) {}
|
||||
int find(char *) {return -1;}
|
||||
int variable_match(char *, char *, int) {return -1;}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
236
src/variable.cpp
236
src/variable.cpp
@ -28,14 +28,15 @@
|
||||
#include "compute.h"
|
||||
#include "fix.h"
|
||||
#include "fix_store.h"
|
||||
#include "force.h"
|
||||
#include "output.h"
|
||||
#include "thermo.h"
|
||||
#include "random_mars.h"
|
||||
#include "math_const.h"
|
||||
#include "atom_masks.h"
|
||||
#include "python_wrapper.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
@ -44,13 +45,13 @@ using namespace MathConst;
|
||||
#define MAXLEVEL 4
|
||||
#define MAXLINE 256
|
||||
#define CHUNK 1024
|
||||
#define VALUELENGTH 64
|
||||
#define VALUELENGTH 64 // also in python.cpp
|
||||
#define MAXFUNCARG 6
|
||||
|
||||
#define MYROUND(a) (( a-floor(a) ) >= .5) ? ceil(a) : floor(a)
|
||||
|
||||
enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,GETENV,
|
||||
SCALARFILE,ATOMFILE,FORMAT,EQUAL,ATOM};
|
||||
SCALARFILE,ATOMFILE,FORMAT,EQUAL,ATOM,PYTHON};
|
||||
enum{ARG,OP};
|
||||
|
||||
// customize by adding a function
|
||||
@ -106,6 +107,10 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
|
||||
precedence[MULTIPLY] = precedence[DIVIDE] = precedence[MODULO] = 6;
|
||||
precedence[CARAT] = 7;
|
||||
precedence[UNARY] = precedence[NOT] = 8;
|
||||
|
||||
// Python wrapper, real or dummy
|
||||
|
||||
python = new Python(lmp);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -131,6 +136,8 @@ Variable::~Variable()
|
||||
|
||||
delete randomequal;
|
||||
delete randomatom;
|
||||
|
||||
delete python;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -413,9 +420,36 @@ void Variable::set(int narg, char **arg)
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
}
|
||||
|
||||
// PYTHON
|
||||
// replace pre-existing var if also style PYTHON (allows it to be reset)
|
||||
// num = 2, which = 1st value
|
||||
// data = 2 values, 1st is Python func to invoke, 2nd is filled by invoke
|
||||
|
||||
} else if (strcmp(arg[1],"python") == 0) {
|
||||
if (narg != 3) error->all(FLERR,"Illegal variable command");
|
||||
if (!python->python_exists)
|
||||
error->all(FLERR,"LAMMPS is not built with Python embedded");
|
||||
int ivar = find(arg[0]);
|
||||
if (ivar >= 0) {
|
||||
if (style[ivar] != PYTHON)
|
||||
error->all(FLERR,"Cannot redefine variable as a different style");
|
||||
delete [] data[ivar][0];
|
||||
copy(1,&arg[2],data[ivar]);
|
||||
replaceflag = 1;
|
||||
} else {
|
||||
if (nvar == maxvar) grow();
|
||||
style[nvar] = PYTHON;
|
||||
num[nvar] = 2;
|
||||
which[nvar] = 1;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
data[nvar][1] = new char[VALUELENGTH];
|
||||
}
|
||||
|
||||
} else error->all(FLERR,"Illegal variable command");
|
||||
|
||||
// set name of variable, if not replacing (STRING/EQUAL/ATOM)
|
||||
// set name of variable, if not replacing (EQUAL/ATOM/STRING/PYTHON)
|
||||
// name must be all alphanumeric chars or underscores
|
||||
|
||||
if (replaceflag) return;
|
||||
@ -446,6 +480,23 @@ void Variable::set(char *name, int narg, char **arg)
|
||||
delete [] newarg;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set existing STRING variable to str
|
||||
return 0 if successful
|
||||
return -1 if variable doesn't exist or isn't a STRING variable
|
||||
called via library interface, so external programs can set variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::set_string(char *name, char *str)
|
||||
{
|
||||
int ivar = find(name);
|
||||
if (ivar < 0) return -1;
|
||||
if (style[ivar] != STRING) return -1;
|
||||
delete [] data[ivar][0];
|
||||
copy(1,&str,data[ivar]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
increment variable(s)
|
||||
return 0 if OK if successfully incremented
|
||||
@ -470,11 +521,12 @@ int Variable::next(int narg, char **arg)
|
||||
error->all(FLERR,"All variables in next command must be same style");
|
||||
}
|
||||
|
||||
// invalid styles STRING or EQUAL or WORLD or ATOM or GETENV or FORMAT
|
||||
// invalid styles: STRING, EQUAL, WORLD, ATOM, GETENV, FORMAT, PYTHON
|
||||
|
||||
int istyle = style[find(arg[0])];
|
||||
if (istyle == STRING || istyle == EQUAL || istyle == WORLD
|
||||
|| istyle == GETENV || istyle == ATOM || istyle == FORMAT)
|
||||
if (istyle == STRING || istyle == EQUAL || istyle == WORLD ||
|
||||
istyle == GETENV || istyle == ATOM || istyle == FORMAT ||
|
||||
istyle == PYTHON)
|
||||
error->all(FLERR,"Invalid variable style with next command");
|
||||
|
||||
// if istyle = UNIVERSE or ULOOP, insure all such variables are incremented
|
||||
@ -587,16 +639,96 @@ int Variable::next(int narg, char **arg)
|
||||
return flag;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
search for name in list of variables names
|
||||
return index or -1 if not found
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::find(char *name)
|
||||
{
|
||||
for (int i = 0; i < nvar; i++)
|
||||
if (strcmp(name,names[i]) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
initialize one atom's storage values in all VarReaders via fix STORE
|
||||
called when atom is created
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::set_arrays(int i)
|
||||
{
|
||||
for (int i = 0; i < nvar; i++)
|
||||
if (reader[i] && style[i] == ATOMFILE)
|
||||
reader[i]->fixstore->vstore[i] = 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
called by python command in input script
|
||||
simply pass input script line args to Python class
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::python_command(int narg, char **arg)
|
||||
{
|
||||
if (!python->python_exists)
|
||||
error->all(FLERR,"LAMMPS is not built with Python embedded");
|
||||
python->command(narg,arg);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return 1 if variable is EQUAL or PYTHON numeric style, 0 if not
|
||||
this is checked before call to compute_equal() to return a double
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::equalstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == EQUAL) return 1;
|
||||
if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->variable_match(data[ivar][0],names[ivar],1);
|
||||
if (ifunc < 0) return 0;
|
||||
else return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return 1 if variable is ATOM or ATOMFILE style, 0 if not
|
||||
this is checked before call to compute_atom() to return a vector of doubles
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::atomstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == ATOM || style[ivar] == ATOMFILE) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
check if variable with name is PYTHON and matches funcname
|
||||
called by Python class before it invokes a Python function
|
||||
return data storage so Python function can return a value for this variable
|
||||
return NULL if not a match
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
char *Variable::pythonstyle(char *name, char *funcname)
|
||||
{
|
||||
int ivar = find(name);
|
||||
if (ivar == -1) return NULL;
|
||||
if (style[ivar] != PYTHON) return NULL;
|
||||
if (strcmp(data[ivar][0],funcname) != 0) return NULL;
|
||||
return data[ivar][1];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return ptr to the data text associated with a variable
|
||||
if INDEX or WORLD or UNIVERSE or STRING or SCALARFILE var,
|
||||
if INDEX or WORLD or UNIVERSE or STRING or SCALARFILE,
|
||||
return ptr to stored string
|
||||
if LOOP or ULOOP var, write int to data[0] and return ptr to string
|
||||
if EQUAL var, evaluate variable and put result in str
|
||||
if FORMAT var, evaluate its variable and put formatted result in str
|
||||
if GETENV var, query environment and put result in str
|
||||
if ATOM or ATOMFILE var, return NULL
|
||||
return NULL if no variable with name or which value is bad,
|
||||
if LOOP or ULOOP, write int to data[0] and return ptr to string
|
||||
if EQUAL, evaluate variable and put result in str
|
||||
if FORMAT, evaluate its variable and put formatted result in str
|
||||
if GETENV, query environment and put result in str
|
||||
if PYTHON, evaluate Python function, it will put result in str
|
||||
if ATOM or ATOMFILE, return NULL
|
||||
return NULL if no variable with name, or which value is bad,
|
||||
caller must respond
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -606,6 +738,10 @@ char *Variable::retrieve(char *name)
|
||||
if (ivar == -1) return NULL;
|
||||
if (which[ivar] >= num[ivar]) return NULL;
|
||||
|
||||
if (eval_in_progress[ivar])
|
||||
error->all(FLERR,"Variable has circular dependency");
|
||||
eval_in_progress[ivar] = 1;
|
||||
|
||||
char *str;
|
||||
if (style[ivar] == INDEX || style[ivar] == WORLD ||
|
||||
style[ivar] == UNIVERSE || style[ivar] == STRING ||
|
||||
@ -625,16 +761,14 @@ char *Variable::retrieve(char *name)
|
||||
strcpy(data[ivar][0],result);
|
||||
str = data[ivar][0];
|
||||
} else if (style[ivar] == EQUAL) {
|
||||
eval_in_progress[ivar] = 1;
|
||||
double answer = evaluate(data[ivar][0],NULL);
|
||||
eval_in_progress[ivar] = 0;
|
||||
sprintf(data[ivar][1],"%.15g",answer);
|
||||
str = data[ivar][1];
|
||||
} else if (style[ivar] == FORMAT) {
|
||||
int jvar = find(data[ivar][0]);
|
||||
if (jvar == -1) return NULL;
|
||||
if (!equalstyle(jvar)) return NULL;
|
||||
double answer = evaluate(data[jvar][0],NULL);
|
||||
double answer = compute_equal(jvar);
|
||||
sprintf(data[ivar][2],data[ivar][1],answer);
|
||||
str = data[ivar][2];
|
||||
} else if (style[ivar] == GETENV) {
|
||||
@ -647,13 +781,24 @@ char *Variable::retrieve(char *name)
|
||||
}
|
||||
strcpy(data[ivar][1],result);
|
||||
str = data[ivar][1];
|
||||
} else if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->variable_match(data[ivar][0],names[ivar],0);
|
||||
if (ifunc < 0)
|
||||
error->all(FLERR,"Python variable does not match Python function");
|
||||
python->invoke_function(ifunc,data[ivar][1]);
|
||||
str = data[ivar][1];
|
||||
} else if (style[ivar] == ATOM || style[ivar] == ATOMFILE) return NULL;
|
||||
|
||||
eval_in_progress[ivar] = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return result of equal-style variable evaluation
|
||||
can be EQUAL style or PYTHON numeric style
|
||||
for PYTHON, don't need to check python->variable_match() error return,
|
||||
since caller will have already checked via equalstyle()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double Variable::compute_equal(int ivar)
|
||||
@ -662,7 +807,14 @@ double Variable::compute_equal(int ivar)
|
||||
error->all(FLERR,"Variable has circular dependency");
|
||||
eval_in_progress[ivar] = 1;
|
||||
|
||||
double value = evaluate(data[ivar][0],NULL);
|
||||
double value;
|
||||
if (style[ivar] == EQUAL) value = evaluate(data[ivar][0],NULL);
|
||||
else if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->find(data[ivar][0]);
|
||||
if (ifunc < 0) error->all(FLERR,"Python variable has no function");
|
||||
python->invoke_function(ifunc,data[ivar][1]);
|
||||
value = atof(data[ivar][1]);
|
||||
}
|
||||
|
||||
eval_in_progress[ivar] = 0;
|
||||
return value;
|
||||
@ -671,6 +823,7 @@ double Variable::compute_equal(int ivar)
|
||||
/* ----------------------------------------------------------------------
|
||||
return result of immediate equal-style variable evaluation
|
||||
called from Input::substitute()
|
||||
don't need to flag eval_in_progress since is an immediate variable
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double Variable::compute_equal(char *str)
|
||||
@ -744,54 +897,11 @@ void Variable::compute_atom(int ivar, int igroup,
|
||||
eval_in_progress[ivar] = 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
search for name in list of variables names
|
||||
return index or -1 if not found
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::find(char *name)
|
||||
{
|
||||
for (int i = 0; i < nvar; i++)
|
||||
if (strcmp(name,names[i]) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
initialize one atom's storage values in all VarReaders via fix STORE
|
||||
called when atom is created
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::set_arrays(int i)
|
||||
{
|
||||
for (int i = 0; i < nvar; i++)
|
||||
if (reader[i] && style[i] == ATOMFILE)
|
||||
reader[i]->fixstore->vstore[i] = 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return 1 if variable is EQUAL style, 0 if not
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::equalstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == EQUAL) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return 1 if variable is ATOM or ATOMFILE style, 0 if not
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::atomstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == ATOM || style[ivar] == ATOMFILE) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
save copy of EQUAL style ivar formula in copy
|
||||
allocate copy here, later equal_restore() call will free it
|
||||
insure data[ivar][0] is of VALUELENGTH since will be overridden
|
||||
next 3 functions are used by create_atoms to temporarily override variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Variable::equal_save(int ivar, char *©)
|
||||
@ -2712,8 +2822,6 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow)
|
||||
int ivar = find(id);
|
||||
if (ivar < 0)
|
||||
error->all(FLERR,"Invalid variable name in variable formula");
|
||||
if (eval_in_progress[ivar])
|
||||
error->all(FLERR,"Variable has circular dependency");
|
||||
|
||||
char *var = retrieve(id);
|
||||
if (var == NULL)
|
||||
|
||||
@ -25,11 +25,17 @@ class Variable : protected Pointers {
|
||||
~Variable();
|
||||
void set(int, char **);
|
||||
void set(char *, int, char **);
|
||||
int set_string(char *, char *);
|
||||
int next(int, char **);
|
||||
|
||||
int find(char *);
|
||||
void set_arrays(int);
|
||||
void python_command(int, char **);
|
||||
|
||||
int equalstyle(int);
|
||||
int atomstyle(int);
|
||||
char *pythonstyle(char *, char *);
|
||||
|
||||
char *retrieve(char *);
|
||||
double compute_equal(int);
|
||||
double compute_equal(char *);
|
||||
@ -64,6 +70,8 @@ class Variable : protected Pointers {
|
||||
int precedence[17]; // precedence level of math operators
|
||||
// set length to include up to OR in enum
|
||||
|
||||
class Python *python; // ptr to embedded Python interpreter
|
||||
|
||||
struct Tree { // parse tree for atom-style variables
|
||||
double value; // single scalar
|
||||
double *array; // per-atom or per-type list of doubles
|
||||
@ -78,6 +86,7 @@ class Variable : protected Pointers {
|
||||
Tree **extra; // ptrs further down tree for nextra args
|
||||
};
|
||||
|
||||
int compute_python(int);
|
||||
void remove(int);
|
||||
void grow();
|
||||
void copy(int, char **, char **);
|
||||
|
||||
@ -1 +1 @@
|
||||
#define LAMMPS_VERSION "12 Mar 2015"
|
||||
#define LAMMPS_VERSION "14 Mar 2015"
|
||||
|
||||
Reference in New Issue
Block a user